- 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:
thorpej 2001-11-21 23:27:20 +00:00
parent 741c7a2997
commit 38afb59582

View File

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