summaryrefslogtreecommitdiffstats
path: root/sys/boot/sparc64/loader
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2002-02-23 11:06:37 +0000
committerjake <jake@FreeBSD.org>2002-02-23 11:06:37 +0000
commit33e8ee5265ca2838260ab581a9cebdedb1e1e29b (patch)
tree1049a0be439b4808c81cd4904a54ea8a5373d761 /sys/boot/sparc64/loader
parentcb7151318ebc080fcd1fd2c9049283fc99d2087a (diff)
downloadFreeBSD-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/loader')
-rw-r--r--sys/boot/sparc64/loader/locore.S25
-rw-r--r--sys/boot/sparc64/loader/locore.s25
-rw-r--r--sys/boot/sparc64/loader/main.c92
-rw-r--r--sys/boot/sparc64/loader/metadata.c19
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);
OpenPOWER on IntegriCloud