mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-19 06:44:31 +00:00
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:
parent
1210c77166
commit
4aaca88542
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=91139
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue