integrator_machdep.c revision 1.74 1 /* $NetBSD: integrator_machdep.c,v 1.74 2013/08/18 15:58:20 matt Exp $ */
2
3 /*
4 * Copyright (c) 2001,2002 ARM Ltd
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 *
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 /*
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 dependent functions for kernel setup for integrator board
66 *
67 * Created : 24/11/97
68 */
69
70 #include <sys/cdefs.h>
71 __KERNEL_RCSID(0, "$NetBSD: integrator_machdep.c,v 1.74 2013/08/18 15:58:20 matt Exp $");
72
73 #include "opt_ddb.h"
74 #include "opt_pmap_debug.h"
75
76 #include <sys/param.h>
77 #include <sys/device.h>
78 #include <sys/systm.h>
79 #include <sys/kernel.h>
80 #include <sys/exec.h>
81 #include <sys/proc.h>
82 #include <sys/msgbuf.h>
83 #include <sys/reboot.h>
84 #include <sys/termios.h>
85 #include <sys/ksyms.h>
86 #include <sys/bus.h>
87 #include <sys/cpu.h>
88 #include <sys/intr.h>
89
90 #include <uvm/uvm_extern.h>
91
92 #include <dev/cons.h>
93
94 #include <machine/db_machdep.h>
95 #include <ddb/db_sym.h>
96 #include <ddb/db_extern.h>
97
98 #include <machine/bootconfig.h>
99 #include <arm/locore.h>
100 #include <arm/undefined.h>
101
102 #include <arm/arm32/machdep.h>
103
104 #include <evbarm/integrator/integrator_boot.h>
105
106 #include "pci.h"
107 #include "ksyms.h"
108
109 void ifpga_reset(void) __attribute__((noreturn));
110
111 /*
112 * The range 0xc1000000 - 0xccffffff is available for kernel VM space
113 * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff
114 */
115 #define KERNEL_VM_BASE (KERNEL_BASE + 0x01000000)
116 #define KERNEL_VM_SIZE 0x0C000000
117
118 BootConfig bootconfig; /* Boot config storage */
119 char *boot_args = NULL;
120 char *boot_file = NULL;
121
122 /* Prototypes */
123
124 static void integrator_sdram_bounds (paddr_t *, psize_t *);
125
126 void consinit(void);
127
128 /* A load of console goo. */
129 #include "vga.h"
130 #if NVGA > 0
131 #include <dev/ic/mc6845reg.h>
132 #include <dev/ic/pcdisplayvar.h>
133 #include <dev/ic/vgareg.h>
134 #include <dev/ic/vgavar.h>
135 #endif
136
137 #include "pckbc.h"
138 #if NPCKBC > 0
139 #include <dev/ic/i8042reg.h>
140 #include <dev/ic/pckbcvar.h>
141 #endif
142
143 #include "com.h"
144 #if NCOM > 0
145 #include <dev/ic/comreg.h>
146 #include <dev/ic/comvar.h>
147 #ifndef CONCOMADDR
148 #define CONCOMADDR 0x3f8
149 #endif
150 #endif
151
152 /*
153 * Define the default console speed for the board. This is generally
154 * what the firmware provided with the board defaults to.
155 */
156 #ifndef CONSPEED
157 #define CONSPEED B115200
158 #endif
159 #ifndef CONMODE
160 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
161 #endif
162
163 int comcnspeed = CONSPEED;
164 int comcnmode = CONMODE;
165
166 #include "plcom.h"
167 #if (NPLCOM > 0)
168 #include <evbarm/dev/plcomreg.h>
169 #include <evbarm/dev/plcomvar.h>
170
171 #include <evbarm/ifpga/ifpgamem.h>
172 #include <evbarm/ifpga/ifpgareg.h>
173 #include <evbarm/ifpga/ifpgavar.h>
174 #endif
175
176 #ifndef CONSDEVNAME
177 #define CONSDEVNAME "plcom"
178 #endif
179
180 #ifndef PLCONSPEED
181 #define PLCONSPEED B38400
182 #endif
183 #ifndef PLCONMODE
184 #define PLCONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
185 #endif
186 #ifndef PLCOMCNUNIT
187 #define PLCOMCNUNIT -1
188 #endif
189
190 int plcomcnspeed = PLCONSPEED;
191 int plcomcnmode = PLCONMODE;
192
193 #if 0
194 extern struct consdev kcomcons;
195 static void kcomcnputc(dev_t, int);
196 #endif
197
198 /*
199 * void cpu_reboot(int howto, char *bootstr)
200 *
201 * Reboots the system
202 *
203 * Deal with any syncing, unmounting, dumping and shutdown hooks,
204 * then reset the CPU.
205 */
206 void
207 cpu_reboot(int howto, char *bootstr)
208 {
209
210 /*
211 * If we are still cold then hit the air brakes
212 * and crash to earth fast
213 */
214 if (cold) {
215 doshutdownhooks();
216 pmf_system_shutdown(boothowto);
217 printf("The operating system has halted.\n");
218 printf("Please press any key to reboot.\n\n");
219 cngetc();
220 printf("rebooting...\n");
221 ifpga_reset();
222 /*NOTREACHED*/
223 }
224
225 /* Disable console buffering */
226
227 /*
228 * If RB_NOSYNC was not specified sync the discs.
229 * Note: Unless cold is set to 1 here, syslogd will die during the
230 * unmount. It looks like syslogd is getting woken up only to find
231 * that it cannot page part of the binary in as the filesystem has
232 * been unmounted.
233 */
234 if (!(howto & RB_NOSYNC))
235 bootsync();
236
237 /* Say NO to interrupts */
238 splhigh();
239
240 /* Do a dump if requested. */
241 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
242 dumpsys();
243
244 /* Run any shutdown hooks */
245 doshutdownhooks();
246
247 pmf_system_shutdown(boothowto);
248
249 /* Make sure IRQ's are disabled */
250 IRQdisable;
251
252 if (howto & RB_HALT) {
253 printf("The operating system has halted.\n");
254 printf("Please press any key to reboot.\n\n");
255 cngetc();
256 }
257
258 printf("rebooting...\n");
259 ifpga_reset();
260 /*NOTREACHED*/
261 }
262
263 /* Statically mapped devices. */
264 static const struct pmap_devmap integrator_devmap[] = {
265 #if NPLCOM > 0 && defined(PLCONSOLE)
266 {
267 UART0_BOOT_BASE,
268 IFPGA_IO_BASE + IFPGA_UART0,
269 1024 * 1024,
270 VM_PROT_READ|VM_PROT_WRITE,
271 PTE_NOCACHE
272 },
273
274 {
275 UART1_BOOT_BASE,
276 IFPGA_IO_BASE + IFPGA_UART1,
277 1024 * 1024,
278 VM_PROT_READ|VM_PROT_WRITE,
279 PTE_NOCACHE
280 },
281 #endif
282 #if NPCI > 0
283 {
284 IFPGA_PCI_IO_VBASE,
285 IFPGA_PCI_IO_BASE,
286 IFPGA_PCI_IO_VSIZE,
287 VM_PROT_READ|VM_PROT_WRITE,
288 PTE_NOCACHE
289 },
290
291 {
292 IFPGA_PCI_CONF_VBASE,
293 IFPGA_PCI_CONF_BASE,
294 IFPGA_PCI_CONF_VSIZE,
295 VM_PROT_READ|VM_PROT_WRITE,
296 PTE_NOCACHE
297 },
298 #endif
299
300 {
301 0,
302 0,
303 0,
304 0,
305 0
306 }
307 };
308
309 /*
310 * u_int initarm(...)
311 *
312 * Initial entry point on startup. This gets called before main() is
313 * entered.
314 * It should be responsible for setting up everything that must be
315 * in place when main is called.
316 * This includes
317 * Taking a copy of the boot configuration structure.
318 * Initialising the physical console so characters can be printed.
319 * Setting up page tables for the kernel
320 * Relocating the kernel to the bottom of physical memory
321 */
322
323 u_int
324 initarm(void *arg)
325 {
326 extern int KERNEL_BASE_phys[];
327 paddr_t memstart;
328 psize_t memsize;
329
330 /*
331 * Heads up ... Setup the CPU / MMU / TLB functions
332 */
333 if (set_cpufuncs())
334 panic("cpu not recognized!");
335
336 /* map some peripheral registers */
337
338 pmap_devmap_bootstrap((vaddr_t)armreg_ttbr_read() & -L1_TABLE_SIZE,
339 integrator_devmap);
340
341 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
342
343 consinit();
344
345 /* Talk to the user */
346 #define BDSTR(s) _BDSTR(s)
347 #define _BDSTR(s) #s
348 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
349
350 /*
351 * Fetch the SDRAM start/size from the CM configuration registers.
352 */
353 integrator_sdram_bounds(&memstart, &memsize);
354
355 #if defined(INTEGRATOR_CP)
356 /*
357 * XXX QEMU reports SDRAM starting at 0x100000, but presents a flat
358 * physical memory model. Set memstart to 0x0, so arm32_bootmem_init
359 * doesn't get fooled later.
360 */
361 memstart = 0;
362 #endif
363
364 #ifdef VERBOSE_INIT_ARM
365 printf("initarm: Configuring system ...\n");
366 #endif
367
368 /* Fake bootconfig structure for the benefit of pmap.c */
369 /* XXX must make the memory description h/w independent */
370 bootconfig.dramblocks = 1;
371 bootconfig.dram[0].address = memstart;
372 bootconfig.dram[0].pages = memsize / PAGE_SIZE;
373 bootconfig.dram[0].flags = BOOT_DRAM_CAN_DMA | BOOT_DRAM_PREFER;
374
375 arm32_bootmem_init(bootconfig.dram[0].address,
376 bootconfig.dram[0].pages * PAGE_SIZE, (unsigned int) KERNEL_BASE_phys);
377
378 arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0, integrator_devmap,
379 false);
380
381 #ifdef VERBOSE_INIT_ARM
382 printf("done.\n");
383 #endif
384
385 return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
386 }
387
388 void
389 consinit(void)
390 {
391 static int consinit_called = 0;
392 #if 0
393 char *console = CONSDEVNAME;
394 #endif
395
396 if (consinit_called != 0)
397 return;
398
399 consinit_called = 1;
400
401 #if NPLCOM > 0 && defined(PLCONSOLE)
402 if (PLCOMCNUNIT == 0) {
403 extern struct bus_space ifpga_common_bs_tag;
404 static struct plcom_instance ifpga_pi1 = {
405 #if defined(INTEGRATOR_CP)
406 .pi_type = PLCOM_TYPE_PL011,
407 #else
408 .pi_type = PLCOM_TYPE_PL010,
409 #endif
410 .pi_iot = &ifpga_common_bs_tag,
411 .pi_size = IFPGA_UART_SIZE,
412 .pi_iobase = IFPGA_UART0
413 };
414
415 if (plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
416 plcomcnmode, PLCOMCNUNIT))
417 panic("can't init serial console");
418 return;
419 } else if (PLCOMCNUNIT == 1) {
420 extern struct bus_space ifpga_common_bs_tag;
421 static struct plcom_instance ifpga_pi1 = {
422 #if defined(INTEGRATOR_CP)
423 .pi_type = PLCOM_TYPE_PL011,
424 #else
425 .pi_type = PLCOM_TYPE_PL010,
426 #endif
427 .pi_iot = &ifpga_common_bs_tag,
428 .pi_size = IFPGA_UART_SIZE,
429 .pi_iobase = IFPGA_UART1
430 };
431
432 if (plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
433 plcomcnmode, PLCOMCNUNIT))
434 panic("can't init serial console");
435 return;
436 }
437 #endif
438 #if (NCOM > 0)
439 if (comcnattach(&isa_io_bs_tag, CONCOMADDR, comcnspeed,
440 COM_FREQ, COM_TYPE_NORMAL, comcnmode))
441 panic("can't init serial console @%x", CONCOMADDR);
442 return;
443 #endif
444 panic("No serial console configured");
445 }
446
447 static void
448 integrator_sdram_bounds(paddr_t *memstart, psize_t *memsize)
449 {
450 volatile unsigned long *cm_sdram
451 = (volatile unsigned long *)0x10000020;
452 volatile unsigned long *cm_stat
453 = (volatile unsigned long *)0x10000010;
454
455 *memstart = *cm_stat & 0x00ff0000;
456
457 /*
458 * Although the SSRAM overlaps the SDRAM, we can use the wrap-around
459 * to access the entire bank.
460 */
461 switch ((*cm_sdram >> 2) & 0x7)
462 {
463 case 0:
464 *memsize = 16 * 1024 * 1024;
465 break;
466 case 1:
467 *memsize = 32 * 1024 * 1024;
468 break;
469 case 2:
470 *memsize = 64 * 1024 * 1024;
471 break;
472 case 3:
473 *memsize = 128 * 1024 * 1024;
474 break;
475 case 4:
476 /* With 256M of memory there is no wrap-around. */
477 *memsize = 256 * 1024 * 1024 - *memstart;
478 break;
479 default:
480 printf("CM_SDRAM retuns unknown value, using 16M\n");
481 *memsize = 16 * 1024 * 1024;
482 break;
483 }
484 }
485