diff options
author | jake <jake@FreeBSD.org> | 2002-02-23 11:06:37 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2002-02-23 11:06:37 +0000 |
commit | 33e8ee5265ca2838260ab581a9cebdedb1e1e29b (patch) | |
tree | 1049a0be439b4808c81cd4904a54ea8a5373d761 /sys/boot/sparc64 | |
parent | cb7151318ebc080fcd1fd2c9049283fc99d2087a (diff) | |
download | FreeBSD-src-33e8ee5265ca2838260ab581a9cebdedb1e1e29b.zip FreeBSD-src-33e8ee5265ca2838260ab581a9cebdedb1e1e29b.tar.gz |
Keep track of the ttes used to map the kernel and pass them to it as loader
metadata. Modify tlb handling functions to take a tte, instead of virtual
address, physical address and flags.
Diffstat (limited to 'sys/boot/sparc64')
-rw-r--r-- | sys/boot/sparc64/loader/locore.S | 25 | ||||
-rw-r--r-- | sys/boot/sparc64/loader/locore.s | 25 | ||||
-rw-r--r-- | sys/boot/sparc64/loader/main.c | 92 | ||||
-rw-r--r-- | sys/boot/sparc64/loader/metadata.c | 19 |
4 files changed, 126 insertions, 35 deletions
diff --git a/sys/boot/sparc64/loader/locore.S b/sys/boot/sparc64/loader/locore.S index 8d89c3d..920171a 100644 --- a/sys/boot/sparc64/loader/locore.S +++ b/sys/boot/sparc64/loader/locore.S @@ -8,9 +8,14 @@ * * $FreeBSD$ */ + +#define LOCORE + #include <machine/asi.h> #include <machine/asm.h> #include <machine/pstate.h> +#include <machine/smp.h> +#include <machine/upa.h> #define PAGE_SIZE 8192 #define PAGE_SHIFT 13 @@ -33,7 +38,7 @@ ENTRY(_start) mov %l6, %sp call main mov %o4, %o0 - illtrap + sir /* * %o0 input VA constant @@ -82,18 +87,17 @@ ENTRY(dtlb_va_to_pa) /* * %o0 = slot number - * %o1 = pa - * %o2 = va - * %o3 = flags + * %o1 = vpn + * %o2 = tte data */ ENTRY(itlb_enter) rdpr %pstate, %o4 wrpr %o4, PSTATE_IE, %pstate sllx %o0, 3, %o0 - or %o1, %o3, %o1 + sllx %o1, PAGE_SHIFT, %o1 mov AA_IMMU_TAR, %o3 - stxa %o2, [%o3] ASI_IMMU - stxa %o1, [%o0] ASI_ITLB_DATA_ACCESS_REG + stxa %o1, [%o3] ASI_IMMU + stxa %o2, [%o0] ASI_ITLB_DATA_ACCESS_REG membar #Sync retl wrpr %o4, 0, %pstate @@ -102,12 +106,13 @@ ENTRY(dtlb_enter) rdpr %pstate, %o4 wrpr %o4, PSTATE_IE, %pstate sllx %o0, 3, %o0 - or %o1, %o3, %o1 + sllx %o1, PAGE_SHIFT, %o1 mov AA_DMMU_TAR, %o3 - stxa %o2, [%o3] ASI_DMMU - stxa %o1, [%o0] ASI_DTLB_DATA_ACCESS_REG + stxa %o1, [%o3] ASI_DMMU + stxa %o2, [%o0] ASI_DTLB_DATA_ACCESS_REG membar #Sync retl wrpr %o4, 0, %pstate .comm stack, STACK_SIZE, 32 + .comm smp_stack, STACK_SIZE, 32 diff --git a/sys/boot/sparc64/loader/locore.s b/sys/boot/sparc64/loader/locore.s index 8d89c3d..920171a 100644 --- a/sys/boot/sparc64/loader/locore.s +++ b/sys/boot/sparc64/loader/locore.s @@ -8,9 +8,14 @@ * * $FreeBSD$ */ + +#define LOCORE + #include <machine/asi.h> #include <machine/asm.h> #include <machine/pstate.h> +#include <machine/smp.h> +#include <machine/upa.h> #define PAGE_SIZE 8192 #define PAGE_SHIFT 13 @@ -33,7 +38,7 @@ ENTRY(_start) mov %l6, %sp call main mov %o4, %o0 - illtrap + sir /* * %o0 input VA constant @@ -82,18 +87,17 @@ ENTRY(dtlb_va_to_pa) /* * %o0 = slot number - * %o1 = pa - * %o2 = va - * %o3 = flags + * %o1 = vpn + * %o2 = tte data */ ENTRY(itlb_enter) rdpr %pstate, %o4 wrpr %o4, PSTATE_IE, %pstate sllx %o0, 3, %o0 - or %o1, %o3, %o1 + sllx %o1, PAGE_SHIFT, %o1 mov AA_IMMU_TAR, %o3 - stxa %o2, [%o3] ASI_IMMU - stxa %o1, [%o0] ASI_ITLB_DATA_ACCESS_REG + stxa %o1, [%o3] ASI_IMMU + stxa %o2, [%o0] ASI_ITLB_DATA_ACCESS_REG membar #Sync retl wrpr %o4, 0, %pstate @@ -102,12 +106,13 @@ ENTRY(dtlb_enter) rdpr %pstate, %o4 wrpr %o4, PSTATE_IE, %pstate sllx %o0, 3, %o0 - or %o1, %o3, %o1 + sllx %o1, PAGE_SHIFT, %o1 mov AA_DMMU_TAR, %o3 - stxa %o2, [%o3] ASI_DMMU - stxa %o1, [%o0] ASI_DTLB_DATA_ACCESS_REG + stxa %o1, [%o3] ASI_DMMU + stxa %o2, [%o0] ASI_DTLB_DATA_ACCESS_REG membar #Sync retl wrpr %o4, 0, %pstate .comm stack, STACK_SIZE, 32 + .comm smp_stack, STACK_SIZE, 32 diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c index ab66c99..5975f63 100644 --- a/sys/boot/sparc64/loader/main.c +++ b/sys/boot/sparc64/loader/main.c @@ -17,16 +17,22 @@ * TTEs and install just one 4MB mapping seemed to limiting * to me. */ + #include <stand.h> #include <sys/exec.h> #include <sys/param.h> #include <sys/linker.h> +#include <sys/pcpu.h> #include <machine/asi.h> +#include <machine/atomic.h> +#include <machine/cpufunc.h> #include <machine/elf.h> #include <machine/lsu.h> #include <machine/metadata.h> +#include <machine/smp.h> #include <machine/tte.h> +#include <machine/upa.h> #include "bootstrap.h" #include "libofw.h" @@ -46,8 +52,8 @@ struct memory_slice { typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3, void *openfirmware); -extern void itlb_enter(int, vm_offset_t, vm_offset_t, unsigned long); -extern void dtlb_enter(int, vm_offset_t, vm_offset_t, unsigned long); +extern void itlb_enter(int slot, u_long vpn, u_long data); +extern void dtlb_enter(int slot, 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); extern vm_offset_t md_load(char *, vm_offset_t *); @@ -57,9 +63,16 @@ static int mmu_mapin(vm_offset_t, vm_size_t); char __progname[] = "FreeBSD/sparc64 loader"; +struct tte *dtlb_store; +struct tte *itlb_store; + +int dtlb_slot; +int itlb_slot; +int dtlb_slot_max; +int itlb_slot_max; + vm_offset_t curkva = 0; vm_offset_t heapva; -int tlbslot = 63; /* Insert first entry at this TLB slot. XXX */ phandle_t pmemh; /* OFW memory handle */ struct memory_slice memslices[18]; @@ -92,7 +105,7 @@ struct fs_ops *file_system[] = { #ifdef LOADER_UFS_SUPPORT &ufs_fsops, #endif -#ifdef LOADER_NFS_SUPPORT +#ifdef LOADER_NET_SUPPORT &nfs_fsops, #endif #ifdef LOADER_TFTP_SUPPORT @@ -198,26 +211,24 @@ static int elf_exec(struct preloaded_file *fp) { struct file_metadata *fmp; - vm_offset_t entry; vm_offset_t mdp; - Elf_Ehdr *Ehdr; + Elf_Ehdr *e; int error; if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == 0) { return EFTYPE; } - Ehdr = (Elf_Ehdr *)&fmp->md_data; - entry = Ehdr->e_entry; + e = (Elf_Ehdr *)&fmp->md_data; if ((error = md_load(fp->f_args, &mdp)) != 0) return error; - printf("jumping to kernel entry at 0x%lx.\n", entry); + printf("jumping to kernel entry at %#lx.\n", e->e_entry); #if 0 pmap_print_tlb('i'); pmap_print_tlb('d'); #endif - ((kernel_entry_t *)entry)(mdp, 0, 0, 0, openfirmware); + ((kernel_entry_t *)e->e_entry)(mdp, 0, 0, 0, openfirmware); panic("exec returned"); } @@ -226,7 +237,12 @@ static int mmu_mapin(vm_offset_t va, vm_size_t len) { vm_offset_t pa, mva; + struct tte tte; + if (dtlb_slot < 0) + panic("mmu_mapin: out of dtlb_slots"); + if (itlb_slot < 0) + panic("mmu_mapin: out of itlb_slots"); if (va + len > curkva) curkva = va + len; @@ -252,11 +268,13 @@ mmu_mapin(vm_offset_t va, vm_size_t len) /* The mappings may have changed, be paranoid. */ continue; } - dtlb_enter(tlbslot, pa, va, - TD_V | TD_4M | TD_L | TD_CP | TD_CV | TD_P | TD_W); - itlb_enter(tlbslot, pa, va, - TD_V | TD_4M | TD_L | TD_CP | TD_CV | TD_P | TD_W); - tlbslot--; + tte.tte_tag = va >> PAGE_SHIFT; + tte.tte_data = TD_V | TD_4M | TD_PA(pa) | TD_L | TD_CP | + TD_CV | TD_P | TD_W; + dtlb_store[--dtlb_slot] = tte; + itlb_store[--itlb_slot] = tte; + dtlb_enter(dtlb_slot, tte.tte_tag, tte.tte_data); + itlb_enter(itlb_slot, tte.tte_tag, tte.tte_data); pa = (vm_offset_t)-1; } len -= len > PAGE_SIZE_4M ? PAGE_SIZE_4M : len; @@ -280,6 +298,45 @@ init_heap(void) return heapva; } +static void +tlb_init(void) +{ + phandle_t child; + phandle_t root; + char buf[128]; + u_int bootcpu; + u_int cpu; + + bootcpu = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); + if ((root = OF_peer(0)) == -1) + panic("main: OF_peer"); + for (child = OF_child(root); child != 0; child = OF_peer(child)) { + if (child == -1) + panic("main: OF_child"); + if (OF_getprop(child, "device_type", buf, sizeof(buf)) > 0 && + strcmp(buf, "cpu") == 0) { + if (OF_getprop(child, "upa-portid", &cpu, + sizeof(cpu)) == -1) + panic("main: OF_getprop"); + if (cpu == bootcpu) + break; + } + } + if (cpu != bootcpu) + panic("init_tlb: no node for bootcpu?!?!"); + if (OF_getprop(child, "#dtlb-entries", &dtlb_slot_max, + sizeof(dtlb_slot_max)) == -1 || + OF_getprop(child, "#itlb-entries", &itlb_slot_max, + sizeof(itlb_slot_max)) == -1) + panic("init_tlb: OF_getprop"); + dtlb_store = malloc(dtlb_slot_max * sizeof(*dtlb_store)); + itlb_store = malloc(itlb_slot_max * sizeof(*itlb_store)); + if (dtlb_store == NULL || itlb_store == NULL) + panic("init_tlb: malloc"); + dtlb_slot = dtlb_slot_max; + itlb_slot = itlb_slot_max; +} + int main(int (*openfirm)(void *)) { @@ -297,6 +354,9 @@ main(int (*openfirm)(void *)) archsw.arch_copyout = ofw_copyout; archsw.arch_readin = sparc64_readin; archsw.arch_autoload = sparc64_autoload; +#ifdef ELF_CRC32 + archsw.arch_crc32 = sparc64_crc32; +#endif init_heap(); setheap((void *)heapva, (void *)(heapva + HEAPSZ)); @@ -306,6 +366,8 @@ main(int (*openfirm)(void *)) */ cons_probe(); + tlb_init(); + bcache_init(32, 512); /* diff --git a/sys/boot/sparc64/loader/metadata.c b/sys/boot/sparc64/loader/metadata.c index dbbcaf4..e530792 100644 --- a/sys/boot/sparc64/loader/metadata.c +++ b/sys/boot/sparc64/loader/metadata.c @@ -31,12 +31,21 @@ #include <sys/param.h> #include <sys/reboot.h> #include <sys/linker.h> +#include <machine/tte.h> #include <machine/metadata.h> #include "bootstrap.h" #include "libofw.h" +extern struct tte *dtlb_store; +extern struct tte *itlb_store; + +extern int dtlb_slot; +extern int itlb_slot; +extern int dtlb_slot_max; +extern int itlb_slot_max; + /* * Return a 'boothowto' value corresponding to the kernel arguments in * (kargs) and any relevant environment variables. @@ -260,6 +269,8 @@ md_load(char *args, vm_offset_t *modulep) vm_offset_t size; char *rootdevname; int howto; + int dtlb_slots; + int itlb_slots; howto = md_getboothowto(args); @@ -297,12 +308,20 @@ md_load(char *args, vm_offset_t *modulep) addr = roundup(addr, PAGE_SIZE); kernend = 0; + dtlb_slots = dtlb_slot_max - dtlb_slot; + itlb_slots = itlb_slot_max - itlb_slot; kfp = file_findfile(NULL, "elf kernel"); if (kfp == NULL) panic("can't find kernel file"); file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); + file_addmetadata(kfp, MODINFOMD_DTLB_SLOTS, sizeof dtlb_slots, &dtlb_slots); + file_addmetadata(kfp, MODINFOMD_ITLB_SLOTS, sizeof itlb_slots, &itlb_slots); + file_addmetadata(kfp, MODINFOMD_DTLB, dtlb_slots * sizeof(struct tte), + &dtlb_store[dtlb_slot]); + file_addmetadata(kfp, MODINFOMD_ITLB, itlb_slots * sizeof(struct tte), + &itlb_store[itlb_slot]); *modulep = addr; size = md_copymodules(0); |