1 /* $NetBSD: netwinder_machdep.c,v 1.93 2024/02/21 23:23:06 andvar 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 dependent functions for kernel setup for EBSA285 core architecture
37 * using Netwinder firmware
38 *
39 * Created : 24/11/97
40 */
41
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: netwinder_machdep.c,v 1.93 2024/02/21 23:23:06 andvar Exp $");
44
45 #include "opt_ddb.h"
46
47 #define _ARM32_BUS_DMA_PRIVATE
48
49 #include "isa.h"
50 #include "isadma.h"
51 #include "igsfb.h"
52 #include "pckbc.h"
53 #include "com.h"
54 #include "ksyms.h"
55
56 #include <sys/param.h>
57 #include <sys/device.h>
58 #include <sys/systm.h>
59 #include <sys/kernel.h>
60 #include <sys/exec.h>
61 #include <sys/proc.h>
62 #include <sys/msgbuf.h>
63 #include <sys/reboot.h>
64 #include <sys/termios.h>
65 #include <sys/ksyms.h>
66 #include <sys/bus.h>
67 #include <sys/cpu.h>
68 #include <sys/intr.h>
69
70 #include <uvm/uvm_extern.h>
71
72 #include <dev/cons.h>
73
74 #if NISA > 0
75 #include <dev/isa/isareg.h>
76 #include <dev/isa/isavar.h>
77 #endif
78
79 #if NIGSFB > 0
80 #include <dev/pci/pcivar.h>
81 #include <dev/pci/igsfb_pcivar.h>
82 #endif
83
84 #if NPCKBC > 0
85 #include <dev/ic/i8042reg.h>
86 #include <dev/ic/pckbcvar.h>
87 #endif
88
89 #include <dev/ic/comreg.h>
90 #include <dev/ic/comvar.h>
91
92 #include <machine/db_machdep.h>
93 #include <ddb/db_sym.h>
94 #include <ddb/db_extern.h>
95
96 #include <arm/arm32/machdep.h>
97
98 #include <machine/bootconfig.h>
99 #include <arm/locore.h>
100 #include <arm/undefined.h>
101
102 #include <machine/netwinder_boot.h>
103 #include <arm/footbridge/dc21285mem.h>
104 #include <arm/footbridge/dc21285reg.h>
105
106
107 static bus_space_handle_t isa_base = (bus_space_handle_t) DC21285_PCI_IO_VBASE;
108
109 bs_protos(generic);
110
111 #define ISA_GETBYTE(r) generic_bs_r_1(0, isa_base, (r))
112 #define ISA_PUTBYTE(r,v) generic_bs_w_1(0, isa_base, (r), (v))
113
114 static void netwinder_reset(void);
115
116 u_int dc21285_fclk = 63750000;
117
118 struct nwbootinfo nwbootinfo;
119 BootConfig bootconfig; /* Boot config storage */
120 static char bootargs[MAX_BOOT_STRING + 1];
121 char *boot_args = NULL;
122 char *boot_file = NULL;
123
124 vaddr_t physical_start;
125 vaddr_t physical_freestart;
126 vaddr_t physical_freeend;
127 vaddr_t physical_end;
128 u_int free_pages;
129 vaddr_t pagetables_start;
130
131 /*int debug_flags;*/
132 #ifndef PMAP_STATIC_L1S
133 int max_processes = 64; /* Default number */
134 #endif /* !PMAP_STATIC_L1S */
135
136 paddr_t msgbufphys;
137
138 #define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
139 #define KERNEL_PT_KERNEL 1 /* Page table for mapping kernel */
140 #define KERNEL_PT_VMDATA 2 /* Page tables for mapping kernel VM */
141 #define KERNEL_PT_VMDATA_NUM 4 /* start with 16MB of KVM */
142 #define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)
143
144 pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];
145
146 #define KERNEL_VM_BASE (KERNEL_BASE + 0x01000000)
147 /*
148 * The range 0xf1000000 - 0xfcffffff is available for kernel VM space
149 * Footbridge registers and I/O mappings occupy 0xfd000000 - 0xffffffff
150 */
151 #if NIGSFB > 0
152 /* XXX: uwe: map 16 megs at 0xfc000000 for igsfb(4) */
153 #define KERNEL_VM_SIZE 0x0B000000
154 #else
155 #define KERNEL_VM_SIZE 0x0C000000
156 #endif
157
158 /* Prototypes */
159
160 void consinit(void);
161 void process_kernel_args(char *);
162 void data_abort_handler(trapframe_t *);
163 void prefetch_abort_handler(trapframe_t *);
164 void undefinedinstruction_bounce(trapframe_t *);
165
166
167 /* A load of console goo. */
168 #ifndef CONSDEVNAME
169 # if (NIGSFB > 0) && (NPCKBC > 0)
170 # define CONSDEVNAME "igsfb"
171 # elif NCOM > 0
172 # define CONSDEVNAME "com"
173 # else
174 # error CONSDEVNAME not defined and no known console device configured
175 # endif
176 #endif /* !CONSDEVNAME */
177
178 #ifndef CONCOMADDR
179 #define CONCOMADDR 0x3f8
180 #endif
181
182 #ifndef CONSPEED
183 #define CONSPEED B115200 /* match NeTTrom */
184 #endif
185
186 #ifndef CONMODE
187 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
188 #endif
189
190 int comcnspeed = CONSPEED;
191 int comcnmode = CONMODE;
192
193 extern struct consdev kcomcons;
194 static void kcomcnputc(dev_t, int);
195
196 #if NIGSFB > 0
197 /* XXX: uwe */
198 #define IGS_PCI_MEM_VBASE 0xfc000000
199 #define IGS_PCI_MEM_VSIZE 0x01000000
200 #define IGS_PCI_MEM_BASE 0x08000000
201
202 extern struct arm32_pci_chipset footbridge_pci_chipset;
203 extern struct bus_space footbridge_pci_io_bs_tag;
204 extern struct bus_space footbridge_pci_mem_bs_tag;
205 extern void footbridge_pci_bs_tag_init(void);
206
207 /* standard methods */
208 extern bs_map_proto(footbridge_mem);
209 extern bs_unmap_proto(footbridge_mem);
210
211 /* our hooks */
212 static bs_map_proto(nw_footbridge_mem);
213 static bs_unmap_proto(nw_footbridge_mem);
214 #endif
215
216
217 /*
218 * void cpu_reboot(int howto, char *bootstr)
219 *
220 * Reboots the system
221 *
222 * Deal with any syncing, unmounting, dumping and shutdown hooks,
223 * then reset the CPU.
224 */
225
226 void
cpu_reboot(int howto,char * bootstr)227 cpu_reboot(int howto, char *bootstr)
228 {
229 #ifdef DIAGNOSTIC
230 /* info */
231 printf("boot: howto=%08x curlwp=%p\n", howto, curlwp);
232 #endif
233
234 /*
235 * If we are still cold then hit the air brakes
236 * and crash to earth fast
237 */
238 if (cold) {
239 doshutdownhooks();
240 pmf_system_shutdown(boothowto);
241 printf("The operating system has halted.\n");
242 printf("Please press any key to reboot.\n\n");
243 cngetc();
244 printf("rebooting...\n");
245 cpu_reset();
246 /*NOTREACHED*/
247 }
248
249 /* Disable console buffering */
250 /* cnpollc(1);*/
251
252 /*
253 * If RB_NOSYNC was not specified sync the discs.
254 * Note: Unless cold is set to 1 here, syslogd will die during
255 * the unmount. It looks like syslogd is getting woken up
256 * only to find that it cannot page part of the binary in as
257 * the filesystem has been unmounted.
258 */
259 if (!(howto & RB_NOSYNC))
260 bootsync();
261
262 /* Say NO to interrupts */
263 splhigh();
264
265 /* Do a dump if requested. */
266 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
267 dumpsys();
268
269 /* Run any shutdown hooks */
270 doshutdownhooks();
271
272 pmf_system_shutdown(boothowto);
273
274 /* Make sure IRQ's are disabled */
275 IRQdisable;
276
277 if (howto & RB_HALT) {
278 printf("The operating system has halted.\n");
279 printf("Please press any key to reboot.\n\n");
280 cngetc();
281 }
282
283 printf("rebooting...\n");
284 cpu_reset();
285 /*NOTREACHED*/
286 }
287
288 /*
289 * NB: this function runs with MMU disabled!
290 */
291 static void
netwinder_reset(void)292 netwinder_reset(void)
293 {
294 register u_int base = DC21285_PCI_IO_BASE;
295
296 #define PUTBYTE(reg, val) \
297 *((volatile u_int8_t *)(base + (reg))) = (val)
298
299 PUTBYTE(0x338, 0x84); /* Red led(GP17), fan on(GP12) */
300 PUTBYTE(0x370, 0x87); /* Enter the extended function mode */
301 PUTBYTE(0x370, 0x87); /* (need to write the magic twice) */
302 PUTBYTE(0x370, 0x07); /* Select Logical Device Number reg */
303 PUTBYTE(0x371, 0x07); /* Select Logical Device 7 (GPIO) */
304 PUTBYTE(0x370, 0xe6); /* Select GP16 Control Reg */
305 PUTBYTE(0x371, 0x00); /* Make GP16 an output */
306 PUTBYTE(0x338, 0xc4); /* RESET(GP16), red led, fan on */
307 }
308
309 /*
310 * Mapping table for core kernel memory. This memory is mapped at init
311 * time with section mappings.
312 */
313 struct l1_sec_map {
314 vaddr_t va;
315 vaddr_t pa;
316 vsize_t size;
317 vm_prot_t prot;
318 int cache;
319 } l1_sec_table[] = {
320 /* Map 1MB for CSR space */
321 { DC21285_ARMCSR_VBASE, DC21285_ARMCSR_BASE,
322 DC21285_ARMCSR_VSIZE, VM_PROT_READ|VM_PROT_WRITE,
323 PTE_NOCACHE },
324
325 /* Map 1MB for fast cache cleaning space */
326 { DC21285_CACHE_FLUSH_VBASE, DC21285_SA_CACHE_FLUSH_BASE,
327 DC21285_CACHE_FLUSH_VSIZE, VM_PROT_READ|VM_PROT_WRITE,
328 PTE_CACHE },
329
330 /* Map 1MB for PCI IO space */
331 { DC21285_PCI_IO_VBASE, DC21285_PCI_IO_BASE,
332 DC21285_PCI_IO_VSIZE, VM_PROT_READ|VM_PROT_WRITE,
333 PTE_NOCACHE },
334
335 /* Map 1MB for PCI IACK space */
336 { DC21285_PCI_IACK_VBASE, DC21285_PCI_IACK_SPECIAL,
337 DC21285_PCI_IACK_VSIZE, VM_PROT_READ|VM_PROT_WRITE,
338 PTE_NOCACHE },
339
340 /* Map 16MB of type 1 PCI config access */
341 { DC21285_PCI_TYPE_1_CONFIG_VBASE, DC21285_PCI_TYPE_1_CONFIG,
342 DC21285_PCI_TYPE_1_CONFIG_VSIZE, VM_PROT_READ|VM_PROT_WRITE,
343 PTE_NOCACHE },
344
345 /* Map 16MB of type 0 PCI config access */
346 { DC21285_PCI_TYPE_0_CONFIG_VBASE, DC21285_PCI_TYPE_0_CONFIG,
347 DC21285_PCI_TYPE_0_CONFIG_VSIZE, VM_PROT_READ|VM_PROT_WRITE,
348 PTE_NOCACHE },
349
350 /* Map 1MB of 32 bit PCI address space for ISA MEM accesses via PCI */
351 { DC21285_PCI_ISA_MEM_VBASE, DC21285_PCI_MEM_BASE,
352 DC21285_PCI_ISA_MEM_VSIZE, VM_PROT_READ|VM_PROT_WRITE,
353 PTE_NOCACHE },
354
355 #if NIGSFB > 0
356 /* XXX: uwe: Map 16MB of PCI address space for CyberPro as console */
357 { IGS_PCI_MEM_VBASE, DC21285_PCI_MEM_BASE + IGS_PCI_MEM_BASE,
358 IGS_PCI_MEM_VSIZE, VM_PROT_READ|VM_PROT_WRITE,
359 PTE_NOCACHE },
360 #endif
361
362 { 0, 0, 0, 0, 0 }
363 };
364
365 /*
366 * vaddr_t initarm(...);
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 vaddr_t
initarm(void * arg)380 initarm(void *arg)
381 {
382 int loop;
383 int loop1;
384 u_int l1pagetable;
385 extern char _end[];
386
387 /*
388 * Turn the led off, then turn it yellow.
389 * 0x80 - red; 0x04 - fan; 0x02 - green.
390 */
391 ISA_PUTBYTE(0x338, 0x04);
392 ISA_PUTBYTE(0x338, 0x86);
393
394 /*
395 * Set up a diagnostic console so we can see what's going
396 * on.
397 */
398 cn_tab = &kcomcons;
399
400 /* Talk to the user */
401 printf("\nNetBSD/netwinder booting ...\n");
402
403 /*
404 * Heads up ... Setup the CPU / MMU / TLB functions
405 */
406 if (set_cpufuncs())
407 panic("CPU not recognized!");
408
409 /*
410 * We are currently running with the MMU enabled and the
411 * entire address space mapped VA==PA, except for the
412 * first 64MB of RAM is also double-mapped at 0xf0000000.
413 * There is an L1 page table at 0x00008000.
414 *
415 * We also have the 21285's PCI I/O space mapped where
416 * we expect it.
417 */
418
419 printf("initarm: Configuring system ...\n");
420
421 /*
422 * Copy out the boot info passed by the firmware. Note that
423 * early versions of NeTTrom fill this in with bogus values,
424 * so we need to sanity check it.
425 */
426 memcpy(&nwbootinfo, (void *)(KERNEL_BASE + 0x100),
427 sizeof(nwbootinfo));
428 #ifdef VERBOSE_INIT_ARM
429 printf("NeTTrom boot info:\n");
430 printf("\tpage size = 0x%08lx\n", nwbootinfo.bi_pagesize);
431 printf("\tnpages = %ld (0x%08lx)\n", nwbootinfo.bi_nrpages,
432 nwbootinfo.bi_nrpages);
433 printf("\trootdev = 0x%08lx\n", nwbootinfo.bi_rootdev);
434 printf("\tcmdline = %s\n", nwbootinfo.bi_cmdline);
435 #endif
436 if (nwbootinfo.bi_nrpages != 0x02000 &&
437 nwbootinfo.bi_nrpages != 0x04000 &&
438 nwbootinfo.bi_nrpages != 0x08000 &&
439 nwbootinfo.bi_nrpages != 0x10000) {
440 nwbootinfo.bi_pagesize = 0xdeadbeef;
441 nwbootinfo.bi_nrpages = 0x01000; /* 16MB */
442 nwbootinfo.bi_rootdev = 0;
443 }
444
445 /* Fake bootconfig structure for the benefit of pmap.c */
446 /* XXX must make the memory description h/w independent */
447 bootconfig.dramblocks = 1;
448 bootconfig.dram[0].address = 0;
449 bootconfig.dram[0].pages = nwbootinfo.bi_nrpages;
450
451 /*
452 * Set up the variables that define the availability of
453 * physical memory.
454 *
455 * Since the NetWinder NeTTrom doesn't load ELF symbols
456 * for us, we can safely assume that everything after end[]
457 * is free. We start there and allocate upwards.
458 */
459 physical_start = bootconfig.dram[0].address;
460 physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
461
462 physical_freestart = ((((vaddr_t) _end) + PGOFSET) & ~PGOFSET) -
463 KERNEL_BASE;
464 physical_freeend = physical_end;
465 free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE;
466
467 #ifdef VERBOSE_INIT_ARM
468 printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n",
469 physical_freestart, free_pages, free_pages);
470 #endif
471
472 physmem = (physical_end - physical_start) / PAGE_SIZE;
473
474 /* Tell the user about the memory */
475 printf("physmemory: 0x%"PRIxPSIZE" pages at 0x%08lx -> 0x%08lx\n",
476 physmem, physical_start, physical_end - 1);
477
478 /*
479 * Okay, we need to allocate some fixed page tables to get the
480 * kernel going. We allocate one page directory and a number
481 * of page tables and store the physical addresses in the
482 * kernel_pt_table array.
483 *
484 * The kernel page directory must be on a 16K boundary. The page
485 * tables must be on 4K boundaries. What we do is allocate the
486 * page directory on the first 16K boundary that we encounter,
487 * and the page tables on 4K boundaries otherwise. Since we
488 * allocate at least 3 L2 page tables, we are guaranteed to
489 * encounter at least one 16K aligned region.
490 */
491
492 #ifdef VERBOSE_INIT_ARM
493 printf("Allocating page tables\n");
494 #endif
495
496 /* Define a macro to simplify memory allocation */
497 #define valloc_pages(var, np) \
498 alloc_pages((var).pv_pa, (np)); \
499 (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start;
500
501 #define alloc_pages(var, np) \
502 (var) = physical_freestart; \
503 physical_freestart += ((np) * PAGE_SIZE);\
504 free_pages -= (np); \
505 memset((char *)(var), 0, ((np) * PAGE_SIZE));
506
507 loop1 = 0;
508 for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
509 /* Are we 16KB aligned for an L1 ? */
510 if ((physical_freestart & (L1_TABLE_SIZE - 1)) == 0
511 && kernel_l1pt.pv_pa == 0) {
512 valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
513 } else {
514 valloc_pages(kernel_pt_table[loop1],
515 L2_TABLE_SIZE / PAGE_SIZE);
516 ++loop1;
517 }
518 }
519
520 /* This should never be able to happen but better confirm that. */
521 if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0)
522 panic("initarm: Failed to align the kernel page directory");
523
524 /*
525 * Allocate a page for the system page mapped to V0x00000000
526 * This page will just contain the system vectors and can be
527 * shared by all processes.
528 */
529 alloc_pages(systempage.pv_pa, 1);
530
531 /* Allocate stacks for all modes */
532 valloc_pages(irqstack, IRQ_STACK_SIZE);
533 valloc_pages(abtstack, ABT_STACK_SIZE);
534 valloc_pages(undstack, UND_STACK_SIZE);
535 valloc_pages(kernelstack, UPAGES);
536
537 #ifdef VERBOSE_INIT_ARM
538 printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa,
539 irqstack.pv_va);
540 printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa,
541 abtstack.pv_va);
542 printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa,
543 undstack.pv_va);
544 printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa,
545 kernelstack.pv_va);
546 #endif
547
548 alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE);
549
550 /*
551 * Ok we have allocated physical pages for the primary kernel
552 * page tables
553 */
554
555 #ifdef VERBOSE_INIT_ARM
556 printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa);
557 #endif
558
559 /*
560 * Now we start construction of the L1 page table
561 * We start by mapping the L2 page tables into the L1.
562 * This means that we can replace L1 mappings later on if necessary
563 */
564 l1pagetable = kernel_l1pt.pv_pa;
565
566 /* Map the L2 pages tables in the L1 page table */
567 pmap_link_l2pt(l1pagetable, 0x00000000,
568 &kernel_pt_table[KERNEL_PT_SYS]);
569 pmap_link_l2pt(l1pagetable, KERNEL_BASE,
570 &kernel_pt_table[KERNEL_PT_KERNEL]);
571 for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop)
572 pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
573 &kernel_pt_table[KERNEL_PT_VMDATA + loop]);
574
575 /* update the top of the kernel VM */
576 pmap_curmaxkvaddr =
577 KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);
578
579 #ifdef VERBOSE_INIT_ARM
580 printf("Mapping kernel\n");
581 #endif
582
583 /* Now we fill in the L2 pagetable for the kernel static code/data */
584 {
585 /*
586 * The kernel starts in the first 1MB of RAM, and we'd
587 * like to use a section mapping for text, so we'll just
588 * map from KERNEL_BASE to etext[] to _end[].
589 */
590
591 extern char etext[];
592 size_t textsize = (uintptr_t) etext - KERNEL_BASE;
593 size_t totalsize = (uintptr_t) _end - KERNEL_BASE;
594 u_int logical;
595
596 textsize = (textsize + PGOFSET) & ~PGOFSET;
597 totalsize = (totalsize + PGOFSET) & ~PGOFSET;
598
599 textsize = textsize & ~PGOFSET;
600 totalsize = (totalsize + PGOFSET) & ~PGOFSET;
601
602 logical = 0; /* offset into RAM */
603
604 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
605 physical_start + logical, textsize,
606 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
607 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
608 physical_start + logical, totalsize - textsize,
609 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
610 }
611
612 #ifdef VERBOSE_INIT_ARM
613 printf("Constructing L2 page tables\n");
614 #endif
615
616 /* Map the stack pages */
617 pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
618 IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
619 pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
620 ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
621 pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
622 UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
623 pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
624 UPAGES * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
625
626 pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
627 L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
628
629 for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
630 pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
631 kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
632 VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
633 }
634
635 /* Map the vector page. */
636 pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
637 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
638
639 /*
640 * Map devices we can map w/ section mappings.
641 */
642 loop = 0;
643 while (l1_sec_table[loop].size) {
644 vsize_t sz;
645
646 #ifdef VERBOSE_INIT_ARM
647 printf("%08lx -> %08lx @ %08lx\n", l1_sec_table[loop].pa,
648 l1_sec_table[loop].pa + l1_sec_table[loop].size - 1,
649 l1_sec_table[loop].va);
650 #endif
651 for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_S_SIZE)
652 pmap_map_section(l1pagetable,
653 l1_sec_table[loop].va + sz,
654 l1_sec_table[loop].pa + sz,
655 l1_sec_table[loop].prot,
656 l1_sec_table[loop].cache);
657 ++loop;
658 }
659
660 /*
661 * Now we have the real page tables in place so we can switch to them.
662 * Once this is done we will be running with the REAL kernel page
663 * tables.
664 */
665
666 /* Switch tables */
667 #ifdef VERBOSE_INIT_ARM
668 printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n",
669 physical_freestart, free_pages, free_pages);
670 printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa);
671 #endif
672
673 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
674 cpu_setttb(kernel_l1pt.pv_pa, true);
675 cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
676
677 /*
678 * Moved from cpu_startup() as data_abort_handler() references
679 * this during uvm init
680 */
681 uvm_lwp_setuarea(&lwp0, kernelstack.pv_va);
682
683 #ifdef VERBOSE_INIT_ARM
684 printf("done!\n");
685 #endif
686
687 /*
688 * XXX this should only be done in main() but it useful to
689 * have output earlier ...
690 */
691 consinit();
692
693 #ifdef VERBOSE_INIT_ARM
694 printf("bootstrap done.\n");
695 #endif
696
697 arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL);
698
699 /*
700 * Pages were allocated during the secondary bootstrap for the
701 * stacks for different CPU modes.
702 * We must now set the r13 registers in the different CPU modes to
703 * point to these stacks.
704 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
705 * of the stack memory.
706 */
707 printf("init subsystems: stacks ");
708
709 set_stackptr(PSR_IRQ32_MODE,
710 irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
711 set_stackptr(PSR_ABT32_MODE,
712 abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
713 set_stackptr(PSR_UND32_MODE,
714 undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
715
716 /*
717 * Well we should set a data abort handler.
718 * Once things get going this will change as we will need a proper
719 * handler.
720 * Until then we will use a handler that just panics but tells us
721 * why.
722 * Initialisation of the vectors will just panic on a data abort.
723 * This just fills in a slightly better one.
724 */
725 printf("vectors ");
726 data_abort_handler_address = (u_int)data_abort_handler;
727 prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
728 undefined_handler_address = (u_int)undefinedinstruction_bounce;
729
730 /* Initialise the undefined instruction handlers */
731 printf("undefined ");
732 undefined_init();
733
734 /* Load memory into UVM. */
735 printf("page ");
736 uvm_md_init();
737
738 /* XXX Always one RAM block -- nuke the loop. */
739 for (loop = 0; loop < bootconfig.dramblocks; loop++) {
740 paddr_t start = (paddr_t)bootconfig.dram[loop].address;
741 paddr_t end = start + (bootconfig.dram[loop].pages * PAGE_SIZE);
742 #if NISADMA > 0
743 paddr_t istart, isize;
744 extern struct arm32_dma_range *footbridge_isa_dma_ranges;
745 extern int footbridge_isa_dma_nranges;
746 #endif
747
748 if (start < physical_freestart)
749 start = physical_freestart;
750 if (end > physical_freeend)
751 end = physical_freeend;
752
753 #if 0
754 printf("%d: %lx -> %lx\n", loop, start, end - 1);
755 #endif
756
757 #if NISADMA > 0
758 if (arm32_dma_range_intersect(footbridge_isa_dma_ranges,
759 footbridge_isa_dma_nranges,
760 start, end - start,
761 &istart, &isize)) {
762 /*
763 * Place the pages that intersect with the
764 * ISA DMA range onto the ISA DMA free list.
765 */
766 #if 0
767 printf(" ISADMA 0x%lx -> 0x%lx\n", istart,
768 istart + isize - 1);
769 #endif
770 uvm_page_physload(atop(istart),
771 atop(istart + isize), atop(istart),
772 atop(istart + isize), VM_FREELIST_ISADMA);
773
774 /*
775 * Load the pieces that come before the
776 * intersection onto the default free list.
777 */
778 if (start < istart) {
779 #if 0
780 printf(" BEFORE 0x%lx -> 0x%lx\n",
781 start, istart - 1);
782 #endif
783 uvm_page_physload(atop(start),
784 atop(istart), atop(start),
785 atop(istart), VM_FREELIST_DEFAULT);
786 }
787
788 /*
789 * Load the pieces that come after the
790 * intersection onto the default free list.
791 */
792 if ((istart + isize) < end) {
793 #if 0
794 printf(" AFTER 0x%lx -> 0x%lx\n",
795 (istart + isize), end - 1);
796 #endif
797 uvm_page_physload(atop(istart + isize),
798 atop(end), atop(istart + isize),
799 atop(end), VM_FREELIST_DEFAULT);
800 }
801 } else {
802 uvm_page_physload(atop(start), atop(end),
803 atop(start), atop(end), VM_FREELIST_DEFAULT);
804 }
805 #else /* NISADMA > 0 */
806 uvm_page_physload(atop(start), atop(end),
807 atop(start), atop(end), VM_FREELIST_DEFAULT);
808 #endif /* NISADMA > 0 */
809 }
810
811 /* Boot strap pmap telling it where managed kernel virtual memory is */
812 printf("pmap ");
813 pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE);
814
815 /* Now that pmap is inited, we can set cpu_reset_address */
816 cpu_reset_address_paddr = vtophys((vaddr_t)netwinder_reset);
817
818 /* Setup the IRQ system */
819 printf("irq ");
820 footbridge_intr_init();
821 printf("done.\n");
822
823 /*
824 * Warn the user if the bootinfo was bogus. We already
825 * faked up some safe values.
826 */
827 if (nwbootinfo.bi_pagesize == 0xdeadbeef)
828 printf("WARNING: NeTTrom boot info corrupt\n");
829
830 #ifdef DDB
831 db_machine_init();
832 if (boothowto & RB_KDB)
833 Debugger();
834 #endif
835
836 /* Turn the led green */
837 ISA_PUTBYTE(0x338, 0x06);
838
839 /* We return the new stack pointer address */
840 return kernelstack.pv_va + USPACE_SVC_STACK_TOP;
841 }
842
843 void
process_kernel_args(char * args)844 process_kernel_args(char *args)
845 {
846
847 boothowto = 0;
848
849 /* Make a local copy of the bootargs */
850 strncpy(bootargs, args, MAX_BOOT_STRING);
851
852 args = bootargs;
853 boot_file = bootargs;
854
855 /* Skip the kernel image filename */
856 while (*args != ' ' && *args != 0)
857 ++args;
858
859 if (*args != 0)
860 *args++ = 0;
861
862 while (*args == ' ')
863 ++args;
864
865 boot_args = args;
866
867 printf("bootfile: %s\n", boot_file);
868 printf("bootargs: %s\n", boot_args);
869
870 parse_mi_bootargs(boot_args);
871 }
872
873 void
consinit(void)874 consinit(void)
875 {
876 static int consinit_called = 0;
877 const char *console = CONSDEVNAME;
878
879 if (consinit_called != 0)
880 return;
881
882 consinit_called = 1;
883
884 #ifdef DIAGNOSTIC
885 printf("consinit(\"%s\")\n", console);
886 #endif
887
888 #if NISA > 0
889 /* Initialise the ISA subsystem early ... */
890 isa_footbridge_init(DC21285_PCI_IO_VBASE, DC21285_PCI_ISA_MEM_VBASE);
891 #endif
892
893 if (strncmp(console, "igsfb", 5) == 0) {
894 #if NIGSFB > 0
895 int res;
896
897 footbridge_pci_bs_tag_init();
898
899 /*
900 * XXX: uwe: special case mapping for the igsfb memory space.
901 *
902 * The problem with this is that when footbridge is
903 * attached during normal autoconfiguration the bus
904 * space tags will be reinited and these hooks lost.
905 * However, since igsfb(4) don't unmap memory during
906 * normal operation, this is ok. But if the igsfb is
907 * configured but is not a console, we waste 16M of
908 * kernel VA space.
909 */
910 footbridge_pci_mem_bs_tag.bs_map = nw_footbridge_mem_bs_map;
911 footbridge_pci_mem_bs_tag.bs_unmap = nw_footbridge_mem_bs_unmap;
912
913 igsfb_pci_cnattach(&footbridge_pci_io_bs_tag,
914 &footbridge_pci_mem_bs_tag,
915 &footbridge_pci_chipset,
916 0, 8, 0);
917 #if NPCKBC > 0
918 res = pckbc_cnattach(&isa_io_bs_tag,
919 IO_KBD, KBCMDP, PCKBC_KBD_SLOT, 0);
920 if (res)
921 printf("pckbc_cnattach: %d!\n", res);
922 #endif
923 #else
924 panic("igsfb console not configured");
925 #endif /* NIGSFB */
926 } else {
927 #ifdef DIAGNOSTIC
928 if (strncmp(console, "com", 3) != 0) {
929 printf("consinit: unknown CONSDEVNAME=\"%s\","
930 " falling back to \"com\"\n", console);
931 }
932 #endif
933 #if NCOM > 0
934 if (comcnattach(&isa_io_bs_tag, CONCOMADDR, comcnspeed,
935 COM_FREQ, COM_TYPE_NORMAL, comcnmode))
936 panic("can't init serial console @%x", CONCOMADDR);
937 #else
938 panic("serial console @%x not configured", CONCOMADDR);
939 #endif
940 }
941 }
942
943
944 #if NIGSFB > 0
945 static int
nw_footbridge_mem_bs_map(void * t,bus_addr_t bpa,bus_size_t size,int cacheable,bus_space_handle_t * bshp)946 nw_footbridge_mem_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int cacheable, bus_space_handle_t *bshp)
947 {
948 bus_addr_t startpa, endpa;
949
950 /* Round the allocation to page boundaries */
951 startpa = trunc_page(bpa);
952 endpa = round_page(bpa + size);
953
954 /*
955 * Check for mappings of the igsfb(4) memory space as we have
956 * this space already mapped.
957 */
958 if (startpa >= IGS_PCI_MEM_BASE
959 && endpa < (IGS_PCI_MEM_BASE + IGS_PCI_MEM_VSIZE)) {
960 /* Store the bus space handle */
961 *bshp = IGS_PCI_MEM_VBASE
962 + (bpa - IGS_PCI_MEM_BASE);
963 #ifdef DEBUG
964 printf("nw/mem_bs_map: %08x+%08x: %08x..%08x -> %08x\n",
965 (u_int32_t)bpa, (u_int32_t)size,
966 (u_int32_t)startpa, (u_int32_t)endpa,
967 (u_int32_t)*bshp);
968 #endif
969 return 0;
970 }
971
972 return (footbridge_mem_bs_map(t, bpa, size, cacheable, bshp));
973 }
974
975
976 static void
nw_footbridge_mem_bs_unmap(void * t,bus_space_handle_t bsh,bus_size_t size)977 nw_footbridge_mem_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size)
978 {
979
980 /*
981 * Check for mappings of the igsfb(4) memory space as we have
982 * this space already mapped.
983 */
984 if (bsh >= IGS_PCI_MEM_VBASE
985 && bsh < (IGS_PCI_MEM_VBASE + IGS_PCI_MEM_VSIZE)) {
986 #ifdef DEBUG
987 printf("nw/bs_unmap: 0x%08x\n", (u_int32_t)bsh);
988 #endif
989 return;
990 }
991
992 footbridge_mem_bs_unmap(t, bsh, size);
993 }
994 #endif /* NIGSFB */
995
996
997 static bus_space_handle_t kcom_base = (bus_space_handle_t) (DC21285_PCI_IO_VBASE + CONCOMADDR);
998
999 #define KCOM_GETBYTE(r) generic_bs_r_1(0, kcom_base, (r))
1000 #define KCOM_PUTBYTE(r,v) generic_bs_w_1(0, kcom_base, (r), (v))
1001
1002 static int
kcomcngetc(dev_t dev)1003 kcomcngetc(dev_t dev)
1004 {
1005 int stat, c;
1006
1007 /* block until a character becomes available */
1008 while (!ISSET(stat = KCOM_GETBYTE(com_lsr), LSR_RXRDY))
1009 ;
1010
1011 c = KCOM_GETBYTE(com_data);
1012 stat = KCOM_GETBYTE(com_iir);
1013 return c;
1014 }
1015
1016 /*
1017 * Console kernel output character routine.
1018 */
1019 static void
kcomcnputc(dev_t dev,int c)1020 kcomcnputc(dev_t dev, int c)
1021 {
1022 int timo;
1023
1024 /* wait for any pending transmission to finish */
1025 timo = 150000;
1026 while (!ISSET(KCOM_GETBYTE(com_lsr), LSR_TXRDY) && --timo)
1027 continue;
1028
1029 KCOM_PUTBYTE(com_data, c);
1030
1031 /* wait for this transmission to complete */
1032 timo = 1500000;
1033 while (!ISSET(KCOM_GETBYTE(com_lsr), LSR_TXRDY) && --timo)
1034 continue;
1035 }
1036
1037 static void
kcomcnpollc(dev_t dev,int on)1038 kcomcnpollc(dev_t dev, int on)
1039 {
1040 }
1041
1042 struct consdev kcomcons = {
1043 NULL, NULL, kcomcngetc, kcomcnputc, kcomcnpollc, NULL,
1044 NULL, NULL, NODEV, CN_NORMAL
1045 };
1046