[BACK]Return to integrator_machdep.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / evbarm / integrator

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/evbarm/integrator/integrator_machdep.c between version 1.4 and 1.4.2.7

version 1.4, 2001/11/09 07:21:39 version 1.4.2.7, 2002/08/01 02:41:35
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
 /*  /*
  * Copyright (c) 2001 ARM Ltd   * Copyright (c) 2001,2002 ARM Ltd
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 16 
Line 16 
  *    products derived from this software without specific prior written   *    products derived from this software without specific prior written
  *    permission.   *    permission.
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED   * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ARM LTD
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * SUCH DAMAGE.   * POSSIBILITY OF SUCH DAMAGE.
  *   */
   
   /*
  * Copyright (c) 1997,1998 Mark Brinicombe.   * Copyright (c) 1997,1998 Mark Brinicombe.
  * Copyright (c) 1997,1998 Causality Limited.   * Copyright (c) 1997,1998 Causality Limited.
  * All rights reserved.   * All rights reserved.
Line 89 
Line 91 
 #include <machine/cpu.h>  #include <machine/cpu.h>
 #include <machine/frame.h>  #include <machine/frame.h>
 #include <machine/intr.h>  #include <machine/intr.h>
 #include <machine/pte.h>  #include <evbarm/ifpga/irqhandler.h>    /* XXX XXX XXX */
 #include <machine/undefined.h>  #include <arm/undefined.h>
   
   #include <arm/arm32/machdep.h>
   
 #include <evbarm/integrator/integrator_boot.h>  #include <evbarm/integrator/integrator_boot.h>
   
Line 115  u_int cpu_reset_address = (u_int) ifpga_
Line 119  u_int cpu_reset_address = (u_int) ifpga_
 #define UND_STACK_SIZE  1  #define UND_STACK_SIZE  1
 #endif  #endif
   
 struct intbootinfo intbootinfo;  
 BootConfig bootconfig;          /* Boot config storage */  BootConfig bootconfig;          /* Boot config storage */
 static char bootargs[MAX_BOOT_STRING + 1];  
 char *boot_args = NULL;  char *boot_args = NULL;
 char *boot_file = NULL;  char *boot_file = NULL;
   
Line 151  extern u_int undefined_handler_address;
Line 153  extern u_int undefined_handler_address;
 extern int pmap_debug_level;  extern int pmap_debug_level;
 #endif  #endif
   
 #define KERNEL_PT_SYS           0       /* Page table for mapping proc0 zero page */  #define KERNEL_PT_SYS           0       /* L2 table for mapping zero page */
 #define KERNEL_PT_KERNEL        1       /* Page table for mapping kernel */  
 #define KERNEL_PT_VMDATA        2       /* Page tables for mapping kernel VM */  #define KERNEL_PT_KERNEL        1       /* L2 table for mapping kernel */
 #define KERNEL_PT_VMDATA_NUM    (KERNEL_VM_SIZE >> (PDSHIFT + 2))  #define KERNEL_PT_KERNEL_NUM    2
                                           /* L2 tables for mapping kernel VM */
   #define KERNEL_PT_VMDATA        (KERNEL_PT_KERNEL + KERNEL_PT_KERNEL_NUM)
   #define KERNEL_PT_VMDATA_NUM    4       /* start with 16MB of KVM */
 #define NUM_KERNEL_PTS          (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)  #define NUM_KERNEL_PTS          (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)
   
 pt_entry_t kernel_pt_table[NUM_KERNEL_PTS];  pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];
   
 struct user *proc0paddr;  struct user *proc0paddr;
   
 /* Prototypes */  /* Prototypes */
   
 void consinit           __P((void));  static void     integrator_sdram_bounds (paddr_t *, psize_t *);
   
 void map_section        __P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa,  void    consinit(void);
                              int cacheable));  
 void map_pagetable      __P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa));  
 void map_entry          __P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa));  
 void map_entry_nc       __P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa));  
 void map_entry_ro       __P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa));  
 vm_size_t map_chunk     __P((vm_offset_t pd, vm_offset_t pt, vm_offset_t va,  
                              vm_offset_t pa, vm_size_t size, u_int acc,  
                              u_int flg));  
   
 void process_kernel_args        __P((char *));  
 void data_abort_handler         __P((trapframe_t *frame));  
 void prefetch_abort_handler     __P((trapframe_t *frame));  
 void undefinedinstruction_bounce        __P((trapframe_t *frame));  
 extern void configure           __P((void));  
 extern void parse_mi_bootargs   __P((char *args));  
 extern void dumpsys             __P((void));  
   
 /* A load of console goo. */  /* A load of console goo. */
 #include "vga.h"  #include "vga.h"
 #if (NVGA > 0)  #if NVGA > 0
 #include <dev/ic/mc6845reg.h>  #include <dev/ic/mc6845reg.h>
 #include <dev/ic/pcdisplayvar.h>  #include <dev/ic/pcdisplayvar.h>
 #include <dev/ic/vgareg.h>  #include <dev/ic/vgareg.h>
Line 193  extern void dumpsys  __P((void));
Line 182  extern void dumpsys  __P((void));
 #endif  #endif
   
 #include "pckbc.h"  #include "pckbc.h"
 #if (NPCKBC > 0)  #if NPCKBC > 0
 #include <dev/ic/i8042reg.h>  #include <dev/ic/i8042reg.h>
 #include <dev/ic/pckbcvar.h>  #include <dev/ic/pckbcvar.h>
 #endif  #endif
   
 #include "com.h"  #include "com.h"
 #if (NCOM > 0)  #if NCOM > 0
 #include <dev/ic/comreg.h>  #include <dev/ic/comreg.h>
 #include <dev/ic/comvar.h>  #include <dev/ic/comvar.h>
 #ifndef CONCOMADDR  #ifndef CONCOMADDR
Line 207  extern void dumpsys  __P((void));
Line 196  extern void dumpsys  __P((void));
 #endif  #endif
 #endif  #endif
   
   /*
    * Define the default console speed for the board.  This is generally
    * what the firmware provided with the board defaults to.
    */
 #define CONSPEED B115200  #define CONSPEED B115200
 #ifndef CONSPEED  #ifndef CONSPEED
 #define CONSPEED B9600  /* TTYDEF_SPEED */  #define CONSPEED B9600  /* TTYDEF_SPEED */
Line 258  static void kcomcnputc(dev_t, int);
Line 251  static void kcomcnputc(dev_t, int);
  * Deal with any syncing, unmounting, dumping and shutdown hooks,   * Deal with any syncing, unmounting, dumping and shutdown hooks,
  * then reset the CPU.   * then reset the CPU.
  */   */
   
 void  void
 cpu_reboot(howto, bootstr)  cpu_reboot(int howto, char *bootstr)
         int howto;  
         char *bootstr;  
 {  {
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         /* info */          /* info */
         printf("boot: howto=%08x curproc=%p\n", howto, curproc);          printf("boot: howto=%08x curlwp=%p\n", howto, curlwp);
 #endif  #endif
   
         /*          /*
Line 284  cpu_reboot(howto, bootstr)
Line 274  cpu_reboot(howto, bootstr)
         }          }
   
         /* Disable console buffering */          /* Disable console buffering */
 /*      cnpollc(1);*/  
   
         /*          /*
          * If RB_NOSYNC was not specified sync the discs.           * If RB_NOSYNC was not specified sync the discs.
          * Note: Unless cold is set to 1 here, syslogd will die during the unmount.           * Note: Unless cold is set to 1 here, syslogd will die during the
          * It looks like syslogd is getting woken up only to find that it cannot           * unmount.  It looks like syslogd is getting woken up only to find
          * page part of the binary in as the filesystem has been unmounted.           * that it cannot page part of the binary in as the filesystem has
            * been unmounted.
          */           */
         if (!(howto & RB_NOSYNC))          if (!(howto & RB_NOSYNC))
                 bootsync();                  bootsync();
Line 324  cpu_reboot(howto, bootstr)
Line 314  cpu_reboot(howto, bootstr)
  * time with section mappings.   * time with section mappings.
  */   */
 struct l1_sec_map {  struct l1_sec_map {
         vm_offset_t     va;          vaddr_t va;
         vm_offset_t     pa;          vaddr_t pa;
         vm_size_t       size;          vsize_t size;
         int             flags;          vm_prot_t prot;
           int cache;
 } l1_sec_table[] = {  } l1_sec_table[] = {
 #if NPLCOM > 0 && defined(PLCONSOLE)  #if NPLCOM > 0 && defined(PLCONSOLE)
         { UART0_BOOT_BASE, IFPGA_IO_BASE + IFPGA_UART0, 1024 * 1024, 0},          {
         { UART1_BOOT_BASE, IFPGA_IO_BASE + IFPGA_UART1, 1024 * 1024, 0},                  UART0_BOOT_BASE,
                   IFPGA_IO_BASE + IFPGA_UART0,
                   1024 * 1024,
                   VM_PROT_READ|VM_PROT_WRITE,
                   PTE_NOCACHE
           },
   
           {
                   UART1_BOOT_BASE,
                   IFPGA_IO_BASE + IFPGA_UART1,
                   1024 * 1024,
                   VM_PROT_READ|VM_PROT_WRITE,
                   PTE_NOCACHE
           },
 #endif  #endif
 #if NPCI > 0  #if NPCI > 0
         { IFPGA_PCI_IO_VBASE, IFPGA_PCI_IO_BASE, IFPGA_PCI_IO_VSIZE, 0},          {
         { IFPGA_PCI_CONF_VBASE, IFPGA_PCI_CONF_BASE, IFPGA_PCI_CONF_VSIZE, 0},                  IFPGA_PCI_IO_VBASE,
                   IFPGA_PCI_IO_BASE,
                   IFPGA_PCI_IO_VSIZE,
                   VM_PROT_READ|VM_PROT_WRITE,
                   PTE_NOCACHE
           },
   
           {
                   IFPGA_PCI_CONF_VBASE,
                   IFPGA_PCI_CONF_BASE,
                   IFPGA_PCI_CONF_VSIZE,
                   VM_PROT_READ|VM_PROT_WRITE,
                   PTE_NOCACHE },
 #endif  #endif
   
         { 0, 0, 0, 0 }          {
                   0,
                   0,
                   0,
                   0,
                   0
           }
 };  };
   
 /*  /*
  * u_int initarm(struct ebsaboot *bootinfo)   * u_int initarm(...)
  *   *
  * Initial entry point on startup. This gets called before main() is   * Initial entry point on startup. This gets called before main() is
  * entered.   * entered.
Line 356  struct l1_sec_map {
Line 378  struct l1_sec_map {
  */   */
   
 u_int  u_int
 initarm(bootinfo)  initarm(void *arg)
         struct intbootinfo *bootinfo;  
 {  {
         int loop;          int loop;
         int loop1;          int loop1;
         u_int l1pagetable;          u_int l1pagetable;
         u_int l2pagetable;  
         extern char page0[], page0_end[];  
         extern int etext asm ("_etext");          extern int etext asm ("_etext");
         extern int end asm ("_end");          extern int end asm ("_end");
         pv_addr_t kernel_l1pt;          pv_addr_t kernel_l1pt;
         pv_addr_t kernel_ptpt;          pv_addr_t kernel_ptpt;
           paddr_t memstart;
           psize_t memsize;
 #if NPLCOM > 0 && defined(PLCONSOLE)  #if NPLCOM > 0 && defined(PLCONSOLE)
         static struct bus_space plcom_bus_space;          static struct bus_space plcom_bus_space;
 #endif  #endif
   
   
 #if 0  
         cn_tab = &kcomcons;  
 #endif  
         /*          /*
          * Heads up ... Setup the CPU / MMU / TLB functions           * Heads up ... Setup the CPU / MMU / TLB functions
          */           */
         if (set_cpufuncs())          if (set_cpufuncs())
                 panic("cpu not recognized!");                  panic("cpu not recognized!");
   
         /*    - intbootinfo.bt_memstart) / NBPG */;  
   
 #if NPLCOM > 0 && defined(PLCONSOLE)  #if NPLCOM > 0 && defined(PLCONSOLE)
         /*          /*
          * Initialise the diagnostic serial console           * Initialise the diagnostic serial console
Line 404  initarm(bootinfo)
Line 419  initarm(bootinfo)
 #endif  #endif
   
         /* Talk to the user */          /* Talk to the user */
         printf("\nNetBSD/integrator booting ...\n");          printf("\nNetBSD/evbarm (Integrator) booting ...\n");
   
 #if 0  
         if (intbootinfo.bt_magic != BT_MAGIC_NUMBER_EBSA  
             && intbootinfo.bt_magic != BT_MAGIC_NUMBER_CATS)  
                 panic("Incompatible magic number passed in boot args\n");  
 #endif  
   
 /*      {  
         int loop;  
         for (loop = 0; loop < 8; ++loop) {  
                 printf("%08x\n", *(((int *)bootinfo)+loop));  
         }  
         }*/  
   
         /*          /*
          * Ok we have the following memory map           * Ok we have the following memory map
          *           *
            * XXX NO WE DON'T
            *
          * virtual address == physical address apart from the areas:           * virtual address == physical address apart from the areas:
          * 0x00000000 -> 0x000fffff which is mapped to           * 0x00000000 -> 0x000fffff which is mapped to
          * top 1MB of physical memory           * top 1MB of physical memory
Line 445  initarm(bootinfo)
Line 449  initarm(bootinfo)
          */           */
   
         /*          /*
          * Examine the boot args string for options we need to know about           * Fetch the SDRAM start/size from the CM configuration registers.
          * now.  
          */           */
 #if 0          integrator_sdram_bounds(&memstart, &memsize);
         process_kernel_args((char *)intbootinfo.bt_args);  
 #endif  
   
         printf("initarm: Configuring system ...\n");          printf("initarm: Configuring system ...\n");
   
           /* Fake bootconfig structure for the benefit of pmap.c */
           /* XXX must make the memory description h/w independent */
           bootconfig.dramblocks = 1;
           bootconfig.dram[0].address = memstart;
           bootconfig.dram[0].pages = memsize / NBPG;
   
         /*          /*
          * Set up the variables that define the availablilty of           * Set up the variables that define the availablilty of
          * physical memory           * physical memory.  For now, we're going to set
            * physical_freestart to 0x00200000 (where the kernel
            * was loaded), and allocate the memory we need downwards.
            * If we get too close to the L1 table that we set up, we
            * will panic.  We will update physical_freestart and
            * physical_freeend later to reflect what pmap_bootstrap()
            * wants to see.
            *
            * XXX pmap_bootstrap() needs an enema.
          */           */
         physical_start = 0 /*intbootinfo.bt_memstart*/;          physical_start = bootconfig.dram[0].address;
         physical_freestart = physical_start;          physical_end = physical_start + (bootconfig.dram[0].pages * NBPG);
   
 #if 0  
         physical_end = /*intbootinfo.bt_memend*/ /*intbootinfo.bi_nrpages * NBPG */ 32*1024*1024;  
 #else  
         {  
                 volatile unsigned long *cm_sdram  
                     = (volatile unsigned long *)0x10000020;  
   
                 switch ((*cm_sdram >> 2) & 0x7)  
                 {  
                 case 0:  
                         physical_end = 16 * 1024 * 1024;  
                         break;  
                 case 1:  
                         physical_end = 32 * 1024 * 1024;  
                         break;  
                 case 2:  
                         physical_end = 64 * 1024 * 1024;  
                         break;  
                 case 3:  
                         physical_end = 128 * 1024 * 1024;  
                         break;  
                 case 4:  
                         physical_end = 256 * 1024 * 1024;  
                         break;  
                 default:  
                         printf("CM_SDRAM retuns unknown value, using 16M\n");  
                         physical_end = 16 * 1024 * 1024;  
                         break;  
                 }  
         }  
 #endif  
   
         physical_freeend = physical_end;          physical_freestart = 0x00009000UL;
         free_pages = (physical_end - physical_start) / NBPG;          physical_freeend = 0x00200000UL;
   
         /* Set up the bootconfig structure for the benefit of pmap.c */  
         bootconfig.dramblocks = 1;  
         bootconfig.dram[0].address = physical_start;  
         bootconfig.dram[0].pages = free_pages;  
   
         physmem = (physical_end - physical_start) / NBPG;          physmem = (physical_end - physical_start) / NBPG;
   
         /* Tell the user about the memory */          /* Tell the user about the memory */
Line 508  initarm(bootinfo)
Line 486  initarm(bootinfo)
             physical_start, physical_end - 1);              physical_start, physical_end - 1);
   
         /*          /*
          * Ok the kernel occupies the bottom of physical memory.           * Okay, the kernel starts 2MB in from the bottom of physical
          * The first free page after the kernel can be found in           * memory.  We are going to allocate our bootstrap pages downwards
          * intbootinfo->bt_memavail           * from there.
          * We now need to allocate some fixed page tables to get the kernel  
          * going.  
          * We allocate one page directory and a number page tables and store  
          * the physical addresses in the kernel_pt_table array.  
          *           *
          * Ok the next bit of physical allocation may look complex but it is           * We need to allocate some fixed page tables to get the kernel
          * simple really. I have done it like this so that no memory gets           * going.  We allocate one page directory and a number of page
          * wasted during the allocation of various pages and tables that are           * tables and store the physical addresses in the kernel_pt_table
          * all different sizes.           * array.
          * The start addresses will be page aligned.           *
          * We allocate the kernel page directory on the first free 16KB boundry           * The kernel page directory must be on a 16K boundary.  The page
          * we find.           * tables must be on 4K bounaries.  What we do is allocate the
          * We allocate the kernel page tables on the first 4KB boundry we find.           * page directory on the first 16K boundary that we encounter, and
          * Since we allocate at least 3 L2 pagetables we know that we must           * the page tables on 4K boundaries otherwise.  Since we allocate
          * encounter at least one 16KB aligned address.           * at least 3 L2 page tables, we are guaranteed to encounter at
            * least one 16K aligned region.
          */           */
   
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("Allocating page tables\n");          printf("Allocating page tables\n");
 #endif  #endif
   
         /* Update the address of the first free 16KB chunk of physical memory */          free_pages = (physical_freeend - physical_freestart) / NBPG;
         physical_freestart = ((uintptr_t) &end - KERNEL_TEXT_BASE + PGOFSET)  
             & ~PGOFSET;  
 #if 0  
         physical_freestart += (kernexec->a_syms + sizeof(int)  
                     + *(u_int *)((int)end + kernexec->a_syms + sizeof(int))  
                     + (NBPG - 1)) & ~(NBPG - 1);  
 #endif  
   
         free_pages -= (physical_freestart - physical_start) / NBPG;  
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("freestart = %#lx, free_pages = %d (%#x)\n",          printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n",
                physical_freestart, free_pages, free_pages);                 physical_freestart, free_pages, free_pages);
 #endif  #endif
   
         /* Define a macro to simplify memory allocation */          /* Define a macro to simplify memory allocation */
 #define valloc_pages(var, np)                   \  #define valloc_pages(var, np)                           \
         alloc_pages((var).pv_pa, (np));         \          alloc_pages((var).pv_pa, (np));                 \
         (var).pv_va = KERNEL_TEXT_BASE + (var).pv_pa - physical_start;          (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start;
   
 #define alloc_pages(var, np)                    \  #define alloc_pages(var, np)                            \
         (var) = physical_freestart;             \          physical_freeend -= ((np) * NBPG);              \
         physical_freestart += ((np) * NBPG);    \          if (physical_freeend < physical_freestart)      \
         free_pages -= (np);                     \                  panic("initarm: out of memory");        \
           (var) = physical_freeend;                       \
           free_pages -= (np);                             \
         memset((char *)(var), 0, ((np) * NBPG));          memset((char *)(var), 0, ((np) * NBPG));
   
         loop1 = 0;          loop1 = 0;
         kernel_l1pt.pv_pa = 0;          kernel_l1pt.pv_pa = 0;
         for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {          for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
                 /* Are we 16KB aligned for an L1 ? */                  /* Are we 16KB aligned for an L1 ? */
                 if ((physical_freestart & (PD_SIZE - 1)) == 0                  if (((physical_freeend - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) == 0
                     && kernel_l1pt.pv_pa == 0) {                      && kernel_l1pt.pv_pa == 0) {
                         valloc_pages(kernel_l1pt, PD_SIZE / NBPG);                          valloc_pages(kernel_l1pt, L1_TABLE_SIZE / NBPG);
                 } else {                  } else {
                         alloc_pages(kernel_pt_table[loop1], PT_SIZE / NBPG);                          alloc_pages(kernel_pt_table[loop1].pv_pa,
                               L2_TABLE_SIZE / NBPG);
                           kernel_pt_table[loop1].pv_va =
                               kernel_pt_table[loop1].pv_pa;
                         ++loop1;                          ++loop1;
                 }                  }
         }          }
   
         /* This should never be able to happen but better confirm that. */          /* This should never be able to happen but better confirm that. */
         if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (PD_SIZE-1)) != 0)          if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0)
                 panic("initarm: Failed to align the kernel page directory\n");                  panic("initarm: Failed to align the kernel page directory\n");
   
         /*          /*
Line 582  initarm(bootinfo)
Line 554  initarm(bootinfo)
          */           */
         alloc_pages(systempage.pv_pa, 1);          alloc_pages(systempage.pv_pa, 1);
   
         /* Allocate a page for the page table to map kernel page tables*/          /* Allocate a page for the page table to map kernel page tables. */
         valloc_pages(kernel_ptpt, PT_SIZE / NBPG);          valloc_pages(kernel_ptpt, L2_TABLE_SIZE / NBPG);
   
         /* Allocate stacks for all modes */          /* Allocate stacks for all modes */
         valloc_pages(irqstack, IRQ_STACK_SIZE);          valloc_pages(irqstack, IRQ_STACK_SIZE);
Line 592  initarm(bootinfo)
Line 564  initarm(bootinfo)
         valloc_pages(kernelstack, UPAGES);          valloc_pages(kernelstack, UPAGES);
   
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa, irqstack.pv_va);          printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa,
         printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa, abtstack.pv_va);              irqstack.pv_va);
         printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa, undstack.pv_va);          printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa,
         printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa, kernelstack.pv_va);              abtstack.pv_va);
           printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa,
               undstack.pv_va);
           printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa,
               kernelstack.pv_va);
 #endif  #endif
   
         alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / NBPG);          alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / NBPG);
Line 606  initarm(bootinfo)
Line 582  initarm(bootinfo)
          */           */
   
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("Creating L1 page table at %#lx\n", kernel_l1pt.pv_pa);          printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa);
 #endif  #endif
   
         /*          /*
          * Now we start consturction of the L1 page table           * Now we start construction of the L1 page table
          * We start by mapping the L2 page tables into the L1.           * We start by mapping the L2 page tables into the L1.
          * This means that we can replace L1 mappings later on if necessary           * This means that we can replace L1 mappings later on if necessary
          */           */
         l1pagetable = kernel_l1pt.pv_pa;          l1pagetable = kernel_l1pt.pv_pa;
   
         /* Map the L2 pages tables in the L1 page table */          /* Map the L2 pages tables in the L1 page table */
         map_pagetable(l1pagetable, 0x00000000,          pmap_link_l2pt(l1pagetable, 0x00000000,
             kernel_pt_table[KERNEL_PT_SYS]);              &kernel_pt_table[KERNEL_PT_SYS]);
         map_pagetable(l1pagetable, KERNEL_BASE,          for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++)
             kernel_pt_table[KERNEL_PT_KERNEL]);                  pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000,
         for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop)                      &kernel_pt_table[KERNEL_PT_KERNEL + loop]);
                 map_pagetable(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,          for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
                     kernel_pt_table[KERNEL_PT_VMDATA + loop]);                  pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
         map_pagetable(l1pagetable, PROCESS_PAGE_TBLS_BASE,                      &kernel_pt_table[KERNEL_PT_VMDATA + loop]);
             kernel_ptpt.pv_pa);          pmap_link_l2pt(l1pagetable, PTE_BASE, &kernel_ptpt);
   
           /* update the top of the kernel VM */
           pmap_curmaxkvaddr =
               KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);
   
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("Mapping kernel\n");          printf("Mapping kernel\n");
 #endif  #endif
   
         /* Now we fill in the L2 pagetable for the kernel static code/data */          /* Now we fill in the L2 pagetable for the kernel static code/data */
         l2pagetable = kernel_pt_table[KERNEL_PT_KERNEL];  
   
         {          {
                 u_int logical;  
                 size_t textsize = (uintptr_t) &etext - KERNEL_TEXT_BASE;                  size_t textsize = (uintptr_t) &etext - KERNEL_TEXT_BASE;
                 size_t totalsize = (uintptr_t) &end - KERNEL_TEXT_BASE;                  size_t totalsize = (uintptr_t) &end - KERNEL_TEXT_BASE;
                   u_int logical;
   
                 /* Round down text size and round up total size                  textsize = (textsize + PGOFSET) & ~PGOFSET;
                  */  
                 textsize = textsize & ~PGOFSET;  
                 totalsize = (totalsize + PGOFSET) & ~PGOFSET;                  totalsize = (totalsize + PGOFSET) & ~PGOFSET;
                 /* logical  = map_chunk(l1pagetable, l2pagetable, KERNEL_BASE,  
                     physical_start, KERNEL_TEXT_BASE - KERNEL_BASE,                  logical = 0x00200000;   /* offset of kernel in RAM */
                     AP_KRW, PT_CACHEABLE); */  
                 logical = map_chunk(l1pagetable, l2pagetable,                  logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
                     KERNEL_TEXT_BASE, physical_start, textsize,                      physical_start + logical, textsize,
                     AP_KRW, PT_CACHEABLE);                      VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
                 logical += map_chunk(l1pagetable, l2pagetable,                  logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
                     KERNEL_TEXT_BASE + logical, physical_start + logical,                      physical_start + logical, totalsize - textsize,
                     totalsize - textsize, AP_KRW, PT_CACHEABLE);                      VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
 #if 0  
                 logical += map_chunk(0, l2pagetable, KERNEL_BASE + logical,  
                     physical_start + logical, kernexec->a_syms + sizeof(int)  
                     + *(u_int *)((int)end + kernexec->a_syms + sizeof(int)),  
                     AP_KRW, PT_CACHEABLE);  
 #endif  
         }          }
   
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("Constructing L2 page tables\n");          printf("Constructing L2 page tables\n");
 #endif  #endif
   
         /* Map the boot arguments page */  
 #if 0  
         map_entry_ro(l2pagetable, intbootinfo.bt_vargp, intbootinfo.bt_pargp);  
 #endif  
   
         /* Map the stack pages */          /* Map the stack pages */
         map_chunk(0, l2pagetable, irqstack.pv_va, irqstack.pv_pa,          pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
             IRQ_STACK_SIZE * NBPG, AP_KRW, PT_CACHEABLE);              IRQ_STACK_SIZE * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
         map_chunk(0, l2pagetable, abtstack.pv_va, abtstack.pv_pa,          pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
             ABT_STACK_SIZE * NBPG, AP_KRW, PT_CACHEABLE);              ABT_STACK_SIZE * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
         map_chunk(0, l2pagetable, undstack.pv_va, undstack.pv_pa,          pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
             UND_STACK_SIZE * NBPG, AP_KRW, PT_CACHEABLE);              UND_STACK_SIZE * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
         map_chunk(0, l2pagetable, kernelstack.pv_va, kernelstack.pv_pa,          pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
             UPAGES * NBPG, AP_KRW, PT_CACHEABLE);              UPAGES * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
         map_chunk(0, l2pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,  
             PD_SIZE, AP_KRW, 0);          pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
               L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
   
         /* Map the page table that maps the kernel pages */          /* Map the page table that maps the kernel pages */
         map_entry_nc(l2pagetable, kernel_ptpt.pv_pa, kernel_ptpt.pv_pa);          pmap_map_entry(l1pagetable, kernel_ptpt.pv_va, kernel_ptpt.pv_pa,
               VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
   
         /*          /*
          * Map entries in the page table used to map PTE's           * Map entries in the page table used to map PTE's
          * Basically every kernel page table gets mapped here           * Basically every kernel page table gets mapped here
          */           */
         /* The -2 is slightly bogus, it should be -log2(sizeof(pt_entry_t)) */          /* The -2 is slightly bogus, it should be -log2(sizeof(pt_entry_t)) */
         l2pagetable = kernel_ptpt.pv_pa;          for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++) {
         map_entry_nc(l2pagetable, (KERNEL_BASE >> (PGSHIFT-2)),                  pmap_map_entry(l1pagetable,
             kernel_pt_table[KERNEL_PT_KERNEL]);                      PTE_BASE + ((KERNEL_BASE +
         map_entry_nc(l2pagetable, (PROCESS_PAGE_TBLS_BASE >> (PGSHIFT-2)),  
             kernel_ptpt.pv_pa);  
         map_entry_nc(l2pagetable, (0x00000000 >> (PGSHIFT-2)),  
             kernel_pt_table[KERNEL_PT_SYS]);  
         for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop)  
                 map_entry_nc(l2pagetable, ((KERNEL_VM_BASE +  
                     (loop * 0x00400000)) >> (PGSHIFT-2)),                      (loop * 0x00400000)) >> (PGSHIFT-2)),
                     kernel_pt_table[KERNEL_PT_VMDATA + loop]);                      kernel_pt_table[KERNEL_PT_KERNEL + loop].pv_pa,
                       VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
           }
           pmap_map_entry(l1pagetable,
               PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
               kernel_ptpt.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
           pmap_map_entry(l1pagetable,
               PTE_BASE + (0x00000000 >> (PGSHIFT-2)),
               kernel_pt_table[KERNEL_PT_SYS].pv_pa,
               VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
           for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
                   pmap_map_entry(l1pagetable,
                       PTE_BASE + ((KERNEL_VM_BASE +
                       (loop * 0x00400000)) >> (PGSHIFT-2)),
                       kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa,
                       VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
   
         /*          /* Map the vector page. */
          * Map the system page in the kernel page table for the bottom 1Meg  
          * of the virtual memory map.  
          */  
         l2pagetable = kernel_pt_table[KERNEL_PT_SYS];  
 #if 1  #if 1
         /* MULTI-ICE requires that page 0 is NC/NB so that it can download          /* MULTI-ICE requires that page 0 is NC/NB so that it can download
            the cache-clean code there.  */             the cache-clean code there.  */
         map_entry_nc(l2pagetable, 0x00000000, systempage.pv_pa);          pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
               VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
 #else  #else
         map_entry_nc(l2pagetable, 0x00000000, systempage.pv_pa);          pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
               VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
 #endif  #endif
         /* Map the core memory needed before autoconfig */          /* Map the core memory needed before autoconfig */
         loop = 0;          loop = 0;
Line 723  initarm(bootinfo)
Line 697  initarm(bootinfo)
                     l1_sec_table[loop].pa + l1_sec_table[loop].size - 1,                      l1_sec_table[loop].pa + l1_sec_table[loop].size - 1,
                     l1_sec_table[loop].va);                      l1_sec_table[loop].va);
 #endif  #endif
                 for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_SEC_SIZE)                  for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_S_SIZE)
                         map_section(l1pagetable, l1_sec_table[loop].va + sz,                          pmap_map_section(l1pagetable,
                               l1_sec_table[loop].va + sz,
                             l1_sec_table[loop].pa + sz,                              l1_sec_table[loop].pa + sz,
                             l1_sec_table[loop].flags);                              l1_sec_table[loop].prot,
                               l1_sec_table[loop].cache);
                 ++loop;                  ++loop;
         }          }
   
         /*          /*
          * Now we have the real page tables in place so we can switch to them.           * Now we have the real page tables in place so we can switch to them.
          * Once this is done we will be running with the REAL kernel page tables.           * Once this is done we will be running with the REAL kernel page
            * tables.
          */           */
   
           /*
            * Update the physical_freestart/physical_freeend/free_pages
            * variables.
            */
           {
                   physical_freestart = physical_start +
                       (((((uintptr_t) &end) + PGOFSET) & ~PGOFSET) -
                        KERNEL_BASE);
                   physical_freeend = physical_end;
                   free_pages = (physical_freeend - physical_freestart) / NBPG;
           }
   
         /* Switch tables */          /* Switch tables */
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("freestart = %#lx, free_pages = %d (%#x)\n",          printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n",
                physical_freestart, free_pages, free_pages);                 physical_freestart, free_pages, free_pages);
         printf("switching to new L1 page table  @%#lx...", kernel_l1pt.pv_pa);          printf("switching to new L1 page table  @%#lx...", kernel_l1pt.pv_pa);
 #endif  #endif
   
         setttb(kernel_l1pt.pv_pa);          setttb(kernel_l1pt.pv_pa);
           cpu_tlb_flushID();
   
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("done!\n");          printf("done!\n");
Line 766  initarm(bootinfo)
Line 755  initarm(bootinfo)
         printf("bootstrap done.\n");          printf("bootstrap done.\n");
 #endif  #endif
   
         /* Right set up the vectors at the bottom of page 0 */          arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL);
         memcpy((char *)0x00000000, page0, page0_end - page0);  
   
         /* We have modified a text page so sync the icache */  
         cpu_cache_syncI();  
   
         /*          /*
          * Pages were allocated during the secondary bootstrap for the           * Pages were allocated during the secondary bootstrap for the
Line 788  initarm(bootinfo)
Line 773  initarm(bootinfo)
   
         /*          /*
          * Well we should set a data abort handler.           * Well we should set a data abort handler.
          * Once things get going this will change as we will need a proper handler.           * Once things get going this will change as we will need a proper
            * handler.
          * Until then we will use a handler that just panics but tells us           * Until then we will use a handler that just panics but tells us
          * why.           * why.
          * Initialisation of the vectors will just panic on a data abort.           * Initialisation of the vectors will just panic on a data abort.
Line 799  initarm(bootinfo)
Line 785  initarm(bootinfo)
         prefetch_abort_handler_address = (u_int)prefetch_abort_handler;          prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
         undefined_handler_address = (u_int)undefinedinstruction_bounce;          undefined_handler_address = (u_int)undefinedinstruction_bounce;
   
         /* At last !  
          * We now have the kernel in physical memory from the bottom upwards.  
          * Kernel page tables are physically above this.  
          * The kernel is mapped to KERNEL_TEXT_BASE  
          * The kernel data PTs will handle the mapping of 0xf1000000-0xf3ffffff  
          * The page tables are mapped to 0xefc00000  
          */  
   
         /* Initialise the undefined instruction handlers */          /* Initialise the undefined instruction handlers */
         printf("undefined ");          printf("undefined ");
         undefined_init();          undefined_init();
   
           /* Load memory into UVM. */
           printf("page ");
           uvm_setpagesize();      /* initialize PAGE_SIZE-dependent variables */
           uvm_page_physload(atop(physical_freestart), atop(physical_freeend),
               atop(physical_freestart), atop(physical_freeend),
               VM_FREELIST_DEFAULT);
   
         /* Boot strap pmap telling it where the kernel page table is */          /* Boot strap pmap telling it where the kernel page table is */
         printf("pmap ");          printf("pmap ");
         pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, kernel_ptpt);          pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, kernel_ptpt);
Line 843  initarm(bootinfo)
Line 828  initarm(bootinfo)
 }  }
   
 void  void
 process_kernel_args(args)  
         char *args;  
 {  
   
         boothowto = 0;  
   
         /* Make a local copy of the bootargs */  
         strncpy(bootargs, args, MAX_BOOT_STRING);  
   
         args = bootargs;  
         boot_file = bootargs;  
   
         /* Skip the kernel image filename */  
         while (*args != ' ' && *args != 0)  
                 ++args;  
   
         if (*args != 0)  
                 *args++ = 0;  
   
         while (*args == ' ')  
                 ++args;  
   
         boot_args = args;  
   
         printf("bootfile: %s\n", boot_file);  
         printf("bootargs: %s\n", boot_args);  
   
         parse_mi_bootargs(boot_args);  
 }  
   
 void  
 consinit(void)  consinit(void)
 {  {
         static int consinit_called = 0;          static int consinit_called = 0;
Line 915  consinit(void)
Line 869  consinit(void)
         panic("No serial console configured");          panic("No serial console configured");
 }  }
   
 #if 0  
 static bus_space_handle_t kcom_base = (bus_space_handle_t) (DC21285_PCI_IO_VBASE + CONCOMADDR);  
   
 u_int8_t footbridge_bs_r_1(void *, bus_space_handle_t, bus_size_t);  
 void footbridge_bs_w_1(void *, bus_space_handle_t, bus_size_t, u_int8_t);  
   
 #define KCOM_GETBYTE(r)         footbridge_bs_r_1(0, kcom_base, (r))  
 #define KCOM_PUTBYTE(r,v)       footbridge_bs_w_1(0, kcom_base, (r), (v))  
   
 static int  
 kcomcngetc(dev_t dev)  
 {  
         int stat, c;  
   
         /* block until a character becomes available */  
         while (!ISSET(stat = KCOM_GETBYTE(com_lsr), LSR_RXRDY))  
                 ;  
   
         c = KCOM_GETBYTE(com_data);  
         stat = KCOM_GETBYTE(com_iir);  
         return c;  
 }  
   
 /*  
  * Console kernel output character routine.  
  */  
 static void  static void
 kcomcnputc(dev_t dev, int c)  integrator_sdram_bounds(paddr_t *memstart, psize_t *memsize)
 {  {
         int timo;          volatile unsigned long *cm_sdram
               = (volatile unsigned long *)0x10000020;
   
         /* wait for any pending transmission to finish */          *memstart = 0;
         timo = 150000;  
         while (!ISSET(KCOM_GETBYTE(com_lsr), LSR_TXRDY) && --timo)  
                 continue;  
   
         KCOM_PUTBYTE(com_data, c);  
   
         /* wait for this transmission to complete */  
         timo = 1500000;  
         while (!ISSET(KCOM_GETBYTE(com_lsr), LSR_TXRDY) && --timo)  
                 continue;  
 }  
   
 static void          switch ((*cm_sdram >> 2) & 0x7)
 kcomcnpollc(dev_t dev, int on)          {
 {          case 0:
                   *memsize = 16 * 1024 * 1024;
                   break;
           case 1:
                   *memsize = 32 * 1024 * 1024;
                   break;
           case 2:
                   *memsize = 64 * 1024 * 1024;
                   break;
           case 3:
                   *memsize = 128 * 1024 * 1024;
                   break;
           case 4:
                   *memsize = 256 * 1024 * 1024;
                   break;
           default:
                   printf("CM_SDRAM retuns unknown value, using 16M\n");
                   *memsize = 16 * 1024 * 1024;
                   break;
           }
 }  }
   
 struct consdev kcomcons = {  
         NULL, NULL, kcomcngetc, kcomcnputc, kcomcnpollc, NULL,  
         NODEV, CN_NORMAL  
 };  
   
 #endif  

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.4.2.7

CVSweb <webmaster@jp.NetBSD.org>