Annotation of src/sys/arch/evbarm/fdt/fdt_machdep.c, Revision 1.20.2.1
1.20.2.1! pgoyette 1: /* $NetBSD: fdt_machdep.c,v 1.21 2018/04/01 04:35:04 ryo Exp $ */
1.1 jmcneill 2:
3: /*-
4: * Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
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: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23: * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26: * SUCH DAMAGE.
27: */
28:
29: #include <sys/cdefs.h>
1.20.2.1! pgoyette 30: __KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.21 2018/04/01 04:35:04 ryo Exp $");
1.1 jmcneill 31:
32: #include "opt_machdep.h"
1.20.2.1! pgoyette 33: #include "opt_bootconfig.h"
1.1 jmcneill 34: #include "opt_ddb.h"
35: #include "opt_md.h"
36: #include "opt_arm_debug.h"
37: #include "opt_multiprocessor.h"
38: #include "opt_cpuoptions.h"
39:
1.14 jmcneill 40: #include "ukbd.h"
41:
1.1 jmcneill 42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/bus.h>
45: #include <sys/atomic.h>
46: #include <sys/cpu.h>
47: #include <sys/device.h>
48: #include <sys/exec.h>
49: #include <sys/kernel.h>
50: #include <sys/kmem.h>
51: #include <sys/ksyms.h>
52: #include <sys/msgbuf.h>
53: #include <sys/proc.h>
54: #include <sys/reboot.h>
55: #include <sys/termios.h>
1.8 jmcneill 56: #include <sys/extent.h>
1.1 jmcneill 57:
58: #include <uvm/uvm_extern.h>
59:
60: #include <sys/conf.h>
61:
62: #include <machine/db_machdep.h>
63: #include <ddb/db_sym.h>
64: #include <ddb/db_extern.h>
65:
66: #include <machine/bootconfig.h>
67: #include <arm/armreg.h>
68:
1.20.2.1! pgoyette 69: #include <arm/cpufunc.h>
! 70: #ifdef __aarch64__
! 71: #include <aarch64/machdep.h>
! 72: #else
1.1 jmcneill 73: #include <arm/arm32/machdep.h>
1.20.2.1! pgoyette 74: #endif
! 75:
1.1 jmcneill 76:
77: #include <evbarm/include/autoconf.h>
78: #include <evbarm/fdt/platform.h>
79:
80: #include <arm/fdt/arm_fdtvar.h>
81:
1.14 jmcneill 82: #if NUKBD > 0
83: #include <dev/usb/ukbdvar.h>
84: #endif
85:
1.8 jmcneill 86: #ifdef MEMORY_DISK_DYNAMIC
87: #include <dev/md.h>
88: #endif
89:
1.1 jmcneill 90: #ifndef FDT_MAX_BOOT_STRING
91: #define FDT_MAX_BOOT_STRING 1024
92: #endif
93:
94: BootConfig bootconfig;
95: char bootargs[FDT_MAX_BOOT_STRING] = "";
96: char *boot_args = NULL;
1.20 skrll 97: /*
98: * filled in by xxx_start.S (must not be in bss)
99: */
100: unsigned long uboot_args[4] = { 0 };
101: const uint8_t *fdt_addr_r = (const uint8_t *)0xdeadc0de;
1.1 jmcneill 102:
1.8 jmcneill 103: static char fdt_memory_ext_storage[EXTENT_FIXED_STORAGE_SIZE(DRAM_BLOCKS)];
104: static struct extent *fdt_memory_ext;
105:
106: static uint64_t initrd_start, initrd_end;
107:
1.1 jmcneill 108: #include <libfdt.h>
109: #include <dev/fdt/fdtvar.h>
110: #define FDT_BUF_SIZE (128*1024)
111: static uint8_t fdt_data[FDT_BUF_SIZE];
112:
113: extern char KERNEL_BASE_phys[];
114: #define KERNEL_BASE_PHYS ((paddr_t)KERNEL_BASE_phys)
115:
1.5 jmcneill 116: static void fdt_update_stdout_path(void);
1.1 jmcneill 117: static void fdt_device_register(device_t, void *);
118: static void fdt_reset(void);
119: static void fdt_powerdown(void);
120:
121: #ifdef VERBOSE_INIT_ARM
122: static void
123: fdt_putchar(char c)
124: {
125: const struct arm_platform *plat = arm_fdt_platform();
1.2 jmcneill 126: if (plat && plat->early_putchar)
1.1 jmcneill 127: plat->early_putchar(c);
128: }
129:
130: static void
131: fdt_putstr(const char *s)
132: {
133: for (const char *p = s; *p; p++)
134: fdt_putchar(*p);
135: }
136:
137: static void
1.20.2.1! pgoyette 138: fdt_printn(unsigned long n, int base)
1.1 jmcneill 139: {
1.20.2.1! pgoyette 140: char *p, buf[(sizeof(unsigned long) * NBBY / 3) + 1 + 2 /* ALT + SIGN */];
1.1 jmcneill 141:
142: p = buf;
143: do {
144: *p++ = hexdigits[n % base];
145: } while (n /= base);
146:
147: do {
148: fdt_putchar(*--p);
149: } while (p > buf);
150: }
151: #define DPRINTF(...) printf(__VA_ARGS__)
152: #define DPRINT(x) fdt_putstr(x)
153: #define DPRINTN(x,b) fdt_printn((x), (b))
154: #else
155: #define DPRINTF(...)
156: #define DPRINT(x)
157: #define DPRINTN(x,b)
158: #endif
159:
1.7 jmcneill 160: /*
1.20.2.1! pgoyette 161: * ARM: Get the first physically contiguous region of memory.
! 162: * ARM64: Get all of physical memory, including holes.
1.7 jmcneill 163: */
164: static void
1.20.2.1! pgoyette 165: fdt_get_memory(uint64_t *pstart, uint64_t *pend)
1.7 jmcneill 166: {
167: const int memory = OF_finddevice("/memory");
168: uint64_t cur_addr, cur_size;
169: int index;
170:
171: /* Assume the first entry is the start of memory */
1.20.2.1! pgoyette 172: if (fdtbus_get_reg64(memory, 0, &cur_addr, &cur_size) != 0)
1.7 jmcneill 173: panic("Cannot determine memory size");
174:
1.20.2.1! pgoyette 175: *pstart = cur_addr;
! 176: *pend = cur_addr + cur_size;
! 177:
1.7 jmcneill 178: DPRINTF("FDT /memory [%d] @ 0x%" PRIx64 " size 0x%" PRIx64 "\n",
1.20.2.1! pgoyette 179: 0, *pstart, *pend - *pstart);
1.7 jmcneill 180:
181: for (index = 1;
182: fdtbus_get_reg64(memory, index, &cur_addr, &cur_size) == 0;
183: index++) {
184: DPRINTF("FDT /memory [%d] @ 0x%" PRIx64 " size 0x%" PRIx64 "\n",
185: index, cur_addr, cur_size);
1.20.2.1! pgoyette 186:
! 187: #ifdef __aarch64__
! 188: if (cur_addr + cur_size > *pend)
! 189: *pend = cur_addr + cur_size;
! 190: #else
! 191: /* If subsequent entries follow the previous, append them. */
! 192: if (*pend == cur_addr)
! 193: *pend = cur_addr + cur_size;
! 194: #endif
1.7 jmcneill 195: }
196: }
197:
1.16 skrll 198: void
1.8 jmcneill 199: fdt_add_reserved_memory_range(uint64_t addr, uint64_t size)
200: {
1.18 martin 201: uint64_t start = trunc_page(addr);
202: uint64_t end = round_page(addr + size);
1.8 jmcneill 203:
1.18 martin 204: int error = extent_free(fdt_memory_ext, start,
205: end - start, EX_NOWAIT);
1.8 jmcneill 206: if (error != 0)
1.11 jmcneill 207: printf("MEM ERROR: res %llx-%llx failed: %d\n",
1.18 martin 208: start, end, error);
1.11 jmcneill 209: else
1.18 martin 210: DPRINTF("MEM: res %llx-%llx\n", start, end);
1.8 jmcneill 211: }
212:
213: /*
1.11 jmcneill 214: * Exclude memory ranges from memory config from the device tree
1.8 jmcneill 215: */
216: static void
1.11 jmcneill 217: fdt_add_reserved_memory(uint64_t max_addr)
1.8 jmcneill 218: {
219: uint64_t addr, size;
1.11 jmcneill 220: int index, error;
1.8 jmcneill 221:
1.11 jmcneill 222: const int num = fdt_num_mem_rsv(fdtbus_get_data());
223: for (index = 0; index <= num; index++) {
224: error = fdt_get_mem_rsv(fdtbus_get_data(), index,
225: &addr, &size);
226: if (error != 0 || size == 0)
227: continue;
1.8 jmcneill 228: if (addr >= max_addr)
229: continue;
230: if (addr + size > max_addr)
231: size = max_addr - addr;
232: fdt_add_reserved_memory_range(addr, size);
233: }
234: }
235:
236: /*
237: * Define usable memory regions.
238: */
239: static void
1.20.2.1! pgoyette 240: fdt_build_bootconfig(uint64_t mem_start, uint64_t mem_end)
1.8 jmcneill 241: {
242: const int memory = OF_finddevice("/memory");
243: BootConfig *bc = &bootconfig;
244: struct extent_region *er;
245: uint64_t addr, size;
1.11 jmcneill 246: int index, error;
1.15 skrll 247:
1.20.2.1! pgoyette 248: fdt_memory_ext = extent_create("FDT Memory", mem_start, mem_end,
1.13 jmcneill 249: fdt_memory_ext_storage, sizeof(fdt_memory_ext_storage), EX_EARLY);
1.8 jmcneill 250:
251: for (index = 0;
252: fdtbus_get_reg64(memory, index, &addr, &size) == 0;
253: index++) {
1.20.2.1! pgoyette 254: if (addr >= mem_end || size == 0)
1.8 jmcneill 255: continue;
1.20.2.1! pgoyette 256: if (addr + size > mem_end)
! 257: size = mem_end - addr;
1.8 jmcneill 258:
259: error = extent_alloc_region(fdt_memory_ext, addr, size,
260: EX_NOWAIT);
261: if (error != 0)
262: printf("MEM ERROR: add %llx-%llx failed: %d\n",
1.18 martin 263: addr, addr + size, error);
264: DPRINTF("MEM: add %llx-%llx\n", addr, addr + size);
1.8 jmcneill 265: }
266:
1.20.2.1! pgoyette 267: fdt_add_reserved_memory(mem_end);
1.8 jmcneill 268:
269: const uint64_t initrd_size = initrd_end - initrd_start;
270: if (initrd_size > 0)
271: fdt_add_reserved_memory_range(initrd_start, initrd_size);
272:
273: DPRINTF("Usable memory:\n");
274: bc->dramblocks = 0;
275: LIST_FOREACH(er, &fdt_memory_ext->ex_regions, er_link) {
276: DPRINTF(" %lx - %lx\n", er->er_start, er->er_end);
277: bc->dram[bc->dramblocks].address = er->er_start;
278: bc->dram[bc->dramblocks].pages =
279: (er->er_end - er->er_start) / PAGE_SIZE;
280: bc->dramblocks++;
281: }
282: }
283:
284: static void
285: fdt_probe_initrd(uint64_t *pstart, uint64_t *pend)
286: {
287: *pstart = *pend = 0;
288:
289: #ifdef MEMORY_DISK_DYNAMIC
290: const int chosen = OF_finddevice("/chosen");
291: if (chosen < 0)
292: return;
293:
294: int len;
295: const void *start_data = fdtbus_get_prop(chosen,
296: "linux,initrd-start", &len);
297: const void *end_data = fdtbus_get_prop(chosen,
298: "linux,initrd-end", NULL);
299: if (start_data == NULL || end_data == NULL)
300: return;
301:
302: switch (len) {
303: case 4:
304: *pstart = be32dec(start_data);
305: *pend = be32dec(end_data);
306: break;
307: case 8:
308: *pstart = be64dec(start_data);
309: *pend = be64dec(end_data);
310: break;
311: default:
312: printf("Unsupported len %d for /chosen/initrd-start\n", len);
313: return;
314: }
315: #endif
316: }
317:
318: static void
319: fdt_setup_initrd(void)
320: {
321: #ifdef MEMORY_DISK_DYNAMIC
322: const uint64_t initrd_size = initrd_end - initrd_start;
323: paddr_t startpa = trunc_page(initrd_start);
324: paddr_t endpa = round_page(initrd_end);
325: paddr_t pa;
326: vaddr_t va;
327: void *md_start;
328:
329: if (initrd_size == 0)
330: return;
331:
332: va = uvm_km_alloc(kernel_map, initrd_size, 0,
333: UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
334: if (va == 0) {
335: printf("Failed to allocate VA for initrd\n");
336: return;
337: }
338:
339: md_start = (void *)va;
340:
341: for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE)
342: pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE, 0);
343: pmap_update(pmap_kernel());
344:
345: md_root_setconf(md_start, initrd_size);
346: #endif
347: }
348:
1.20.2.1! pgoyette 349: u_int initarm(void *arg);
! 350:
1.1 jmcneill 351: u_int
352: initarm(void *arg)
353: {
354: const struct arm_platform *plat;
1.20.2.1! pgoyette 355: uint64_t memory_start, memory_end;
1.1 jmcneill 356:
357: /* Load FDT */
358: int error = fdt_check_header(fdt_addr_r);
359: if (error == 0) {
360: error = fdt_move(fdt_addr_r, fdt_data, sizeof(fdt_data));
361: if (error != 0)
362: panic("fdt_move failed: %s", fdt_strerror(error));
363: fdtbus_set_data(fdt_data);
364: } else {
365: panic("fdt_check_header failed: %s", fdt_strerror(error));
366: }
367:
368: /* Lookup platform specific backend */
369: plat = arm_fdt_platform();
370: if (plat == NULL)
371: panic("Kernel does not support this device");
372:
373: /* Early console may be available, announce ourselves. */
1.2 jmcneill 374: DPRINT("FDT<");
375: DPRINTN((uintptr_t)fdt_addr_r, 16);
376: DPRINT(">");
1.1 jmcneill 377:
1.6 jmcneill 378: const int chosen = OF_finddevice("/chosen");
379: if (chosen >= 0)
380: OF_getprop(chosen, "bootargs", bootargs, sizeof(bootargs));
381: boot_args = bootargs;
382:
1.1 jmcneill 383: DPRINT(" devmap");
384: pmap_devmap_register(plat->devmap());
1.20.2.1! pgoyette 385: #ifdef __aarch64__
! 386: pmap_devmap_bootstrap(plat->devmap());
! 387: #endif
1.1 jmcneill 388:
389: /* Heads up ... Setup the CPU / MMU / TLB functions. */
390: DPRINT(" cpufunc");
391: if (set_cpufuncs())
392: panic("cpu not recognized!");
393:
1.16 skrll 394: DPRINT(" bootstrap");
395: plat->bootstrap();
396:
1.5 jmcneill 397: /*
398: * If stdout-path is specified on the command line, override the
399: * value in /chosen/stdout-path before initializing console.
400: */
401: fdt_update_stdout_path();
402:
1.1 jmcneill 403: DPRINT(" consinit");
404: consinit();
405:
406: DPRINTF(" ok\n");
407:
1.20.2.1! pgoyette 408: DPRINTF("uboot: args %#lx, %#lx, %#lx, %#lx\n",
1.1 jmcneill 409: uboot_args[0], uboot_args[1], uboot_args[2], uboot_args[3]);
410:
411: cpu_reset_address = fdt_reset;
412: cpu_powerdown_address = fdt_powerdown;
413: evbarm_device_register = fdt_device_register;
414:
415: /* Talk to the user */
416: DPRINTF("\nNetBSD/evbarm (fdt) booting ...\n");
417:
418: #ifdef BOOT_ARGS
419: char mi_bootargs[] = BOOT_ARGS;
420: parse_mi_bootargs(mi_bootargs);
421: #endif
422:
1.20.2.1! pgoyette 423: #ifndef __aarch64__
1.1 jmcneill 424: DPRINTF("KERNEL_BASE=0x%x, "
425: "KERNEL_VM_BASE=0x%x, "
426: "KERNEL_VM_BASE - KERNEL_BASE=0x%x, "
427: "KERNEL_BASE_VOFFSET=0x%x\n",
428: KERNEL_BASE,
429: KERNEL_VM_BASE,
430: KERNEL_VM_BASE - KERNEL_BASE,
431: KERNEL_BASE_VOFFSET);
1.20.2.1! pgoyette 432: #endif
1.1 jmcneill 433:
1.20.2.1! pgoyette 434: fdt_get_memory(&memory_start, &memory_end);
1.1 jmcneill 435:
436: #if !defined(_LP64)
437: /* Cannot map memory above 4GB */
1.20.2.1! pgoyette 438: if (memory_end >= 0x100000000ULL)
! 439: memory_end = 0x100000000ULL - PAGE_SIZE;
! 440:
! 441: uint64_t memory_size = memory_end - memory_start;
1.1 jmcneill 442: #endif
443:
1.20.2.1! pgoyette 444: #ifndef __aarch64__
1.1 jmcneill 445: #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
446: const bool mapallmem_p = true;
447: #ifndef PMAP_NEED_ALLOC_POOLPAGE
1.11 jmcneill 448: if (memory_size > KERNEL_VM_BASE - KERNEL_BASE) {
1.1 jmcneill 449: DPRINTF("%s: dropping RAM size from %luMB to %uMB\n",
1.15 skrll 450: __func__, (unsigned long) (memory_size >> 20),
1.1 jmcneill 451: (KERNEL_VM_BASE - KERNEL_BASE) >> 20);
1.11 jmcneill 452: memory_size = KERNEL_VM_BASE - KERNEL_BASE;
1.1 jmcneill 453: }
454: #endif
455: #else
456: const bool mapallmem_p = false;
457: #endif
1.20.2.1! pgoyette 458: #endif
1.1 jmcneill 459:
1.8 jmcneill 460: /* Parse ramdisk info */
461: fdt_probe_initrd(&initrd_start, &initrd_end);
462:
1.16 skrll 463: /*
464: * Populate bootconfig structure for the benefit of
465: * dodumpsys
466: */
1.20.2.1! pgoyette 467: fdt_build_bootconfig(memory_start, memory_end);
! 468:
! 469: #ifdef __aarch64__
! 470: extern char __kernel_text[];
! 471: extern char _end[];
! 472:
! 473: vaddr_t kernstart = trunc_page((vaddr_t)__kernel_text);
! 474: vaddr_t kernend = round_page((vaddr_t)_end);
! 475:
! 476: paddr_t kernstart_phys = KERN_VTOPHYS(kernstart);
! 477: paddr_t kernend_phys = KERN_VTOPHYS(kernend);
1.1 jmcneill 478:
1.20.2.1! pgoyette 479: DPRINTF("%s: kernel phys start %lx end %lx\n", __func__, kernstart_phys, kernend_phys);
! 480:
! 481: fdt_add_reserved_memory_range(kernstart_phys,
! 482: kernend_phys - kernstart_phys);
! 483: #else
! 484: arm32_bootmem_init(memory_start, memory_size, KERNEL_BASE_PHYS);
1.1 jmcneill 485: arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0,
486: plat->devmap(), mapallmem_p);
1.20.2.1! pgoyette 487: #endif
1.1 jmcneill 488:
489: DPRINTF("bootargs: %s\n", bootargs);
490:
491: parse_mi_bootargs(boot_args);
492:
1.17 jmcneill 493: #define MAX_PHYSMEM 16
1.16 skrll 494: static struct boot_physmem fdt_physmem[MAX_PHYSMEM];
495: int nfdt_physmem = 0;
496: struct extent_region *er;
497:
498: LIST_FOREACH(er, &fdt_memory_ext->ex_regions, er_link) {
499: DPRINTF(" %lx - %lx\n", er->er_start, er->er_end);
500: struct boot_physmem *bp = &fdt_physmem[nfdt_physmem++];
501:
1.17 jmcneill 502: KASSERT(nfdt_physmem <= MAX_PHYSMEM);
1.16 skrll 503: bp->bp_start = atop(er->er_start);
504: bp->bp_pages = atop(er->er_end - er->er_start);
505: bp->bp_freelist = VM_FREELIST_DEFAULT;
506:
1.20.2.1! pgoyette 507: #ifdef _LP64
! 508: if (er->er_end > 0x100000000)
! 509: bp->bp_freelist = VM_FREELIST_HIGHMEM;
! 510: #endif
! 511:
1.1 jmcneill 512: #ifdef PMAP_NEED_ALLOC_POOLPAGE
1.16 skrll 513: if (atop(memory_size) > bp->bp_pages) {
514: arm_poolpage_vmfreelist = VM_FREELIST_DIRECTMAP;
515: bp->bp_freelist = VM_FREELIST_DIRECTMAP;
516: }
517: #endif
1.1 jmcneill 518: }
519:
1.16 skrll 520: return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, fdt_physmem,
521: nfdt_physmem);
1.1 jmcneill 522: }
523:
1.5 jmcneill 524: static void
525: fdt_update_stdout_path(void)
526: {
527: char *stdout_path, *ep;
528: int stdout_path_len;
529: char buf[256];
530:
531: const int chosen_off = fdt_path_offset(fdt_data, "/chosen");
532: if (chosen_off == -1)
533: return;
534:
535: if (get_bootconf_option(boot_args, "stdout-path",
536: BOOTOPT_TYPE_STRING, &stdout_path) == 0)
537: return;
538:
539: ep = strchr(stdout_path, ' ');
540: stdout_path_len = ep ? (ep - stdout_path) : strlen(stdout_path);
541: if (stdout_path_len >= sizeof(buf))
542: return;
543:
544: strncpy(buf, stdout_path, stdout_path_len);
545: buf[stdout_path_len] = '\0';
546: fdt_setprop(fdt_data, chosen_off, "stdout-path",
547: buf, stdout_path_len + 1);
548: }
549:
1.1 jmcneill 550: void
551: consinit(void)
552: {
553: static bool initialized = false;
554: const struct arm_platform *plat = arm_fdt_platform();
555: const struct fdt_console *cons = fdtbus_get_console();
556: struct fdt_attach_args faa;
1.4 jmcneill 557: u_int uart_freq = 0;
1.1 jmcneill 558:
559: if (initialized || cons == NULL)
560: return;
561:
562: plat->init_attach_args(&faa);
563: faa.faa_phandle = fdtbus_get_stdout_phandle();
564:
1.4 jmcneill 565: if (plat->uart_freq != NULL)
566: uart_freq = plat->uart_freq();
567:
568: cons->consinit(&faa, uart_freq);
1.1 jmcneill 569:
1.14 jmcneill 570: #if NUKBD > 0
571: ukbd_cnattach(); /* allow USB keyboard to become console */
572: #endif
573:
1.1 jmcneill 574: initialized = true;
575: }
576:
1.3 jmcneill 577: void
578: delay(u_int us)
579: {
580: const struct arm_platform *plat = arm_fdt_platform();
581:
582: plat->delay(us);
583: }
584:
1.1 jmcneill 585: static void
586: fdt_device_register(device_t self, void *aux)
587: {
588: const struct arm_platform *plat = arm_fdt_platform();
589:
1.8 jmcneill 590: if (device_is_a(self, "armfdt"))
591: fdt_setup_initrd();
592:
1.1 jmcneill 593: if (plat && plat->device_register)
594: plat->device_register(self, aux);
595: }
596:
597: static void
598: fdt_reset(void)
599: {
600: const struct arm_platform *plat = arm_fdt_platform();
601:
602: fdtbus_power_reset();
603:
604: if (plat && plat->reset)
605: plat->reset();
606: }
607:
608: static void
609: fdt_powerdown(void)
610: {
611: fdtbus_power_poweroff();
612: }
CVSweb <webmaster@jp.NetBSD.org>