257 size_t size, offset; |
257 size_t size, offset; |
258 unsigned long i; |
258 unsigned long i; |
259 uint_t attr; |
259 uint_t attr; |
260 page_t *pp; |
260 page_t *pp; |
261 extern struct memlist *virt_avail; |
261 extern struct memlist *virt_avail; |
|
262 char buf[256]; |
262 |
263 |
263 ttep = &tte; |
264 ttep = &tte; |
264 for (i = 0, promt = trans_root; i < ntrans_root; i++, promt++) { |
265 for (i = 0, promt = trans_root; i < ntrans_root; i++, promt++) { |
265 ASSERT(promt->tte_hi != 0); |
266 ASSERT(promt->tte_hi != 0); |
266 ASSERT32(promt->virt_hi == 0 && promt->size_hi == 0); |
267 ASSERT32(promt->virt_hi == 0 && promt->size_hi == 0); |
281 /* |
282 /* |
282 * The prom better not use global translations |
283 * The prom better not use global translations |
283 * because a user process might use the same |
284 * because a user process might use the same |
284 * virtual addresses |
285 * virtual addresses |
285 */ |
286 */ |
286 cmn_err(CE_PANIC, "map_prom: global translation"); |
287 prom_panic("sfmmu_map_prom_mappings: global" |
|
288 " translation"); |
287 TTE_SET_LOFLAGS(ttep, TTE_GLB_INT, 0); |
289 TTE_SET_LOFLAGS(ttep, TTE_GLB_INT, 0); |
288 } |
290 } |
289 #endif |
291 #endif |
290 if (TTE_IS_LOCKED(ttep)) { |
292 if (TTE_IS_LOCKED(ttep)) { |
291 /* clear the lock bits */ |
293 /* clear the lock bits */ |
307 /* |
309 /* |
308 * make sure address is not in virt-avail list |
310 * make sure address is not in virt-avail list |
309 */ |
311 */ |
310 if (address_in_memlist(virt_avail, (uint64_t)vaddr, |
312 if (address_in_memlist(virt_avail, (uint64_t)vaddr, |
311 size)) { |
313 size)) { |
312 cmn_err(CE_PANIC, "map_prom: inconsistent " |
314 prom_panic("sfmmu_map_prom_mappings:" |
313 "translation/avail lists"); |
315 " inconsistent translation/avail lists"); |
314 } |
316 } |
315 |
317 |
316 pfn = basepfn + mmu_btop(offset); |
318 pfn = basepfn + mmu_btop(offset); |
317 if (pf_is_memory(pfn)) { |
319 if (pf_is_memory(pfn)) { |
318 if (attr & SFMMU_UNCACHEPTTE) { |
320 if (attr & SFMMU_UNCACHEPTTE) { |
319 cmn_err(CE_PANIC, "map_prom: " |
321 prom_panic("sfmmu_map_prom_mappings:" |
320 "uncached prom memory page"); |
322 " uncached prom memory page"); |
321 } |
323 } |
322 } else { |
324 } else { |
323 if (!(attr & SFMMU_SIDEFFECT)) { |
325 if (!(attr & SFMMU_SIDEFFECT)) { |
324 cmn_err(CE_PANIC, "map_prom: prom " |
326 prom_panic("sfmmu_map_prom_mappings:" |
325 "i/o page without side-effect"); |
327 " prom i/o page without" |
|
328 " side-effect"); |
326 } |
329 } |
327 } |
330 } |
328 |
331 |
329 /* |
332 /* |
330 * skip kmem64 area |
333 * skip kmem64 area |
331 */ |
334 */ |
332 if (vaddr >= kmem64_base && |
335 if (vaddr >= kmem64_base && |
333 vaddr < kmem64_aligned_end) { |
336 vaddr < kmem64_aligned_end) { |
334 #if !defined(C_OBP) |
337 #if !defined(C_OBP) |
335 cmn_err(CE_PANIC, |
338 prom_panic("sfmmu_map_prom_mappings:" |
336 "unexpected kmem64 prom mapping\n"); |
339 " unexpected kmem64 prom mapping"); |
337 #else /* !C_OBP */ |
340 #else /* !C_OBP */ |
338 size_t mapsz; |
341 size_t mapsz; |
339 |
342 |
340 if (ptob(pfn) != |
343 if (ptob(pfn) != |
341 kmem64_pabase + (vaddr - kmem64_base)) { |
344 kmem64_pabase + (vaddr - kmem64_base)) { |
342 cmn_err(CE_PANIC, |
345 prom_panic("sfmmu_map_prom_mappings:" |
343 "unexpected kmem64 prom mapping\n"); |
346 " unexpected kmem64 prom mapping"); |
344 } |
347 } |
345 |
348 |
346 mapsz = kmem64_aligned_end - vaddr; |
349 mapsz = kmem64_aligned_end - vaddr; |
347 if (mapsz >= size) { |
350 if (mapsz >= size) { |
348 break; |
351 break; |
361 /* |
364 /* |
362 * mapping already exists. |
365 * mapping already exists. |
363 * Verify they are equal |
366 * Verify they are equal |
364 */ |
367 */ |
365 if (pfn != oldpfn) { |
368 if (pfn != oldpfn) { |
366 cmn_err(CE_PANIC, "map_prom: mapping " |
369 (void) snprintf(buf, sizeof (buf), |
367 "conflict (va=0x%p pfn=%p, " |
370 "sfmmu_map_prom_mappings: mapping" |
368 "oldpfn=%p)", |
371 " conflict (va = 0x%p, pfn = 0x%p," |
369 (void *)vaddr, (void *)pfn, |
372 " oldpfn = 0x%p)", (void *)vaddr, |
370 (void *)oldpfn); |
373 (void *)pfn, (void *)oldpfn); |
|
374 prom_panic(buf); |
371 } |
375 } |
372 size -= MMU_PAGESIZE; |
376 size -= MMU_PAGESIZE; |
373 offset += MMU_PAGESIZE; |
377 offset += MMU_PAGESIZE; |
374 continue; |
378 continue; |
375 } |
379 } |
376 |
380 |
377 pp = page_numtopp_nolock(pfn); |
381 pp = page_numtopp_nolock(pfn); |
378 if ((pp != NULL) && PP_ISFREE((page_t *)pp)) { |
382 if ((pp != NULL) && PP_ISFREE((page_t *)pp)) { |
379 cmn_err(CE_PANIC, "map_prom: " |
383 (void) snprintf(buf, sizeof (buf), |
380 "prom-mapped page (va 0x%p, pfn 0x%p) " |
384 "sfmmu_map_prom_mappings: prom-mapped" |
381 "on free list", (void *)vaddr, (void *)pfn); |
385 " page (va = 0x%p, pfn = 0x%p) on free list", |
|
386 (void *)vaddr, (void *)pfn); |
|
387 prom_panic(buf); |
382 } |
388 } |
383 |
389 |
384 sfmmu_memtte(ttep, pfn, attr, TTE8K); |
390 sfmmu_memtte(ttep, pfn, attr, TTE8K); |
385 sfmmu_tteload(kas.a_hat, ttep, vaddr, pp, |
391 sfmmu_tteload(kas.a_hat, ttep, vaddr, pp, |
386 HAT_LOAD_LOCK | SFMMU_NO_TSBLOAD); |
392 HAT_LOAD_LOCK | SFMMU_NO_TSBLOAD); |