Home | History | Annotate | Line # | Download | only in iq80310
iq80310_machdep.c revision 1.1
      1 /*	$NetBSD: iq80310_machdep.c,v 1.1 2001/09/05 04:53:41 matt Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997,1998 Mark Brinicombe.
      5  * Copyright (c) 1997,1998 Causality Limited.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *	This product includes software developed by Mark Brinicombe
     19  *	for the NetBSD Project.
     20  * 4. The name of the company nor the name of the author may be used to
     21  *    endorse or promote products derived from this software without specific
     22  *    prior written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     25  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     27  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     28  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     29  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  * SUCH DAMAGE.
     35  *
     36  * Machine dependant functions for kernel setup for EBSA285 core architecture
     37  * using Netwinder firmware
     38  *
     39  * Created      : 24/11/97
     40  */
     41 
     42 #include "opt_ddb.h"
     43 #include "opt_pmap_debug.h"
     44 
     45 #include <sys/param.h>
     46 #include <sys/device.h>
     47 #include <sys/systm.h>
     48 #include <sys/kernel.h>
     49 #include <sys/exec.h>
     50 #include <sys/proc.h>
     51 #include <sys/msgbuf.h>
     52 #include <sys/reboot.h>
     53 #include <sys/termios.h>
     54 
     55 #include <dev/cons.h>
     56 
     57 #include <machine/db_machdep.h>
     58 #include <ddb/db_sym.h>
     59 #include <ddb/db_extern.h>
     60 
     61 #include <machine/bootconfig.h>
     62 #include <machine/bus.h>
     63 #include <machine/cpu.h>
     64 #include <machine/frame.h>
     65 #include <machine/irqhandler.h>
     66 #include <machine/pte.h>
     67 #include <machine/undefined.h>
     68 
     69 #include <machine/iq80310_boot.h>
     70 #include <arm/xscale/i80312reg.h>
     71 #include <arm/xscale/i80312var.h>
     72 
     73 #include "opt_ipkdb.h"
     74 
     75 #include "isa.h"
     76 #if NISA > 0
     77 #include <dev/isa/isareg.h>
     78 #include <dev/isa/isavar.h>
     79 #endif
     80 
     81 /*
     82  * Address to call from cpu_reset() to reset the machine.
     83  * This is machine architecture dependant as it varies depending
     84  * on where the ROM appears when you turn the MMU off.
     85  */
     86 
     87 u_int cpu_reset_address = I80312_ROM_BASE;
     88 
     89 u_int dc21285_fclk = FCLK;
     90 
     91 /* Define various stack sizes in pages */
     92 #define IRQ_STACK_SIZE	1
     93 #define ABT_STACK_SIZE	1
     94 #ifdef IPKDB
     95 #define UND_STACK_SIZE	2
     96 #else
     97 #define UND_STACK_SIZE	1
     98 #endif
     99 
    100 struct nwbootinfo nwbootinfo;
    101 BootConfig bootconfig;		/* Boot config storage */
    102 static char bootargs[MAX_BOOT_STRING + 1];
    103 char *boot_args = NULL;
    104 char *boot_file = NULL;
    105 
    106 vm_offset_t physical_start;
    107 vm_offset_t physical_freestart;
    108 vm_offset_t physical_freeend;
    109 vm_offset_t physical_end;
    110 u_int free_pages;
    111 vm_offset_t pagetables_start;
    112 int physmem = 0;
    113 
    114 /*int debug_flags;*/
    115 #ifndef PMAP_STATIC_L1S
    116 int max_processes = 64;			/* Default number */
    117 #endif	/* !PMAP_STATIC_L1S */
    118 
    119 /* Physical and virtual addresses for some global pages */
    120 pv_addr_t systempage;
    121 pv_addr_t irqstack;
    122 pv_addr_t undstack;
    123 pv_addr_t abtstack;
    124 pv_addr_t kernelstack;
    125 
    126 vm_offset_t msgbufphys;
    127 
    128 extern u_int data_abort_handler_address;
    129 extern u_int prefetch_abort_handler_address;
    130 extern u_int undefined_handler_address;
    131 
    132 #ifdef PMAP_DEBUG
    133 extern int pmap_debug_level;
    134 #endif
    135 
    136 #define KERNEL_PT_SYS		0	/* Page table for mapping proc0 zero page */
    137 #define KERNEL_PT_KERNEL	1	/* Page table for mapping kernel */
    138 #define KERNEL_PT_VMDATA	2	/* Page tables for mapping kernel VM */
    139 #define	KERNEL_PT_VMDATA_NUM	(KERNEL_VM_SIZE >> (PDSHIFT + 2))
    140 #define NUM_KERNEL_PTS		(KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)
    141 
    142 pt_entry_t kernel_pt_table[NUM_KERNEL_PTS];
    143 
    144 struct user *proc0paddr;
    145 
    146 /* Prototypes */
    147 
    148 void consinit		__P((void));
    149 
    150 void map_section	__P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa,
    151 			     int cacheable));
    152 void map_pagetable	__P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa));
    153 void map_entry		__P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa));
    154 void map_entry_nc	__P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa));
    155 void map_entry_ro	__P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa));
    156 vm_size_t map_chunk	__P((vm_offset_t pd, vm_offset_t pt, vm_offset_t va,
    157 			     vm_offset_t pa, vm_size_t size, u_int acc,
    158 			     u_int flg));
    159 
    160 void process_kernel_args	__P((char *));
    161 void data_abort_handler		__P((trapframe_t *frame));
    162 void prefetch_abort_handler	__P((trapframe_t *frame));
    163 void undefinedinstruction_bounce	__P((trapframe_t *frame));
    164 void zero_page_readonly		__P((void));
    165 void zero_page_readwrite	__P((void));
    166 extern void configure		__P((void));
    167 extern void db_machine_init	__P((void));
    168 extern void parse_mi_bootargs	__P((char *args));
    169 extern void dumpsys		__P((void));
    170 
    171 /* A load of console goo. */
    172 #include "vga.h"
    173 #if (NVGA > 0)
    174 #include <dev/ic/mc6845reg.h>
    175 #include <dev/ic/pcdisplayvar.h>
    176 #include <dev/ic/vgareg.h>
    177 #include <dev/ic/vgavar.h>
    178 #endif
    179 
    180 #include "pckbc.h"
    181 #if (NPCKBC > 0)
    182 #include <dev/ic/i8042reg.h>
    183 #include <dev/ic/pckbcvar.h>
    184 #endif
    185 
    186 #include "com.h"
    187 #if (NCOM > 0)
    188 #include <dev/ic/comreg.h>
    189 #include <dev/ic/comvar.h>
    190 #ifndef CONCOMADDR
    191 #define CONCOMADDR 0
    192 #endif
    193 #endif
    194 
    195 #ifndef CONSDEVNAME
    196 #define CONSDEVNAME "com"
    197 #endif
    198 
    199 #define CONSPEED B115200
    200 #ifndef CONSPEED
    201 #define CONSPEED B9600	/* TTYDEF_SPEED */
    202 #endif
    203 #ifndef CONMODE
    204 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    205 #endif
    206 
    207 int comcnspeed = CONSPEED;
    208 int comcnmode = CONMODE;
    209 
    210 extern struct consdev kcomcons;
    211 static void kcomcnputc(dev_t, int);
    212 
    213 /*
    214  * void cpu_reboot(int howto, char *bootstr)
    215  *
    216  * Reboots the system
    217  *
    218  * Deal with any syncing, unmounting, dumping and shutdown hooks,
    219  * then reset the CPU.
    220  */
    221 
    222 void
    223 cpu_reboot(int howto, char *bootstr)
    224 {
    225 #ifdef DIAGNOSTIC
    226 	/* info */
    227 	printf("boot: howto=%08x curproc=%p\n", howto, curproc);
    228 #endif
    229 
    230 	/*
    231 	 * If we are still cold then hit the air brakes
    232 	 * and crash to earth fast
    233 	 */
    234 	if (cold) {
    235 		doshutdownhooks();
    236 		printf("The operating system has halted.\n");
    237 		printf("Please press any key to reboot.\n\n");
    238 		cngetc();
    239 		printf("rebooting...\n");
    240 		cpu_reset();
    241 		/*NOTREACHED*/
    242 	}
    243 
    244 	/* Disable console buffering */
    245 /*	cnpollc(1);*/
    246 
    247 	/*
    248 	 * If RB_NOSYNC was not specified sync the discs.
    249 	 * Note: Unless cold is set to 1 here, syslogd will die during the unmount.
    250 	 * It looks like syslogd is getting woken up only to find that it cannot
    251 	 * page part of the binary in as the filesystem has been unmounted.
    252 	 */
    253 	if (!(howto & RB_NOSYNC))
    254 		bootsync();
    255 
    256 	/* Say NO to interrupts */
    257 	splhigh();
    258 
    259 	/* Do a dump if requested. */
    260 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
    261 		dumpsys();
    262 
    263 	/* Run any shutdown hooks */
    264 	doshutdownhooks();
    265 
    266 	/* Make sure IRQ's are disabled */
    267 	IRQdisable;
    268 
    269 	if (howto & RB_HALT) {
    270 		printf("The operating system has halted.\n");
    271 		printf("Please press any key to reboot.\n\n");
    272 		cngetc();
    273 	}
    274 
    275 	printf("rebooting...\n");
    276 	cpu_reset();
    277 	/*NOTREACHED*/
    278 }
    279 
    280 /*
    281  * Mapping table for core kernel memory. This memory is mapped at init
    282  * time with section mappings.
    283  */
    284 struct l1_sec_map {
    285 	vaddr_t	va;
    286 	vaddr_t	pa;
    287 	vsize_t	size;
    288 	int flags;
    289 } l1_sec_table[] = {
    290     {
    291 				/* Map 1MB for CSR space */
    292 	I80312_ARMCSR_VBASE,
    293 	I80312_ARMCSR_BASE,
    294 	I80312_ARMCSR_VSIZE,
    295 	0
    296     }, {
    297 				/* Map 1MB for fast cache cleaning space */
    298 	I80312_CACHE_FLUSH_VBASE,
    299 	I80312_SA_CACHE_FLUSH_BASE,
    300 	I80312_CACHE_FLUSH_VSIZE,
    301 	1
    302     }, {
    303 				/* Map 1MB for PCI IO space */
    304 	I80312_PCI_IO_VBASE,
    305 	I80312_PCI_IO_BASE,
    306 	I80312_PCI_IO_VSIZE,
    307 	0
    308     }, {
    309 				/* Map 1MB for PCI IACK space */
    310 	I80312_PCI_IACK_VBASE,
    311 	I80312_PCI_IACK_SPECIAL,
    312 	I80312_PCI_IACK_VSIZE,
    313 	0
    314     }, {
    315 				/* Map 16MB of type 1 PCI config access */
    316 	I80312_PCI_TYPE_1_CONFIG_VBASE,
    317 	I80312_PCI_TYPE_1_CONFIG,
    318 	I80312_PCI_TYPE_1_CONFIG_VSIZE,
    319 	0
    320     }, {
    321 				/* Map 16MB of type 0 PCI config access */
    322 	I80312_PCI_TYPE_0_CONFIG_VBASE,
    323 	I80312_PCI_TYPE_0_CONFIG,
    324 	I80312_PCI_TYPE_0_CONFIG_VSIZE,
    325 	0
    326     }, {
    327 #if NISA > 0
    328 	/* Map 1MB of 32 bit PCI address space for ISA MEM accesses via PCI */
    329 	I80312_PCI_ISA_MEM_VBASE,
    330 	I80312_PCI_MEM_BASE,
    331 	I80312_PCI_ISA_MEM_VSIZE,
    332 	0
    333 #endif
    334     }, {
    335 	0,
    336 	0,
    337 	0,
    338 	0,
    339     }
    340 };
    341 
    342 /*
    343  * u_int initarm(struct ebsaboot *bootinfo)
    344  *
    345  * Initial entry point on startup. This gets called before main() is
    346  * entered.
    347  * It should be responsible for setting up everything that must be
    348  * in place when main is called.
    349  * This includes
    350  *   Taking a copy of the boot configuration structure.
    351  *   Initialising the physical console so characters can be printed.
    352  *   Setting up page tables for the kernel
    353  *   Relocating the kernel to the bottom of physical memory
    354  */
    355 
    356 u_int
    357 initarm(bootinfo)
    358 	struct nwbootinfo *bootinfo;
    359 {
    360 	int loop;
    361 	int loop1;
    362 	u_int l1pagetable;
    363 	u_int l2pagetable;
    364 	extern char page0[], page0_end[];
    365 #if 0
    366 	extern int end[];
    367 	extern int *esym;
    368 #endif
    369 	pv_addr_t kernel_l1pt;
    370 	pv_addr_t kernel_ptpt;
    371 
    372 	cn_tab = &kcomcons;
    373 	/*
    374 	 * Heads up ... Setup the CPU / MMU / TLB functions
    375 	 */
    376 	if (set_cpufuncs())
    377 		panic("cpu not recognized!");
    378 
    379 	/* Fake bootconfig structure for the benefit of pmap.c */
    380 	/* XXX must make the memory description h/w independant */
    381 	bootconfig.dramblocks = 1;
    382 	bootconfig.dram[0].address = 0xa0000000;
    383 	bootconfig.dram[0].pages = 0x02000000 / NBPG; /* nwbootinfo.bi_nrpages */
    384 	/*    - nwbootinfo.bt_memstart) / NBPG */;
    385 
    386 	/*
    387 	 * Initialise the diagnostic serial console
    388 	 * This allows a means of generating output during initarm().
    389 	 * Once all the memory map changes are complete we can call consinit()
    390 	 * and not have to worry about things moving.
    391 	 */
    392 
    393 	/* Talk to the user */
    394 	printf("\nNetBSD/netwinder booting ...\n");
    395 
    396 	/*
    397 	 * Ok we have the following memory map
    398 	 *
    399 	 * virtual address == physical address apart from the areas:
    400 	 * 0x00000000 -> 0x000fffff which is mapped to
    401 	 * top 1MB of physical memory
    402 	 * 0x00100000 -> 0x0fffffff which is mapped to
    403 	 * physical addresses 0x00100000 -> 0x0fffffff
    404 	 * 0x10000000 -> 0x1fffffff which is mapped to
    405 	 * physical addresses 0x00000000 -> 0x0fffffff
    406 	 * 0x20000000 -> 0xefffffff which is mapped to
    407 	 * physical addresses 0x20000000 -> 0xefffffff
    408 	 * 0xf0000000 -> 0xf03fffff which is mapped to
    409 	 * physical addresses 0xa0000000 -> 0xa03fffff
    410 	 *
    411 	 * This means that the kernel is mapped suitably for continuing
    412 	 * execution, all I/O is mapped 1:1 virtual to physical and
    413 	 * physical memory is accessible.
    414 	 *
    415 	 * The initarm() has the responsibility for creating the kernel
    416 	 * page tables.
    417 	 * It must also set up various memory pointers that are used
    418 	 * by pmap etc.
    419 	 */
    420 
    421 	/*
    422 	 * Examine the boot args string for options we need to know about
    423 	 * now.
    424 	 */
    425 #if 0
    426 	process_kernel_args((char *)nwbootinfo.bt_args);
    427 #endif
    428 
    429 	printf("initarm: Configuring system ...\n");
    430 
    431 	/*
    432 	 * Set up the variables that define the availablilty of
    433 	 * physical memory
    434 	 */
    435 	physical_start = 0 /*nwbootinfo.bt_memstart*/;
    436 	physical_freestart = physical_start;
    437 	physical_end = /*nwbootinfo.bt_memend*/ /*nwbootinfo.bi_nrpages * NBPG */ 64*1024*1024;
    438 	physical_freeend = physical_end;
    439 	free_pages = (physical_end - physical_start) / NBPG;
    440 
    441 	physmem = (physical_end - physical_start) / NBPG;
    442 
    443 	/* Tell the user about the memory */
    444 	printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem,
    445 	    physical_start, physical_end - 1);
    446 
    447 	/*
    448 	 * Ok the kernel occupies the bottom of physical memory.
    449 	 * The first free page after the kernel can be found in
    450 	 * nwbootinfo->bt_memavail
    451 	 * We now need to allocate some fixed page tables to get the kernel
    452 	 * going.
    453 	 * We allocate one page directory and a number page tables and store
    454 	 * the physical addresses in the kernel_pt_table array.
    455 	 *
    456 	 * Ok the next bit of physical allocation may look complex but it is
    457 	 * simple really. I have done it like this so that no memory gets
    458 	 * wasted during the allocation of various pages and tables that are
    459 	 * all different sizes.
    460 	 * The start addresses will be page aligned.
    461 	 * We allocate the kernel page directory on the first free 16KB boundry
    462 	 * we find.
    463 	 * We allocate the kernel page tables on the first 4KB boundry we find.
    464 	 * Since we allocate at least 3 L2 pagetables we know that we must
    465 	 * encounter at least one 16KB aligned address.
    466 	 */
    467 
    468 #ifdef VERBOSE_INIT_ARM
    469 	printf("Allocating page tables\n");
    470 #endif
    471 
    472 #if 0
    473 	/* Update the address of the first free 16KB chunk of physical memory */
    474         physical_freestart = ((uintptr_t) &end + PGOFSET) & ~PGOFSET;
    475 #if 0
    476         physical_freestart += (kernexec->a_syms + sizeof(int)
    477 		    + *(u_int *)((int)end + kernexec->a_syms + sizeof(int))
    478 		    + (NBPG - 1)) & ~(NBPG - 1);
    479 #endif
    480 #else
    481 	physical_freestart = 0x00200000;	/* start at 2MB */
    482 #endif
    483 
    484 	free_pages -= (physical_freestart - physical_start) / NBPG;
    485 #ifdef VERBOSE_INIT_ARM
    486 	printf("freestart = %#lx, free_pages = %d (%#x)\n",
    487 	       physical_freestart, free_pages, free_pages);
    488 #endif
    489 
    490 	/* Define a macro to simplify memory allocation */
    491 #define	valloc_pages(var, np)			\
    492 	alloc_pages((var).pv_pa, (np));		\
    493 	(var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start;
    494 
    495 #define alloc_pages(var, np)			\
    496 	(var) = physical_freestart;		\
    497 	physical_freestart += ((np) * NBPG);	\
    498 	free_pages -= (np);			\
    499 	memset((char *)(var), 0, ((np) * NBPG));
    500 
    501 	loop1 = 0;
    502 	kernel_l1pt.pv_pa = 0;
    503 	for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
    504 		/* Are we 16KB aligned for an L1 ? */
    505 		if ((physical_freestart & (PD_SIZE - 1)) == 0
    506 		    && kernel_l1pt.pv_pa == 0) {
    507 			valloc_pages(kernel_l1pt, PD_SIZE / NBPG);
    508 		} else {
    509 			alloc_pages(kernel_pt_table[loop1], PT_SIZE / NBPG);
    510 			++loop1;
    511 		}
    512 	}
    513 
    514 	/* This should never be able to happen but better confirm that. */
    515 	if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (PD_SIZE-1)) != 0)
    516 		panic("initarm: Failed to align the kernel page directory\n");
    517 
    518 	/*
    519 	 * Allocate a page for the system page mapped to V0x00000000
    520 	 * This page will just contain the system vectors and can be
    521 	 * shared by all processes.
    522 	 */
    523 	alloc_pages(systempage.pv_pa, 1);
    524 
    525 	/* Allocate a page for the page table to map kernel page tables*/
    526 	valloc_pages(kernel_ptpt, PT_SIZE / NBPG);
    527 
    528 	/* Allocate stacks for all modes */
    529 	valloc_pages(irqstack, IRQ_STACK_SIZE);
    530 	valloc_pages(abtstack, ABT_STACK_SIZE);
    531 	valloc_pages(undstack, UND_STACK_SIZE);
    532 	valloc_pages(kernelstack, UPAGES);
    533 
    534 #ifdef VERBOSE_INIT_ARM
    535 	printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa, irqstack.pv_va);
    536 	printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa, abtstack.pv_va);
    537 	printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa, undstack.pv_va);
    538 	printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa, kernelstack.pv_va);
    539 #endif
    540 
    541 	alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / NBPG);
    542 
    543 	/*
    544 	 * Ok we have allocated physical pages for the primary kernel
    545 	 * page tables
    546 	 */
    547 
    548 #ifdef VERBOSE_INIT_ARM
    549 	printf("Creating L1 page table at %#lx\n", kernel_l1pt.pv_pa);
    550 #endif
    551 
    552 	/*
    553 	 * Now we start consturction of the L1 page table
    554 	 * We start by mapping the L2 page tables into the L1.
    555 	 * This means that we can replace L1 mappings later on if necessary
    556 	 */
    557 	l1pagetable = kernel_l1pt.pv_pa;
    558 
    559 	/* Map the L2 pages tables in the L1 page table */
    560 	map_pagetable(l1pagetable, 0x00000000,
    561 	    kernel_pt_table[KERNEL_PT_SYS]);
    562 	map_pagetable(l1pagetable, KERNEL_BASE,
    563 	    kernel_pt_table[KERNEL_PT_KERNEL]);
    564 	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop)
    565 		map_pagetable(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
    566 		    kernel_pt_table[KERNEL_PT_VMDATA + loop]);
    567 	map_pagetable(l1pagetable, PROCESS_PAGE_TBLS_BASE,
    568 	    kernel_ptpt.pv_pa);
    569 
    570 #ifdef VERBOSE_INIT_ARM
    571 	printf("Mapping kernel\n");
    572 #endif
    573 
    574 	/* Now we fill in the L2 pagetable for the kernel static code/data */
    575 	l2pagetable = kernel_pt_table[KERNEL_PT_KERNEL];
    576 
    577 #if 0
    578 	{
    579 		u_int logical;
    580 		extern int etext, end;
    581 		size_t textsize = (uintptr_t) &etext - KERNEL_TEXT_BASE;
    582 		size_t totalsize = (uintptr_t) &end - KERNEL_TEXT_BASE;
    583 
    584 		/* Round down text size and round up total size
    585 		 */
    586 		textsize = textsize & ~PGOFSET;
    587 		totalsize = (totalsize + PGOFSET) & ~PGOFSET;
    588 		logical  = map_chunk(0, l2pagetable, KERNEL_BASE,
    589 		    physical_start, KERNEL_TEXT_BASE - KERNEL_BASE,
    590 		    AP_KRW, PT_CACHEABLE);
    591 		logical += map_chunk(0, l2pagetable, KERNEL_BASE + logical,
    592 		    physical_start + logical, textsize,
    593 		    AP_KRW, PT_CACHEABLE);
    594 		logical += map_chunk(0, l2pagetable, KERNEL_BASE + logical,
    595 		    physical_start + logical, totalsize - textsize,
    596 		    AP_KRW, PT_CACHEABLE);
    597 #if 0
    598 		logical += map_chunk(0, l2pagetable, KERNEL_BASE + logical,
    599 		    physical_start + logical, kernexec->a_syms + sizeof(int)
    600 		    + *(u_int *)((int)end + kernexec->a_syms + sizeof(int)),
    601 		    AP_KRW, PT_CACHEABLE);
    602 #endif
    603 	}
    604 #else
    605 	map_section(l1pagetable, 0xf0000000, 0x00000000, 1);
    606 	map_section(l1pagetable, 0xf0100000, 0x00100000, 1);
    607 #endif
    608 #if 0
    609 	/*
    610 	 * PATCH PATCH ...
    611 	 *
    612 	 * Fixup the first word of the kernel to be the instruction
    613 	 * add pc, pc, #0x41000000
    614 	 *
    615 	 * This traps the case where the CPU core resets due to bus contention
    616 	 * on a prototype CATS system and will reboot into the firmware.
    617 	 */
    618 	*((u_int *)KERNEL_TEXT_BASE) = 0xe28ff441;
    619 #endif
    620 
    621 #ifdef VERBOSE_INIT_ARM
    622 	printf("Constructing L2 page tables\n");
    623 #endif
    624 
    625 	/* Map the boot arguments page */
    626 #if 0
    627 	map_entry_ro(l2pagetable, nwbootinfo.bt_vargp, nwbootinfo.bt_pargp);
    628 #endif
    629 
    630 	/* Map the stack pages */
    631 	map_chunk(0, l2pagetable, irqstack.pv_va, irqstack.pv_pa,
    632 	    IRQ_STACK_SIZE * NBPG, AP_KRW, PT_CACHEABLE);
    633 	map_chunk(0, l2pagetable, abtstack.pv_va, abtstack.pv_pa,
    634 	    ABT_STACK_SIZE * NBPG, AP_KRW, PT_CACHEABLE);
    635 	map_chunk(0, l2pagetable, undstack.pv_va, undstack.pv_pa,
    636 	    UND_STACK_SIZE * NBPG, AP_KRW, PT_CACHEABLE);
    637 	map_chunk(0, l2pagetable, kernelstack.pv_va, kernelstack.pv_pa,
    638 	    UPAGES * NBPG, AP_KRW, PT_CACHEABLE);
    639 	map_chunk(0, l2pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
    640 	    PD_SIZE, AP_KRW, 0);
    641 
    642 	/* Map the page table that maps the kernel pages */
    643 	map_entry_nc(l2pagetable, kernel_ptpt.pv_pa, kernel_ptpt.pv_pa);
    644 
    645 	/*
    646 	 * Map entries in the page table used to map PTE's
    647 	 * Basically every kernel page table gets mapped here
    648 	 */
    649 	/* The -2 is slightly bogus, it should be -log2(sizeof(pt_entry_t)) */
    650 	l2pagetable = kernel_ptpt.pv_pa;
    651 	map_entry_nc(l2pagetable, (KERNEL_BASE >> (PGSHIFT-2)),
    652 	    kernel_pt_table[KERNEL_PT_KERNEL]);
    653 	map_entry_nc(l2pagetable, (PROCESS_PAGE_TBLS_BASE >> (PGSHIFT-2)),
    654 	    kernel_ptpt.pv_pa);
    655 	map_entry_nc(l2pagetable, (0x00000000 >> (PGSHIFT-2)),
    656 	    kernel_pt_table[KERNEL_PT_SYS]);
    657 	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop)
    658 		map_entry_nc(l2pagetable, ((KERNEL_VM_BASE +
    659 		    (loop * 0x00400000)) >> (PGSHIFT-2)),
    660 		    kernel_pt_table[KERNEL_PT_VMDATA + loop]);
    661 
    662 	/*
    663 	 * Map the system page in the kernel page table for the bottom 1Meg
    664 	 * of the virtual memory map.
    665 	 */
    666 	l2pagetable = kernel_pt_table[KERNEL_PT_SYS];
    667 	map_entry(l2pagetable, 0x00000000, systempage.pv_pa);
    668 
    669 	/* Map the core memory needed before autoconfig */
    670 	loop = 0;
    671 	while (l1_sec_table[loop].size) {
    672 		vm_size_t sz;
    673 
    674 #ifdef VERBOSE_INIT_ARM
    675 		printf("%08lx -> %08lx @ %08lx\n", l1_sec_table[loop].pa,
    676 		    l1_sec_table[loop].pa + l1_sec_table[loop].size - 1,
    677 		    l1_sec_table[loop].va);
    678 #endif
    679 		for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_SEC_SIZE)
    680 			map_section(l1pagetable, l1_sec_table[loop].va + sz,
    681 			    l1_sec_table[loop].pa + sz,
    682 			    l1_sec_table[loop].flags);
    683 		++loop;
    684 	}
    685 
    686 	/*
    687 	 * Now we have the real page tables in place so we can switch to them.
    688 	 * Once this is done we will be running with the REAL kernel page tables.
    689 	 */
    690 
    691 	/* Switch tables */
    692 #ifdef VERBOSE_INIT_ARM
    693 	printf("freestart = %#lx, free_pages = %d (%#x)\n",
    694 	       physical_freestart, free_pages, free_pages);
    695 	printf("switching to new L1 page table  @%#lx...", kernel_l1pt.pv_pa);
    696 #endif
    697 
    698 	setttb(kernel_l1pt.pv_pa);
    699 
    700 #ifdef VERBOSE_INIT_ARM
    701 	printf("done!\n");
    702 #endif
    703 	/*
    704 	 * Ok the I80312 CSR registers have just moved.
    705 	 * Detach the diagnostic serial port and reattach at the new address.
    706 	 */
    707 
    708 	/*
    709 	 * XXX this should only be done in main() but it useful to
    710 	 * have output earlier ...
    711 	 */
    712 	consinit();
    713 
    714 #ifdef VERBOSE_INIT_ARM
    715 	printf("bootstrap done.\n");
    716 #endif
    717 
    718 	/* Right set up the vectors at the bottom of page 0 */
    719 	memcpy((char *)0x00000000, page0, page0_end - page0);
    720 
    721 	/* We have modified a text page so sync the icache */
    722 	cpu_cache_syncI();
    723 
    724 	/*
    725 	 * Pages were allocated during the secondary bootstrap for the
    726 	 * stacks for different CPU modes.
    727 	 * We must now set the r13 registers in the different CPU modes to
    728 	 * point to these stacks.
    729 	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
    730 	 * of the stack memory.
    731 	 */
    732 	printf("init subsystems: stacks ");
    733 
    734 	set_stackptr(PSR_IRQ32_MODE, irqstack.pv_va + IRQ_STACK_SIZE * NBPG);
    735 	set_stackptr(PSR_ABT32_MODE, abtstack.pv_va + ABT_STACK_SIZE * NBPG);
    736 	set_stackptr(PSR_UND32_MODE, undstack.pv_va + UND_STACK_SIZE * NBPG);
    737 
    738 	/*
    739 	 * Well we should set a data abort handler.
    740 	 * Once things get going this will change as we will need a proper handler.
    741 	 * Until then we will use a handler that just panics but tells us
    742 	 * why.
    743 	 * Initialisation of the vectors will just panic on a data abort.
    744 	 * This just fills in a slighly better one.
    745 	 */
    746 	printf("vectors ");
    747 	data_abort_handler_address = (u_int)data_abort_handler;
    748 	prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
    749 	undefined_handler_address = (u_int)undefinedinstruction_bounce;
    750 
    751 	/* At last !
    752 	 * We now have the kernel in physical memory from the bottom upwards.
    753 	 * Kernel page tables are physically above this.
    754 	 * The kernel is mapped to KERNEL_TEXT_BASE
    755 	 * The kernel data PTs will handle the mapping of 0xf1000000-0xf3ffffff
    756 	 * The page tables are mapped to 0xefc00000
    757 	 */
    758 
    759 	/* Initialise the undefined instruction handlers */
    760 	printf("undefined ");
    761 	undefined_init();
    762 
    763 	/* Boot strap pmap telling it where the kernel page table is */
    764 	printf("pmap ");
    765 	pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, kernel_ptpt);
    766 
    767 	/* Setup the IRQ system */
    768 	printf("irq ");
    769 	irq_init();
    770 	printf("done.\n");
    771 
    772 #ifdef IPKDB
    773 	/* Initialise ipkdb */
    774 	ipkdb_init();
    775 	if (boothowto & RB_KDB)
    776 		ipkdb_connect(0);
    777 #endif
    778 
    779 #ifdef DDB
    780 	printf("ddb: ");
    781 	db_machine_init();
    782 #if 0
    783 	ddb_init(end[0], end + 1, esym);
    784 #endif
    785 
    786 	if (boothowto & RB_KDB)
    787 		Debugger();
    788 #endif
    789 
    790 	/* We return the new stack pointer address */
    791 	return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
    792 }
    793 
    794 void
    795 process_kernel_args(args)
    796 	char *args;
    797 {
    798 
    799 	boothowto = 0;
    800 
    801 	/* Make a local copy of the bootargs */
    802 	strncpy(bootargs, args, MAX_BOOT_STRING);
    803 
    804 	args = bootargs;
    805 	boot_file = bootargs;
    806 
    807 	/* Skip the kernel image filename */
    808 	while (*args != ' ' && *args != 0)
    809 		++args;
    810 
    811 	if (*args != 0)
    812 		*args++ = 0;
    813 
    814 	while (*args == ' ')
    815 		++args;
    816 
    817 	boot_args = args;
    818 
    819 	printf("bootfile: %s\n", boot_file);
    820 	printf("bootargs: %s\n", boot_args);
    821 
    822 	parse_mi_bootargs(boot_args);
    823 }
    824 
    825 #if 0
    826 void
    827 arm32_cachectl(va, len, flags)
    828 	vm_offset_t va;
    829 	int len;
    830 	int flags;
    831 {
    832 	pt_entry_t *ptep, pte;
    833 	int loop;
    834 	vm_offset_t addr;
    835 
    836 /*	printf("arm32_cachectl(%x,%x,%x)\n", va, len, flags);*/
    837 
    838 	if (flags & 1) {
    839 		addr = va;
    840 		loop = len;
    841 		while (loop > 0) {
    842 			ptep = vtopte(addr & (~PGOFSET));
    843 			pte = *ptep;
    844 
    845 			*ptep = (pte & ~(PT_C | PT_B)) | (flags & (PT_C | PT_B));
    846 
    847 			loop -= NBPG;
    848 			addr += NBPG;
    849 		}
    850 		tlb_flush();
    851 	}
    852 
    853 	cpu_cache_purgeD_rng(va, len);
    854 }
    855 #endif
    856 
    857 extern struct bus_space footbridge_pci_io_bs_tag;
    858 extern struct bus_space footbridge_pci_mem_bs_tag;
    859 void footbridge_pci_bs_tag_init __P((void));
    860 
    861 void
    862 consinit(void)
    863 {
    864 	static int consinit_called = 0;
    865 
    866 	if (consinit_called != 0)
    867 		return;
    868 
    869 	consinit_called = 1;
    870 
    871 	bust = iq80310_bs_init();
    872 #if (NCOM > 0)
    873 	if (comcnattach(&bust, CONCOMADDR, comcnspeed,
    874 		    COM_FREQ, comcnmode))
    875 			panic("can't init serial console @%x", CONCOMADDR);
    876 #else
    877 	panic("serial console @%x not configured", CONCOMADDR);
    878 #endif
    879 	}
    880 }
    881 
    882 static bus_space_handle_t kcom_base = (bus_space_handle_t) I80312_COM0_VBASE;
    883 
    884 u_int8_t i80312_bs_r_1(void *, bus_space_handle_t, bus_size_t);
    885 void i80312_bs_w_1(void *, bus_space_handle_t, bus_size_t, u_int8_t);
    886 
    887 #define	KCOM_GETBYTE(r)		i80312_bs_r_1(0, kcom_base, (r))
    888 #define	KCOM_PUTBYTE(r,v)	i80312_bs_w_1(0, kcom_base, (r), (v))
    889 
    890 static int
    891 kcomcngetc(dev_t dev)
    892 {
    893 	int stat, c;
    894 
    895 	/* block until a character becomes available */
    896 	while (!ISSET(stat = KCOM_GETBYTE(com_lsr), LSR_RXRDY))
    897 		;
    898 
    899 	c = KCOM_GETBYTE(com_data);
    900 	stat = KCOM_GETBYTE(com_iir);
    901 	return c;
    902 }
    903 
    904 /*
    905  * Console kernel output character routine.
    906  */
    907 static void
    908 kcomcnputc(dev_t dev, int c)
    909 {
    910 	int timo;
    911 
    912 	/* wait for any pending transmission to finish */
    913 	timo = 150000;
    914 	while (!ISSET(KCOM_GETBYTE(com_lsr), LSR_TXRDY) && --timo)
    915 		continue;
    916 
    917 	KCOM_PUTBYTE(com_data, c);
    918 
    919 	/* wait for this transmission to complete */
    920 	timo = 1500000;
    921 	while (!ISSET(KCOM_GETBYTE(com_lsr), LSR_TXRDY) && --timo)
    922 		continue;
    923 }
    924 
    925 static void
    926 kcomcnpollc(dev_t dev, int on)
    927 {
    928 }
    929 
    930 struct consdev kcomcons = {
    931 	NULL, NULL, kcomcngetc, kcomcnputc, kcomcnpollc, NULL,
    932 	NODEV, CN_NORMAL
    933 };
    934