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>