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.
This commit is contained in:
Jake Burkholder 2002-02-23 11:06:37 +00:00
parent 1210c77166
commit 4aaca88542
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=91139
4 changed files with 126 additions and 35 deletions

View file

@ -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

View file

@ -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

View file

@ -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);
/*

View file

@ -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);