Deleted Added
full compact
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