Date: Fri, 23 Jan 2015 23:54:56 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r277623 - in projects/powernv: conf powerpc/conf powerpc/powernv Message-ID: <201501232354.t0NNsuEI086763@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Fri Jan 23 23:54:55 2015 New Revision: 277623 URL: https://svnweb.freebsd.org/changeset/base/277623 Log: First round of PowerNV support: platform module, OPAL firmware abstraction layer interface, and console driver. The next set of interesting things is interrupt controller and PCI host bridge drivers. Sponsored by: FreeBSD Foundation Added: projects/powernv/powerpc/powernv/ projects/powernv/powerpc/powernv/opal.c (contents, props changed) projects/powernv/powerpc/powernv/opal.h (contents, props changed) projects/powernv/powerpc/powernv/opal_console.c - copied, changed from r277539, head/sys/powerpc/pseries/phyp_console.c projects/powernv/powerpc/powernv/opalcall.S (contents, props changed) projects/powernv/powerpc/powernv/platform_powernv.c (contents, props changed) Modified: projects/powernv/conf/files.powerpc projects/powernv/conf/options.powerpc projects/powernv/powerpc/conf/GENERIC64 Modified: projects/powernv/conf/files.powerpc ============================================================================== --- projects/powernv/conf/files.powerpc Fri Jan 23 23:53:56 2015 (r277622) +++ projects/powernv/conf/files.powerpc Fri Jan 23 23:54:55 2015 (r277623) @@ -170,6 +170,10 @@ powerpc/powermac/smusat.c optional power powerpc/powermac/uninorth.c optional powermac powerpc/powermac/uninorthpci.c optional powermac pci powerpc/powermac/vcoregpio.c optional powermac +powerpc/powernv/opal.c optional powernv +powerpc/powernv/opal_console.c optional powernv +powerpc/powernv/opalcall.S optional powernv +powerpc/powernv/platform_powernv.c optional powernv powerpc/powerpc/altivec.c standard powerpc/powerpc/autoconf.c standard powerpc/powerpc/bcopy.c standard Modified: projects/powernv/conf/options.powerpc ============================================================================== --- projects/powernv/conf/options.powerpc Fri Jan 23 23:53:56 2015 (r277622) +++ projects/powernv/conf/options.powerpc Fri Jan 23 23:54:55 2015 (r277623) @@ -22,6 +22,7 @@ MPC85XX opt_platform.h POWERMAC opt_platform.h PS3 opt_platform.h MAMBO +POWERNV PSERIES PSIM WII opt_platform.h Modified: projects/powernv/powerpc/conf/GENERIC64 ============================================================================== --- projects/powernv/powerpc/conf/GENERIC64 Fri Jan 23 23:53:56 2015 (r277622) +++ projects/powernv/powerpc/conf/GENERIC64 Fri Jan 23 23:54:55 2015 (r277623) @@ -31,6 +31,7 @@ options POWERMAC #NewWorld Apple Power options PS3 #Sony Playstation 3 options MAMBO #IBM Mambo Full System Simulator options PSERIES #PAPR-compliant systems (e.g. IBM p) +options POWERNV #Non-virtualized OpenPOWER systems options FDT #Flattened Device Tree options SCHED_ULE #ULE scheduler Added: projects/powernv/powerpc/powernv/opal.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/powernv/powerpc/powernv/opal.c Fri Jan 23 23:54:55 2015 (r277623) @@ -0,0 +1,66 @@ +/*- + * Copyright (C) 2015 Nathan Whitehorn + * All rights reserved. + * + * 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 AUTHOR ``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 TOOLS GMBH 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. + * + * $FreeBSD$ + */ + +#include <dev/ofw/openfirm.h> + +#include "opal.h" + +extern uint64_t opal_entrypoint; +extern uint64_t opal_data; +extern uint64_t opal_msr; + +static int opal_initialized = 0; + +int +opal_check(void) +{ + phandle_t opal; + cell_t val[2]; + + if (opal_initialized) + return (0); + + opal = OF_finddevice("/ibm,opal"); + if (opal == -1) + return (ENOENT); + + if (!OF_hasprop(opal, "opal-base-address") || + !OF_hasprop(opal, "opal-entry-address")) + return (ENOENT); + + OF_getencprop(opal, "opal-base-address", val, sizeof(val)); + opal_data = ((uint64_t)val[0] << 32) | val[1]; + OF_getencprop(opal, "opal-entry-address", val, sizeof(val)); + opal_entrypoint = ((uint64_t)val[0] << 32) | val[1]; + + opal_msr = mfmsr() & ~(PSL_EE | PSL_IR | PSL_DR | PSL_SE); + + opal_initialized = 1; + + return (0); +} + Added: projects/powernv/powerpc/powernv/opal.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/powernv/powerpc/powernv/opal.h Fri Jan 23 23:54:55 2015 (r277623) @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2015 Nathan Whitehorn + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _POWERNV_OPAL_H +#define _POWERNV_OPAL_H + +#include <sys/cdefs.h> +#include <sys/types.h> + +/* Check if OPAL is correctly instantiated. Will try to instantiate it. */ +int opal_check(void); + +/* Call an OPAL method. Any pointers passed must be real-mode accessible! */ +int opal_call(uint64_t token, ...); + +#define OPAL_CONSOLE_WRITE 1 +#define OPAL_CONSOLE_READ 2 +#define OPAL_START_CPU 41 + +#define OPAL_SUCCESS 0 +#define OPAL_BUSY_EVENT -12 + +#endif Copied and modified: projects/powernv/powerpc/powernv/opal_console.c (from r277539, head/sys/powerpc/pseries/phyp_console.c) ============================================================================== --- head/sys/powerpc/pseries/phyp_console.c Thu Jan 22 22:04:43 2015 (r277539, copy source) +++ projects/powernv/powerpc/powernv/opal_console.c Fri Jan 23 23:54:55 2015 (r277623) @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2011 by Nathan Whitehorn. All rights reserved. + * Copyright (C) 2011,2015 by Nathan Whitehorn. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,7 +35,9 @@ __FBSDID("$FreeBSD$"); #include <sys/conf.h> #include <sys/cons.h> #include <sys/tty.h> -#include <machine/bus.h> + +#include <vm/vm.h> +#include <vm/pmap.h> #include <dev/ofw/openfirm.h> #include <dev/ofw/ofw_bus.h> @@ -44,10 +46,10 @@ __FBSDID("$FreeBSD$"); #include <dev/uart/uart_cpu.h> #include <dev/uart/uart_bus.h> -#include "phyp-hvcall.h" +#include "opal.h" #include "uart_if.h" -struct uart_phyp_softc { +struct uart_opal_softc { device_t dev; phandle_t node; int vtermid; @@ -62,21 +64,18 @@ struct uart_phyp_softc { struct mtx sc_mtx; int protocol; - union { - uint64_t u64[2]; - char str[16]; - } phyp_inbuf; + char opal_inbuf[16]; uint64_t inbuflen; uint8_t outseqno; }; -static struct uart_phyp_softc *console_sc = NULL; +static struct uart_opal_softc *console_sc = NULL; #if defined(KDB) static int alt_break_state; #endif enum { - HVTERM1, HVTERMPROT + OPAL_RAW, OPAL_HVSI }; #define VS_DATA_PACKET_HEADER 0xff @@ -89,45 +88,45 @@ enum { #define VSV_SEND_MODEM_CTL_STATUS 0x02 #define VS_QUERY_RESPONSE_PACKET_HEADER 0xfc -static int uart_phyp_probe(device_t dev); -static int uart_phyp_attach(device_t dev); -static void uart_phyp_intr(void *v); +static int uart_opal_probe(device_t dev); +static int uart_opal_attach(device_t dev); +static void uart_opal_intr(void *v); -static device_method_t uart_phyp_methods[] = { +static device_method_t uart_opal_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, uart_phyp_probe), - DEVMETHOD(device_attach, uart_phyp_attach), + DEVMETHOD(device_probe, uart_opal_probe), + DEVMETHOD(device_attach, uart_opal_attach), DEVMETHOD_END }; -static driver_t uart_phyp_driver = { +static driver_t uart_opal_driver = { "uart", - uart_phyp_methods, - sizeof(struct uart_phyp_softc), + uart_opal_methods, + sizeof(struct uart_opal_softc), }; -DRIVER_MODULE(uart_phyp, vdevice, uart_phyp_driver, uart_devclass, 0, 0); +DRIVER_MODULE(uart_opal, opalcons, uart_opal_driver, uart_devclass, 0, 0); -static cn_probe_t uart_phyp_cnprobe; -static cn_init_t uart_phyp_cninit; -static cn_term_t uart_phyp_cnterm; -static cn_getc_t uart_phyp_cngetc; -static cn_putc_t uart_phyp_cnputc; -static cn_grab_t uart_phyp_cngrab; -static cn_ungrab_t uart_phyp_cnungrab; +static cn_probe_t uart_opal_cnprobe; +static cn_init_t uart_opal_cninit; +static cn_term_t uart_opal_cnterm; +static cn_getc_t uart_opal_cngetc; +static cn_putc_t uart_opal_cnputc; +static cn_grab_t uart_opal_cngrab; +static cn_ungrab_t uart_opal_cnungrab; -CONSOLE_DRIVER(uart_phyp); +CONSOLE_DRIVER(uart_opal); -static void uart_phyp_ttyoutwakeup(struct tty *tp); +static void uart_opal_ttyoutwakeup(struct tty *tp); -static struct ttydevsw uart_phyp_tty_class = { +static struct ttydevsw uart_opal_tty_class = { .tsw_flags = TF_INITLOCK|TF_CALLOUT, - .tsw_outwakeup = uart_phyp_ttyoutwakeup, + .tsw_outwakeup = uart_opal_ttyoutwakeup, }; static int -uart_phyp_probe_node(struct uart_phyp_softc *sc) +uart_opal_probe_node(struct uart_opal_softc *sc) { phandle_t node = sc->node; uint32_t reg; @@ -136,11 +135,6 @@ uart_phyp_probe_node(struct uart_phyp_so sc->inbuflen = 0; sc->outseqno = 0; - if (OF_getprop(node, "name", buf, sizeof(buf)) <= 0) - return (ENXIO); - if (strcmp(buf, "vty") != 0) - return (ENXIO); - if (OF_getprop(node, "device_type", buf, sizeof(buf)) <= 0) return (ENXIO); if (strcmp(buf, "serial") != 0) @@ -155,11 +149,11 @@ uart_phyp_probe_node(struct uart_phyp_so if (OF_getprop(node, "compatible", buf, sizeof(buf)) <= 0) return (ENXIO); - if (strcmp(buf, "hvterm1") == 0) { - sc->protocol = HVTERM1; + if (strcmp(buf, "ibm,opal-console-raw") == 0) { + sc->protocol = OPAL_RAW; return (0); - } else if (strcmp(buf, "hvterm-protocol") == 0) { - sc->protocol = HVTERMPROT; + } else if (strcmp(buf, "ibm,opal-console-hvsi") == 0) { + sc->protocol = OPAL_HVSI; return (0); } @@ -167,54 +161,46 @@ uart_phyp_probe_node(struct uart_phyp_so } static int -uart_phyp_probe(device_t dev) +uart_opal_probe(device_t dev) { - const char *name; - struct uart_phyp_softc sc; + struct uart_opal_softc sc; int err; - name = ofw_bus_get_name(dev); - if (name == NULL || strcmp(name, "vty") != 0) - return (ENXIO); - sc.node = ofw_bus_get_node(dev); - err = uart_phyp_probe_node(&sc); + err = uart_opal_probe_node(&sc); if (err != 0) return (err); - device_set_desc(dev, "POWER Hypervisor Virtual Serial Port"); + device_set_desc(dev, "OPAL Serial Port"); return (err); } static void -uart_phyp_cnprobe(struct consdev *cp) +uart_opal_cnprobe(struct consdev *cp) { char buf[64]; - ihandle_t stdout; phandle_t input, chosen; - static struct uart_phyp_softc sc; + static struct uart_opal_softc sc; - if ((chosen = OF_finddevice("/chosen")) == -1) + if (opal_check() != 0) goto fail; - /* Check if OF has an active stdin/stdout */ - input = -1; - if (OF_getprop(chosen, "stdout", &stdout, - sizeof(stdout)) == sizeof(stdout) && stdout != 0) - input = OF_instance_to_package(stdout); - if (input == -1) + if ((chosen = OF_finddevice("/chosen")) == -1) goto fail; - if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) + /* Check if OF has an active stdin/stdout */ + if (OF_getprop(chosen, "linux,stdout-path", buf, sizeof(buf)) <= 0) goto fail; - if (strcmp(buf, "serial") != 0) + + input = OF_finddevice(buf); + if (input == -1) goto fail; sc.node = input; - if (uart_phyp_probe_node(&sc) != 0) + if (uart_opal_probe_node(&sc) != 0) goto fail; - mtx_init(&sc.sc_mtx, "uart_phyp", NULL, MTX_SPIN | MTX_QUIET | + mtx_init(&sc.sc_mtx, "uart_opal", NULL, MTX_SPIN | MTX_QUIET | MTX_NOWITNESS); cp->cn_pri = CN_NORMAL; @@ -227,25 +213,25 @@ fail: } static int -uart_phyp_attach(device_t dev) +uart_opal_attach(device_t dev) { - struct uart_phyp_softc *sc; + struct uart_opal_softc *sc; int unit; sc = device_get_softc(dev); sc->dev = dev; sc->node = ofw_bus_get_node(dev); - uart_phyp_probe_node(sc); + uart_opal_probe_node(sc); unit = device_get_unit(dev); - sc->tp = tty_alloc(&uart_phyp_tty_class, sc); + sc->tp = tty_alloc(&uart_opal_tty_class, sc); mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_SPIN | MTX_QUIET | MTX_NOWITNESS); if (console_sc != NULL && console_sc->vtermid == sc->vtermid) { sc->outseqno = console_sc->outseqno; console_sc = sc; - sprintf(uart_phyp_consdev.cn_name, "ttyu%r", unit); + sprintf(uart_opal_consdev.cn_name, "ttyu%r", unit); tty_init_console(sc->tp, 0); } @@ -254,13 +240,13 @@ uart_phyp_attach(device_t dev) RF_ACTIVE | RF_SHAREABLE); if (sc->irqres != NULL) { bus_setup_intr(dev, sc->irqres, INTR_TYPE_TTY | INTR_MPSAFE, - NULL, uart_phyp_intr, sc, &sc->sc_icookie); + NULL, uart_opal_intr, sc, &sc->sc_icookie); } else { callout_init(&sc->callout, CALLOUT_MPSAFE); sc->polltime = hz / 20; if (sc->polltime < 1) sc->polltime = 1; - callout_reset(&sc->callout, sc->polltime, uart_phyp_intr, sc); + callout_reset(&sc->callout, sc->polltime, uart_opal_intr, sc); } tty_makedev(sc->tp, NULL, "u%r", unit); @@ -269,111 +255,131 @@ uart_phyp_attach(device_t dev) } static void -uart_phyp_cninit(struct consdev *cp) +uart_opal_cninit(struct consdev *cp) { - strcpy(cp->cn_name, "phypcons"); + strcpy(cp->cn_name, "opalcons"); } static void -uart_phyp_cnterm(struct consdev *cp) +uart_opal_cnterm(struct consdev *cp) { } static int -uart_phyp_get(struct uart_phyp_softc *sc, void *buffer, size_t bufsize) +uart_opal_get(struct uart_opal_softc *sc, void *buffer, size_t bufsize) { int err; int hdr = 0; - uart_lock(&sc->sc_mtx); - if (sc->inbuflen == 0) { - err = phyp_pft_hcall(H_GET_TERM_CHAR, sc->vtermid, - 0, 0, 0, &sc->inbuflen, &sc->phyp_inbuf.u64[0], - &sc->phyp_inbuf.u64[1]); - if (err != H_SUCCESS) { - uart_unlock(&sc->sc_mtx); + if (sc->protocol == OPAL_RAW) { + uint64_t len = bufsize; + uint64_t olen = (uint64_t)&len; + uint64_t obuf = (uint64_t)buffer; + + if (pmap_bootstrapped) { + olen = vtophys(&len); + obuf = vtophys(buffer); + } + + err = opal_call(OPAL_CONSOLE_READ, sc->vtermid, olen, obuf); + if (err != OPAL_SUCCESS) return (-1); + + bufsize = len; + } else { + uart_lock(&sc->sc_mtx); + if (sc->inbuflen == 0) { + err = opal_call(OPAL_CONSOLE_READ, sc->vtermid, + &sc->inbuflen, sc->opal_inbuf); + if (err != OPAL_SUCCESS) { + uart_unlock(&sc->sc_mtx); + return (-1); + } + hdr = 1; } - hdr = 1; - } - if (sc->inbuflen == 0) { - uart_unlock(&sc->sc_mtx); - return (0); - } + if (sc->inbuflen == 0) { + uart_unlock(&sc->sc_mtx); + return (0); + } - if (bufsize > sc->inbuflen) - bufsize = sc->inbuflen; + if (bufsize > sc->inbuflen) + bufsize = sc->inbuflen; - if ((sc->protocol == HVTERMPROT) && (hdr == 1)) { - sc->inbuflen = sc->inbuflen - 4; - /* The VTERM protocol has a 4 byte header, skip it here. */ - memmove(&sc->phyp_inbuf.str[0], &sc->phyp_inbuf.str[4], - sc->inbuflen); - } + if (hdr == 1) { + sc->inbuflen = sc->inbuflen - 4; + /* The HVSI protocol has a 4 byte header, skip it */ + memmove(&sc->opal_inbuf[0], &sc->opal_inbuf[4], + sc->inbuflen); + } - memcpy(buffer, sc->phyp_inbuf.str, bufsize); - sc->inbuflen -= bufsize; - if (sc->inbuflen > 0) - memmove(&sc->phyp_inbuf.str[0], &sc->phyp_inbuf.str[bufsize], - sc->inbuflen); + memcpy(buffer, sc->opal_inbuf, bufsize); + sc->inbuflen -= bufsize; + if (sc->inbuflen > 0) + memmove(&sc->opal_inbuf[0], &sc->opal_inbuf[bufsize], + sc->inbuflen); + + uart_unlock(&sc->sc_mtx); + } - uart_unlock(&sc->sc_mtx); return (bufsize); } static int -uart_phyp_put(struct uart_phyp_softc *sc, void *buffer, size_t bufsize) +uart_opal_put(struct uart_opal_softc *sc, void *buffer, size_t bufsize) { uint16_t seqno; - uint64_t len = 0; + uint64_t len = bufsize; + char cbuf[16]; int err; + uint64_t olen = (uint64_t)&len; + uint64_t obuf = (uint64_t)cbuf; + + if (pmap_bootstrapped) + olen = vtophys(&len); + + if (sc->protocol == OPAL_RAW) { + if (pmap_bootstrapped) + obuf = vtophys(buffer); + else + obuf = (uint64_t)(buffer); - union { - uint64_t u64[2]; - char bytes[16]; - } cbuf; - - uart_lock(&sc->sc_mtx); - switch (sc->protocol) { - case HVTERM1: - if (bufsize > 16) - bufsize = 16; - memcpy(&cbuf, buffer, bufsize); - len = bufsize; - break; - case HVTERMPROT: + err = opal_call(OPAL_CONSOLE_WRITE, sc->vtermid, olen, obuf); + } else { + if (pmap_bootstrapped) + obuf = vtophys(cbuf); + uart_lock(&sc->sc_mtx); if (bufsize > 12) bufsize = 12; seqno = sc->outseqno++; - cbuf.bytes[0] = VS_DATA_PACKET_HEADER; - cbuf.bytes[1] = 4 + bufsize; /* total length, max 16 bytes */ - cbuf.bytes[2] = (seqno >> 8) & 0xff; - cbuf.bytes[3] = seqno & 0xff; - memcpy(&cbuf.bytes[4], buffer, bufsize); + cbuf[0] = VS_DATA_PACKET_HEADER; + cbuf[1] = 4 + bufsize; /* total length */ + cbuf[2] = (seqno >> 8) & 0xff; + cbuf[3] = seqno & 0xff; + memcpy(&cbuf[4], buffer, bufsize); len = 4 + bufsize; - break; - } + err = opal_call(OPAL_CONSOLE_WRITE, sc->vtermid, olen, obuf); + uart_unlock(&sc->sc_mtx); - do { - err = phyp_hcall(H_PUT_TERM_CHAR, sc->vtermid, len, cbuf.u64[0], - cbuf.u64[1]); - DELAY(100); - } while (err == H_BUSY); + len -= 4; + } - uart_unlock(&sc->sc_mtx); +#if 0 + if (err != OPAL_SUCCESS) + len = 0; +#endif - return (bufsize); + return (len); } static int -uart_phyp_cngetc(struct consdev *cp) +uart_opal_cngetc(struct consdev *cp) { unsigned char c; int retval; - retval = uart_phyp_get(console_sc, &c, 1); + retval = uart_opal_get(console_sc, &c, 1); if (retval != 1) return (-1); #if defined(KDB) @@ -384,50 +390,50 @@ uart_phyp_cngetc(struct consdev *cp) } static void -uart_phyp_cnputc(struct consdev *cp, int c) +uart_opal_cnputc(struct consdev *cp, int c) { unsigned char ch = c; - uart_phyp_put(console_sc, &ch, 1); + uart_opal_put(console_sc, &ch, 1); } static void -uart_phyp_cngrab(struct consdev *cp) +uart_opal_cngrab(struct consdev *cp) { } static void -uart_phyp_cnungrab(struct consdev *cp) +uart_opal_cnungrab(struct consdev *cp) { } static void -uart_phyp_ttyoutwakeup(struct tty *tp) +uart_opal_ttyoutwakeup(struct tty *tp) { - struct uart_phyp_softc *sc; + struct uart_opal_softc *sc; char buffer[8]; int len; sc = tty_softc(tp); while ((len = ttydisc_getc(tp, buffer, sizeof(buffer))) != 0) - uart_phyp_put(sc, buffer, len); + uart_opal_put(sc, buffer, len); } static void -uart_phyp_intr(void *v) +uart_opal_intr(void *v) { - struct uart_phyp_softc *sc = v; + struct uart_opal_softc *sc = v; struct tty *tp = sc->tp; unsigned char c; int len; tty_lock(tp); - while ((len = uart_phyp_get(sc, &c, 1)) > 0) + while ((len = uart_opal_get(sc, &c, 1)) > 0) ttydisc_rint(tp, c, 0); ttydisc_rint_done(tp); tty_unlock(tp); if (sc->irqres == NULL) - callout_reset(&sc->callout, sc->polltime, uart_phyp_intr, sc); + callout_reset(&sc->callout, sc->polltime, uart_opal_intr, sc); } Added: projects/powernv/powerpc/powernv/opalcall.S ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/powernv/powerpc/powernv/opalcall.S Fri Jan 23 23:54:55 2015 (r277623) @@ -0,0 +1,99 @@ +/*- + * Copyright (C) 2015 Nathan Whitehorn + * All rights reserved. + * + * 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 AUTHOR ``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 TOOLS GMBH 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. + * + * $FreeBSD$ + */ + +#include <machine/asm.h> + +GLOBAL(opal_entrypoint) + .llong 0 +GLOBAL(opal_data) + .llong 0 +GLOBAL(opal_msr) + .llong 0 + +TOC_ENTRY(opal_entrypoint) +TOC_ENTRY(opal_data) +TOC_ENTRY(opal_msr) + +ASENTRY(opal_call) + /* Args: + * r3: opal token + * r4-r10 opal arguments + */ + + /* Save call stuff on stack */ + mflr %r0 + std %r0,16(%r1) + std %r2,-16(%r1) + mfcr %r0 + std %r0,8(%r1) + + /* Load OPAL entry information */ + mr %r0,%r3 + ld %r3,TOC_REF(opal_entrypoint)(%r2) + ld %r3,0(%r3) + mtctr %r3 + + /* Save MSR in non-volatile scratch register and turn off translation */ + std %r31,-8(%r1) + mfmsr %r31 + + /* Load last bits from the TOC */ + ld %r3,TOC_REF(opal_msr)(%r2) + ld %r3,0(%r3) + ld %r2,TOC_REF(opal_data)(%r2) + ld %r2,0(%r2) + + mtmsrd %r3 + isync + + /* Shift registers over */ + mr %r3,%r4 + mr %r4,%r5 + mr %r5,%r6 + mr %r6,%r7 + mr %r7,%r8 + mr %r8,%r9 + mr %r9,%r10 + + /* Call OPAL */ + bctrl + + /* Restore MSR */ + mtmsrd %r31 + isync + ld %r31,-8(%r1) + + /* Restore call stuff from stack */ + ld %r0,16(%r1) + mtlr %r0 + ld %r2,-16(%r1) + ld %r0,8(%r1) + mtcr %r0 + + /* And return */ + blr + Added: projects/powernv/powerpc/powernv/platform_powernv.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/powernv/powerpc/powernv/platform_powernv.c Fri Jan 23 23:54:55 2015 (r277623) @@ -0,0 +1,333 @@ +/*- + * Copyright (c) 2015 Nathan Whitehorn + * All rights reserved. + * + * 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 AUTHOR ``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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/bus.h> +#include <sys/pcpu.h> +#include <sys/proc.h> +#include <sys/smp.h> +#include <vm/vm.h> +#include <vm/pmap.h> + +#include <machine/bus.h> +#include <machine/cpu.h> +#include <machine/hid.h> +#include <machine/platformvar.h> +#include <machine/pmap.h> +#include <machine/rtas.h> +#include <machine/smp.h> +#include <machine/spr.h> +#include <machine/trap.h> + +#include <dev/ofw/openfirm.h> +#include <machine/ofw_machdep.h> + +#include "platform_if.h" +#include "opal.h" + +#ifdef SMP +extern void *ap_pcpu; +#endif + +static int powernv_probe(platform_t); +static int powernv_attach(platform_t); +void powernv_mem_regions(platform_t, struct mem_region *phys, int *physsz, + struct mem_region *avail, int *availsz); +static u_long powernv_timebase_freq(platform_t, struct cpuref *cpuref); +static int powernv_smp_first_cpu(platform_t, struct cpuref *cpuref); +static int powernv_smp_next_cpu(platform_t, struct cpuref *cpuref); +static int powernv_smp_get_bsp(platform_t, struct cpuref *cpuref); +static void powernv_smp_ap_init(platform_t); +#ifdef SMP +static int powernv_smp_start_cpu(platform_t, struct pcpu *cpu); +static struct cpu_group *powernv_smp_topo(platform_t plat); +#endif +static void powernv_reset(platform_t); + +static platform_method_t powernv_methods[] = { + PLATFORMMETHOD(platform_probe, powernv_probe), + PLATFORMMETHOD(platform_attach, powernv_attach), + PLATFORMMETHOD(platform_mem_regions, powernv_mem_regions), + PLATFORMMETHOD(platform_timebase_freq, powernv_timebase_freq), + + PLATFORMMETHOD(platform_smp_ap_init, powernv_smp_ap_init), + PLATFORMMETHOD(platform_smp_first_cpu, powernv_smp_first_cpu), + PLATFORMMETHOD(platform_smp_next_cpu, powernv_smp_next_cpu), + PLATFORMMETHOD(platform_smp_get_bsp, powernv_smp_get_bsp), +#ifdef SMP + PLATFORMMETHOD(platform_smp_start_cpu, powernv_smp_start_cpu), + PLATFORMMETHOD(platform_smp_topo, powernv_smp_topo), +#endif + + PLATFORMMETHOD(platform_reset, powernv_reset), + + { 0, 0 } +}; + +static platform_def_t powernv_platform = { + "powernv", + powernv_methods, + 0 +}; + +PLATFORM_DEF(powernv_platform); + +static int +powernv_probe(platform_t plat) +{ + if (opal_check() == 0) + return (BUS_PROBE_SPECIFIC); + + return (ENXIO); +} + +static int +powernv_attach(platform_t plat) +{ + /* Ping OPAL again just to make sure */ + opal_check(); + + return (0); +} + +void +powernv_mem_regions(platform_t plat, struct mem_region *phys, int *physsz, + struct mem_region *avail, int *availsz) +{ + + ofw_mem_regions(phys, physsz, avail, availsz); +} + +static u_long +powernv_timebase_freq(platform_t plat, struct cpuref *cpuref) +{ + phandle_t phandle; + int32_t ticks = -1; + + phandle = cpuref->cr_hwref; + + OF_getprop(phandle, "timebase-frequency", &ticks, sizeof(ticks)); + + if (ticks <= 0) + panic("Unable to determine timebase frequency!"); + + return (ticks); +} + +static int +powernv_smp_first_cpu(platform_t plat, struct cpuref *cpuref) +{ + char buf[8]; + phandle_t cpu, dev, root; + int res, cpuid; + + root = OF_peer(0); + + dev = OF_child(root); + while (dev != 0) { + res = OF_getprop(dev, "name", buf, sizeof(buf)); + if (res > 0 && strcmp(buf, "cpus") == 0) + break; + dev = OF_peer(dev); + } + if (dev == 0) { + /* + * psim doesn't have a name property on the /cpus node, + * but it can be found directly + */ + dev = OF_finddevice("/cpus"); + if (dev == 0) + return (ENOENT); + } + + cpu = OF_child(dev); + + while (cpu != 0) { + res = OF_getprop(cpu, "device_type", buf, sizeof(buf)); + if (res > 0 && strcmp(buf, "cpu") == 0) + break; + cpu = OF_peer(cpu); + } + if (cpu == 0) + return (ENOENT); + + cpuref->cr_hwref = cpu; + res = OF_getprop(cpu, "ibm,ppc-interrupt-server#s", &cpuid, + sizeof(cpuid)); + if (res <= 0) + res = OF_getprop(cpu, "reg", &cpuid, sizeof(cpuid)); + if (res <= 0) + cpuid = 0; + cpuref->cr_cpuid = cpuid; + + return (0); +} + +static int +powernv_smp_next_cpu(platform_t plat, struct cpuref *cpuref) +{ + char buf[8]; + phandle_t cpu; + int i, res, cpuid; + + /* Check for whether it should be the next thread */ + res = OF_getproplen(cpuref->cr_hwref, "ibm,ppc-interrupt-server#s"); + if (res > 0) { + cell_t interrupt_servers[res/sizeof(cell_t)]; + OF_getprop(cpuref->cr_hwref, "ibm,ppc-interrupt-server#s", + interrupt_servers, res); + for (i = 0; i < res/sizeof(cell_t) - 1; i++) { + if (interrupt_servers[i] == cpuref->cr_cpuid) { + cpuref->cr_cpuid = interrupt_servers[i+1]; + return (0); + } + } + } + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501232354.t0NNsuEI086763>