- Check for provided bootinfo from the bootloader. If we find it,
save off DDB symbol table information. - Make loading of memory work reliably with the bootloader; for each candidate memory type from ARCS (which now includes LoadedProgram), check to see if the kernel is within that chunk, and load the pages around it if it is.
This commit is contained in:
parent
741c7a2997
commit
38afb59582
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.31 2001/11/19 17:29:53 soren Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.32 2001/11/21 23:27:20 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Soren S. Jorvang
|
||||
@ -67,6 +67,7 @@
|
||||
#include <machine/machtype.h>
|
||||
#include <machine/sysconf.h>
|
||||
#include <machine/intr.h>
|
||||
#include <machine/bootinfo.h>
|
||||
#include <mips/locore.h>
|
||||
|
||||
#include <dev/arcbios/arcbios.h>
|
||||
@ -135,7 +136,7 @@ void ip32_init(void);
|
||||
|
||||
void * cpu_intr_establish(int, int, int (*)(void *), void *);
|
||||
|
||||
void mach_init(int, char **, char **);
|
||||
void mach_init(int, char **, int, struct btinfo_common *);
|
||||
void unconfigured_system_type(int);
|
||||
|
||||
void sgimips_count_cpus(struct arcbios_component *,
|
||||
@ -173,48 +174,36 @@ extern caddr_t esym;
|
||||
extern u_int32_t ssir;
|
||||
extern struct user *proc0paddr;
|
||||
|
||||
static struct btinfo_common *bootinfo;
|
||||
|
||||
/*
|
||||
* Do all the stuff that locore normally does before calling main().
|
||||
* Process arguments passed to us by the ARCS firmware.
|
||||
*/
|
||||
void
|
||||
mach_init(argc, argv, envp)
|
||||
mach_init(argc, argv, magic, btinfo)
|
||||
int argc;
|
||||
char **argv;
|
||||
char **envp;
|
||||
int magic;
|
||||
struct btinfo_common *btinfo;
|
||||
{
|
||||
unsigned long first, last;
|
||||
caddr_t kernend, v;
|
||||
extern char kernel_text[], _end[];
|
||||
paddr_t first, last;
|
||||
int firstpfn, lastpfn;
|
||||
caddr_t v;
|
||||
vsize_t size;
|
||||
extern char edata[], end[];
|
||||
struct arcbios_mem *mem;
|
||||
char *cpufreq;
|
||||
int i;
|
||||
struct btinfo_symtab *bi_syms;
|
||||
caddr_t ssym;
|
||||
vaddr_t kernend;
|
||||
int kernstartpfn, kernendpfn;
|
||||
int i, nsym;
|
||||
|
||||
/*
|
||||
* Clear the BSS segment.
|
||||
*/
|
||||
#ifdef DDB
|
||||
if (memcmp(((Elf_Ehdr *)end)->e_ident, ELFMAG, SELFMAG) == 0 &&
|
||||
((Elf_Ehdr *)end)->e_ident[EI_CLASS] == ELFCLASS) {
|
||||
esym = end;
|
||||
#if 0
|
||||
/*
|
||||
* This isn't right: end is a KSEG0 address, and the
|
||||
* kernel entry is a KSEG0 address. Adding them overflows
|
||||
* into user address space and will hang during boot.
|
||||
* For now, leave esym pointing to end.
|
||||
*/
|
||||
esym += ((Elf_Ehdr *)end)->e_entry;
|
||||
/* Clear the BSS segment. XXX Is this really necessary? */
|
||||
memset(_edata, 0, _end - _edata);
|
||||
#endif
|
||||
kernend = (caddr_t)mips_round_page(esym);
|
||||
memset(edata, 0, end - edata);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
kernend = (caddr_t)mips_round_page(end);
|
||||
memset(edata, 0, kernend - edata);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize ARCS. This will set up the bootstrap console.
|
||||
@ -222,6 +211,30 @@ mach_init(argc, argv, envp)
|
||||
arcbios_init(MIPS_PHYS_TO_KSEG0(0x00001000));
|
||||
strcpy(cpu_model, arcbios_system_identifier);
|
||||
|
||||
uvm_setpagesize();
|
||||
|
||||
if (magic == BOOTINFO_MAGIC && btinfo != NULL) {
|
||||
#ifdef DEBUG
|
||||
printf("Found bootinfo at %p\n", btinfo);
|
||||
#endif
|
||||
bootinfo = btinfo;
|
||||
}
|
||||
|
||||
bi_syms = lookup_bootinfo(BTINFO_SYMTAB);
|
||||
if (bi_syms != NULL) {
|
||||
nsym = bi_syms->nsym;
|
||||
ssym = (caddr_t) bi_syms->ssym;
|
||||
esym = (caddr_t) bi_syms->esym;
|
||||
kernend = round_page((vaddr_t) esym);
|
||||
} else {
|
||||
nsym = 0;
|
||||
ssym = esym = NULL;
|
||||
kernend = round_page((vaddr_t) _end);
|
||||
}
|
||||
|
||||
kernstartpfn = atop(MIPS_KSEG0_TO_PHYS((vaddr_t) kernel_text));
|
||||
kernendpfn = atop(MIPS_KSEG0_TO_PHYS(kernend));
|
||||
|
||||
/*
|
||||
* Now set up the real console.
|
||||
* XXX Should be done later after we determine systype.
|
||||
@ -242,8 +255,6 @@ mach_init(argc, argv, envp)
|
||||
... something ... = strtoul(cpufreq, NULL, 10) * 5000000;
|
||||
#endif
|
||||
|
||||
uvm_setpagesize();
|
||||
|
||||
/*
|
||||
* argv[0] can be either the bootloader loaded by the PROM, or a
|
||||
* kernel loaded directly by the PROM.
|
||||
@ -281,6 +292,7 @@ mach_init(argc, argv, envp)
|
||||
db_trap_callback = ddb_trap_hook;
|
||||
|
||||
#ifdef DDB
|
||||
ddb_init(nsym, ssym, esym);
|
||||
if (boothowto & RB_KDB)
|
||||
Debugger();
|
||||
#endif
|
||||
@ -344,14 +356,18 @@ mach_init(argc, argv, envp)
|
||||
do {
|
||||
if ((mem = ARCBIOS->GetMemoryDescriptor(mem)) != NULL) {
|
||||
i++;
|
||||
printf("Mem block %d: type %d, base %d, size %d\n",
|
||||
printf("Mem block %d: type %d, base 0x%x, size 0x%x\n",
|
||||
i, mem->Type, mem->BasePage, mem->PageCount);
|
||||
}
|
||||
} while (mem != NULL);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XXX This code assumes that ARCS provides the memory
|
||||
* XXX sorted in ascending order.
|
||||
*/
|
||||
mem = NULL;
|
||||
for (i = 0; i < VM_PHYSSEG_MAX; i++) {
|
||||
for (i = 0; mem_cluster_cnt < VM_PHYSSEG_MAX; i++) {
|
||||
mem = ARCBIOS->GetMemoryDescriptor(mem);
|
||||
|
||||
if (mem == NULL)
|
||||
@ -361,30 +377,75 @@ mach_init(argc, argv, envp)
|
||||
last = trunc_page(first + mem->PageCount * ARCBIOS_PAGESIZE);
|
||||
size = last - first;
|
||||
|
||||
firstpfn = atop(first);
|
||||
lastpfn = atop(last);
|
||||
|
||||
switch (mem->Type) {
|
||||
case ARCBIOS_MEM_FreeContiguous:
|
||||
case ARCBIOS_MEM_FreeMemory:
|
||||
if (last > MIPS_KSEG0_TO_PHYS(kernend))
|
||||
if (first < MIPS_KSEG0_TO_PHYS(kernend))
|
||||
first = MIPS_KSEG0_TO_PHYS(kernend);
|
||||
|
||||
case ARCBIOS_MEM_LoadedProgram:
|
||||
if (firstpfn <= kernstartpfn &&
|
||||
kernendpfn <= lastpfn) {
|
||||
/*
|
||||
* Must compute the location of the kernel
|
||||
* within the segment.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
printf("Cluster %d contains kernel\n", i);
|
||||
#endif
|
||||
if (firstpfn < kernstartpfn) {
|
||||
/*
|
||||
* There is a chunk before the kernel.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
printf("Loading chunk before kernel: "
|
||||
"0x%x / 0x%x\n", firstpfn,
|
||||
kernstartpfn);
|
||||
#endif
|
||||
uvm_page_physload(firstpfn,
|
||||
kernstartpfn,
|
||||
firstpfn, kernstartpfn,
|
||||
VM_FREELIST_DEFAULT);
|
||||
}
|
||||
if (kernendpfn < lastpfn) {
|
||||
/*
|
||||
* There is a chunk after the kernel.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
printf("Loading chunk after kernel: "
|
||||
"0x%x / 0x%x\n", kernendpfn,
|
||||
lastpfn);
|
||||
#endif
|
||||
uvm_page_physload(kernendpfn,
|
||||
lastpfn, kernendpfn,
|
||||
lastpfn, VM_FREELIST_DEFAULT);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Just load this cluster as one chunk.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
printf("Loading cluster %d: 0x%x / 0x%x\n", i,
|
||||
firstpfn, lastpfn);
|
||||
#endif
|
||||
uvm_page_physload(firstpfn, lastpfn,
|
||||
firstpfn, lastpfn, VM_FREELIST_DEFAULT);
|
||||
}
|
||||
mem_clusters[mem_cluster_cnt].start = first;
|
||||
mem_clusters[mem_cluster_cnt].size = size;
|
||||
mem_cluster_cnt++;
|
||||
|
||||
uvm_page_physload(atop(first), atop(last), atop(first),
|
||||
atop(last), VM_FREELIST_DEFAULT);
|
||||
|
||||
break;
|
||||
|
||||
case ARCBIOS_MEM_FirmwareTemporary:
|
||||
case ARCBIOS_MEM_FirmwarePermanent:
|
||||
arcsmem += btoc(size);
|
||||
break;
|
||||
|
||||
case ARCBIOS_MEM_ExecptionBlock:
|
||||
case ARCBIOS_MEM_SystemParameterBlock:
|
||||
case ARCBIOS_MEM_BadMemory:
|
||||
case ARCBIOS_MEM_LoadedProgram:
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("unknown memory descriptor %d type %d",
|
||||
i, mem->Type);
|
||||
@ -397,6 +458,9 @@ mach_init(argc, argv, envp)
|
||||
if (mem_cluster_cnt == 0)
|
||||
panic("no free memory descriptors found");
|
||||
|
||||
/* We can now no longer use bootinfo. */
|
||||
bootinfo = NULL;
|
||||
|
||||
/*
|
||||
* Walk the component tree and count the number of CPUs
|
||||
* present in the system.
|
||||
@ -775,6 +839,20 @@ void unconfigured_system_type(int ipnum)
|
||||
panic("Kernel not configured for current hardware!");
|
||||
}
|
||||
|
||||
void *
|
||||
lookup_bootinfo(int type)
|
||||
{
|
||||
struct btinfo_common *b = bootinfo;
|
||||
|
||||
while (bootinfo != NULL) {
|
||||
if (b->type == type)
|
||||
return (b);
|
||||
b = b->next;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#if defined(DDB) || defined(KGDB)
|
||||
|
||||
void ddb_trap_hook(int where)
|
||||
|
Loading…
Reference in New Issue
Block a user