Annotation of sys/arch/zaurus/zaurus/zaurus_machdep.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: zaurus_machdep.c,v 1.27 2007/05/19 15:49:06 miod Exp $ */
2: /* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */
3:
4: /*
5: * Copyright (c) 2002, 2003 Genetec Corporation. All rights reserved.
6: * Written by Hiroyuki Bessho for Genetec Corporation.
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. The name of Genetec Corporation may not be used to endorse or
17: * promote products derived from this software without specific prior
18: * written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
24: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30: * POSSIBILITY OF SUCH DAMAGE.
31: *
32: * Machine dependant functions for kernel setup for
33: * Intel DBPXA250 evaluation board (a.k.a. Lubbock).
34: * Based on iq80310_machhdep.c
35: */
36: /*
37: * Copyright (c) 2001 Wasabi Systems, Inc.
38: * All rights reserved.
39: *
40: * Written by Jason R. Thorpe for Wasabi Systems, Inc.
41: *
42: * Redistribution and use in source and binary forms, with or without
43: * modification, are permitted provided that the following conditions
44: * are met:
45: * 1. Redistributions of source code must retain the above copyright
46: * notice, this list of conditions and the following disclaimer.
47: * 2. Redistributions in binary form must reproduce the above copyright
48: * notice, this list of conditions and the following disclaimer in the
49: * documentation and/or other materials provided with the distribution.
50: * 3. All advertising materials mentioning features or use of this software
51: * must display the following acknowledgement:
52: * This product includes software developed for the NetBSD Project by
53: * Wasabi Systems, Inc.
54: * 4. The name of Wasabi Systems, Inc. may not be used to endorse
55: * or promote products derived from this software without specific prior
56: * written permission.
57: *
58: * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
59: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
60: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
61: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
62: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
63: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
64: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
65: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
66: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
67: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
68: * POSSIBILITY OF SUCH DAMAGE.
69: */
70:
71: /*
72: * Copyright (c) 1997,1998 Mark Brinicombe.
73: * Copyright (c) 1997,1998 Causality Limited.
74: * All rights reserved.
75: *
76: * Redistribution and use in source and binary forms, with or without
77: * modification, are permitted provided that the following conditions
78: * are met:
79: * 1. Redistributions of source code must retain the above copyright
80: * notice, this list of conditions and the following disclaimer.
81: * 2. Redistributions in binary form must reproduce the above copyright
82: * notice, this list of conditions and the following disclaimer in the
83: * documentation and/or other materials provided with the distribution.
84: * 3. All advertising materials mentioning features or use of this software
85: * must display the following acknowledgement:
86: * This product includes software developed by Mark Brinicombe
87: * for the NetBSD Project.
88: * 4. The name of the company nor the name of the author may be used to
89: * endorse or promote products derived from this software without specific
90: * prior written permission.
91: *
92: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
93: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
94: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
95: * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
96: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
98: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
100: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
101: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
102: * SUCH DAMAGE.
103: *
104: * Machine dependant functions for kernel setup for Intel IQ80310 evaluation
105: * boards using RedBoot firmware.
106: */
107:
108: /*
109: * DIP switches:
110: *
111: * S19: no-dot: set RB_KDB. enter kgdb session.
112: * S20: no-dot: set RB_SINGLE. don't go multi user mode.
113: */
114:
115: #include <sys/param.h>
116: #include <sys/device.h>
117: #include <sys/systm.h>
118: #include <sys/kernel.h>
119: #include <sys/exec.h>
120: #include <sys/proc.h>
121: #include <sys/msgbuf.h>
122: #include <sys/reboot.h>
123: #include <sys/termios.h>
124: #include <sys/kcore.h>
125:
126: #include <uvm/uvm_extern.h>
127:
128: #include <sys/conf.h>
129: #include <sys/queue.h>
130: #include <sys/device.h>
131: #include <dev/cons.h>
132: #include <dev/ic/smc91cxxreg.h>
133:
134: #include <machine/db_machdep.h>
135: #include <ddb/db_sym.h>
136: #include <ddb/db_extern.h>
137: #ifdef KGDB
138: #include <sys/kgdb.h>
139: #endif
140:
141: #include <machine/bootconfig.h>
142: #include <machine/bus.h>
143: #include <machine/cpu.h>
144: #include <machine/frame.h>
145: #include <arm/kcore.h>
146: #include <arm/undefined.h>
147: #include <arm/machdep.h>
148:
149: #include <arm/xscale/pxa2x0reg.h>
150: #include <arm/xscale/pxa2x0var.h>
151: #include <arm/xscale/pxa2x0_gpio.h>
152: #include <arm/sa11x0/sa1111_reg.h>
153: #include <machine/zaurus_reg.h>
154: #include <machine/zaurus_var.h>
155:
156: #include <zaurus/dev/zaurus_scoopreg.h>
157:
158: #include "apm.h"
159: #if NAPM > 0
160: #include <zaurus/dev/zaurus_apm.h>
161: #endif
162:
163: #include "wsdisplay.h"
164:
165: /* Kernel text starts 2MB in from the bottom of the kernel address space. */
166: #define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00200000)
167: #define KERNEL_VM_BASE (KERNEL_BASE + 0x04000000)
168:
169: /*
170: * The range 0xc1000000 - 0xccffffff is available for kernel VM space
171: * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff
172: */
173: /*
174: #define KERNEL_VM_SIZE 0x0C000000
175: */
176: #define KERNEL_VM_SIZE 0x10000000
177:
178:
179: /*
180: * Address to call from cpu_reset() to reset the machine.
181: * This is machine architecture dependant as it varies depending
182: * on where the ROM appears when you turn the MMU off.
183: */
184:
185: u_int cpu_reset_address = 0;
186:
187: /* Define various stack sizes in pages */
188: #define IRQ_STACK_SIZE 1
189: #define ABT_STACK_SIZE 1
190: #ifdef IPKDB
191: #define UND_STACK_SIZE 2
192: #else
193: #define UND_STACK_SIZE 1
194: #endif
195:
196: int zaurusmod;
197:
198: BootConfig bootconfig; /* Boot config storage */
199: char *boot_args = NULL;
200: char *boot_file = NULL;
201:
202: paddr_t physical_start;
203: paddr_t physical_freestart;
204: paddr_t physical_freeend;
205: paddr_t physical_end;
206: u_int free_pages;
207: int physmem = 0;
208:
209: /*int debug_flags;*/
210: #ifndef PMAP_STATIC_L1S
211: int max_processes = 64; /* Default number */
212: #endif /* !PMAP_STATIC_L1S */
213:
214: /* Physical and virtual addresses for some global pages */
215: pv_addr_t systempage;
216: pv_addr_t irqstack;
217: pv_addr_t undstack;
218: pv_addr_t abtstack;
219: extern pv_addr_t kernelstack;
220: pv_addr_t minidataclean;
221:
222: paddr_t msgbufphys;
223:
224: extern u_int data_abort_handler_address;
225: extern u_int prefetch_abort_handler_address;
226: extern u_int undefined_handler_address;
227:
228: #ifdef PMAP_DEBUG
229: extern int pmap_debug_level;
230: #endif
231:
232: #define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
233: #define KERNEL_PT_KERNEL 1 /* Page table for mapping kernel */
234: #define KERNEL_PT_KERNEL_NUM 32
235: #define KERNEL_PT_VMDATA (KERNEL_PT_KERNEL+KERNEL_PT_KERNEL_NUM)
236: /* Page tables for mapping kernel VM */
237: #define KERNEL_PT_VMDATA_NUM 8 /* start with 32MB of KVM */
238: #define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)
239:
240: pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];
241:
242: extern struct user *proc0paddr;
243:
244: /* Prototypes */
245:
246: #define BOOT_STRING_MAGIC 0x4f425344
247:
248: char bootargs[MAX_BOOT_STRING];
249: void process_kernel_args(char *);
250:
251: void consinit(void);
252: void early_clkman(u_int, int);
253: void kgdb_port_init(void);
254: void change_clock(uint32_t v);
255:
256: bs_protos(bs_notimpl);
257:
258: #include "com.h"
259: #if NCOM > 0
260: #include <dev/ic/comvar.h>
261: #include <dev/ic/comreg.h>
262: #endif
263:
264: #ifndef CONSPEED
265: #define CONSPEED B9600 /* What RedBoot uses */
266: #endif
267: #ifndef CONMODE
268: #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
269: #endif
270:
271: int comcnspeed = CONSPEED;
272: int comcnmode = CONMODE;
273:
274:
275: /*
276: * void boot(int howto, char *bootstr)
277: *
278: * Reboots the system
279: *
280: * Deal with any syncing, unmounting, dumping and shutdown hooks,
281: * then reset the CPU.
282: */
283: void
284: boot(int howto)
285: {
286: /*
287: * If we are still cold then hit the air brakes
288: * and crash to earth fast
289: */
290: if (cold) {
291: doshutdownhooks();
292: if ((howto & (RB_HALT | RB_USERREQ)) != RB_USERREQ) {
293: printf("The operating system has halted.\n");
294: printf("Please press any key to reboot.\n\n");
295: cngetc();
296: }
297: printf("rebooting...\n");
298: delay(6000000);
299: #if NAPM > 0
300: zapm_restart();
301: #endif
302: printf("reboot failed; spinning\n");
303: while(1);
304: /*NOTREACHED*/
305: }
306:
307: /* Disable console buffering */
308: /* cnpollc(1);*/
309:
310: /*
311: * If RB_NOSYNC was not specified sync the discs.
312: * Note: Unless cold is set to 1 here, syslogd will die during the
313: * unmount. It looks like syslogd is getting woken up only to find
314: * that it cannot page part of the binary in as the filesystem has
315: * been unmounted.
316: */
317: if (!(howto & RB_NOSYNC))
318: bootsync(howto);
319:
320: /* Say NO to interrupts */
321: splhigh();
322:
323: /* Do a dump if requested. */
324: if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
325: dumpsys();
326:
327: /* Run any shutdown hooks */
328: doshutdownhooks();
329:
330: /* Make sure IRQ's are disabled */
331: IRQdisable;
332:
333: if (howto & RB_HALT) {
334: #if NAPM > 0
335: if (howto & RB_POWERDOWN) {
336:
337: printf("\nAttempting to power down...\n");
338: delay(6000000);
339: zapm_poweroff();
340: }
341: #endif
342:
343: printf("The operating system has halted.\n");
344: printf("Please press any key to reboot.\n\n");
345: cngetc();
346: }
347:
348: printf("rebooting...\n");
349: delay(6000000);
350: #if NAPM > 0
351: zapm_restart();
352: #endif
353: printf("reboot failed; spinning\n");
354: while(1);
355: /*NOTREACHED*/
356: }
357:
358: static __inline
359: pd_entry_t *
360: read_ttb(void)
361: {
362: long ttb;
363:
364: __asm __volatile("mrc p15, 0, %0, c2, c0, 0" : "=r" (ttb));
365:
366:
367: return (pd_entry_t *)(ttb & ~((1<<14)-1));
368: }
369:
370: /*
371: * Mapping table for core kernel memory. These areas are mapped in
372: * init time at fixed virtual address with section mappings.
373: */
374: struct l1_sec_map {
375: vaddr_t va;
376: vaddr_t pa;
377: vsize_t size;
378: int flags;
379: } l1_sec_table[] = {
380: {
381: ZAURUS_GPIO_VBASE,
382: PXA2X0_GPIO_BASE,
383: PXA2X0_GPIO_SIZE,
384: PTE_NOCACHE,
385: },
386: {
387: ZAURUS_CLKMAN_VBASE,
388: PXA2X0_CLKMAN_BASE,
389: PXA2X0_CLKMAN_SIZE,
390: PTE_NOCACHE,
391: },
392: {
393: ZAURUS_INTCTL_VBASE,
394: PXA2X0_INTCTL_BASE,
395: PXA2X0_INTCTL_SIZE,
396: PTE_NOCACHE,
397: },
398: {
399: ZAURUS_SCOOP0_VBASE,
400: C3000_SCOOP0_BASE,
401: SCOOP_SIZE,
402: PTE_NOCACHE,
403: },
404: {
405: ZAURUS_SCOOP1_VBASE,
406: trunc_page(C3000_SCOOP1_BASE),
407: round_page(SCOOP_SIZE),
408: PTE_NOCACHE,
409: },
410: {0, 0, 0, 0,}
411: };
412:
413: static void
414: map_io_area(paddr_t pagedir)
415: {
416: int loop;
417:
418: /*
419: * Map devices we can map w/ section mappings.
420: */
421: loop = 0;
422: while (l1_sec_table[loop].size) {
423: vsize_t sz;
424:
425: #define VERBOSE_INIT_ARM
426: #ifdef VERBOSE_INIT_ARM
427: printf("%08lx -> %08lx @ %08lx\n", l1_sec_table[loop].pa,
428: l1_sec_table[loop].pa + l1_sec_table[loop].size - 1,
429: l1_sec_table[loop].va);
430: #endif
431: for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_S_SIZE)
432: pmap_map_section(pagedir, l1_sec_table[loop].va + sz,
433: l1_sec_table[loop].pa + sz,
434: VM_PROT_READ|VM_PROT_WRITE,
435: l1_sec_table[loop].flags);
436: ++loop;
437: }
438: }
439:
440: /*
441: * simple memory mapping function used in early bootstrap stage
442: * before pmap is initialized.
443: * size and cacheability are ignored and map one section with nocache.
444: */
445: static vaddr_t section_free = ZAURUS_VBASE_FREE;
446:
447: static int
448: bootstrap_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
449: int cacheable, bus_space_handle_t *bshp)
450: {
451: u_long startpa;
452: vaddr_t va;
453: pd_entry_t *pagedir = read_ttb();
454: /* This assumes PA==VA for page directory */
455:
456: va = section_free;
457: section_free += L1_S_SIZE;
458:
459: startpa = trunc_page(bpa);
460: pmap_map_section((vaddr_t)pagedir, va, startpa,
461: VM_PROT_READ | VM_PROT_WRITE, PTE_NOCACHE);
462: cpu_tlb_flushD();
463:
464: *bshp = (bus_space_handle_t)(va + (bpa - startpa));
465:
466: return(0);
467: }
468:
469: static void
470: copy_io_area_map(pd_entry_t *new_pd)
471: {
472: pd_entry_t *cur_pd = read_ttb();
473: vaddr_t va;
474:
475: for (va = ZAURUS_IO_AREA_VBASE;
476: (cur_pd[va>>L1_S_SHIFT] & L1_TYPE_MASK) == L1_TYPE_S;
477: va += L1_S_SIZE) {
478:
479: new_pd[va>>L1_S_SHIFT] = cur_pd[va>>L1_S_SHIFT];
480: if (va == (0 - L1_S_SIZE))
481: break; /* STUPID */
482:
483: }
484: }
485:
486: /* XXX tidy up! */
487: void green_on(int virt);
488: void
489: green_on(int virt)
490: {
491: /* clobber green led p */
492: volatile u_int16_t *p;
493: if (virt)
494: p = (u_int16_t *)(ZAURUS_SCOOP0_VBASE+SCOOP_GPWR);
495: else
496: p = (u_int16_t *)(C3000_SCOOP0_BASE+SCOOP_GPWR);
497:
498: *p = *p | (1<<SCOOP0_LED_GREEN);
499: }
500: void irda_on(int virt);
501: void
502: irda_on(int virt)
503: {
504: /* clobber IrDA led p */
505: volatile u_int16_t *p;
506: /* XXX scoop1 registers are not page-aligned! */
507: int ofs = C3000_SCOOP1_BASE - trunc_page(C3000_SCOOP1_BASE);
508:
509: if (virt)
510: p = (u_int16_t *)(ZAURUS_SCOOP1_VBASE+ofs+SCOOP_GPWR);
511: else
512: p = (u_int16_t *)(C3000_SCOOP1_BASE+SCOOP_GPWR);
513:
514: *p = *p & ~(1<<SCOOP1_IR_ON);
515: }
516:
517: #if 0
518: void sysprobe(void);
519: void
520: sysprobe(void)
521: {
522: u_int32_t *p;
523:
524: p = (void *)0x48000014; /* MECR */
525: printf("MECR %x\n", *p);
526:
527: p = (void *)0x48000028; /* MCMEM0 */
528: printf("MCMEM0 %x\n", *p);
529: p = (void *)0x4800002C; /* MCMEM1 */
530: printf("MCMEM1 %x\n", *p);
531:
532: p = (void *)0x48000030; /* MCATTx */
533: printf("MCATT0 %x\n", *p);
534: p = (void *)0x48000034; /* MCATTx */
535: printf("MCATT1 %x\n", *p);
536:
537: p = (void *)0x48000038; /* MCIOx */
538: printf("MCIO0 %x\n", *p);
539: p = (void *)0x4800003C; /* MCIOx */
540: printf("MCIO1 %x\n", *p);
541: }
542: #endif
543:
544: /*
545: * u_int initarm(...)
546: *
547: * Initial entry point on startup. This gets called before main() is
548: * entered.
549: * It should be responsible for setting up everything that must be
550: * in place when main is called.
551: * This includes
552: * Taking a copy of the boot configuration structure.
553: * Initialising the physical console so characters can be printed.
554: * Setting up page tables for the kernel
555: * Relocating the kernel to the bottom of physical memory
556: */
557: u_int
558: initarm(void *arg)
559: {
560: extern vaddr_t xscale_cache_clean_addr;
561: extern cpu_kcore_hdr_t cpu_kcore_hdr;
562: int loop;
563: int loop1;
564: u_int l1pagetable;
565: pv_addr_t kernel_l1pt;
566: paddr_t memstart;
567: psize_t memsize;
568: extern u_int32_t esym; /* &_end if no symbols are loaded */
569:
570: #if 0
571: int led_data = 0;
572: #endif
573: #ifdef DIAGNOSTIC
574: extern vsize_t xscale_minidata_clean_size; /* used in KASSERT */
575: #endif
576: /* early bus_space_map support */
577: struct bus_space tmp_bs_tag;
578: int (*map_func_save)(void *, bus_addr_t, bus_size_t, int,
579: bus_space_handle_t *);
580:
581:
582: #if 0
583: /* XXX */
584: /* start 32.768KHz OSC */
585: ioreg_write(PXA2X0_CLKMAN_BASE + 0x08, 2);
586: #endif
587:
588: /*
589: * Heads up ... Setup the CPU / MMU / TLB functions
590: */
591: if (set_cpufuncs())
592: panic("cpu not recognized!");
593:
594: /* Get ready for splfoo() */
595: pxa2x0_intr_bootstrap(PXA2X0_INTCTL_BASE);
596:
597: #if 0
598: /* Calibrate the delay loop. */
599: #endif
600:
601: /*
602: * Okay, RedBoot has provided us with the following memory map:
603: *
604: * Physical Address Range Description
605: * ----------------------- ----------------------------------
606: * 0x00000000 - 0x01ffffff flash Memory (32MB)
607: * 0x04000000 - 0x05ffffff Application flash Memory (32MB)
608: * 0x08000000 - 0x080000ff I/O baseboard registers
609: * 0x0a000000 - 0x0a0fffff SRAM (1MB)
610: * 0x0c000000 - 0x0c0fffff Ethernet Controller
611: * 0x0e000000 - 0x0e0fffff Ethernet Controller (Attribute)
612: * 0x10000000 - 0x103fffff SA-1111 Companion Chip
613: * 0x14000000 - 0x17ffffff Expansion Card (64MB)
614: * 0x40000000 - 0x480fffff Processor Registers
615: * 0xa0000000 - 0xa3ffffff SDRAM Bank 0 (64MB)
616: *
617: *
618: * Virtual Address Range X C B Description
619: * ----------------------- - - - ----------------------------------
620: * 0x00000000 - 0x00003fff N Y Y SDRAM
621: * 0x00004000 - 0x000fffff N Y N Boot ROM
622: * 0x00100000 - 0x01ffffff N N N Application Flash
623: * 0x04000000 - 0x05ffffff N N N Exp Application Flash
624: * 0x08000000 - 0x080fffff N N N I/O baseboard registers
625: * 0x0a000000 - 0x0a0fffff N N N SRAM
626: * 0x40000000 - 0x480fffff N N N Processor Registers
627: * 0xa0000000 - 0xa000ffff N Y N RedBoot SDRAM
628: * 0xa0017000 - 0xa3ffffff Y Y Y SDRAM
629: * 0xc0000000 - 0xcfffffff Y Y Y Cache Flush Region
630: * (done by this routine)
631: * 0xfd000000 - 0xfd0000ff N N N I/O baseboard registers
632: * 0xfd100000 - 0xfd2fffff N N N Processor Registers.
633: * 0xfd200000 - 0xfd2fffff N N N 0x10800000 registers
634: *
635: * The first level page table is at 0xa0004000. There are also
636: * 2 second-level tables at 0xa0008000 and 0xa0008400.
637: *
638: */
639:
640: {
641: /*
642: * Tweak RedBoot's pagetable so that we can access to
643: * some registers at same VA before and after installing
644: * our page table.
645: */
646: paddr_t ttb = (paddr_t)read_ttb();
647:
648: map_io_area(ttb);
649: cpu_tlb_flushD();
650: }
651:
652: /*
653: * Examine the boot args string for options we need to know about
654: * now.
655: */
656: /* XXX should really be done after setting up the console, but we
657: * XXX need to parse the console selection flags right now. */
658: process_kernel_args((char *)0xa0200000 - MAX_BOOT_STRING - 1);
659: #ifdef RAMDISK_HOOKS
660: boothowto |= RB_DFLTROOT;
661: #endif /* RAMDISK_HOOKS */
662:
663: /*
664: * This test will work for now but has to be revised when support
665: * for other models is added.
666: */
667: if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X)
668: zaurusmod = ZAURUS_C3000;
669: else
670: zaurusmod = ZAURUS_C860;
671:
672: /* setup GPIO for BTUART, in case bootloader doesn't take care of it */
673: pxa2x0_gpio_bootstrap(ZAURUS_GPIO_VBASE);
674: #if 0
675: pxa2x0_gpio_set_function(42, GPIO_ALT_FN_1_IN);
676: pxa2x0_gpio_set_function(43, GPIO_ALT_FN_2_OUT);
677: pxa2x0_gpio_set_function(44, GPIO_ALT_FN_1_IN);
678: pxa2x0_gpio_set_function(45, GPIO_ALT_FN_2_OUT);
679:
680: /* FFUART */
681: pxa2x0_gpio_set_function(34, GPIO_ALT_FN_1_IN);
682: pxa2x0_gpio_set_function(39, GPIO_ALT_FN_2_OUT);
683: pxa2x0_gpio_set_function(35, GPIO_ALT_FN_1_IN);
684: pxa2x0_gpio_set_function(40, GPIO_ALT_FN_2_OUT);
685: pxa2x0_gpio_set_function(41, GPIO_ALT_FN_2_OUT);
686:
687: /* STUART */
688: pxa2x0_gpio_set_function(46, GPIO_ALT_FN_2_IN);
689: pxa2x0_gpio_set_function(47, GPIO_ALT_FN_1_OUT);
690: #endif
691:
692: /* tell com to drive STUART in slow infrared mode */
693: comsiraddr = (bus_addr_t)PXA2X0_STUART_BASE;
694:
695: #if 1
696: /* turn on clock to UART block.
697: XXX this should not be necessary, consinit() will do it */
698: early_clkman(CKEN_FFUART | CKEN_BTUART | CKEN_STUART, 1);
699: #endif
700:
701: green_on(0);
702:
703: /*
704: * Temporarily replace bus_space_map() functions so that
705: * console devices can get mapped.
706: *
707: * Note that this relies upon the fact that both regular
708: * and a4x bus_space tags use the same map function.
709: */
710: tmp_bs_tag = pxa2x0_bs_tag;
711: tmp_bs_tag.bs_map = bootstrap_bs_map;
712: map_func_save = pxa2x0_bs_tag.bs_map;
713: pxa2x0_a4x_bs_tag.bs_map = pxa2x0_bs_tag.bs_map = bootstrap_bs_map;
714:
715: /* setup a serial console for very early boot */
716: consinit();
717: #ifdef KGDB
718: kgdb_port_init();
719: #endif
720:
721:
722: /* Talk to the user */
723: printf("\nOpenBSD/zaurus booting ...\n");
724:
725: {
726: /* XXX - all Zaurus have this for now, fix memory sizing */
727: memstart = 0xa0000000;
728: memsize = 0x04000000; /* 64MB */
729: }
730:
731: #if 0
732: {
733: volatile int *p;
734: char *membase;
735: char *memmax;
736: int chunksize = 0x02000000;
737: printf("probing memory");
738:
739: membase = (char *)0xa0000000;
740: memmax = (char *)0xc0000000;
741: for (p = (int *)membase;
742: p < (int *)memmax;
743: p = (int *) (((char *)p) + chunksize)) {
744: printf ("cbase %p\n", p);
745: p[0] = 0x12345678;
746: p[1] = 0x12345678;
747: if ((p[0] != 0x12345678) || (p[1] != 0x12345678))
748: break;
749: }
750: memsize = ((char *)p) - membase;
751:
752: printf("probing memory done found memsize %d\n", memsize);
753: }
754: #else
755: #endif
756:
757: #define DEBUG
758: #ifdef DEBUG
759: printf("initarm: Configuring system ...\n");
760: #endif
761:
762: /* Fake bootconfig structure for the benefit of pmap.c */
763: /* XXX must make the memory description h/w independant */
764: bootconfig.dramblocks = 1;
765: bootconfig.dram[0].address = memstart;
766: bootconfig.dram[0].pages = memsize / PAGE_SIZE;
767:
768: /*
769: * Set up the variables that define the availablilty of
770: * physical memory. For now, we're going to set
771: * physical_freestart to 0xa0200000 (where the kernel
772: * was loaded), and allocate the memory we need downwards.
773: * If we get too close to the page tables that RedBoot
774: * set up, we will panic. We will update physical_freestart
775: * and physical_freeend later to reflect what pmap_bootstrap()
776: * wants to see.
777: *
778: * XXX pmap_bootstrap() needs an enema.
779: */
780: physical_start = bootconfig.dram[0].address;
781: physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
782:
783: physical_freestart = 0xa0009000UL;
784: physical_freeend = 0xa0200000UL;
785:
786: physmem = (physical_end - physical_start) / PAGE_SIZE;
787:
788: #ifdef DEBUG
789: /* Tell the user about the memory */
790: printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem,
791: physical_start, physical_end - 1);
792: #endif
793:
794: /*
795: * Okay, the kernel starts 2MB in from the bottom of physical
796: * memory. We are going to allocate our bootstrap pages downwards
797: * from there.
798: *
799: * We need to allocate some fixed page tables to get the kernel
800: * going. We allocate one page directory and a number of page
801: * tables and store the physical addresses in the kernel_pt_table
802: * array.
803: *
804: * The kernel page directory must be on a 16K boundary. The page
805: * tables must be on 4K bounaries. What we do is allocate the
806: * page directory on the first 16K boundary that we encounter, and
807: * the page tables on 4K boundaries otherwise. Since we allocate
808: * at least 3 L2 page tables, we are guaranteed to encounter at
809: * least one 16K aligned region.
810: */
811:
812: #ifdef VERBOSE_INIT_ARM
813: printf("Allocating page tables\n");
814: #endif
815:
816: free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE;
817:
818: #ifdef VERBOSE_INIT_ARM
819: printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n",
820: physical_freestart, free_pages, free_pages);
821: #endif
822:
823: /* Define a macro to simplify memory allocation */
824: #define valloc_pages(var, np) \
825: alloc_pages((var).pv_pa, (np)); \
826: (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start;
827:
828: #define alloc_pages(var, np) \
829: physical_freeend -= ((np) * PAGE_SIZE); \
830: if (physical_freeend < physical_freestart) \
831: panic("initarm: out of memory"); \
832: (var) = physical_freeend; \
833: free_pages -= (np); \
834: memset((char *)(var), 0, ((np) * PAGE_SIZE));
835:
836: loop1 = 0;
837: kernel_l1pt.pv_pa = 0;
838: for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
839: /* Are we 16KB aligned for an L1 ? */
840: if (((physical_freeend - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) == 0
841: && kernel_l1pt.pv_pa == 0) {
842: valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
843: } else {
844: valloc_pages(kernel_pt_table[loop1],
845: L2_TABLE_SIZE / PAGE_SIZE);
846: ++loop1;
847: }
848: }
849:
850: /* This should never be able to happen but better confirm that. */
851: if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0)
852: panic("initarm: Failed to align the kernel page directory");
853:
854: /*
855: * Allocate a page for the system page mapped to V0x00000000
856: * This page will just contain the system vectors and can be
857: * shared by all processes.
858: */
859: alloc_pages(systempage.pv_pa, 1);
860:
861: /* Allocate stacks for all modes */
862: valloc_pages(irqstack, IRQ_STACK_SIZE);
863: valloc_pages(abtstack, ABT_STACK_SIZE);
864: valloc_pages(undstack, UND_STACK_SIZE);
865: valloc_pages(kernelstack, UPAGES);
866:
867: /* Allocate enough pages for cleaning the Mini-Data cache. */
868: KASSERT(xscale_minidata_clean_size <= PAGE_SIZE);
869: valloc_pages(minidataclean, 1);
870:
871: #ifdef VERBOSE_INIT_ARM
872: printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa,
873: irqstack.pv_va);
874: printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa,
875: abtstack.pv_va);
876: printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa,
877: undstack.pv_va);
878: printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa,
879: kernelstack.pv_va);
880: #endif
881:
882: /*
883: * XXX Defer this to later so that we can reclaim the memory
884: * XXX used by the RedBoot page tables.
885: */
886: alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE);
887:
888: /*
889: * Ok we have allocated physical pages for the primary kernel
890: * page tables
891: */
892:
893: #ifdef VERBOSE_INIT_ARM
894: printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa);
895: #endif
896:
897: /*
898: * Now we start construction of the L1 page table
899: * We start by mapping the L2 page tables into the L1.
900: * This means that we can replace L1 mappings later on if necessary
901: */
902: l1pagetable = kernel_l1pt.pv_pa;
903:
904: /* Map the L2 pages tables in the L1 page table */
905: pmap_link_l2pt(l1pagetable, 0x00000000,
906: &kernel_pt_table[KERNEL_PT_SYS]);
907:
908: for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++)
909: pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000,
910: &kernel_pt_table[KERNEL_PT_KERNEL + loop]);
911:
912: for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
913: pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
914: &kernel_pt_table[KERNEL_PT_VMDATA + loop]);
915:
916: /* update the top of the kernel VM */
917: pmap_curmaxkvaddr =
918: KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);
919:
920: #ifdef VERBOSE_INIT_ARM
921: printf("Mapping kernel\n");
922: #endif
923:
924: /* Now we fill in the L2 pagetable for the kernel static code/data
925: * and the symbol table. */
926: {
927: extern char etext[];
928: size_t textsize = (u_int32_t) etext - KERNEL_TEXT_BASE;
929: size_t totalsize = esym - KERNEL_TEXT_BASE;
930: u_int logical;
931:
932: textsize = (textsize + PGOFSET) & ~PGOFSET;
933: totalsize = (totalsize + PGOFSET) & ~PGOFSET;
934:
935: logical = 0x00200000; /* offset of kernel in RAM */
936:
937: /* Update dump information */
938: cpu_kcore_hdr.kernelbase = KERNEL_BASE;
939: cpu_kcore_hdr.kerneloffs = logical;
940: cpu_kcore_hdr.staticsize = totalsize;
941:
942: logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
943: physical_start + logical, textsize,
944: VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
945: pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
946: physical_start + logical, totalsize - textsize,
947: VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
948: }
949:
950: #ifdef VERBOSE_INIT_ARM
951: printf("Constructing L2 page tables\n");
952: #endif
953:
954: /* Map the stack pages */
955: pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
956: IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
957: pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
958: ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
959: pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
960: UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
961: pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
962: UPAGES * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE);
963:
964: pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
965: L1_TABLE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE);
966:
967: for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
968: pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
969: kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
970: VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
971: }
972:
973: /* Map the Mini-Data cache clean area. */
974: xscale_setup_minidata(l1pagetable, minidataclean.pv_va,
975: minidataclean.pv_pa);
976:
977: /* Map the vector page. */
978: #if 1
979: /* MULTI-ICE requires that page 0 is NC/NB so that it can download the
980: * cache-clean code there. */
981: pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
982: VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
983: #else
984: pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
985: VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
986: #endif
987:
988: /*
989: * map integrated peripherals at same address in l1pagetable
990: * so that we can continue to use console.
991: */
992: copy_io_area_map((pd_entry_t *)l1pagetable);
993:
994: /*
995: * Give the XScale global cache clean code an appropriately
996: * sized chunk of unmapped VA space starting at 0xff000000
997: * (our device mappings end before this address).
998: */
999: xscale_cache_clean_addr = 0xff000000U;
1000:
1001: /*
1002: * Now we have the real page tables in place so we can switch to them.
1003: * Once this is done we will be running with the REAL kernel page
1004: * tables.
1005: */
1006:
1007: /*
1008: * Update the physical_freestart/physical_freeend/free_pages
1009: * variables.
1010: */
1011: {
1012: physical_freestart = physical_start +
1013: (((esym + PGOFSET) & ~PGOFSET) - KERNEL_BASE);
1014: physical_freeend = physical_end;
1015: free_pages =
1016: (physical_freeend - physical_freestart) / PAGE_SIZE;
1017: }
1018:
1019: /* be a client to all domains */
1020: cpu_domains(0x55555555);
1021: /* Switch tables */
1022: #ifdef VERBOSE_INIT_ARM
1023: printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n",
1024: physical_freestart, free_pages, free_pages);
1025: printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa);
1026: #endif
1027:
1028: /* set new intc register address so that splfoo() doesn't
1029: touch illegal address. */
1030: pxa2x0_intr_bootstrap(ZAURUS_INTCTL_VBASE);
1031:
1032: cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
1033: setttb(kernel_l1pt.pv_pa);
1034: cpu_tlb_flushID();
1035: cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
1036:
1037: /*
1038: * Moved from cpu_startup() as data_abort_handler() references
1039: * this during uvm init
1040: */
1041: proc0paddr = (struct user *)kernelstack.pv_va;
1042: proc0.p_addr = proc0paddr;
1043:
1044: #ifdef VERBOSE_INIT_ARM
1045: printf("bootstrap done.\n");
1046: #endif
1047:
1048: arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL);
1049:
1050: /*
1051: * Pages were allocated during the secondary bootstrap for the
1052: * stacks for different CPU modes.
1053: * We must now set the r13 registers in the different CPU modes to
1054: * point to these stacks.
1055: * Since the ARM stacks use STMFD etc. we must set r13 to the top end
1056: * of the stack memory.
1057: */
1058: #ifdef VERBOSE_INIT_ARM
1059: printf("init subsystems: stacks ");
1060: #endif
1061:
1062: set_stackptr(PSR_IRQ32_MODE,
1063: irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
1064: set_stackptr(PSR_ABT32_MODE,
1065: abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
1066: set_stackptr(PSR_UND32_MODE,
1067: undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
1068:
1069: /*
1070: * Well we should set a data abort handler.
1071: * Once things get going this will change as we will need a proper
1072: * handler.
1073: * Until then we will use a handler that just panics but tells us
1074: * why.
1075: * Initialisation of the vectors will just panic on a data abort.
1076: * This just fills in a slightly better one.
1077: */
1078: #ifdef VERBOSE_INIT_ARM
1079: printf("vectors ");
1080: #endif
1081: data_abort_handler_address = (u_int)data_abort_handler;
1082: prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
1083: undefined_handler_address = (u_int)undefinedinstruction_bounce;
1084:
1085: /* Initialise the undefined instruction handlers */
1086: #ifdef VERBOSE_INIT_ARM
1087: printf("undefined ");
1088: #endif
1089: undefined_init();
1090:
1091: /* Load memory into UVM. */
1092: #ifdef VERBOSE_INIT_ARM
1093: printf("page ");
1094: #endif
1095: uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */
1096: uvm_page_physload(atop(physical_freestart), atop(physical_freeend),
1097: atop(physical_freestart), atop(physical_freeend),
1098: VM_FREELIST_DEFAULT);
1099:
1100: /* Boot strap pmap telling it where the kernel page table is */
1101: #ifdef VERBOSE_INIT_ARM
1102: printf("pmap ");
1103: #endif
1104: pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, KERNEL_VM_BASE,
1105: KERNEL_VM_BASE + KERNEL_VM_SIZE);
1106:
1107: /* Update dump information */
1108: cpu_kcore_hdr.pmap_kernel_l1 = (u_int32_t)pmap_kernel()->pm_l1;
1109: cpu_kcore_hdr.pmap_kernel_l2 = (u_int32_t)&(pmap_kernel()->pm_l2);
1110:
1111: #ifdef __HAVE_MEMORY_DISK__
1112: md_root_setconf(memory_disk, sizeof memory_disk);
1113: #endif
1114:
1115: #ifdef IPKDB
1116: /* Initialise ipkdb */
1117: ipkdb_init();
1118: if (boothowto & RB_KDB)
1119: ipkdb_connect(0);
1120: #endif
1121:
1122: #ifdef KGDB
1123: if (boothowto & RB_KDB) {
1124: kgdb_debug_init = 1;
1125: kgdb_connect(1);
1126: }
1127: #endif
1128:
1129: /*
1130: * Restore proper bus_space operation, now that pmap is initialized.
1131: */
1132: pxa2x0_a4x_bs_tag.bs_map = pxa2x0_bs_tag.bs_map = map_func_save;
1133:
1134: #ifdef DDB
1135: db_machine_init();
1136:
1137: /* Firmware doesn't load symbols. */
1138: ddb_init();
1139:
1140: if (boothowto & RB_KDB)
1141: Debugger();
1142: #endif
1143:
1144: /* We return the new stack pointer address */
1145: return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
1146: }
1147:
1148: const char *console = "glass";
1149:
1150: void
1151: process_kernel_args(char *args)
1152: {
1153: char *cp = args;
1154:
1155: if (cp == NULL || *(int *)cp != BOOT_STRING_MAGIC) {
1156: boothowto = RB_AUTOBOOT;
1157: return;
1158: }
1159:
1160: /* Eat the cookie */
1161: *(int *)cp = 0;
1162: cp += sizeof(int);
1163:
1164: boothowto = 0;
1165:
1166: /* Make a local copy of the bootargs */
1167: strncpy(bootargs, cp, MAX_BOOT_STRING - sizeof(int));
1168:
1169: cp = bootargs;
1170: boot_file = bootargs;
1171:
1172: /* Skip the kernel image filename */
1173: while (*cp != ' ' && *cp != 0)
1174: ++cp;
1175:
1176: if (*cp != 0)
1177: *cp++ = 0;
1178:
1179: while (*cp == ' ')
1180: ++cp;
1181:
1182: boot_args = cp;
1183:
1184: printf("bootfile: %s\n", boot_file);
1185: printf("bootargs: %s\n", boot_args);
1186:
1187: /* Setup pointer to boot flags */
1188: while (*cp != '-')
1189: if (*cp++ == '\0')
1190: return;
1191:
1192: for (;*++cp;) {
1193: int fl;
1194:
1195: fl = 0;
1196: switch(*cp) {
1197: case 'a':
1198: fl |= RB_ASKNAME;
1199: break;
1200: case 'c':
1201: fl |= RB_CONFIG;
1202: break;
1203: case 'd':
1204: fl |= RB_KDB;
1205: break;
1206: case 's':
1207: fl |= RB_SINGLE;
1208: break;
1209: /* XXX undocumented console switching flags */
1210: case '0':
1211: console = "ffuart";
1212: break;
1213: case '1':
1214: console = "btuart";
1215: break;
1216: case '2':
1217: console = "stuart";
1218: break;
1219: default:
1220: printf("unknown option `%c'\n", *cp);
1221: break;
1222: }
1223: boothowto |= fl;
1224: }
1225: }
1226:
1227: #ifdef KGDB
1228: #ifndef KGDB_DEVNAME
1229: #define KGDB_DEVNAME "ffuart"
1230: #endif
1231: const char kgdb_devname[] = KGDB_DEVNAME;
1232:
1233: #if (NCOM > 0)
1234: #ifndef KGDB_DEVMODE
1235: #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
1236: #endif
1237: int comkgdbmode = KGDB_DEVMODE;
1238: #endif /* NCOM */
1239:
1240: #endif /* KGDB */
1241:
1242: void
1243: consinit(void)
1244: {
1245: #if NCOM > 0
1246: static int consinit_called = 0;
1247: paddr_t paddr;
1248: u_int cken = 0;
1249:
1250: if (consinit_called != 0)
1251: return;
1252:
1253: consinit_called = 1;
1254:
1255: #ifdef KGDB
1256: if (strcmp(kgdb_devname, console) == 0) {
1257: /* port is reserved for kgdb */
1258: } else
1259: #endif
1260: if (strcmp(console, "ffuart") == 0) {
1261: paddr = PXA2X0_FFUART_BASE;
1262: cken = CKEN_FFUART;
1263: } else if (strcmp(console, "btuart") == 0) {
1264: paddr = PXA2X0_BTUART_BASE;
1265: cken = CKEN_BTUART;
1266: } else if (strcmp(console, "stuart") == 0) {
1267: paddr = PXA2X0_STUART_BASE;
1268: cken = CKEN_STUART;
1269: irda_on(0);
1270: }
1271: if (cken != 0 && comcnattach(&pxa2x0_a4x_bs_tag, paddr, comcnspeed,
1272: PXA2X0_COM_FREQ, comcnmode) == 0) {
1273: early_clkman(cken, 1);
1274: }
1275: #endif /* NCOM */
1276: }
1277:
1278: #ifdef KGDB
1279: void
1280: kgdb_port_init(void)
1281: {
1282: #if (NCOM > 0) && defined(COM_PXA2X0)
1283: paddr_t paddr;
1284: u_int cken;
1285:
1286: if (strcmp(kgdb_devname, "ffuart") == 0) {
1287: paddr = PXA2X0_FFUART_BASE;
1288: cken = CKEN_FFUART;
1289: } else if (strcmp(kgdb_devname, "btuart") == 0) {
1290: paddr = PXA2X0_BTUART_BASE;
1291: cken = CKEN_BTUART;
1292: } else if (strcmp(kgdb_devname, "stuart") == 0) {
1293: paddr = PXA2X0_STUART_BASE;
1294: cken = CKEN_STUART;
1295: irda_on(0);
1296: } else
1297: return;
1298:
1299: if (com_kgdb_attach_pxa2x0(&pxa2x0_a4x_bs_tag, paddr,
1300: kgdb_rate, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comkgdbmode) == 0) {
1301: early_clkman(cken, 1);
1302: }
1303: #endif
1304: }
1305: #endif
1306:
1307: /* same as pxa2x0_clkman, but before autoconf */
1308: void
1309: early_clkman(u_int clk, int enable)
1310: {
1311: u_int32_t rv;
1312:
1313: rv = ioreg_read(ZAURUS_CLKMAN_VBASE + CLKMAN_CKEN);
1314: if (enable)
1315: rv |= clk;
1316: else
1317: rv &= ~clk;
1318: ioreg_write(ZAURUS_CLKMAN_VBASE + CLKMAN_CKEN, rv);
1319: }
1320:
1321: int glass_console = 0;
1322:
1323: void
1324: board_startup(void)
1325: {
1326: extern int lcd_cnattach(void (*)(u_int, int));
1327: extern bus_addr_t comconsaddr;
1328:
1329: #if NWSDISPLAY > 0
1330: /*
1331: * Try to attach the display console now that VM services
1332: * are available.
1333: */
1334:
1335: if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X) {
1336: if (strcmp(console, "glass") == 0) {
1337: printf("attempting to switch console to lcd screen\n");
1338: glass_console = 1;
1339: }
1340: if (glass_console == 1 && lcd_cnattach(early_clkman) == 0) {
1341: /*
1342: * Kill the existing serial console.
1343: * XXX need to bus_space_unmap resources and disable
1344: * clocks...
1345: */
1346: comconsaddr = 0;
1347:
1348: /*
1349: * Display the copyright notice again on the new console
1350: */
1351: extern const char copyright[];
1352: printf("%s\n", copyright);
1353: }
1354: }
1355: #endif
1356:
1357: if (boothowto & RB_CONFIG) {
1358: #ifdef BOOT_CONFIG
1359: user_config();
1360: #else
1361: printf("kernel does not support -c; continuing..\n");
1362: #endif
1363: }
1364: }
CVSweb