Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sgimips/sgimips - Check for provided bootinfo from ...



details:   https://anonhg.NetBSD.org/src/rev/2a5c4fb87ed3
branches:  trunk
changeset: 517954:2a5c4fb87ed3
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Wed Nov 21 23:27:20 2001 +0000

description:
- 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.

diffstat:

 sys/arch/sgimips/sgimips/machdep.c |  164 +++++++++++++++++++++++++++---------
 1 files changed, 121 insertions(+), 43 deletions(-)

diffs (276 lines):

diff -r d6f871b3788d -r 2a5c4fb87ed3 sys/arch/sgimips/sgimips/machdep.c
--- a/sys/arch/sgimips/sgimips/machdep.c        Wed Nov 21 23:22:25 2001 +0000
+++ b/sys/arch/sgimips/sgimips/machdep.c        Wed Nov 21 23:27:20 2001 +0000
@@ -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 * 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 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 @@
        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 @@
        ... 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 @@
        db_trap_callback = ddb_trap_hook;
 
 #ifdef DDB
+       ddb_init(nsym, ssym, esym);
        if (boothowto & RB_KDB)
                Debugger();
 #endif
@@ -344,14 +356,18 @@
        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 @@
                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++;
+                       break;
 
-                       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 @@
        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 @@
        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)



Home | Main Index | Thread Index | Old Index