diff options
author | marius <marius@FreeBSD.org> | 2008-08-07 22:46:25 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2008-08-07 22:46:25 +0000 |
commit | d335d6871aeb19ec02d0484ca3608820b06af7ab (patch) | |
tree | 5b357a34d4393b5feca4fe437362997ea3f19820 /sys/boot/sparc64/loader/main.c | |
parent | 714809ddf1353c47264bfd10532b75cd8ad00375 (diff) | |
download | FreeBSD-src-d335d6871aeb19ec02d0484ca3608820b06af7ab.zip FreeBSD-src-d335d6871aeb19ec02d0484ca3608820b06af7ab.tar.gz |
- Reimplement {d,i}tlb_enter() and {d,i}tlb_va_to_pa() in C. There's
no particular reason for them to be implemented in assembler and
having them in C allows easier extension as well as using more C
macros and {d,i}tlb_slot_max rather than hard-coding magic (and
actually spitfire-only) values.
- Fix the compilation of pmap_print_tte().
- Change pmap_print_tlb() to use ldxa() rather than re-rolling it
inline as well as TLB_DAR_SLOT and {d,i}tlb_slot_max rather than
hardcoding magic (and actually spitfire-only) values.
- While at it, suffix the above mentioned functions with "_sun4u" to
underline they're architecture-specific.
- Use __FBSDID and macros instead of magic values in locore.S.
- Remove unused includes and smp_stack in locore.S.
Diffstat (limited to 'sys/boot/sparc64/loader/main.c')
-rw-r--r-- | sys/boot/sparc64/loader/main.c | 138 |
1 files changed, 98 insertions, 40 deletions
diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c index 39d9602..7a85dc2 100644 --- a/sys/boot/sparc64/loader/main.c +++ b/sys/boot/sparc64/loader/main.c @@ -4,7 +4,7 @@ * All rights reserved. * * As long as the above copyright statement and this notice remain - * unchanged, you can do what ever you want with this file. + * unchanged, you can do what ever you want with this file. */ #include <sys/cdefs.h> @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <machine/lsu.h> #include <machine/metadata.h> #include <machine/tte.h> +#include <machine/tlb.h> #include <machine/upa.h> #include "bootstrap.h" @@ -56,10 +57,10 @@ static struct mmu_ops { typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3, void *openfirmware); -extern void itlb_enter(u_long vpn, u_long data); -extern void dtlb_enter(u_long vpn, u_long data); -extern vm_offset_t itlb_va_to_pa(vm_offset_t); -extern vm_offset_t dtlb_va_to_pa(vm_offset_t); +static void dtlb_enter_sun4u(u_long vpn, u_long data); +static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t); +static void itlb_enter_sun4u(u_long vpn, u_long data); +static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t); extern vm_offset_t md_load(char *, vm_offset_t *); static int sparc64_autoload(void); static ssize_t sparc64_readin(const int, vm_offset_t, const size_t); @@ -76,6 +77,13 @@ static vm_offset_t init_heap(void); static void tlb_init_sun4u(void); static void tlb_init_sun4v(void); +#ifdef LOADER_DEBUG +typedef u_int64_t tte_t; + +static void pmap_print_tlb_sun4u(void); +static void pmap_print_tte_sun4u(tte_t, tte_t); +#endif + static struct mmu_ops mmu_ops_sun4u = { tlb_init_sun4u, mmu_mapin_sun4u }; static struct mmu_ops mmu_ops_sun4v = { tlb_init_sun4v, mmu_mapin_sun4v }; @@ -344,9 +352,8 @@ __elfN(exec)(struct preloaded_file *fp) return (error); printf("jumping to kernel entry at %#lx.\n", e->e_entry); -#if 0 - pmap_print_tlb('i'); - pmap_print_tlb('d'); +#if LOADER_DEBUG + pmap_print_tlb_sun4u(); #endif entry = e->e_entry; @@ -358,6 +365,64 @@ __elfN(exec)(struct preloaded_file *fp) panic("%s: exec returned", __func__); } +static vm_offset_t +dtlb_va_to_pa_sun4u(vm_offset_t va) +{ + u_long reg; + int i; + + for (i = 0; i < dtlb_slot_max; i++) { + reg = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG); + if (TLB_TAR_VA(reg) != va) + continue; + reg = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_DATA_ACCESS_REG); + return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT); + } + return (-1); +} + +static vm_offset_t +itlb_va_to_pa_sun4u(vm_offset_t va) +{ + u_long reg; + int i; + + for (i = 0; i < itlb_slot_max; i++) { + reg = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG); + if (TLB_TAR_VA(reg) != va) + continue; + reg = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG); + return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT); + } + return (-1); +} + +static void +itlb_enter_sun4u(u_long vpn, u_long data) +{ + u_long reg; + + reg = rdpr(pstate); + wrpr(pstate, reg & ~PSTATE_IE, 0); + stxa(AA_IMMU_TAR, ASI_IMMU, vpn); + stxa(0, ASI_ITLB_DATA_IN_REG, data); + membar(Sync); + wrpr(pstate, reg, 0); +} + +static void +dtlb_enter_sun4u(u_long vpn, u_long data) +{ + u_long reg; + + reg = rdpr(pstate); + wrpr(pstate, reg & ~PSTATE_IE, 0); + stxa(AA_DMMU_TAR, ASI_DMMU, vpn); + stxa(0, ASI_DTLB_DATA_IN_REG, data); + membar(Sync); + wrpr(pstate, reg, 0); +} + static int mmu_mapin_sun4u(vm_offset_t va, vm_size_t len) { @@ -371,8 +436,8 @@ mmu_mapin_sun4u(vm_offset_t va, vm_size_t len) len += va & PAGE_MASK_4M; va &= ~PAGE_MASK_4M; while (len) { - if (dtlb_va_to_pa(va) == (vm_offset_t)-1 || - itlb_va_to_pa(va) == (vm_offset_t)-1) { + if (dtlb_va_to_pa_sun4u(va) == (vm_offset_t)-1 || + itlb_va_to_pa_sun4u(va) == (vm_offset_t)-1) { /* Allocate a physical page, claim the virtual area */ if (pa == (vm_offset_t)-1) { pa = alloc_phys(PAGE_SIZE_4M, PAGE_SIZE_4M); @@ -402,8 +467,8 @@ mmu_mapin_sun4u(vm_offset_t va, vm_size_t len) itlb_store[itlb_slot].te_va = va; dtlb_slot++; itlb_slot++; - dtlb_enter(va, data); - itlb_enter(va, data); + dtlb_enter_sun4u(va, data); + itlb_enter_sun4u(va, data); pa = (vm_offset_t)-1; } len -= len > PAGE_SIZE_4M ? PAGE_SIZE_4M : len; @@ -617,14 +682,12 @@ exit(int code) } #ifdef LOADER_DEBUG -typedef u_int64_t tte_t; - static const char *page_sizes[] = { " 8k", " 64k", "512k", " 4m" }; static void -pmap_print_tte(tte_t tag, tte_t tte) +pmap_print_tte_sun4u(tte_t tag, tte_t tte) { printf("%s %s ", @@ -638,36 +701,31 @@ pmap_print_tte(tte_t tag, tte_t tte) printf(tte & TD_L ? "\e[32mL\e[0m " : " "); printf(tte & TD_IE ? "IE " : " "); printf(tte & TD_NFO ? "NFO " : " "); - printf("tag=0x%lx pa=0x%lx va=0x%lx ctx=%ld\n", tag, TD_PA(tte), - TT_VA(tag), TT_CTX(tag)); + printf("pa=0x%lx va=0x%lx ctx=%ld\n", + TD_PA(tte), TLB_TAR_VA(tag), TLB_TAR_CTX(tag)); } -void -pmap_print_tlb(char which) + +static void +pmap_print_tlb_sun4u(void) { + tte_t tag, tte; int i; - tte_t tte, tag; - - for (i = 0; i < 64*8; i += 8) { - if (which == 'i') { - __asm__ __volatile__("ldxa [%1] %2, %0\n" : - "=r" (tag) : "r" (i), - "i" (ASI_ITLB_TAG_READ_REG)); - __asm__ __volatile__("ldxa [%1] %2, %0\n" : - "=r" (tte) : "r" (i), - "i" (ASI_ITLB_DATA_ACCESS_REG)); - } - else { - __asm__ __volatile__("ldxa [%1] %2, %0\n" : - "=r" (tag) : "r" (i), - "i" (ASI_DTLB_TAG_READ_REG)); - __asm__ __volatile__("ldxa [%1] %2, %0\n" : - "=r" (tte) : "r" (i), - "i" (ASI_DTLB_DATA_ACCESS_REG)); - } + + for (i = 0; i < itlb_slot_max; i++) { + tte = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG); + if (!(tte & TD_V)) + continue; + tag = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG); + printf("iTLB-%2u: ", i); + pmap_print_tte_sun4u(tag, tte); + } + for (i = 0; i < dtlb_slot_max; i++) { + tte = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_DATA_ACCESS_REG); if (!(tte & TD_V)) continue; - printf("%cTLB-%2u: ", which, i>>3); - pmap_print_tte(tag, tte); + tag = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG); + printf("dTLB-%2u: ", i); + pmap_print_tte_sun4u(tag, tte); } } #endif |