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

Annotation of src/sys/arch/evbarm/integrator/integrator_machdep.c, Revision 1.30

1.30    ! mycroft     1: /*     $NetBSD: integrator_machdep.c,v 1.29 2003/01/17 22:45:40 thorpej Exp $  */
1.1       rearnsha    2:
                      3: /*
1.23      rearnsha    4:  * Copyright (c) 2001,2002 ARM Ltd
1.1       rearnsha    5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. The name of the company may not be used to endorse or promote
                     16:  *    products derived from this software without specific prior written
                     17:  *    permission.
                     18:  *
1.23      rearnsha   19:  * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ARM LTD
                     23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
                     32: /*
1.1       rearnsha   33:  * Copyright (c) 1997,1998 Mark Brinicombe.
                     34:  * Copyright (c) 1997,1998 Causality Limited.
                     35:  * All rights reserved.
                     36:  *
                     37:  * Redistribution and use in source and binary forms, with or without
                     38:  * modification, are permitted provided that the following conditions
                     39:  * are met:
                     40:  * 1. Redistributions of source code must retain the above copyright
                     41:  *    notice, this list of conditions and the following disclaimer.
                     42:  * 2. Redistributions in binary form must reproduce the above copyright
                     43:  *    notice, this list of conditions and the following disclaimer in the
                     44:  *    documentation and/or other materials provided with the distribution.
                     45:  * 3. All advertising materials mentioning features or use of this software
                     46:  *    must display the following acknowledgement:
                     47:  *     This product includes software developed by Mark Brinicombe
                     48:  *     for the NetBSD Project.
                     49:  * 4. The name of the company nor the name of the author may be used to
                     50:  *    endorse or promote products derived from this software without specific
                     51:  *    prior written permission.
                     52:  *
                     53:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
                     54:  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
                     55:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     56:  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
                     57:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     58:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     59:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     60:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     61:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     62:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     63:  * SUCH DAMAGE.
                     64:  *
                     65:  * Machine dependant functions for kernel setup for integrator board
                     66:  *
                     67:  * Created      : 24/11/97
                     68:  */
                     69:
                     70: #include "opt_ddb.h"
                     71: #include "opt_pmap_debug.h"
                     72:
                     73: #include <sys/param.h>
                     74: #include <sys/device.h>
                     75: #include <sys/systm.h>
                     76: #include <sys/kernel.h>
                     77: #include <sys/exec.h>
                     78: #include <sys/proc.h>
                     79: #include <sys/msgbuf.h>
                     80: #include <sys/reboot.h>
                     81: #include <sys/termios.h>
                     82:
                     83: #include <dev/cons.h>
                     84:
                     85: #include <machine/db_machdep.h>
                     86: #include <ddb/db_sym.h>
                     87: #include <ddb/db_extern.h>
                     88:
                     89: #include <machine/bootconfig.h>
                     90: #include <machine/bus.h>
                     91: #include <machine/cpu.h>
                     92: #include <machine/frame.h>
                     93: #include <machine/intr.h>
1.8       thorpej    94: #include <evbarm/ifpga/irqhandler.h>   /* XXX XXX XXX */
1.6       thorpej    95: #include <arm/undefined.h>
1.1       rearnsha   96:
1.23      rearnsha   97: #include <arm/arm32/machdep.h>
                     98:
1.1       rearnsha   99: #include <evbarm/integrator/integrator_boot.h>
                    100:
                    101: #include "opt_ipkdb.h"
                    102: #include "pci.h"
                    103:
                    104: void ifpga_reset(void) __attribute__((noreturn));
                    105: /*
                    106:  * Address to call from cpu_reset() to reset the machine.
                    107:  * This is machine architecture dependant as it varies depending
                    108:  * on where the ROM appears when you turn the MMU off.
                    109:  */
                    110:
                    111: u_int cpu_reset_address = (u_int) ifpga_reset;
                    112:
                    113: /* Define various stack sizes in pages */
                    114: #define IRQ_STACK_SIZE 1
                    115: #define ABT_STACK_SIZE 1
                    116: #ifdef IPKDB
                    117: #define UND_STACK_SIZE 2
                    118: #else
                    119: #define UND_STACK_SIZE 1
                    120: #endif
                    121:
                    122: BootConfig bootconfig;         /* Boot config storage */
                    123: char *boot_args = NULL;
                    124: char *boot_file = NULL;
                    125:
                    126: vm_offset_t physical_start;
                    127: vm_offset_t physical_freestart;
                    128: vm_offset_t physical_freeend;
                    129: vm_offset_t physical_end;
                    130: u_int free_pages;
                    131: vm_offset_t pagetables_start;
                    132: int physmem = 0;
                    133:
                    134: /*int debug_flags;*/
                    135: #ifndef PMAP_STATIC_L1S
                    136: int max_processes = 64;                        /* Default number */
                    137: #endif /* !PMAP_STATIC_L1S */
                    138:
                    139: /* Physical and virtual addresses for some global pages */
                    140: pv_addr_t systempage;
                    141: pv_addr_t irqstack;
                    142: pv_addr_t undstack;
                    143: pv_addr_t abtstack;
                    144: pv_addr_t kernelstack;
                    145:
                    146: vm_offset_t msgbufphys;
                    147:
                    148: extern u_int data_abort_handler_address;
                    149: extern u_int prefetch_abort_handler_address;
                    150: extern u_int undefined_handler_address;
                    151:
                    152: #ifdef PMAP_DEBUG
                    153: extern int pmap_debug_level;
                    154: #endif
                    155:
1.23      rearnsha  156: #define KERNEL_PT_SYS          0       /* L2 table for mapping zero page */
                    157:
                    158: #define KERNEL_PT_KERNEL       1       /* L2 table for mapping kernel */
                    159: #define        KERNEL_PT_KERNEL_NUM    2
                    160:                                        /* L2 tables for mapping kernel VM */
                    161: #define KERNEL_PT_VMDATA       (KERNEL_PT_KERNEL + KERNEL_PT_KERNEL_NUM)
1.17      chris     162: #define        KERNEL_PT_VMDATA_NUM    4       /* start with 16MB of KVM */
1.1       rearnsha  163: #define NUM_KERNEL_PTS         (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)
                    164:
1.14      thorpej   165: pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];
1.1       rearnsha  166:
                    167: struct user *proc0paddr;
                    168:
                    169: /* Prototypes */
                    170:
1.23      rearnsha  171: static void    integrator_sdram_bounds (paddr_t *, psize_t *);
1.1       rearnsha  172:
1.23      rearnsha  173: void   consinit(void);
1.1       rearnsha  174:
                    175: /* A load of console goo. */
                    176: #include "vga.h"
1.23      rearnsha  177: #if NVGA > 0
1.1       rearnsha  178: #include <dev/ic/mc6845reg.h>
                    179: #include <dev/ic/pcdisplayvar.h>
                    180: #include <dev/ic/vgareg.h>
                    181: #include <dev/ic/vgavar.h>
                    182: #endif
                    183:
                    184: #include "pckbc.h"
1.23      rearnsha  185: #if NPCKBC > 0
1.1       rearnsha  186: #include <dev/ic/i8042reg.h>
                    187: #include <dev/ic/pckbcvar.h>
                    188: #endif
                    189:
                    190: #include "com.h"
1.23      rearnsha  191: #if NCOM > 0
1.1       rearnsha  192: #include <dev/ic/comreg.h>
                    193: #include <dev/ic/comvar.h>
                    194: #ifndef CONCOMADDR
                    195: #define CONCOMADDR 0x3f8
                    196: #endif
                    197: #endif
                    198:
1.23      rearnsha  199: /*
                    200:  * Define the default console speed for the board.  This is generally
                    201:  * what the firmware provided with the board defaults to.
                    202:  */
1.30    ! mycroft   203: #ifndef CONSPEED
1.1       rearnsha  204: #define CONSPEED B115200
                    205: #endif
                    206: #ifndef CONMODE
                    207: #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
                    208: #endif
                    209:
                    210: int comcnspeed = CONSPEED;
                    211: int comcnmode = CONMODE;
                    212:
                    213: #include "plcom.h"
                    214: #if (NPLCOM > 0)
                    215: #include <evbarm/dev/plcomreg.h>
                    216: #include <evbarm/dev/plcomvar.h>
                    217:
                    218: #include <evbarm/ifpga/ifpgamem.h>
                    219: #include <evbarm/ifpga/ifpgareg.h>
                    220: #include <evbarm/ifpga/ifpgavar.h>
                    221: #endif
                    222:
                    223: #ifndef CONSDEVNAME
                    224: #define CONSDEVNAME "plcom"
                    225: #endif
                    226:
                    227: #ifndef PLCONSPEED
                    228: #define PLCONSPEED B38400
                    229: #endif
                    230: #ifndef PLCONMODE
                    231: #define PLCONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
                    232: #endif
                    233: #ifndef PLCOMCNUNIT
                    234: #define PLCOMCNUNIT -1
                    235: #endif
                    236:
                    237: int plcomcnspeed = PLCONSPEED;
                    238: int plcomcnmode = PLCONMODE;
                    239:
                    240: #if 0
                    241: extern struct consdev kcomcons;
                    242: static void kcomcnputc(dev_t, int);
                    243: #endif
                    244:
                    245: /*
                    246:  * void cpu_reboot(int howto, char *bootstr)
                    247:  *
                    248:  * Reboots the system
                    249:  *
                    250:  * Deal with any syncing, unmounting, dumping and shutdown hooks,
                    251:  * then reset the CPU.
                    252:  */
                    253: void
1.23      rearnsha  254: cpu_reboot(int howto, char *bootstr)
1.1       rearnsha  255: {
                    256: #ifdef DIAGNOSTIC
                    257:        /* info */
1.29      thorpej   258:        printf("boot: howto=%08x curlwp=%p\n", howto, curlwp);
1.1       rearnsha  259: #endif
                    260:
                    261:        /*
                    262:         * If we are still cold then hit the air brakes
                    263:         * and crash to earth fast
                    264:         */
                    265:        if (cold) {
                    266:                doshutdownhooks();
                    267:                printf("The operating system has halted.\n");
                    268:                printf("Please press any key to reboot.\n\n");
                    269:                cngetc();
                    270:                printf("rebooting...\n");
                    271:                ifpga_reset();
                    272:                /*NOTREACHED*/
                    273:        }
                    274:
                    275:        /* Disable console buffering */
                    276:
                    277:        /*
                    278:         * If RB_NOSYNC was not specified sync the discs.
1.23      rearnsha  279:         * Note: Unless cold is set to 1 here, syslogd will die during the
                    280:         * unmount.  It looks like syslogd is getting woken up only to find
                    281:         * that it cannot page part of the binary in as the filesystem has
                    282:         * been unmounted.
1.1       rearnsha  283:         */
                    284:        if (!(howto & RB_NOSYNC))
                    285:                bootsync();
                    286:
                    287:        /* Say NO to interrupts */
                    288:        splhigh();
                    289:
                    290:        /* Do a dump if requested. */
                    291:        if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
                    292:                dumpsys();
                    293:
                    294:        /* Run any shutdown hooks */
                    295:        doshutdownhooks();
                    296:
                    297:        /* Make sure IRQ's are disabled */
                    298:        IRQdisable;
                    299:
                    300:        if (howto & RB_HALT) {
                    301:                printf("The operating system has halted.\n");
                    302:                printf("Please press any key to reboot.\n\n");
                    303:                cngetc();
                    304:        }
                    305:
                    306:        printf("rebooting...\n");
                    307:        ifpga_reset();
                    308:        /*NOTREACHED*/
                    309: }
                    310:
                    311: /*
                    312:  * Mapping table for core kernel memory. This memory is mapped at init
                    313:  * time with section mappings.
                    314:  */
                    315: struct l1_sec_map {
1.23      rearnsha  316:        vaddr_t va;
                    317:        vaddr_t pa;
                    318:        vsize_t size;
                    319:        vm_prot_t prot;
                    320:        int cache;
1.1       rearnsha  321: } l1_sec_table[] = {
                    322: #if NPLCOM > 0 && defined(PLCONSOLE)
1.23      rearnsha  323:        {
                    324:                UART0_BOOT_BASE,
                    325:                IFPGA_IO_BASE + IFPGA_UART0,
                    326:                1024 * 1024,
                    327:                VM_PROT_READ|VM_PROT_WRITE,
                    328:                PTE_NOCACHE
                    329:        },
                    330:
                    331:        {
                    332:                UART1_BOOT_BASE,
                    333:                IFPGA_IO_BASE + IFPGA_UART1,
                    334:                1024 * 1024,
                    335:                VM_PROT_READ|VM_PROT_WRITE,
                    336:                PTE_NOCACHE
                    337:        },
1.1       rearnsha  338: #endif
                    339: #if NPCI > 0
1.23      rearnsha  340:        {
                    341:                IFPGA_PCI_IO_VBASE,
                    342:                IFPGA_PCI_IO_BASE,
                    343:                IFPGA_PCI_IO_VSIZE,
                    344:                VM_PROT_READ|VM_PROT_WRITE,
                    345:                PTE_NOCACHE
                    346:        },
                    347:
                    348:        {
                    349:                IFPGA_PCI_CONF_VBASE,
                    350:                IFPGA_PCI_CONF_BASE,
                    351:                IFPGA_PCI_CONF_VSIZE,
                    352:                VM_PROT_READ|VM_PROT_WRITE,
                    353:                PTE_NOCACHE },
1.1       rearnsha  354: #endif
                    355:
1.23      rearnsha  356:        {
                    357:                0,
                    358:                0,
                    359:                0,
                    360:                0,
                    361:                0
                    362:        }
1.1       rearnsha  363: };
                    364:
                    365: /*
1.23      rearnsha  366:  * u_int initarm(...)
1.1       rearnsha  367:  *
                    368:  * Initial entry point on startup. This gets called before main() is
                    369:  * entered.
                    370:  * It should be responsible for setting up everything that must be
                    371:  * in place when main is called.
                    372:  * This includes
                    373:  *   Taking a copy of the boot configuration structure.
                    374:  *   Initialising the physical console so characters can be printed.
                    375:  *   Setting up page tables for the kernel
                    376:  *   Relocating the kernel to the bottom of physical memory
                    377:  */
                    378:
                    379: u_int
1.23      rearnsha  380: initarm(void *arg)
1.1       rearnsha  381: {
                    382:        int loop;
                    383:        int loop1;
                    384:        u_int l1pagetable;
                    385:        extern int etext asm ("_etext");
                    386:        extern int end asm ("_end");
                    387:        pv_addr_t kernel_l1pt;
                    388:        pv_addr_t kernel_ptpt;
1.23      rearnsha  389:        paddr_t memstart;
                    390:        psize_t memsize;
1.1       rearnsha  391: #if NPLCOM > 0 && defined(PLCONSOLE)
                    392:        static struct bus_space plcom_bus_space;
                    393: #endif
                    394:
                    395:        /*
                    396:         * Heads up ... Setup the CPU / MMU / TLB functions
                    397:         */
                    398:        if (set_cpufuncs())
                    399:                panic("cpu not recognized!");
                    400:
                    401: #if NPLCOM > 0 && defined(PLCONSOLE)
                    402:        /*
                    403:         * Initialise the diagnostic serial console
                    404:         * This allows a means of generating output during initarm().
                    405:         * Once all the memory map changes are complete we can call consinit()
                    406:         * and not have to worry about things moving.
                    407:         */
                    408:
                    409:        if (PLCOMCNUNIT == 0) {
                    410:                ifpga_create_io_bs_tag(&plcom_bus_space, (void*)0xfd600000);
                    411:                plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
                    412:                    IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT);
                    413:        } else if (PLCOMCNUNIT == 1) {
                    414:                ifpga_create_io_bs_tag(&plcom_bus_space, (void*)0xfd700000);
                    415:                plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
                    416:                    IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT);
                    417:        }
                    418: #endif
                    419:
                    420:        /* Talk to the user */
1.23      rearnsha  421:        printf("\nNetBSD/evbarm (Integrator) booting ...\n");
1.1       rearnsha  422:
                    423:        /*
                    424:         * Ok we have the following memory map
                    425:         *
1.23      rearnsha  426:         * XXX NO WE DON'T
                    427:         *
1.1       rearnsha  428:         * virtual address == physical address apart from the areas:
                    429:         * 0x00000000 -> 0x000fffff which is mapped to
                    430:         * top 1MB of physical memory
                    431:         * 0x00100000 -> 0x0fffffff which is mapped to
                    432:         * physical addresses 0x00100000 -> 0x0fffffff
                    433:         * 0x10000000 -> 0x1fffffff which is mapped to
                    434:         * physical addresses 0x00000000 -> 0x0fffffff
                    435:         * 0x20000000 -> 0xefffffff which is mapped to
                    436:         * physical addresses 0x20000000 -> 0xefffffff
                    437:         * 0xf0000000 -> 0xf03fffff which is mapped to
                    438:         * physical addresses 0x00000000 -> 0x003fffff
                    439:         *
                    440:         * This means that the kernel is mapped suitably for continuing
                    441:         * execution, all I/O is mapped 1:1 virtual to physical and
                    442:         * physical memory is accessible.
                    443:         *
                    444:         * The initarm() has the responsibility for creating the kernel
                    445:         * page tables.
                    446:         * It must also set up various memory pointers that are used
                    447:         * by pmap etc.
                    448:         */
                    449:
                    450:        /*
1.23      rearnsha  451:         * Fetch the SDRAM start/size from the CM configuration registers.
1.1       rearnsha  452:         */
1.23      rearnsha  453:        integrator_sdram_bounds(&memstart, &memsize);
1.1       rearnsha  454:
                    455:        printf("initarm: Configuring system ...\n");
                    456:
1.23      rearnsha  457:        /* Fake bootconfig structure for the benefit of pmap.c */
                    458:        /* XXX must make the memory description h/w independent */
                    459:        bootconfig.dramblocks = 1;
                    460:        bootconfig.dram[0].address = memstart;
                    461:        bootconfig.dram[0].pages = memsize / NBPG;
                    462:
1.1       rearnsha  463:        /*
                    464:         * Set up the variables that define the availablilty of
1.23      rearnsha  465:         * physical memory.  For now, we're going to set
                    466:         * physical_freestart to 0x00200000 (where the kernel
                    467:         * was loaded), and allocate the memory we need downwards.
                    468:         * If we get too close to the L1 table that we set up, we
                    469:         * will panic.  We will update physical_freestart and
                    470:         * physical_freeend later to reflect what pmap_bootstrap()
                    471:         * wants to see.
                    472:         *
                    473:         * XXX pmap_bootstrap() needs an enema.
1.1       rearnsha  474:         */
1.23      rearnsha  475:        physical_start = bootconfig.dram[0].address;
                    476:        physical_end = physical_start + (bootconfig.dram[0].pages * NBPG);
1.1       rearnsha  477:
1.23      rearnsha  478:        physical_freestart = 0x00009000UL;
                    479:        physical_freeend = 0x00200000UL;
1.1       rearnsha  480:
                    481:        physmem = (physical_end - physical_start) / NBPG;
                    482:
                    483:        /* Tell the user about the memory */
                    484:        printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem,
                    485:            physical_start, physical_end - 1);
                    486:
                    487:        /*
1.23      rearnsha  488:         * Okay, the kernel starts 2MB in from the bottom of physical
                    489:         * memory.  We are going to allocate our bootstrap pages downwards
                    490:         * from there.
1.1       rearnsha  491:         *
1.23      rearnsha  492:         * We need to allocate some fixed page tables to get the kernel
                    493:         * going.  We allocate one page directory and a number of page
                    494:         * tables and store the physical addresses in the kernel_pt_table
                    495:         * array.
                    496:         *
                    497:         * The kernel page directory must be on a 16K boundary.  The page
                    498:         * tables must be on 4K bounaries.  What we do is allocate the
                    499:         * page directory on the first 16K boundary that we encounter, and
                    500:         * the page tables on 4K boundaries otherwise.  Since we allocate
                    501:         * at least 3 L2 page tables, we are guaranteed to encounter at
                    502:         * least one 16K aligned region.
1.1       rearnsha  503:         */
                    504:
                    505: #ifdef VERBOSE_INIT_ARM
                    506:        printf("Allocating page tables\n");
                    507: #endif
                    508:
1.23      rearnsha  509:        free_pages = (physical_freeend - physical_freestart) / NBPG;
1.1       rearnsha  510:
                    511: #ifdef VERBOSE_INIT_ARM
1.23      rearnsha  512:        printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n",
1.1       rearnsha  513:               physical_freestart, free_pages, free_pages);
                    514: #endif
                    515:
                    516:        /* Define a macro to simplify memory allocation */
1.23      rearnsha  517: #define        valloc_pages(var, np)                           \
                    518:        alloc_pages((var).pv_pa, (np));                 \
                    519:        (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start;
                    520:
                    521: #define alloc_pages(var, np)                           \
                    522:        physical_freeend -= ((np) * NBPG);              \
                    523:        if (physical_freeend < physical_freestart)      \
                    524:                panic("initarm: out of memory");        \
                    525:        (var) = physical_freeend;                       \
                    526:        free_pages -= (np);                             \
1.1       rearnsha  527:        memset((char *)(var), 0, ((np) * NBPG));
                    528:
                    529:        loop1 = 0;
                    530:        kernel_l1pt.pv_pa = 0;
                    531:        for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
                    532:                /* Are we 16KB aligned for an L1 ? */
1.23      rearnsha  533:                if (((physical_freeend - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) == 0
1.1       rearnsha  534:                    && kernel_l1pt.pv_pa == 0) {
1.21      thorpej   535:                        valloc_pages(kernel_l1pt, L1_TABLE_SIZE / NBPG);
1.1       rearnsha  536:                } else {
1.14      thorpej   537:                        alloc_pages(kernel_pt_table[loop1].pv_pa,
1.21      thorpej   538:                            L2_TABLE_SIZE / NBPG);
1.14      thorpej   539:                        kernel_pt_table[loop1].pv_va =
                    540:                            kernel_pt_table[loop1].pv_pa;
1.23      rearnsha  541:                        ++loop1;
1.1       rearnsha  542:                }
                    543:        }
                    544:
                    545:        /* This should never be able to happen but better confirm that. */
1.21      thorpej   546:        if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0)
1.28      provos    547:                panic("initarm: Failed to align the kernel page directory");
1.1       rearnsha  548:
                    549:        /*
                    550:         * Allocate a page for the system page mapped to V0x00000000
                    551:         * This page will just contain the system vectors and can be
                    552:         * shared by all processes.
                    553:         */
                    554:        alloc_pages(systempage.pv_pa, 1);
                    555:
1.23      rearnsha  556:        /* Allocate a page for the page table to map kernel page tables. */
1.21      thorpej   557:        valloc_pages(kernel_ptpt, L2_TABLE_SIZE / NBPG);
1.1       rearnsha  558:
                    559:        /* Allocate stacks for all modes */
                    560:        valloc_pages(irqstack, IRQ_STACK_SIZE);
                    561:        valloc_pages(abtstack, ABT_STACK_SIZE);
                    562:        valloc_pages(undstack, UND_STACK_SIZE);
                    563:        valloc_pages(kernelstack, UPAGES);
                    564:
                    565: #ifdef VERBOSE_INIT_ARM
1.23      rearnsha  566:        printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa,
                    567:            irqstack.pv_va);
                    568:        printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa,
                    569:            abtstack.pv_va);
                    570:        printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa,
                    571:            undstack.pv_va);
                    572:        printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa,
                    573:            kernelstack.pv_va);
1.1       rearnsha  574: #endif
                    575:
                    576:        alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / NBPG);
                    577:
                    578:        /*
                    579:         * Ok we have allocated physical pages for the primary kernel
                    580:         * page tables
                    581:         */
                    582:
                    583: #ifdef VERBOSE_INIT_ARM
1.23      rearnsha  584:        printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa);
1.1       rearnsha  585: #endif
                    586:
                    587:        /*
1.23      rearnsha  588:         * Now we start construction of the L1 page table
1.1       rearnsha  589:         * We start by mapping the L2 page tables into the L1.
                    590:         * This means that we can replace L1 mappings later on if necessary
                    591:         */
                    592:        l1pagetable = kernel_l1pt.pv_pa;
                    593:
                    594:        /* Map the L2 pages tables in the L1 page table */
1.11      thorpej   595:        pmap_link_l2pt(l1pagetable, 0x00000000,
1.14      thorpej   596:            &kernel_pt_table[KERNEL_PT_SYS]);
1.23      rearnsha  597:        for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++)
                    598:                pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000,
                    599:                    &kernel_pt_table[KERNEL_PT_KERNEL + loop]);
                    600:        for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
1.11      thorpej   601:                pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
1.14      thorpej   602:                    &kernel_pt_table[KERNEL_PT_VMDATA + loop]);
1.23      rearnsha  603:        pmap_link_l2pt(l1pagetable, PTE_BASE, &kernel_ptpt);
1.17      chris     604:
                    605:        /* update the top of the kernel VM */
1.19      thorpej   606:        pmap_curmaxkvaddr =
                    607:            KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);
1.1       rearnsha  608:
                    609: #ifdef VERBOSE_INIT_ARM
                    610:        printf("Mapping kernel\n");
                    611: #endif
                    612:
                    613:        /* Now we fill in the L2 pagetable for the kernel static code/data */
                    614:        {
                    615:                size_t textsize = (uintptr_t) &etext - KERNEL_TEXT_BASE;
                    616:                size_t totalsize = (uintptr_t) &end - KERNEL_TEXT_BASE;
1.23      rearnsha  617:                u_int logical;
1.1       rearnsha  618:
1.23      rearnsha  619:                textsize = (textsize + PGOFSET) & ~PGOFSET;
1.1       rearnsha  620:                totalsize = (totalsize + PGOFSET) & ~PGOFSET;
1.23      rearnsha  621:
                    622:                logical = 0x00200000;   /* offset of kernel in RAM */
                    623:
                    624:                logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
                    625:                    physical_start + logical, textsize,
1.12      thorpej   626:                    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
1.23      rearnsha  627:                logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
                    628:                    physical_start + logical, totalsize - textsize,
1.12      thorpej   629:                    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
1.1       rearnsha  630:        }
                    631:
                    632: #ifdef VERBOSE_INIT_ARM
                    633:        printf("Constructing L2 page tables\n");
                    634: #endif
                    635:
                    636:        /* Map the stack pages */
1.14      thorpej   637:        pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
                    638:            IRQ_STACK_SIZE * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
                    639:        pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
                    640:            ABT_STACK_SIZE * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
                    641:        pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
                    642:            UND_STACK_SIZE * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
                    643:        pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
                    644:            UPAGES * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
1.13      thorpej   645:
1.14      thorpej   646:        pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
1.26      thorpej   647:            L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
1.1       rearnsha  648:
                    649:        /* Map the page table that maps the kernel pages */
1.16      thorpej   650:        pmap_map_entry(l1pagetable, kernel_ptpt.pv_va, kernel_ptpt.pv_pa,
1.10      thorpej   651:            VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
1.1       rearnsha  652:
                    653:        /*
                    654:         * Map entries in the page table used to map PTE's
                    655:         * Basically every kernel page table gets mapped here
                    656:         */
                    657:        /* The -2 is slightly bogus, it should be -log2(sizeof(pt_entry_t)) */
1.23      rearnsha  658:        for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++) {
                    659:                pmap_map_entry(l1pagetable,
                    660:                    PTE_BASE + ((KERNEL_BASE +
                    661:                    (loop * 0x00400000)) >> (PGSHIFT-2)),
                    662:                    kernel_pt_table[KERNEL_PT_KERNEL + loop].pv_pa,
1.27      thorpej   663:                    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
1.23      rearnsha  664:        }
1.15      thorpej   665:        pmap_map_entry(l1pagetable,
1.18      thorpej   666:            PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
1.23      rearnsha  667:            kernel_ptpt.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
1.15      thorpej   668:        pmap_map_entry(l1pagetable,
1.18      thorpej   669:            PTE_BASE + (0x00000000 >> (PGSHIFT-2)),
1.14      thorpej   670:            kernel_pt_table[KERNEL_PT_SYS].pv_pa,
1.27      thorpej   671:            VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
1.23      rearnsha  672:        for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
1.15      thorpej   673:                pmap_map_entry(l1pagetable,
1.18      thorpej   674:                    PTE_BASE + ((KERNEL_VM_BASE +
1.1       rearnsha  675:                    (loop * 0x00400000)) >> (PGSHIFT-2)),
1.14      thorpej   676:                    kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa,
1.27      thorpej   677:                    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
1.1       rearnsha  678:
1.20      thorpej   679:        /* Map the vector page. */
1.1       rearnsha  680: #if 1
                    681:        /* MULTI-ICE requires that page 0 is NC/NB so that it can download
                    682:           the cache-clean code there.  */
1.20      thorpej   683:        pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
1.10      thorpej   684:            VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
1.1       rearnsha  685: #else
1.20      thorpej   686:        pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
                    687:            VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
1.1       rearnsha  688: #endif
                    689:        /* Map the core memory needed before autoconfig */
                    690:        loop = 0;
                    691:        while (l1_sec_table[loop].size) {
                    692:                vm_size_t sz;
                    693:
                    694: #ifdef VERBOSE_INIT_ARM
                    695:                printf("%08lx -> %08lx @ %08lx\n", l1_sec_table[loop].pa,
                    696:                    l1_sec_table[loop].pa + l1_sec_table[loop].size - 1,
                    697:                    l1_sec_table[loop].va);
                    698: #endif
1.21      thorpej   699:                for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_S_SIZE)
1.9       thorpej   700:                        pmap_map_section(l1pagetable,
                    701:                            l1_sec_table[loop].va + sz,
1.1       rearnsha  702:                            l1_sec_table[loop].pa + sz,
1.9       thorpej   703:                            l1_sec_table[loop].prot,
                    704:                            l1_sec_table[loop].cache);
1.1       rearnsha  705:                ++loop;
                    706:        }
                    707:
                    708:        /*
                    709:         * Now we have the real page tables in place so we can switch to them.
1.23      rearnsha  710:         * Once this is done we will be running with the REAL kernel page
                    711:         * tables.
                    712:         */
                    713:
                    714:        /*
                    715:         * Update the physical_freestart/physical_freeend/free_pages
                    716:         * variables.
1.1       rearnsha  717:         */
1.23      rearnsha  718:        {
                    719:                physical_freestart = physical_start +
                    720:                    (((((uintptr_t) &end) + PGOFSET) & ~PGOFSET) -
                    721:                     KERNEL_BASE);
                    722:                physical_freeend = physical_end;
                    723:                free_pages = (physical_freeend - physical_freestart) / NBPG;
                    724:        }
1.1       rearnsha  725:
                    726:        /* Switch tables */
                    727: #ifdef VERBOSE_INIT_ARM
1.23      rearnsha  728:        printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n",
1.1       rearnsha  729:               physical_freestart, free_pages, free_pages);
                    730:        printf("switching to new L1 page table  @%#lx...", kernel_l1pt.pv_pa);
                    731: #endif
                    732:        setttb(kernel_l1pt.pv_pa);
1.23      rearnsha  733:        cpu_tlb_flushID();
1.1       rearnsha  734:
                    735: #ifdef VERBOSE_INIT_ARM
                    736:        printf("done!\n");
                    737: #endif
                    738:
                    739: #ifdef PLCONSOLE
                    740:        /*
                    741:         * The IFPGA registers have just moved.
                    742:         * Detach the diagnostic serial port and reattach at the new address.
                    743:         */
                    744:        plcomcndetach();
                    745: #endif
                    746:
                    747:        /*
                    748:         * XXX this should only be done in main() but it useful to
                    749:         * have output earlier ...
                    750:         */
                    751:        consinit();
                    752:
                    753: #ifdef VERBOSE_INIT_ARM
                    754:        printf("bootstrap done.\n");
                    755: #endif
                    756:
1.20      thorpej   757:        arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL);
1.1       rearnsha  758:
                    759:        /*
                    760:         * Pages were allocated during the secondary bootstrap for the
                    761:         * stacks for different CPU modes.
                    762:         * We must now set the r13 registers in the different CPU modes to
                    763:         * point to these stacks.
                    764:         * Since the ARM stacks use STMFD etc. we must set r13 to the top end
                    765:         * of the stack memory.
                    766:         */
                    767:        printf("init subsystems: stacks ");
                    768:
                    769:        set_stackptr(PSR_IRQ32_MODE, irqstack.pv_va + IRQ_STACK_SIZE * NBPG);
                    770:        set_stackptr(PSR_ABT32_MODE, abtstack.pv_va + ABT_STACK_SIZE * NBPG);
                    771:        set_stackptr(PSR_UND32_MODE, undstack.pv_va + UND_STACK_SIZE * NBPG);
                    772:
                    773:        /*
                    774:         * Well we should set a data abort handler.
1.23      rearnsha  775:         * Once things get going this will change as we will need a proper
                    776:         * handler.
1.1       rearnsha  777:         * Until then we will use a handler that just panics but tells us
                    778:         * why.
                    779:         * Initialisation of the vectors will just panic on a data abort.
                    780:         * This just fills in a slighly better one.
                    781:         */
                    782:        printf("vectors ");
                    783:        data_abort_handler_address = (u_int)data_abort_handler;
                    784:        prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
                    785:        undefined_handler_address = (u_int)undefinedinstruction_bounce;
                    786:
                    787:        /* Initialise the undefined instruction handlers */
                    788:        printf("undefined ");
                    789:        undefined_init();
                    790:
1.25      thorpej   791:        /* Load memory into UVM. */
                    792:        printf("page ");
                    793:        uvm_setpagesize();      /* initialize PAGE_SIZE-dependent variables */
                    794:        uvm_page_physload(atop(physical_freestart), atop(physical_freeend),
                    795:            atop(physical_freestart), atop(physical_freeend),
                    796:            VM_FREELIST_DEFAULT);
                    797:
1.1       rearnsha  798:        /* Boot strap pmap telling it where the kernel page table is */
                    799:        printf("pmap ");
                    800:        pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, kernel_ptpt);
                    801:
                    802:        /* Setup the IRQ system */
                    803:        printf("irq ");
                    804:        irq_init();
                    805:
                    806:        printf("done.\n");
                    807:
                    808: #ifdef IPKDB
                    809:        /* Initialise ipkdb */
                    810:        ipkdb_init();
                    811:        if (boothowto & RB_KDB)
                    812:                ipkdb_connect(0);
                    813: #endif
                    814:
                    815: #ifdef DDB
                    816:        db_machine_init();
1.4       thorpej   817:
                    818:        /* Firmware doesn't load symbols. */
                    819:        ddb_init(0, NULL, NULL);
1.1       rearnsha  820:
                    821:        if (boothowto & RB_KDB)
                    822:                Debugger();
                    823: #endif
                    824:
                    825:        /* We return the new stack pointer address */
                    826:        return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
                    827: }
                    828:
                    829: void
                    830: consinit(void)
                    831: {
                    832:        static int consinit_called = 0;
                    833: #if NPLCOM > 0 && defined(PLCONSOLE)
                    834:        static struct bus_space plcom_bus_space;
                    835: #endif
                    836: #if 0
                    837:        char *console = CONSDEVNAME;
                    838: #endif
                    839:
                    840:        if (consinit_called != 0)
                    841:                return;
                    842:
                    843:        consinit_called = 1;
                    844:
                    845: #if NPLCOM > 0 && defined(PLCONSOLE)
                    846:        if (PLCOMCNUNIT == 0) {
                    847:                ifpga_create_io_bs_tag(&plcom_bus_space,
                    848:                    (void*)UART0_BOOT_BASE);
                    849:                if (plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
                    850:                    IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT))
                    851:                        panic("can't init serial console");
                    852:                return;
                    853:        } else if (PLCOMCNUNIT == 1) {
                    854:                ifpga_create_io_bs_tag(&plcom_bus_space,
                    855:                    (void*)UART0_BOOT_BASE);
                    856:                if (plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
                    857:                    IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT))
                    858:                        panic("can't init serial console");
                    859:                return;
                    860:        }
                    861: #endif
                    862: #if (NCOM > 0)
                    863:        if (comcnattach(&isa_io_bs_tag, CONCOMADDR, comcnspeed,
                    864:            COM_FREQ, comcnmode))
                    865:                panic("can't init serial console @%x", CONCOMADDR);
                    866:        return;
                    867: #endif
                    868:        panic("No serial console configured");
1.23      rearnsha  869: }
                    870:
                    871: static void
                    872: integrator_sdram_bounds(paddr_t *memstart, psize_t *memsize)
                    873: {
                    874:        volatile unsigned long *cm_sdram
                    875:            = (volatile unsigned long *)0x10000020;
                    876:
                    877:        *memstart = 0;
                    878:
                    879:        switch ((*cm_sdram >> 2) & 0x7)
                    880:        {
                    881:        case 0:
                    882:                *memsize = 16 * 1024 * 1024;
                    883:                break;
                    884:        case 1:
                    885:                *memsize = 32 * 1024 * 1024;
                    886:                break;
                    887:        case 2:
                    888:                *memsize = 64 * 1024 * 1024;
                    889:                break;
                    890:        case 3:
                    891:                *memsize = 128 * 1024 * 1024;
                    892:                break;
                    893:        case 4:
                    894:                *memsize = 256 * 1024 * 1024;
                    895:                break;
                    896:        default:
                    897:                printf("CM_SDRAM retuns unknown value, using 16M\n");
                    898:                *memsize = 16 * 1024 * 1024;
                    899:                break;
                    900:        }
1.1       rearnsha  901: }

CVSweb <webmaster@jp.NetBSD.org>