Module Name: src Committed By: thorpej Date: Fri Feb 19 05:21:39 UTC 2021
Modified Files: src/sys/arch/powerpc/include: ofw_machdep.h src/sys/arch/powerpc/oea: ofw_consinit.c ofwoea_machdep.c src/sys/arch/powerpc/powerpc: ofw_machdep.c Log Message: Shuffle around a couple of things that aren't particularly OEA-specific: - Early bootstrap console initialization moves to ofw_machdep.c, and is called a bit earlier, from ofw_bootstrap(). - Decoding the "translations" property from /chosen/mmu is specified in the general OpenFirmware PowerPC bindings, and is not specific to any particular PowerPC flavor. It's now decoded a bit earlier in ofw_bootstrap(). The *interpretation* of the mode field of a translation is, however, implementation-specific, so that remains in ofwoea_machdep.c. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/arch/powerpc/include/ofw_machdep.h cvs rdiff -u -r1.19 -r1.20 src/sys/arch/powerpc/oea/ofw_consinit.c cvs rdiff -u -r1.51 -r1.52 src/sys/arch/powerpc/oea/ofwoea_machdep.c cvs rdiff -u -r1.27 -r1.28 src/sys/arch/powerpc/powerpc/ofw_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/powerpc/include/ofw_machdep.h diff -u src/sys/arch/powerpc/include/ofw_machdep.h:1.1 src/sys/arch/powerpc/include/ofw_machdep.h:1.2 --- src/sys/arch/powerpc/include/ofw_machdep.h:1.1 Thu Feb 18 18:31:22 2021 +++ src/sys/arch/powerpc/include/ofw_machdep.h Fri Feb 19 05:21:39 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: ofw_machdep.h,v 1.1 2021/02/18 18:31:22 thorpej Exp $ */ +/* $NetBSD: ofw_machdep.h,v 1.2 2021/02/19 05:21:39 thorpej Exp $ */ /*- * Copyright (c) 2021 The NetBSD Foundation, Inc. @@ -32,6 +32,31 @@ #ifdef _KERNEL #include <machine/powerpc.h> +/* + * The general format of an OpenFirmware virtual translation record is: + * + * cell(s) virt + * cell(s) size + * cell(s) phys + * cell mode + * + * "mode" contains PTE WIMG bits. + * + * We define this structure to describe these translations that's independent + * of the number of cells each field consumes. + */ +struct OF_translation { + vaddr_t virt; + vsize_t size; + paddr_t phys; + uint32_t mode; +}; + +#define OFW_MAX_TRANSLATIONS 32 + +extern int ofw_chosen; /* cached handle for "/chosen" */ +extern struct OF_translation ofw_translations[OFW_MAX_TRANSLATIONS]; + void ofw_bootstrap(void); #endif /* _KERNEL */ Index: src/sys/arch/powerpc/oea/ofw_consinit.c diff -u src/sys/arch/powerpc/oea/ofw_consinit.c:1.19 src/sys/arch/powerpc/oea/ofw_consinit.c:1.20 --- src/sys/arch/powerpc/oea/ofw_consinit.c:1.19 Mon Jul 6 09:34:17 2020 +++ src/sys/arch/powerpc/oea/ofw_consinit.c Fri Feb 19 05:21:39 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: ofw_consinit.c,v 1.19 2020/07/06 09:34:17 rin Exp $ */ +/* $NetBSD: ofw_consinit.c,v 1.20 2021/02/19 05:21:39 thorpej Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ofw_consinit.c,v 1.19 2020/07/06 09:34:17 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ofw_consinit.c,v 1.20 2021/02/19 05:21:39 thorpej Exp $"); #include "adb.h" #include "adbkbd.h" @@ -54,6 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: ofw_consinit #include <sys/bus.h> #include <powerpc/ofw_cons.h> +#include <powerpc/ofw_machdep.h> #include <dev/cons.h> #include <dev/ofw/openfirm.h> @@ -88,26 +89,14 @@ extern struct consdev consdev_zs; #include <dev/ic/pckbcvar.h> #endif -int console_node = 0, console_instance = 0; +extern int console_node, console_instance; -int chosen, stdin, stdout; int ofkbd_ihandle; static void cninit_kd(void); -static void ofwoea_bootstrap_console(void); -static int ofwbootcons_cngetc(dev_t); -static void ofwbootcons_cnputc(dev_t, int); /*#define OFDEBUG*/ -struct consdev consdev_ofwbootcons = { - NULL, NULL, - ofwbootcons_cngetc, - ofwbootcons_cnputc, - nullcnpollc, - NULL, NULL, NULL, NODEV, CN_INTERNAL, -}; - #ifdef OFDEBUG void ofprint(const char *, ...); @@ -133,11 +122,9 @@ cninit(void) { char name[32]; - ofwoea_bootstrap_console(); - OFPRINTF("console node: %08x\n", console_node); - if (console_node == -1) + if (console_node <= 0) goto nocons; memset(name, 0, sizeof(name)); @@ -171,9 +158,7 @@ cninit(void) return; #endif /* NZTTY */ - /* fallback to OFW boot console */ - cp = &consdev_ofwbootcons; - cn_tab = cp; + /* fallback to OFW boot console (already set) */ return; } else @@ -207,7 +192,7 @@ cninit_kd(void) /* * We must determine which keyboard type we have. */ - if (OF_getprop(chosen, "stdin", &kstdin, sizeof(kstdin)) + if (OF_getprop(ofw_chosen, "stdin", &kstdin, sizeof(kstdin)) != sizeof(kstdin)) { printf("WARNING: no `stdin' property in /chosen\n"); return; @@ -324,7 +309,7 @@ cninit_kd(void) */ #if NUKBD > 0 - if (OF_call_method("`usb-kbd-ihandles", stdin, 0, 1, &ukbds) >= 0 && + if (OF_call_method("`usb-kbd-ihandles", kstdin, 0, 1, &ukbds) >= 0 && ukbds != NULL && ukbds->ihandle != 0 && OF_instance_to_package(ukbds->ihandle) != -1) { printf("usb-kbd-ihandles matches\n"); @@ -407,30 +392,6 @@ ofkbd_cngetc(dev_t dev) return c; } -/* - * Bootstrap console support functions - */ - -static int -ofwbootcons_cngetc(dev_t dev) -{ - unsigned char ch = '\0'; - int l; - - while ((l = OF_read(stdin, &ch, 1)) != 1) - if (l != -2 && l != 0) - return -1; - return ch; -} - -static void -ofwbootcons_cnputc(dev_t dev, int c) -{ - char ch = c; - - OF_write(stdout, &ch, 1); -} - void ofwoea_consinit(void) { @@ -442,33 +403,3 @@ ofwoea_consinit(void) initted = 1; cninit(); } - -static void -ofwoea_bootstrap_console(void) -{ - int node; - - chosen = OF_finddevice("/chosen"); - if (chosen == -1) - goto nocons; - - if (OF_getprop(chosen, "stdout", &stdout, - sizeof(stdout)) != sizeof(stdout)) - goto nocons; - if (OF_getprop(chosen, "stdin", &stdin, - sizeof(stdin)) != sizeof(stdin)) - goto nocons; - if (stdout == 0) { - /* screen should be console, but it is not open */ - stdout = OF_open("screen"); - } - node = OF_instance_to_package(stdout); - console_node = node; - console_instance = stdout; - - return; -nocons: - panic("No /chosen could be found!\n"); - console_node = -1; - return; -} Index: src/sys/arch/powerpc/oea/ofwoea_machdep.c diff -u src/sys/arch/powerpc/oea/ofwoea_machdep.c:1.51 src/sys/arch/powerpc/oea/ofwoea_machdep.c:1.52 --- src/sys/arch/powerpc/oea/ofwoea_machdep.c:1.51 Fri Feb 12 23:40:02 2021 +++ src/sys/arch/powerpc/oea/ofwoea_machdep.c Fri Feb 19 05:21:39 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: ofwoea_machdep.c,v 1.51 2021/02/12 23:40:02 thorpej Exp $ */ +/* $NetBSD: ofwoea_machdep.c,v 1.52 2021/02/19 05:21:39 thorpej Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.51 2021/02/12 23:40:02 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.52 2021/02/19 05:21:39 thorpej Exp $"); #include "ksyms.h" #include "wsdisplay.h" @@ -69,6 +69,7 @@ __KERNEL_RCSID(0, "$NetBSD: ofwoea_machd #include <powerpc/oea/cpufeat.h> #include <powerpc/include/oea/spr.h> #include <powerpc/ofw_cons.h> +#include <powerpc/ofw_machdep.h> #include <powerpc/spr.h> #include <powerpc/pic/picvar.h> @@ -97,19 +98,9 @@ typedef struct _rangemap { int type; } rangemap_t; -struct ofw_translations { - vaddr_t va; - int len; -#if defined (PMAC_G5) - register64_t pa; -#else - register_t pa; -#endif - int mode; -}__attribute__((packed)); +struct OF_translation ofw_translations[OFW_MAX_TRANSLATIONS]; struct pmap ofw_pmap; -struct ofw_translations ofmap[32]; char bootpath[256]; char model_name[64]; #if NKSYMS || defined(DDB) || defined(MODULAR) @@ -129,13 +120,11 @@ u_int timebase_freq = 0; int ofw_quiesce; extern int ofwmsr; -extern int chosen; extern uint32_t ticks_per_sec; extern uint32_t ns_per_tick; extern uint32_t ticks_per_intr; -static int save_ofmap(struct ofw_translations *, int); -static void restore_ofmap(struct ofw_translations *, int); +static void restore_ofmap(void); static void set_timebase(void); extern void cpu_spinstart(u_int); @@ -144,7 +133,7 @@ extern volatile u_int cpu_spinstart_ack; void ofwoea_initppc(u_int startkernel, u_int endkernel, char *args) { - int ofmaplen, node, l; + int node, l; register_t scratch; #if defined(MULTIPROCESSOR) && defined(ofppc) @@ -216,10 +205,6 @@ ofwoea_initppc(u_int startkernel, u_int oea_init(pic_ext_intr); - ofmaplen = save_ofmap(NULL, 0); - if (ofmaplen > 0) - save_ofmap(ofmap, ofmaplen); - /* * XXX * we need to do this here instead of earlier on in ofwinit() for some reason @@ -305,7 +290,7 @@ ofwoea_initppc(u_int startkernel, u_int : "=r"(scratch) : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI)); - restore_ofmap(ofmap, ofmaplen); + restore_ofmap(); rascons_finalize(); @@ -376,33 +361,11 @@ found: mtmsr(msr); } -static int -save_ofmap(struct ofw_translations *map, int maxlen) -{ - int mmui, mmu, len; - - OF_getprop(chosen, "mmu", &mmui, sizeof mmui); - mmu = OF_instance_to_package(mmui); - - if (map) { - memset(map, 0, maxlen); /* to be safe */ - len = OF_getprop(mmu, "translations", map, maxlen); - } else - len = OF_getproplen(mmu, "translations"); - - if (len < 0) - len = 0; - return len; -} - - -/* The PMAC_G5 code here needs to be replaced by code that looks for the - size_cells and does the right thing automatically. -*/ void -restore_ofmap(struct ofw_translations *map, int len) +restore_ofmap(void) { - int n = len / sizeof(struct ofw_translations); + vaddr_t va, size; + paddr_t pa; int i; pmap_pinit(&ofw_pmap); @@ -416,24 +379,26 @@ restore_ofmap(struct ofw_translations *m #endif #endif - for (i = 0; i < n; i++) { -#if defined (PMAC_G5) - register64_t pa = map[i].pa; -#else - register_t pa = map[i].pa; -#endif - vaddr_t va = map[i].va; - size_t length = map[i].len; + for (i = 0; i < __arraycount(ofw_translations); i++) { + va = ofw_translations[i].virt; + size = ofw_translations[i].size; + pa = ofw_translations[i].phys; + /* XXX mode */ + + if (size == 0) { + /* No more, all done! */ + break; + } - if (va < 0xf0000000) /* XXX */ + if (va < 0xf0000000) /* XXX */ continue; - while (length > 0) { - pmap_enter(&ofw_pmap, va, (paddr_t)pa, VM_PROT_ALL, + while (size > 0) { + pmap_enter(&ofw_pmap, va, pa, VM_PROT_ALL, VM_PROT_ALL|PMAP_WIRED); pa += PAGE_SIZE; va += PAGE_SIZE; - length -= PAGE_SIZE; + size -= PAGE_SIZE; } } pmap_update(&ofw_pmap); Index: src/sys/arch/powerpc/powerpc/ofw_machdep.c diff -u src/sys/arch/powerpc/powerpc/ofw_machdep.c:1.27 src/sys/arch/powerpc/powerpc/ofw_machdep.c:1.28 --- src/sys/arch/powerpc/powerpc/ofw_machdep.c:1.27 Thu Feb 18 18:31:22 2021 +++ src/sys/arch/powerpc/powerpc/ofw_machdep.c Fri Feb 19 05:21:39 2021 @@ -1,4 +1,33 @@ -/* $NetBSD: ofw_machdep.c,v 1.27 2021/02/18 18:31:22 thorpej Exp $ */ +/* $NetBSD: ofw_machdep.c,v 1.28 2021/02/19 05:21:39 thorpej Exp $ */ + +/*- + * Copyright (c) 2007, 2021 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Tim Rightnour + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ /* * Copyright (C) 1996 Wolfgang Solfrank. @@ -32,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ofw_machdep.c,v 1.27 2021/02/18 18:31:22 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ofw_machdep.c,v 1.28 2021/02/19 05:21:39 thorpej Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -45,6 +74,7 @@ __KERNEL_RCSID(0, "$NetBSD: ofw_machdep. #include <sys/stat.h> #include <sys/systm.h> +#include <dev/cons.h> #include <dev/ofw/openfirm.h> #include <machine/powerpc.h> @@ -58,6 +88,80 @@ __KERNEL_RCSID(0, "$NetBSD: ofw_machdep. #define DPRINTF while(0) printf #endif +int ofw_root; +int ofw_chosen; + +/* + * Bootstrap console support functions. + */ + +int console_node = -1, console_instance = -1; +int ofw_stdin, ofw_stdout; +int ofw_address_cells; +int ofw_size_cells; + +static int +ofwbootcons_cngetc(dev_t dev) +{ + unsigned char ch = '\0'; + int l; + + while ((l = OF_read(ofw_stdin, &ch, 1)) != 1) { + if (l != -2 && l != 0) { + return -1; + } + } + return ch; +} + +static void +ofwbootcons_cnputc(dev_t dev, int c) +{ + char ch = c; + + OF_write(ofw_stdout, &ch, 1); +} + +static struct consdev consdev_ofwbootcons = { + .cn_getc = ofwbootcons_cngetc, + .cn_putc = ofwbootcons_cnputc, + .cn_pollc = nullcnpollc, + .cn_dev = NODEV, + .cn_pri = CN_INTERNAL, +}; + +static void +ofw_bootstrap_console(void) +{ + int node; + + if (ofw_chosen == -1) { + goto nocons; + } + + if (OF_getprop(ofw_chosen, "stdout", &ofw_stdout, + sizeof(ofw_stdout)) != sizeof(ofw_stdout)) + goto nocons; + + if (OF_getprop(ofw_chosen, "stdin", &ofw_stdin, + sizeof(ofw_stdin)) != sizeof(ofw_stdin)) + goto nocons; + if (ofw_stdout == 0) { + /* screen should be console, but it is not open */ + ofw_stdout = OF_open("screen"); + } + node = OF_instance_to_package(ofw_stdout); + console_node = node; + console_instance = ofw_stdout; + + cn_tab = &consdev_ofwbootcons; + + return; + nocons: + panic("No /chosen could be found!\n"); + console_node = -1; +} + #define OFMEM_REGIONS 32 static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3]; @@ -65,22 +169,14 @@ static void ofw_bootstrap_get_memory(void) { const char *macrisc[] = {"MacRISC", "MacRISC2", "MacRISC4", NULL}; - int hroot, hmem, i, cnt, memcnt, regcnt, acells, scells; + int hmem, i, cnt, memcnt, regcnt; int numregs; uint32_t regs[OFMEM_REGIONS * 4]; /* 2 values + 2 for 64bit */ - DPRINTF("calling mem_regions\n"); - /* determine acell size */ - if ((hroot = OF_finddevice("/")) == -1) - goto error; - cnt = OF_getprop(hroot, "#address-cells", &acells, sizeof(int)); - if (cnt <= 0) - acells = 1; + int acells = ofw_address_cells; + int scells = ofw_size_cells; - /* determine scell size */ - cnt = OF_getprop(hroot, "#size-cells", &scells, sizeof(int)); - if (cnt <= 0) - scells = 1; + DPRINTF("calling mem_regions\n"); /* Get memory */ memset(regs, 0, sizeof(regs)); @@ -146,7 +242,7 @@ ofw_bootstrap_get_memory(void) * according to comments in FreeBSD all Apple OF has 32bit values in * "available", no matter what the cell sizes are */ - if (of_compatible(hroot, macrisc)) { + if (of_compatible(ofw_root, macrisc)) { DPRINTF("this appears to be a mac...\n"); acells = 1; scells = 1; @@ -238,6 +334,83 @@ error: return; } +static void +ofw_bootstrap_get_translations(void) +{ + /* 5 cells per: virt(1), size(1), phys(2), mode(1) */ + uint32_t regs[OFW_MAX_TRANSLATIONS * 5]; + uint32_t virt, size, mode; + uint64_t phys; + uint32_t *rp; + int proplen; + int mmu_ihandle, mmu_phandle; + int idx; + + if (OF_getprop(ofw_chosen, "mmu", &mmu_ihandle, + sizeof(mmu_ihandle)) <= 0) { + aprint_normal("No /chosen/mmu\n"); + return; + } + mmu_phandle = OF_instance_to_package(mmu_ihandle); + + proplen = OF_getproplen(mmu_phandle, "translations"); + if (proplen <= 0) { + aprint_normal("No translations in /chosen/mmu\n"); + return; + } + + if (proplen > sizeof(regs)) { + panic("/chosen/mmu translations too large"); + } + + proplen = OF_getprop(mmu_phandle, "translations", regs, sizeof(regs)); + int nregs = proplen / sizeof(regs[0]); + + /* Decode into ofw_translations[]. */ + for (idx = 0, rp = regs; rp < ®s[nregs];) { + virt = *rp++; + size = *rp++; + switch (ofw_address_cells) { + case 1: + phys = *rp++; + break; + case 2: + phys = *rp++; + phys = (phys << 32) | *rp++; + break; + default: + panic("unexpected #address-cells"); + } + mode = *rp++; + if (rp > ®s[nregs]) { + panic("unexpected OFW translations format"); + } + + /* Wouldn't expect this, but... */ + if (size == 0) { + continue; + } + + aprint_normal("translation %d virt=%#"PRIx32 + " size=%#"PRIx32" phys=%#"PRIx64" mode=%#"PRIx32"\n", + idx, virt, size, phys, mode); + + if (sizeof(paddr_t) < 8 && phys >= 0x100000000ULL) { + panic("translation phys out of range"); + } + + if (idx == OFW_MAX_TRANSLATIONS) { + panic("too many OFW translations"); + } + + ofw_translations[idx].virt = virt; + ofw_translations[idx].size = size; + ofw_translations[idx].phys = (paddr_t)phys; + ofw_translations[idx].mode = mode; + idx++; + } +} + /* * Called from ofwinit() very early in bootstrap. We are still * running on the stack provided by OpenFirmware and in the same @@ -248,8 +421,27 @@ error: void ofw_bootstrap(void) { + /* Stash the handles for "/" and "/chosen" for convenience later. */ + ofw_root = OF_finddevice("/"); + ofw_chosen = OF_finddevice("/chosen"); + + /* Initialize the early bootstrap console. */ + ofw_bootstrap_console(); + + /* Get #address-cells and #size-cells to fething memory info. */ + if (OF_getprop(ofw_root, "#address-cells", &ofw_address_cells, + sizeof(ofw_address_cells)) <= 0) + ofw_address_cells = 1; + + if (OF_getprop(ofw_root, "#size-cells", &ofw_size_cells, + sizeof(ofw_size_cells)) <= 0) + ofw_size_cells = 1; + /* Get the system memory configuration. */ ofw_bootstrap_get_memory(); + + /* Get any translations used by OpenFirmware. */ + ofw_bootstrap_get_translations(); } /*