main.c (221869) | main.c (223719) |
---|---|
1/*- 2 * Initial implementation: 3 * Copyright (c) 2001 Robert Drehmel 4 * All rights reserved. 5 * 6 * As long as the above copyright statement and this notice remain 7 * unchanged, you can do what ever you want with this file. 8 */ --- 19 unchanged lines hidden (view full) --- 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#include <sys/cdefs.h> | 1/*- 2 * Initial implementation: 3 * Copyright (c) 2001 Robert Drehmel 4 * All rights reserved. 5 * 6 * As long as the above copyright statement and this notice remain 7 * unchanged, you can do what ever you want with this file. 8 */ --- 19 unchanged lines hidden (view full) --- 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#include <sys/cdefs.h> |
36__FBSDID("$FreeBSD: head/sys/boot/sparc64/loader/main.c 221869 2011-05-14 01:53:38Z attilio $"); | 36__FBSDID("$FreeBSD: head/sys/boot/sparc64/loader/main.c 223719 2011-07-02 11:14:54Z marius $"); |
37 38/* 39 * FreeBSD/sparc64 kernel loader - machine dependent part 40 * 41 * - implements copyin and readin functions that map kernel 42 * pages on demand. The machine independent code does not 43 * know the size of the kernel early enough to pre-enter 44 * TTEs and install just one 4MB mapping seemed to limiting --- 46 unchanged lines hidden (view full) --- 91static struct mmu_ops { 92 void (*tlb_init)(void); 93 int (*mmu_mapin)(vm_offset_t va, vm_size_t len); 94} *mmu_ops; 95 96typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3, 97 void *openfirmware); 98 | 37 38/* 39 * FreeBSD/sparc64 kernel loader - machine dependent part 40 * 41 * - implements copyin and readin functions that map kernel 42 * pages on demand. The machine independent code does not 43 * know the size of the kernel early enough to pre-enter 44 * TTEs and install just one 4MB mapping seemed to limiting --- 46 unchanged lines hidden (view full) --- 91static struct mmu_ops { 92 void (*tlb_init)(void); 93 int (*mmu_mapin)(vm_offset_t va, vm_size_t len); 94} *mmu_ops; 95 96typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3, 97 void *openfirmware); 98 |
99static inline u_long dtlb_get_data_sun4u(u_int); | 99static inline u_long dtlb_get_data_sun4u(u_int, u_int); |
100static int dtlb_enter_sun4u(u_int, u_long data, vm_offset_t); 101static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t); | 100static int dtlb_enter_sun4u(u_int, u_long data, vm_offset_t); 101static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t); |
102static inline u_long itlb_get_data_sun4u(u_int); | 102static inline u_long itlb_get_data_sun4u(u_int, u_int); |
103static int itlb_enter_sun4u(u_int, u_long data, vm_offset_t); 104static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t); 105static void itlb_relocate_locked0_sun4u(void); 106extern vm_offset_t md_load(char *, vm_offset_t *); 107static int sparc64_autoload(void); 108static ssize_t sparc64_readin(const int, vm_offset_t, const size_t); 109static ssize_t sparc64_copyin(const void *, vm_offset_t, size_t); 110static vm_offset_t claim_virt(vm_offset_t, size_t, int); --- 20 unchanged lines hidden (view full) --- 131/* sun4u */ 132struct tlb_entry *dtlb_store; 133struct tlb_entry *itlb_store; 134u_int dtlb_slot; 135u_int itlb_slot; 136static int cpu_impl; 137static u_int dtlb_slot_max; 138static u_int itlb_slot_max; | 103static int itlb_enter_sun4u(u_int, u_long data, vm_offset_t); 104static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t); 105static void itlb_relocate_locked0_sun4u(void); 106extern vm_offset_t md_load(char *, vm_offset_t *); 107static int sparc64_autoload(void); 108static ssize_t sparc64_readin(const int, vm_offset_t, const size_t); 109static ssize_t sparc64_copyin(const void *, vm_offset_t, size_t); 110static vm_offset_t claim_virt(vm_offset_t, size_t, int); --- 20 unchanged lines hidden (view full) --- 131/* sun4u */ 132struct tlb_entry *dtlb_store; 133struct tlb_entry *itlb_store; 134u_int dtlb_slot; 135u_int itlb_slot; 136static int cpu_impl; 137static u_int dtlb_slot_max; 138static u_int itlb_slot_max; |
139static u_int tlb_locked; |
|
139 140static vm_offset_t curkva = 0; 141static vm_offset_t heapva; 142 143static phandle_t root; 144 145/* 146 * Machine dependent structures that the machine independent --- 203 unchanged lines hidden (view full) --- 350 OF_release((void *)heapva, HEAPSZ); 351 352 ((kernel_entry_t *)entry)(mdp, 0, 0, 0, openfirmware); 353 354 panic("%s: exec returned", __func__); 355} 356 357static inline u_long | 140 141static vm_offset_t curkva = 0; 142static vm_offset_t heapva; 143 144static phandle_t root; 145 146/* 147 * Machine dependent structures that the machine independent --- 203 unchanged lines hidden (view full) --- 351 OF_release((void *)heapva, HEAPSZ); 352 353 ((kernel_entry_t *)entry)(mdp, 0, 0, 0, openfirmware); 354 355 panic("%s: exec returned", __func__); 356} 357 358static inline u_long |
358dtlb_get_data_sun4u(u_int slot) | 359dtlb_get_data_sun4u(u_int tlb, u_int slot) |
359{ | 360{ |
361 u_long data, pstate; |
|
360 | 362 |
363 slot = TLB_DAR_SLOT(tlb, slot); |
|
361 /* | 364 /* |
362 * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work 363 * around errata of USIII and beyond. | 365 * We read ASI_DTLB_DATA_ACCESS_REG twice back-to-back in order to 366 * work around errata of USIII and beyond. |
364 */ | 367 */ |
365 (void)ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG); 366 return (ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG)); | 368 pstate = rdpr(pstate); 369 wrpr(pstate, pstate & ~PSTATE_IE, 0); 370 (void)ldxa(slot, ASI_DTLB_DATA_ACCESS_REG); 371 data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG); 372 wrpr(pstate, pstate, 0); 373 return (data); |
367} 368 369static inline u_long | 374} 375 376static inline u_long |
370itlb_get_data_sun4u(u_int slot) | 377itlb_get_data_sun4u(u_int tlb, u_int slot) |
371{ | 378{ |
379 u_long data, pstate; |
|
372 | 380 |
381 slot = TLB_DAR_SLOT(tlb, slot); |
|
373 /* | 382 /* |
374 * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work 375 * around errata of USIII and beyond. | 383 * We read ASI_DTLB_DATA_ACCESS_REG twice back-to-back in order to 384 * work around errata of USIII and beyond. |
376 */ | 385 */ |
377 (void)ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG); 378 return (ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG)); | 386 pstate = rdpr(pstate); 387 wrpr(pstate, pstate & ~PSTATE_IE, 0); 388 (void)ldxa(slot, ASI_ITLB_DATA_ACCESS_REG); 389 data = ldxa(slot, ASI_ITLB_DATA_ACCESS_REG); 390 wrpr(pstate, pstate, 0); 391 return (data); |
379} 380 381static vm_offset_t 382dtlb_va_to_pa_sun4u(vm_offset_t va) 383{ 384 u_long pstate, reg; | 392} 393 394static vm_offset_t 395dtlb_va_to_pa_sun4u(vm_offset_t va) 396{ 397 u_long pstate, reg; |
385 int i; | 398 u_int i, tlb; |
386 387 pstate = rdpr(pstate); 388 wrpr(pstate, pstate & ~PSTATE_IE, 0); 389 for (i = 0; i < dtlb_slot_max; i++) { | 399 400 pstate = rdpr(pstate); 401 wrpr(pstate, pstate & ~PSTATE_IE, 0); 402 for (i = 0; i < dtlb_slot_max; i++) { |
390 reg = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG); | 403 reg = ldxa(TLB_DAR_SLOT(tlb_locked, i), 404 ASI_DTLB_TAG_READ_REG); |
391 if (TLB_TAR_VA(reg) != va) 392 continue; | 405 if (TLB_TAR_VA(reg) != va) 406 continue; |
393 reg = dtlb_get_data_sun4u(i); | 407 reg = dtlb_get_data_sun4u(tlb_locked, i); |
394 wrpr(pstate, pstate, 0); 395 reg >>= TD_PA_SHIFT; 396 if (cpu_impl == CPU_IMPL_SPARC64V || 397 cpu_impl >= CPU_IMPL_ULTRASPARCIII) 398 return (reg & TD_PA_CH_MASK); 399 return (reg & TD_PA_SF_MASK); 400 } 401 wrpr(pstate, pstate, 0); --- 4 unchanged lines hidden (view full) --- 406itlb_va_to_pa_sun4u(vm_offset_t va) 407{ 408 u_long pstate, reg; 409 int i; 410 411 pstate = rdpr(pstate); 412 wrpr(pstate, pstate & ~PSTATE_IE, 0); 413 for (i = 0; i < itlb_slot_max; i++) { | 408 wrpr(pstate, pstate, 0); 409 reg >>= TD_PA_SHIFT; 410 if (cpu_impl == CPU_IMPL_SPARC64V || 411 cpu_impl >= CPU_IMPL_ULTRASPARCIII) 412 return (reg & TD_PA_CH_MASK); 413 return (reg & TD_PA_SF_MASK); 414 } 415 wrpr(pstate, pstate, 0); --- 4 unchanged lines hidden (view full) --- 420itlb_va_to_pa_sun4u(vm_offset_t va) 421{ 422 u_long pstate, reg; 423 int i; 424 425 pstate = rdpr(pstate); 426 wrpr(pstate, pstate & ~PSTATE_IE, 0); 427 for (i = 0; i < itlb_slot_max; i++) { |
414 reg = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG); | 428 reg = ldxa(TLB_DAR_SLOT(tlb_locked, i), 429 ASI_ITLB_TAG_READ_REG); |
415 if (TLB_TAR_VA(reg) != va) 416 continue; | 430 if (TLB_TAR_VA(reg) != va) 431 continue; |
417 reg = itlb_get_data_sun4u(i); | 432 reg = itlb_get_data_sun4u(tlb_locked, i); |
418 wrpr(pstate, pstate, 0); 419 reg >>= TD_PA_SHIFT; 420 if (cpu_impl == CPU_IMPL_SPARC64V || 421 cpu_impl >= CPU_IMPL_ULTRASPARCIII) 422 return (reg & TD_PA_CH_MASK); 423 return (reg & TD_PA_SF_MASK); 424 } 425 wrpr(pstate, pstate, 0); --- 27 unchanged lines hidden (view full) --- 453 int i; 454 455 if (cpu_impl != CPU_IMPL_ULTRASPARCIIIp) 456 return; 457 458 pstate = rdpr(pstate); 459 wrpr(pstate, pstate & ~PSTATE_IE, 0); 460 | 433 wrpr(pstate, pstate, 0); 434 reg >>= TD_PA_SHIFT; 435 if (cpu_impl == CPU_IMPL_SPARC64V || 436 cpu_impl >= CPU_IMPL_ULTRASPARCIII) 437 return (reg & TD_PA_CH_MASK); 438 return (reg & TD_PA_SF_MASK); 439 } 440 wrpr(pstate, pstate, 0); --- 27 unchanged lines hidden (view full) --- 468 int i; 469 470 if (cpu_impl != CPU_IMPL_ULTRASPARCIIIp) 471 return; 472 473 pstate = rdpr(pstate); 474 wrpr(pstate, pstate & ~PSTATE_IE, 0); 475 |
461 data = itlb_get_data_sun4u(0); | 476 data = itlb_get_data_sun4u(tlb_locked, 0); |
462 if ((data & (TD_V | TD_L)) != (TD_V | TD_L)) { 463 wrpr(pstate, pstate, 0); 464 return; 465 } 466 467 /* Flush the mapping of slot 0. */ | 477 if ((data & (TD_V | TD_L)) != (TD_V | TD_L)) { 478 wrpr(pstate, pstate, 0); 479 return; 480 } 481 482 /* Flush the mapping of slot 0. */ |
468 tag = ldxa(TLB_DAR_SLOT(0), ASI_ITLB_TAG_READ_REG); | 483 tag = ldxa(TLB_DAR_SLOT(tlb_locked, 0), ASI_ITLB_TAG_READ_REG); |
469 stxa(TLB_DEMAP_VA(TLB_TAR_VA(tag)) | TLB_DEMAP_PRIMARY | 470 TLB_DEMAP_PAGE, ASI_IMMU_DEMAP, 0); 471 flush(0); /* The USIII-family ignores the address. */ 472 473 /* 474 * Search a replacement slot != 0 and enter the data and tag 475 * that formerly were in slot 0. 476 */ 477 for (i = 1; i < itlb_slot_max; i++) { | 484 stxa(TLB_DEMAP_VA(TLB_TAR_VA(tag)) | TLB_DEMAP_PRIMARY | 485 TLB_DEMAP_PAGE, ASI_IMMU_DEMAP, 0); 486 flush(0); /* The USIII-family ignores the address. */ 487 488 /* 489 * Search a replacement slot != 0 and enter the data and tag 490 * that formerly were in slot 0. 491 */ 492 for (i = 1; i < itlb_slot_max; i++) { |
478 if ((itlb_get_data_sun4u(i) & TD_V) != 0) | 493 if ((itlb_get_data_sun4u(tlb_locked, i) & TD_V) != 0) |
479 continue; 480 481 stxa(AA_IMMU_TAR, ASI_IMMU, tag); | 494 continue; 495 496 stxa(AA_IMMU_TAR, ASI_IMMU, tag); |
482 stxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG, data); | 497 stxa(TLB_DAR_SLOT(tlb_locked, i), ASI_ITLB_DATA_ACCESS_REG, 498 data); |
483 flush(0); /* The USIII-family ignores the address. */ 484 break; 485 } 486 wrpr(pstate, pstate, 0); 487 if (i == itlb_slot_max) 488 panic("%s: could not find a replacement slot", __func__); 489} 490 --- 155 unchanged lines hidden (view full) --- 646} 647 648static void 649tlb_init_sun4u(void) 650{ 651 phandle_t bsp; 652 653 cpu_impl = VER_IMPL(rdpr(ver)); | 499 flush(0); /* The USIII-family ignores the address. */ 500 break; 501 } 502 wrpr(pstate, pstate, 0); 503 if (i == itlb_slot_max) 504 panic("%s: could not find a replacement slot", __func__); 505} 506 --- 155 unchanged lines hidden (view full) --- 662} 663 664static void 665tlb_init_sun4u(void) 666{ 667 phandle_t bsp; 668 669 cpu_impl = VER_IMPL(rdpr(ver)); |
670 switch (cpu_impl) { 671 case CPU_IMPL_SPARC64: 672 case CPU_IMPL_ULTRASPARCI: 673 case CPU_IMPL_ULTRASPARCII: 674 case CPU_IMPL_ULTRASPARCIIi: 675 case CPU_IMPL_ULTRASPARCIIe: 676 tlb_locked = TLB_DAR_T32; 677 break; 678 case CPU_IMPL_ULTRASPARCIII: 679 case CPU_IMPL_ULTRASPARCIIIp: 680 case CPU_IMPL_ULTRASPARCIIIi: 681 case CPU_IMPL_ULTRASPARCIIIip: 682 case CPU_IMPL_ULTRASPARCIV: 683 case CPU_IMPL_ULTRASPARCIVp: 684 tlb_locked = TLB_DAR_T16; 685 break; 686 case CPU_IMPL_SPARC64V: 687 tlb_locked = TLB_DAR_FTLB; 688 break; 689 } |
|
654 bsp = find_bsp_sun4u(OF_child(root), cpu_get_mid_sun4u()); 655 if (bsp == 0) 656 panic("%s: no node for bootcpu?!?!", __func__); 657 658 if (OF_getprop(bsp, "#dtlb-entries", &dtlb_slot_max, 659 sizeof(dtlb_slot_max)) == -1 || 660 OF_getprop(bsp, "#itlb-entries", &itlb_slot_max, 661 sizeof(itlb_slot_max)) == -1) --- 154 unchanged lines hidden (view full) --- 816{ 817 tte_t tag, tte; 818 u_long pstate; 819 int i; 820 821 pstate = rdpr(pstate); 822 for (i = 0; i < itlb_slot_max; i++) { 823 wrpr(pstate, pstate & ~PSTATE_IE, 0); | 690 bsp = find_bsp_sun4u(OF_child(root), cpu_get_mid_sun4u()); 691 if (bsp == 0) 692 panic("%s: no node for bootcpu?!?!", __func__); 693 694 if (OF_getprop(bsp, "#dtlb-entries", &dtlb_slot_max, 695 sizeof(dtlb_slot_max)) == -1 || 696 OF_getprop(bsp, "#itlb-entries", &itlb_slot_max, 697 sizeof(itlb_slot_max)) == -1) --- 154 unchanged lines hidden (view full) --- 852{ 853 tte_t tag, tte; 854 u_long pstate; 855 int i; 856 857 pstate = rdpr(pstate); 858 for (i = 0; i < itlb_slot_max; i++) { 859 wrpr(pstate, pstate & ~PSTATE_IE, 0); |
824 tte = itlb_get_data_sun4u(i); | 860 tte = itlb_get_data_sun4u(tlb_locked, i); |
825 wrpr(pstate, pstate, 0); 826 if (!(tte & TD_V)) 827 continue; | 861 wrpr(pstate, pstate, 0); 862 if (!(tte & TD_V)) 863 continue; |
828 tag = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG); | 864 tag = ldxa(TLB_DAR_SLOT(tlb_locked, i), 865 ASI_ITLB_TAG_READ_REG); |
829 printf("iTLB-%2u: ", i); 830 pmap_print_tte_sun4u(tag, tte); 831 } 832 for (i = 0; i < dtlb_slot_max; i++) { 833 wrpr(pstate, pstate & ~PSTATE_IE, 0); | 866 printf("iTLB-%2u: ", i); 867 pmap_print_tte_sun4u(tag, tte); 868 } 869 for (i = 0; i < dtlb_slot_max; i++) { 870 wrpr(pstate, pstate & ~PSTATE_IE, 0); |
834 tte = dtlb_get_data_sun4u(i); | 871 tte = dtlb_get_data_sun4u(tlb_locked, i); |
835 wrpr(pstate, pstate, 0); 836 if (!(tte & TD_V)) 837 continue; | 872 wrpr(pstate, pstate, 0); 873 if (!(tte & TD_V)) 874 continue; |
838 tag = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG); | 875 tag = ldxa(TLB_DAR_SLOT(tlb_locked, i), 876 ASI_DTLB_TAG_READ_REG); |
839 printf("dTLB-%2u: ", i); 840 pmap_print_tte_sun4u(tag, tte); 841 } 842} 843#endif | 877 printf("dTLB-%2u: ", i); 878 pmap_print_tte_sun4u(tag, tte); 879 } 880} 881#endif |