Esempio n. 1
0
int
netif_open(void *machdep_hint)
{
    struct of_dev *op = machdep_hint;
    struct iodesc *io;

#ifdef	NETIF_DEBUG
    printf("netif_open...");
#endif
    /* find a free socket */
    io = sockets;
    if (io->io_netif) {
#ifdef	NETIF_DEBUG
        printf("device busy\n");
#endif
        errno = ENFILE;
        return -1;
    }
    bzero(io, sizeof *io);

    netif_of.nif_devdata = op;
    io->io_netif = &netif_of;

    /* Put our ethernet address in io->myea */
    OF_getprop(OF_instance_to_package(op->handle),
               "local-mac-address", io->myea, sizeof io->myea) == -1 &&
    OF_getprop(OF_instance_to_package(op->handle),
               "mac-address", io->myea, sizeof io->myea);

#ifdef	NETIF_DEBUG
    printf("OK\n");
#endif
    return 0;
}
Esempio n. 2
0
/*
 * This function replaces sys/dev/cninit.c
 * Determine which device is the console using
 * the PROM "input source" and "output sink".
 */
void
consinit()
{
	register int chosen;
	char buffer[128];
	extern int stdinnode, fbnode;
	char *consname = "unknown";
	
	DBPRINT(("consinit()\r\n"));
	if (cn_tab != &consdev_prom) return;
	
	DBPRINT(("setting up stdin\r\n"));
	chosen = OF_finddevice("/chosen");
	OF_getprop(chosen, "stdin",  &stdin, sizeof(stdin));
	DBPRINT(("stdin instance = %x\r\n", stdin));
	
	if ((stdinnode = OF_instance_to_package(stdin)) == 0) {
		printf("WARNING: no PROM stdin\n");
	}
#if NUKBD > 0
	else {
		if (OF_getprop(stdinnode, "compatible", buffer,
		    sizeof(buffer)) != -1 && strncmp("usb", buffer, 3) == 0)
			ukbd_cnattach();
	}
#endif

	DBPRINT(("setting up stdout\r\n"));
	OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
	
	DBPRINT(("stdout instance = %x\r\n", stdout));
	
	if ((fbnode = OF_instance_to_package(stdout)) == 0)
		printf("WARNING: no PROM stdout\n");
	
	DBPRINT(("stdout package = %x\r\n", fbnode));
	
	if (stdinnode && (OF_getproplen(stdinnode,"keyboard") >= 0)) {
		consname = "keyboard/display";
	} else if (fbnode && 
		   (OF_instance_to_path(stdin, buffer, sizeof(buffer)) >= 0)) {
		consname = buffer;
	}
	printf("console is %s\n", consname);
 
	/* Initialize PROM console */
	(*cn_tab->cn_probe)(cn_tab);
	(*cn_tab->cn_init)(cn_tab);
}
Esempio n. 3
0
void
vcons_attach(struct device *parent, struct device *self, void *aux)
{
	struct vcons_softc *sc = (struct vcons_softc *)self;
	struct vbus_attach_args *va = aux;
	uint64_t sysino;
	int vcons_is_input, vcons_is_output;
	int node, maj;

	sc->sc_si = softintr_establish(IPL_TTY, vcons_softintr, sc);
	if (sc->sc_si == NULL)
		panic(": can't establish soft interrupt");

	if (vbus_intr_map(va->va_node, va->va_intr[0], &sysino))
		printf(": can't map interrupt\n");
	printf(": ivec 0x%lx", sysino);

	sc->sc_ih = bus_intr_establish(va->va_bustag, sysino, IPL_TTY, 0,
	    vcons_intr, sc, sc->sc_dv.dv_xname);
	if (sc->sc_ih == NULL) {
		printf(", can't establish interrupt\n");
		return;
	}

	node = OF_instance_to_package(OF_stdin());
	vcons_is_input = (va->va_node == node);
	node = OF_instance_to_package(OF_stdout());
	vcons_is_output = (va->va_node == node);

	if (vcons_is_input || vcons_is_output) {
		if (vcons_is_input) {
			cn_tab->cn_pollc = nullcnpollc;
			cn_tab->cn_getc = vcons_cngetc;

			/* Locate the major number. */
			for (maj = 0; maj < nchrdev; maj++)
				if (cdevsw[maj].d_open == vconsopen)
					break;
			cn_tab->cn_dev = makedev(maj, self->dv_unit);
		}
		if (vcons_is_output) 
			cn_tab->cn_putc = vcons_cnputc;

		printf(", console");
	}

	printf("\n");
}
Esempio n. 4
0
int
netif_of_open(struct of_dev *op)
{
	struct iodesc *io;
	int fd, error;
	char addr[32];

#ifdef	NETIF_DEBUG
	printf("netif_open...");
#endif
	/* find a free socket */
	io = &sdesc;
	if (io->io_netif) {
#ifdef	NETIF_DEBUG
		printf("device busy\n");
#endif
		errno = ENFILE;
		return -1;
	}
	memset(io, 0, sizeof *io);

	io->io_netif = (void *)op;

	/* Put our ethernet address in io->myea */
	OF_getprop(OF_instance_to_package(op->handle),
		   "mac-address", io->myea, sizeof io->myea);

#ifdef	NETIF_DEBUG
	printf("OK\n");
#endif
	return 0;
}
Esempio n. 5
0
static int
chrp_smp_get_bsp(platform_t plat, struct cpuref *cpuref)
{
	ihandle_t inst;
	phandle_t bsp, chosen;
	int res, cpuid;

	chosen = OF_finddevice("/chosen");
	if (chosen == 0)
		return (ENXIO);

	res = OF_getprop(chosen, "cpu", &inst, sizeof(inst));
	if (res < 0)
		return (ENXIO);

	bsp = OF_instance_to_package(inst);

	/* Pick the primary thread. Can it be any other? */
	cpuref->cr_hwref = bsp;
	res = OF_getprop(bsp, "ibm,ppc-interrupt-server#s", &cpuid,
	    sizeof(cpuid));
	if (res <= 0)
		res = OF_getprop(bsp, "reg", &cpuid, sizeof(cpuid));
	if (res <= 0)
		cpuid = 0;
	cpuref->cr_cpuid = cpuid;

	return (0);
}
Esempio n. 6
0
void
ofw_memmap(void)
{
    phandle_t       mmup;
    int             nmapping, i;
    struct          ofw_mapping mappings[256];

    mmup = OF_instance_to_package(mmu);

    bzero(mappings, sizeof(mappings));

    nmapping = OF_getprop(mmup, "translations", mappings, sizeof(mappings));
    if (nmapping == -1) {
        printf("Could not get memory map (%d)\n",
               nmapping);
        return;
    }
    nmapping /= sizeof(struct ofw_mapping);

    printf("%17s %17s %8s %6s\n", "Virtual Range", "Physical Range",
           "#Pages", "Mode");

    for (i = 0; i < nmapping; i++) {
        printf("%08x-%08x %08x-%08x %8d %6x\n", mappings[i].pa,
               mappings[i].pa + mappings[i].len, mappings[i].va,
               mappings[i].va + mappings[i].len, mappings[i].len / 0x1000,
               mappings[i].mode);
    }
}
Esempio n. 7
0
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;
	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;
}
Esempio n. 8
0
static int
ofw_get_console_phandle_path(phandle_t node, phandle_t *result,
    const char *prop)
{
	union {
		char buf[64];
		phandle_t ref;
	} field;
	phandle_t output;
	ssize_t size;

	size = OF_getproplen(node, prop);
	if (size == -1)
		return (ENXIO);
	OF_getprop(node, prop, &field, sizeof(field));

	/* This property might be either a ihandle or path. Hooray. */

	output = -1;
	if (field.buf[size - 1] == 0)
		output = OF_finddevice(field.buf);
	if (output == -1 && size == 4)
		output = OF_instance_to_package(field.ref);
	
	if (output != -1) {
		*result = output;
		return (0);
	}

	return (ENXIO);
}
Esempio n. 9
0
/*
 * Get the package handle of the UART that is selected as the console, if
 * the console is an UART of course. Note that we enforce that both input
 * and output are selected.
 * Note that the currently active console (i.e. /chosen/stdout and
 * /chosen/stdin) may not be the same as the device selected in the
 * environment (ie /options/output-device and /options/input-device) because
 * keyboard and screen were selected but the keyboard was unplugged or the
 * user has changed the environment. In the latter case I would assume that
 * the user expects that FreeBSD uses the new console setting.
 * For weirder configurations, use ofw_console(4).
 */
static phandle_t
uart_cpu_getdev_console(phandle_t options, char *dev, size_t devsz)
{
	char buf[sizeof("serial")];
	ihandle_t inst;
	phandle_t chosen, input, output;

	if (OF_getprop(options, "input-device", dev, devsz) == -1)
		return (-1);
	input = OF_finddevice(dev);
	if (OF_getprop(options, "output-device", dev, devsz) == -1)
		return (-1);
	output = OF_finddevice(dev);
	if (input == -1 || output == -1 ||
	    OF_getproplen(input, "keyboard") >= 0) {
		if ((chosen = OF_finddevice("/chosen")) == -1)
			return (-1);
		if (OF_getprop(chosen, "stdin", &inst, sizeof(inst)) == -1)
			return (-1);
		if ((input = OF_instance_to_package(inst)) == -1)
			return (-1);
		if (OF_getprop(chosen, "stdout", &inst, sizeof(inst)) == -1)
			return (-1);
		if ((output = OF_instance_to_package(inst)) == -1)
			return (-1);
		snprintf(dev, devsz, "ttya");
	}
	if (input != output)
		return (-1);
	if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1)
		return (-1);
	if (strcmp(buf, "serial") != 0)
		return (-1);
	/* For a Serengeti console device point to the bootbus controller. */
	if (OF_getprop(input, "name", buf, sizeof(buf)) > 0 &&
	    !strcmp(buf, "sgcn")) {
		if ((chosen = OF_finddevice("/chosen")) == -1)
			return (-1);
		if (OF_getprop(chosen, "iosram", &input, sizeof(input)) == -1)
			return (-1);
	}
	return (input);
}
Esempio n. 10
0
/* Return the fully qualified pathname corresponding to an instance. */
static ssize_t
ofw_fdt_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len)
{
	phandle_t phandle;

	phandle = OF_instance_to_package(instance);
	if (phandle == -1)
		return (-1);

	return (OF_package_to_path(phandle, buf, len));
}
Esempio n. 11
0
static int
md_bootserial(void)
{
    char	buf[64];
    ihandle_t	inst;
    phandle_t	input;
    phandle_t	node;
    phandle_t	output;

    if ((node = OF_finddevice("/options")) == -1)
        return(-1);
    if (OF_getprop(node, "input-device", buf, sizeof(buf)) == -1)
        return(-1);
    input = OF_finddevice(buf);
    if (OF_getprop(node, "output-device", buf, sizeof(buf)) == -1)
        return(-1);
    output = OF_finddevice(buf);
    if (input == -1 || output == -1 || OF_getproplen(input, "keyboard") >= 0) {
        if ((node = OF_finddevice("/chosen")) == -1)
            return(-1);
        if (OF_getprop(node, "stdin", &inst, sizeof(inst)) == -1)
            return(-1);
        if ((input = OF_instance_to_package(inst)) == -1)
            return(-1);
        if (OF_getprop(node, "stdout", &inst, sizeof(inst)) == -1)
            return(-1);
        if ((output = OF_instance_to_package(inst)) == -1)
            return(-1);
    }
    if (input != output)
        return(-1);
    if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1)
        return(-1);
    if (strcmp(buf, "serial") != 0)
        return(-1);
    return(0);
}
Esempio n. 12
0
void *
ofw_alloc_heap(unsigned int size)
{
	phandle_t	memoryp;
	struct		ofw_reg available;

	memoryp = OF_instance_to_package(memory);
	OF_getprop(memoryp, "available", &available, sizeof(available));

	heap_base = OF_claim((void *)available.base, size, sizeof(register_t));

	if (heap_base != (void *)-1) {
		heap_size = size;
	}

	return (heap_base);
}
Esempio n. 13
0
static int
powermac_smp_get_bsp(platform_t plat, struct cpuref *cpuref)
{
	ihandle_t inst;
	phandle_t bsp, chosen;
	int res;

	chosen = OF_finddevice("/chosen");
	if (chosen == -1)
		return (ENXIO);

	res = OF_getprop(chosen, "cpu", &inst, sizeof(inst));
	if (res < 0)
		return (ENXIO);

	bsp = OF_instance_to_package(inst);
	return (powermac_smp_fill_cpuref(cpuref, bsp));
}
Esempio n. 14
0
static void
ofnet_attach(struct device *parent, struct device *self, void *aux)
{
	struct ofnet_softc *of = device_private(self);
	struct ifnet *ifp = &of->sc_ethercom.ec_if;
	struct ofbus_attach_args *oba = aux;
	char path[256];
	int l;
	u_int8_t myaddr[ETHER_ADDR_LEN];

	of->sc_phandle = oba->oba_phandle;
#if NIPKDB_OFN > 0
	if (kifp &&
	    kifp->unit - 1 == device_unit(&of->sc_dev) &&
	    OF_instance_to_package(kifp->port) == oba->oba_phandle)  {
		ipkdb_of = of;
		of->sc_ihandle = kifp->port;
	} else
#endif
	if ((l = OF_package_to_path(oba->oba_phandle, path,
	    sizeof path - 1)) < 0 ||
	    l >= sizeof path ||
	    (path[l] = 0, !(of->sc_ihandle = OF_open(path))))
		panic("ofnet_attach: unable to open");
	if (OF_getprop(oba->oba_phandle, "mac-address", myaddr,
	    sizeof myaddr) < 0)
		panic("ofnet_attach: no mac-address");
	printf(": address %s\n", ether_sprintf(myaddr));

	callout_init(&of->sc_callout, 0);

	strlcpy(ifp->if_xname, device_xname(&of->sc_dev), IFNAMSIZ);
	ifp->if_softc = of;
	ifp->if_start = ofnet_start;
	ifp->if_ioctl = ofnet_ioctl;
	ifp->if_watchdog = ofnet_watchdog;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	ether_ifattach(ifp, myaddr);
}
Esempio n. 15
0
static phandle_t
vt_efb_get_fbnode()
{
	phandle_t chosen, node;
	ihandle_t stdout;
	char type[64];

	chosen = OF_finddevice("/chosen");
	OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
	node = OF_instance_to_package(stdout);
	if (node != -1) {
		/* The "/chosen/stdout" present. */
		OF_getprop(node, "device_type", type, sizeof(type));
		/* Check if it has "display" type. */
		if (strcmp(type, "display") == 0)
			return (node);
	}
	/* Try device with name "screen". */
	node = OF_finddevice("screen");

	return (node);
}
Esempio n. 16
0
uint64_t
memsize(void)
{
	phandle_t	memoryp;
	cell_t		reg[24];
	int		i, sz;
	u_int64_t	memsz;

	memsz = 0;
	memoryp = OF_instance_to_package(memory);

	sz = OF_getprop(memoryp, "reg", &reg, sizeof(reg));
	sz /= sizeof(reg[0]);

	for (i = 0; i < sz; i += (acells + scells)) {
		if (scells > 1)
			memsz += (uint64_t)reg[i + acells] << 32;
		memsz += reg[i + acells + scells - 1];
	}

	return (memsz);
}
Esempio n. 17
0
static void
uart_phyp_cnprobe(struct consdev *cp)
{
	char buf[64];
	ihandle_t stdout;
	phandle_t input, chosen;
	static struct uart_phyp_softc sc;

	if ((chosen = OF_finddevice("/chosen")) == -1)
		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)
		goto fail;

	if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1)
		goto fail;
	if (strcmp(buf, "serial") != 0)
		goto fail;

	sc.node = input;
	if (uart_phyp_probe_node(&sc) != 0)
		goto fail;
	mtx_init(&sc.sc_mtx, "uart_phyp", NULL, MTX_SPIN | MTX_QUIET |
	    MTX_NOWITNESS);

	cp->cn_pri = CN_NORMAL;
	console_sc = &sc;
	return;
	
fail:
	cp->cn_pri = CN_DEAD;
	return;
}
Esempio n. 18
0
void *
ofw_alloc_heap(unsigned int size)
{
	phandle_t	memoryp, root;
	cell_t		available[4];
	cell_t		acells;

	root = OF_finddevice("/");
	acells = 1;
	OF_getprop(root, "#address-cells", &acells, sizeof(acells));

	memoryp = OF_instance_to_package(memory);
	OF_getprop(memoryp, "available", available, sizeof(available));

	heap_base = OF_claim((void *)available[acells-1], size,
	    sizeof(register_t));

	if (heap_base != (void *)-1) {
		heap_size = size;
	}

	return (heap_base);
}
Esempio n. 19
0
void
com_ebus_attach(struct device *parent, struct device *self, void *aux)
{
	struct com_softc *sc = (void *)self;
	struct ebus_attach_args *ea = aux;
	int i, com_is_input, com_is_output;
	int node, port;
	char buf[32];

	sc->sc_iobase = EBUS_PADDR_FROM_REG(&ea->ea_regs[0]);
	/*
	 * Addresses that should be supplied by the prom:
	 *	- normal com registers
	 *	- ns873xx configuration registers
	 *	- DMA space
	 * The `com' driver does not use DMA accesses, so we can
	 * ignore that for now.  We should enable the com port in
	 * the ns873xx registers here. XXX
	 *
	 * Use the prom address if there.
	 */
	if (ea->ea_nvaddrs) {
		if (bus_space_map(ea->ea_memtag, ea->ea_vaddrs[0], 0,
		    BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh) != 0) {
			printf(": can't map register space\n");
			return;
		}
		sc->sc_iot = ea->ea_memtag;
	} else if (ebus_bus_map(ea->ea_memtag, 0,
	    EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
	    ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
		sc->sc_iot = ea->ea_memtag;
	} else if (ebus_bus_map(ea->ea_iotag, 0,
	    EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
	    ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
		sc->sc_iot = ea->ea_iotag;
	} else {
		printf(": can't map register space\n");
               	return;
	}
	sc->sc_hwflags = 0;
	sc->sc_swflags = 0;
	sc->sc_frequency = BAUD_BASE;

	for (i = 0; i < ea->ea_nintrs; i++)
		bus_intr_establish(sc->sc_iot, ea->ea_intrs[i],
		    IPL_TTY, 0, comintr, sc, self->dv_xname);

	/*
	 * Figure out if we're the console.
	 *
	 * The Fujitsu SPARC Enterprise M4000/M5000/M8000/M9000 has a
	 * serial port on each I/O board and a pseudo console that is
	 * redirected to one of these serial ports.  The board number
	 * of the serial port in question is encoded in the "tty-port#"
	 * property of the pseudo console, so we figure out what our
	 * board number is by walking up the device tree, and check
	 * for a match.
	 */

	node = OF_instance_to_package(OF_stdin());
	com_is_input = (ea->ea_node == node);
	if (OF_getprop(node, "name", buf, sizeof(buf)) > 0 &&
	    strcmp(buf, "pseudo-console") == 0) {
		port = getpropint(node, "tty-port#", -1);
		node = OF_parent(OF_parent(ea->ea_node));
		com_is_input = (getpropint(node, "board#", -2) == port);
	}

	node = OF_instance_to_package(OF_stdout());
	com_is_output = (ea->ea_node == node);
	if (OF_getprop(node, "name", buf, sizeof(buf)) > 0 &&
	    strcmp(buf, "pseudo-console") == 0) {
		port = getpropint(node, "tty-port#", -1);
		node = OF_parent(OF_parent(ea->ea_node));
		com_is_output = (getpropint(node, "board#", -2) == port);
	}

	if (com_is_input || com_is_output) {
		struct consdev *cn_orig;
		int speed;

		speed = com_ebus_speed(ea);

		comconsioh = sc->sc_ioh;
		cn_orig = cn_tab;
		/* Attach com as the console. */
		if (comcnattach(sc->sc_iot, sc->sc_iobase, speed,
		    sc->sc_frequency,
		    ((TTYDEF_CFLAG & ~(CSIZE | PARENB))|CREAD | CS8 | HUPCL))) {
			printf("Error: comcnattach failed\n");
		}
		cn_tab = cn_orig;
		if (com_is_input) {
			cn_tab->cn_dev = /*XXX*/makedev(36, sc->sc_dev.dv_unit);
			cn_tab->cn_probe = comcnprobe;
			cn_tab->cn_init = comcninit;
			cn_tab->cn_getc = comcngetc;
			cn_tab->cn_pollc = comcnpollc;
		}
		if (com_is_output)
			cn_tab->cn_putc = comcnputc;
	}

	/*
	 * Apparently shoving too much data down the TX FIFO on the
	 * Fujitsu SPARC Enterprise M4000/M5000 causes a hardware
	 * fault.  Avoid this issue by setting the FIFO depth to 1.
	 * This will effectively disable the TX FIFO, but will still
	 * enable the RX FIFO, which is what we really care about.
	 */
	if (OF_getprop(ea->ea_node, "compatible", buf, sizeof(buf)) > 0 &&
	    strcmp(buf, "FJSV,su") == 0)
		sc->sc_uarttype = COM_UART_16550;

        if (OF_getproplen(ea->ea_node, "keyboard") == 0)
		printf(": keyboard");
	else if (OF_getproplen(ea->ea_node, "mouse") == 0)
		printf(": mouse");

	/* Now attach the driver */
	com_attach_subr(sc);
}
Esempio n. 20
0
void
sbbc_attach_cons(struct sbbc_softc *sc, uint32_t offset)
{
	struct sbbc_sram_cons *cons;
	int sgcn_is_input, sgcn_is_output, node, maj;
	char buf[32];

	if (sc->sc_sram_solscie == NULL || sc->sc_sram_solscir == NULL ||
	    sc->sc_sram_scsolie == NULL || sc->sc_sram_scsolir == NULL)
		return;

	cons = (struct sbbc_sram_cons *)(sc->sc_sram + offset);
	if (cons->cons_magic != SBBC_CONS_MAGIC ||
	    cons->cons_version < SBBC_CONS_VERSION)
		return;

	sc->sc_sram_cons = sc->sc_sram + offset;
	sbbc_cons_input = sbbc_cons_output = sc;
	sgcn_is_input = sgcn_is_output = 0;

	sc->sc_cons_si = softintr_establish(IPL_TTY, sbbc_softintr_cons, sc);
	if (sc->sc_cons_si == NULL)
		panic("%s: can't establish soft interrupt",
		    sc->sc_dv.dv_xname);

	*sc->sc_sram_solscie |= SBBC_SRAM_CONS_OUT;
	*sc->sc_sram_scsolie |= SBBC_SRAM_CONS_IN | SBBC_SRAM_CONS_BRK;

	/* Take over console input. */
	prom_serengeti_set_console_input("CON_CLNT");

	/* Check for console input. */
	node = OF_instance_to_package(OF_stdin());
	if (OF_getprop(node, "name", buf, sizeof(buf)) > 0)
		sgcn_is_input = (strcmp(buf, "sgcn") == 0);

	/* Check for console output. */
	node = OF_instance_to_package(OF_stdout());
	if (OF_getprop(node, "name", buf, sizeof(buf)) > 0)
		sgcn_is_output = (strcmp(buf, "sgcn") == 0);

	if (sgcn_is_input) {
		cn_tab->cn_pollc = nullcnpollc;
		cn_tab->cn_getc = sbbc_cngetc;
	}

	if (sgcn_is_output)
		cn_tab->cn_putc = sbbc_cnputc;

	if (sgcn_is_input || sgcn_is_output) {
		/* Locate the major number. */
		for (maj = 0; maj < nchrdev; maj++)
			if (cdevsw[maj].d_open == sbbcopen)
				break;
		cn_tab->cn_dev = makedev(maj, sc->sc_dv.dv_unit);

		/* Let current output drain. */
		DELAY(2000000);

		printf("%s: console\n", sc->sc_dv.dv_xname);
	}
}
Esempio n. 21
0
static void
cninit_kd(void)
{
	int kstdin, node;
	char name[16];
#if (NAKBD > 0) || (NADBKBD > 0)
	int akbd;
#endif
#if NUKBD > 0
	struct usb_kbd_ihandles *ukbds;
	int ukbd;
#endif

	/*
	 * Attach the console output now (so we can see debugging messages,
	 * if any).
	 */
#if NWSDISPLAY > 0
	rascons_cnattach();
#endif

	/*
	 * We must determine which keyboard type we have.
	 */
	if (OF_getprop(chosen, "stdin", &kstdin, sizeof(kstdin))
	    != sizeof(kstdin)) {
		printf("WARNING: no `stdin' property in /chosen\n");
		return;
	}

	node = OF_instance_to_package(kstdin);
	memset(name, 0, sizeof(name));
	OF_getprop(node, "name", name, sizeof(name));
	if (strcmp(name, "keyboard") != 0) {
		printf("WARNING: stdin is not a keyboard: %s\n", name);
		return;
	}

	memset(name, 0, sizeof(name));
	OF_getprop(OF_parent(node), "name", name, sizeof(name));
#if NAKBD > 0
	if (strcmp(name, "adb") == 0) {
		printf("console keyboard type: ADB\n");
		akbd_cnattach();
		goto kbd_found;
	}
#endif
#if NADBKBD > 0
	if (strcmp(name, "adb") == 0) {
		printf("console keyboard type: ADB\n");
		adbkbd_cnattach();
		goto kbd_found;
	}
#endif
#if NPCKBC > 0
	if (strcmp(name, "isa") == 0) {
		printf("console keyboard type: PC Keyboard\n");
		pckbc_cnattach(&genppc_isa_io_space_tag, IO_KBD, KBCMDP,
		    PCKBC_KBD_SLOT, 0);
		goto kbd_found;
	}
#endif

	/*
	 * It is not obviously an ADB/PC keyboard. Could be USB,
	 * or ADB on some firmware versions (e.g.: iBook G4)
	 * This is not enough, we have a few more problems:
	 *
	 *	(1) The stupid Macintosh firmware uses a
	 *	    `psuedo-hid' (no typo) or `pseudo-hid',
	 *	    which apparently merges all keyboards
	 *	    input into a single input stream.
	 *	    Because of this, we can't actually
	 *	    determine which controller or keyboard
	 *	    is really the console keyboard!
	 *
	 *	(2) Even if we could, the keyboard can be USB,
	 *	    and this requires a lot of the kernel to
	 *	    be running in order for it to work.
	 *
	 *      (3) If the keyboard is behind isa, we don't have enough
	 * 	    kernel setup to use it yet, so punt to the ofroutines.
	 *
	 * So, what we do is this:
	 *
	 *	(1) First check for OpenFirmware implementation
	 *	    that will not let us distinguish between
	 *	    USB and ADB. In that situation, try attaching
	 *	    anything as we can, and hope things get better
	 *	    at autoconfiguration time.
	 *
	 *	(2) Assume the keyboard is USB.
	 *	    Tell the ukbd driver that it is the console.
	 *	    At autoconfiguration time, it will attach the
	 *	    first USB keyboard instance as the console
	 *	    keyboard.
	 *
	 *	(3) Until then, so that we have _something_, we
	 *	    use the OpenFirmware I/O facilities to read
	 *	    the keyboard.
	 */

	/*
	 * stdin is /pseudo-hid/keyboard.  There is no
	 * `adb-kbd-ihandle or `usb-kbd-ihandles methods
	 * available. Try attaching as ADB.
	 * But only if ADB support is actually present.
	 *
	 * XXX This must be called before pmap_bootstrap().
	 */
	if (strcmp(name, "pseudo-hid") == 0) {
		int adb_node;

		adb_node = OF_finddevice("/pci/mac-io/via-pmu/adb");
		if (adb_node > 0) {
			printf("ADB support found\n");
#if NAKBD > 0
			akbd_cnattach();
#endif
#if NADBKBD > 0
			adbkbd_cnattach();
#endif
		} else {
			/* must be USB */
			printf("No ADB support present, assuming USB "
			       "keyboard\n");
#if NUKBD > 0
			ukbd_cnattach();
#endif
		}
		goto kbd_found;
	}

	/*
	 * stdin is /psuedo-hid/keyboard.  Test `adb-kbd-ihandle and
	 * `usb-kbd-ihandles to figure out the real keyboard(s).
	 *
	 * XXX This must be called before pmap_bootstrap().
	 */

#if NUKBD > 0
	if (OF_call_method("`usb-kbd-ihandles", stdin, 0, 1, &ukbds) >= 0 &&
	    ukbds != NULL && ukbds->ihandle != 0 &&
	    OF_instance_to_package(ukbds->ihandle) != -1) {
		printf("usb-kbd-ihandles matches\n");
		printf("console keyboard type: USB\n");
		ukbd_cnattach();
		goto kbd_found;
	}
	/* Try old method name. */
	if (OF_call_method("`usb-kbd-ihandle", kstdin, 0, 1, &ukbd) >= 0 &&
	    ukbd != 0 &&
	    OF_instance_to_package(ukbd) != -1) {
		printf("usb-kbd-ihandle matches\n");
		printf("console keyboard type: USB\n");
		kstdin = ukbd;
		ukbd_cnattach();
		goto kbd_found;
	}
#endif

#if (NAKBD > 0) || (NADBKBD > 0)
	if (OF_call_method("`adb-kbd-ihandle", kstdin, 0, 1, &akbd) >= 0 &&
	    akbd != 0 &&
	    OF_instance_to_package(akbd) != -1) {
		printf("adb-kbd-ihandle matches\n");
		printf("console keyboard type: ADB\n");
		kstdin = akbd;
#if NAKBD > 0
		akbd_cnattach();
#endif
#if NADBKBD > 0
		adbkbd_cnattach();
#endif
		goto kbd_found;
	}
#endif

#if NUKBD > 0
	/*
	 * XXX Old firmware does not have `usb-kbd-ihandles method.  Assume
	 * XXX USB keyboard anyway.
	 */
	printf("defaulting to USB...");
	printf("console keyboard type: USB\n");
	ukbd_cnattach();
	goto kbd_found;
#endif

	/*
	 * No keyboard is found.  Just return.
	 */
	printf("no console keyboard\n");
	return;

kbd_found:;
#if NAKBD + NUKBD + NADBKBD + NPCKBC > 0
	/*
	 * XXX This is a little gross, but we don't get to call
	 * XXX wskbd_cnattach() twice.
	 */
	ofkbd_ihandle = kstdin;
#if NWSDISPLAY > 0
	wsdisplay_set_cons_kbd(ofkbd_cngetc, NULL, NULL);
#endif
#endif
}
Esempio n. 22
0
/*
 * locore.s code calls bootstrap() just before calling main().
 *
 * What we try to do is as follows:
 * - Initialize PROM and the console
 * - Read in part of information provided by a bootloader and find out
 *   kernel load and end addresses
 * - Initialize ksyms
 * - Find out number of active CPUs
 * - Finalize the bootstrap by calling pmap_bootstrap() 
 *
 * We will try to run out of the prom until we get out of pmap_bootstrap().
 */
void
bootstrap(void *o0, void *bootargs, void *bootsize, void *o3, void *ofw)
{
	void *bi;
	long bmagic;
	char buf[32];

#if NKSYMS || defined(DDB) || defined(MODULAR)
	struct btinfo_symtab *bi_sym;
#endif
	struct btinfo_count *bi_count;
	struct btinfo_kernend *bi_kend;
	struct btinfo_tlb *bi_tlb;
	struct btinfo_boothowto *bi_howto;

	extern void *romtba;
	extern void* get_romtba(void);
	extern void  OF_val2sym32(void *);
	extern void OF_sym2val32(void *);
	extern struct consdev consdev_prom;

	/* Save OpenFrimware entry point */
	romp   = ofw;
	romtba = get_romtba();

	prom_init();
	console_instance = promops.po_stdout;
	console_node = OF_instance_to_package(promops.po_stdout);

	/* Initialize the PROM console so printf will not panic */
	cn_tab = &consdev_prom;
	(*cn_tab->cn_init)(cn_tab);

	DPRINTF(ACDB_BOOTARGS,
		("sparc64_init(%p, %p, %p, %p, %p)\n", o0, bootargs, bootsize,
			o3, ofw));

	/* Extract bootinfo pointer */
	if ((long)bootsize >= (4 * sizeof(uint64_t))) {
		/* Loaded by 64-bit bootloader */
		bi = (void*)(u_long)(((uint64_t*)bootargs)[3]);
		bmagic = (long)(((uint64_t*)bootargs)[0]);
	} else if ((long)bootsize >= (4 * sizeof(uint32_t))) {
		/* Loaded by 32-bit bootloader */
		bi = (void*)(u_long)(((uint32_t*)bootargs)[3]);
		bmagic = (long)(((uint32_t*)bootargs)[0]);
	} else {
		printf("Bad bootinfo size.\n");
die_old_boot_loader:
		printf("This kernel requires NetBSD boot loader version 1.9 "
		       "or newer\n");
		panic("sparc64_init.");
	}

	DPRINTF(ACDB_BOOTARGS,
		("sparc64_init: bmagic=%lx, bi=%p\n", bmagic, bi));

	/* Read in the information provided by NetBSD boot loader */
	if (SPARC_MACHINE_OPENFIRMWARE != bmagic) {
		printf("No bootinfo information.\n");
		goto die_old_boot_loader;
	}

	bootinfo = (void*)(u_long)((uint64_t*)bi)[1];
	LOOKUP_BOOTINFO(bi_kend, BTINFO_KERNEND);

	if (bi_kend->addr == (vaddr_t)0) {
		panic("Kernel end address is not found in bootinfo.\n");
	}

#if NKSYMS || defined(DDB) || defined(MODULAR)
	LOOKUP_BOOTINFO(bi_sym, BTINFO_SYMTAB);
	ksyms_addsyms_elf(bi_sym->nsym, (int *)(u_long)bi_sym->ssym,
			(int *)(u_long)bi_sym->esym);
#ifdef DDB
#ifdef __arch64__
	/* This can only be installed on an 64-bit system cause otherwise our stack is screwed */
	OF_set_symbol_lookup(OF_sym2val, OF_val2sym);
#else
	OF_set_symbol_lookup(OF_sym2val32, OF_val2sym32);
#endif
#endif
#endif
	if (OF_getprop(findroot(), "compatible", buf, sizeof(buf)) > 0) {
		if (strcmp(buf, "sun4us") == 0)
			setcputyp(CPU_SUN4US);
		else if (strcmp(buf, "sun4v") == 0)
			setcputyp(CPU_SUN4V);
	}

	bi_howto = lookup_bootinfo(BTINFO_BOOTHOWTO);
	if (bi_howto)
		boothowto = bi_howto->boothowto;

	LOOKUP_BOOTINFO(bi_count, BTINFO_DTLB_SLOTS);
	kernel_dtlb_slots = bi_count->count;
	kernel_itlb_slots = kernel_dtlb_slots-1;
	bi_count = lookup_bootinfo(BTINFO_ITLB_SLOTS);
	if (bi_count)
		kernel_itlb_slots = bi_count->count;
	LOOKUP_BOOTINFO(bi_tlb, BTINFO_DTLB);
	kernel_tlbs = &bi_tlb->tlb[0];

	get_ncpus();
	pmap_bootstrap(KERNBASE, bi_kend->addr);
}
Esempio n. 23
0
static int
qman_portals_fdt_attach(device_t dev)
{
	struct dpaa_portals_softc *sc;
	struct resource_list_entry *rle;
	phandle_t node, child, cpu_node;
	vm_paddr_t portal_pa;
	vm_size_t portal_size;
	uint32_t addr, size;
	ihandle_t cpu;
	int cpu_num, cpus, intr_rid;
	struct dpaa_portals_devinfo di;
	struct ofw_bus_devinfo ofw_di = {};

	cpus = 0;
	sc = device_get_softc(dev);
	sc->sc_dev = dev;

	node = ofw_bus_get_node(dev);
	get_addr_props(node, &addr, &size);

	/* Find portals tied to CPUs */
	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
		if (!fdt_is_compatible(child, "fsl,qman-portal")) {
			continue;
		}
		/* Checkout related cpu */
		if (OF_getprop(child, "cpu-handle", (void *)&cpu,
		    sizeof(cpu)) <= 0) {
			continue;
		}
		/* Acquire cpu number */
		cpu_node = OF_instance_to_package(cpu);
		if (OF_getencprop(cpu_node, "reg", &cpu_num, sizeof(cpu_num)) <= 0) {
			device_printf(dev, "Could not retrieve CPU number.\n");
			return (ENXIO);
		}

		cpus++;

		if (cpus > MAXCPU)
			break;

		if (ofw_bus_gen_setup_devinfo(&ofw_di, child) != 0) {
			device_printf(dev, "could not set up devinfo\n");
			continue;
		}

		resource_list_init(&di.di_res);
		if (ofw_bus_reg_to_rl(dev, child, addr, size, &di.di_res)) {
			device_printf(dev, "%s: could not process 'reg' "
			    "property\n", ofw_di.obd_name);
			ofw_bus_gen_destroy_devinfo(&ofw_di);
			continue;
		}
		if (ofw_bus_intr_to_rl(dev, child, &di.di_res, &intr_rid)) {
			device_printf(dev, "%s: could not process "
			    "'interrupts' property\n", ofw_di.obd_name);
			resource_list_free(&di.di_res);
			ofw_bus_gen_destroy_devinfo(&ofw_di);
			continue;
		}
		di.di_intr_rid = intr_rid;
		
		ofw_reg_to_paddr(child, 0, &portal_pa, &portal_size, NULL);
		rle = resource_list_find(&di.di_res, SYS_RES_MEMORY, 0);

		if (sc->sc_dp_pa == 0)
			sc->sc_dp_pa = portal_pa - rle->start;

		portal_size = rle->end + 1;
		rle = resource_list_find(&di.di_res, SYS_RES_MEMORY, 1);
		portal_size = ulmax(rle->end + 1, portal_size);
		sc->sc_dp_size = ulmax(sc->sc_dp_size, portal_size);

		if (dpaa_portal_alloc_res(dev, &di, cpu_num))
			goto err;
	}

	ofw_bus_gen_destroy_devinfo(&ofw_di);

	return (qman_portals_attach(dev));
err:
	resource_list_free(&di.di_res);
	ofw_bus_gen_destroy_devinfo(&ofw_di);
	qman_portals_detach(dev);
	return (ENXIO);
}
Esempio n. 24
0
static int
qman_portals_fdt_attach(device_t dev)
{
	struct dpaa_portals_softc *sc;
	phandle_t node, child, cpu_node;
	vm_paddr_t portal_pa, portal_par_pa;
	vm_size_t portal_size;
	uint32_t addr, paddr, size;
	ihandle_t cpu;
	int cpu_num, cpus, intr_rid;
	struct dpaa_portals_devinfo di;
	struct ofw_bus_devinfo ofw_di = {};
	cell_t *range;
	int nrange;
	int i;

	cpus = 0;
	sc = device_get_softc(dev);
	sc->sc_dev = dev;

	node = ofw_bus_get_node(dev);

	/* Get this node's range */
	get_addr_props(ofw_bus_get_node(device_get_parent(dev)), &paddr, &size);
	get_addr_props(node, &addr, &size);

	nrange = OF_getencprop_alloc(node, "ranges",
	    sizeof(*range), (void **)&range);
	if (nrange < addr + paddr + size)
		return (ENXIO);
	portal_pa = portal_par_pa = 0;
	portal_size = 0;
	for (i = 0; i < addr; i++) {
		portal_pa <<= 32;
		portal_pa |= range[i];
	}
	for (; i < paddr + addr; i++) {
		portal_par_pa <<= 32;
		portal_par_pa |= range[i];
	}
	portal_pa += portal_par_pa;
	for (; i < size + paddr + addr; i++) {
		portal_size = (uintmax_t)portal_size << 32;
		portal_size |= range[i];
	}
	OF_prop_free(range);
	sc->sc_dp_size = portal_size;
	sc->sc_dp_pa = portal_pa;

	/* Find portals tied to CPUs */
	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
		if (cpus >= mp_ncpus)
			break;
		if (!ofw_bus_node_is_compatible(child, "fsl,qman-portal")) {
			continue;
		}
		/* Checkout related cpu */
		if (OF_getprop(child, "cpu-handle", (void *)&cpu,
		    sizeof(cpu)) <= 0) {
			cpu = qman_portal_find_cpu(cpus);
			if (cpu <= 0)
				continue;
		}
		/* Acquire cpu number */
		cpu_node = OF_instance_to_package(cpu);
		if (OF_getencprop(cpu_node, "reg", &cpu_num, sizeof(cpu_num)) <= 0) {
			device_printf(dev, "Could not retrieve CPU number.\n");
			return (ENXIO);
		}

		cpus++;

		if (ofw_bus_gen_setup_devinfo(&ofw_di, child) != 0) {
			device_printf(dev, "could not set up devinfo\n");
			continue;
		}

		resource_list_init(&di.di_res);
		if (ofw_bus_reg_to_rl(dev, child, addr, size, &di.di_res)) {
			device_printf(dev, "%s: could not process 'reg' "
			    "property\n", ofw_di.obd_name);
			ofw_bus_gen_destroy_devinfo(&ofw_di);
			continue;
		}
		if (ofw_bus_intr_to_rl(dev, child, &di.di_res, &intr_rid)) {
			device_printf(dev, "%s: could not process "
			    "'interrupts' property\n", ofw_di.obd_name);
			resource_list_free(&di.di_res);
			ofw_bus_gen_destroy_devinfo(&ofw_di);
			continue;
		}
		di.di_intr_rid = intr_rid;

		if (dpaa_portal_alloc_res(dev, &di, cpu_num))
			goto err;
	}

	ofw_bus_gen_destroy_devinfo(&ofw_di);

	return (qman_portals_attach(dev));
err:
	resource_list_free(&di.di_res);
	ofw_bus_gen_destroy_devinfo(&ofw_di);
	qman_portals_detach(dev);
	return (ENXIO);
}
Esempio n. 25
0
static int
vt_efb_init(struct vt_device *vd)
{
	struct ofw_pci_register pciaddrs[8];
	struct fb_info *info;
	int i, len, n_pciaddrs;
	phandle_t chosen, node;
	ihandle_t stdout;
	char type[64];

	info = vd->vd_softc;

	chosen = OF_finddevice("/chosen");
	OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
	node = OF_instance_to_package(stdout);
	if (node == -1) {
		/*
		 * The "/chosen/stdout" does not exist try
		 * using "screen" directly.
		 */
		node = OF_finddevice("screen");
	}
	OF_getprop(node, "device_type", type, sizeof(type));
	if (strcmp(type, "display") != 0)
		return (CN_DEAD);

#define	GET(name, var)							\
	if (OF_getproplen(node, (name)) != sizeof(info->fb_##var))	\
		return (CN_DEAD);					\
	OF_getencprop(node, (name), &info->fb_##var, sizeof(info->fb_##var)); \
	if (info->fb_##var == 0)					\
		return (CN_DEAD);

	GET("height", height)
	GET("width", width)
	GET("depth", depth)
	GET("linebytes", stride)
#undef GET

	info->fb_size = info->fb_height * info->fb_stride;

	/*
	 * Get the PCI addresses of the adapter, if present. The node may be the
	 * child of the PCI device: in that case, try the parent for
	 * the assigned-addresses property.
	 */
	len = OF_getprop(node, "assigned-addresses", pciaddrs,
	    sizeof(pciaddrs));
	if (len == -1) {
		len = OF_getprop(OF_parent(node), "assigned-addresses",
		    pciaddrs, sizeof(pciaddrs));
        }
        if (len == -1)
                len = 0;
	n_pciaddrs = len / sizeof(struct ofw_pci_register);

	/*
	 * Grab the physical address of the framebuffer, and then map it
	 * into our memory space. If the MMU is not yet up, it will be
	 * remapped for us when relocation turns on.
	 */
	if (OF_getproplen(node, "address") == sizeof(info->fb_pbase)) {
	 	/* XXX We assume #address-cells is 1 at this point. */
		OF_getencprop(node, "address", &info->fb_pbase,
		    sizeof(info->fb_pbase));

	#if defined(__powerpc__)
		sc->sc_memt = &bs_be_tag;
		bus_space_map(sc->sc_memt, info->fb_pbase, info->fb_size,
		    BUS_SPACE_MAP_PREFETCHABLE, &info->fb_vbase);
	#elif defined(__sparc64__)
		OF_decode_addr(node, 0, &space, &phys);
		sc->sc_memt = &vt_efb_memt[0];
		info->addr = sparc64_fake_bustag(space, fb_phys, sc->sc_memt);
	#else
		bus_space_map(fdtbus_bs_tag, info->fb_pbase, info->fb_size,
		    BUS_SPACE_MAP_PREFETCHABLE,
		    (bus_space_handle_t *)&info->fb_vbase);
	#endif
	} else {
		/*
		 * Some IBM systems don't have an address property. Try to
		 * guess the framebuffer region from the assigned addresses.
		 * This is ugly, but there doesn't seem to be an alternative.
		 * Linux does the same thing.
		 */

		info->fb_pbase = n_pciaddrs;
		for (i = 0; i < n_pciaddrs; i++) {
			/* If it is too small, not the framebuffer */
			if (pciaddrs[i].size_lo < info->fb_size)
				continue;
			/* If it is not memory, it isn't either */
			if (!(pciaddrs[i].phys_hi &
			    OFW_PCI_PHYS_HI_SPACE_MEM32))
				continue;

			/* This could be the framebuffer */
			info->fb_pbase = i;

			/* If it is prefetchable, it certainly is */
			if (pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE)
				break;
		}

		if (info->fb_pbase == n_pciaddrs) /* No candidates found */
			return (CN_DEAD);

	#if defined(__powerpc__)
		OF_decode_addr(node, info->fb_pbase, &sc->sc_memt,
		    &info->fb_vbase);
	#elif defined(__sparc64__)
		OF_decode_addr(node, info->fb_pbase, &space, &info->fb_pbase);
		sc->sc_memt = &vt_efb_memt[0];
		info->fb_vbase = sparc64_fake_bustag(space, info->fb_pbase,
		    sc->sc_memt);
	#else
		bus_space_map(fdtbus_bs_tag, info->fb_pbase, info->fb_size,
		    BUS_SPACE_MAP_PREFETCHABLE,
		    (bus_space_handle_t *)&info->fb_vbase);
	#endif
        }


	/* blank full size */
	len = info->fb_size / 4;
	for (i = 0; i < len; i++) {
		((uint32_t *)info->fb_vbase)[i] = 0;
	}

	/* Get pixel storage size. */
	info->fb_bpp = info->fb_stride / info->fb_width * 8;

	/*
	 * Early FB driver work with static window buffer 80x25, so reduce
	 * size to 640x480.
	 */
	info->fb_width = VT_FB_DEFAULT_WIDTH;
	info->fb_height = VT_FB_DEFAULT_HEIGHT;

#ifdef	FDT
	vt_efb_initialize(info, node);
#else
	vt_efb_initialize(info);
#endif
	fb_probe(info);
	vt_fb_init(vd);


	return (CN_INTERNAL);
}
Esempio n. 26
0
static int
ofwfb_configure(int flags)
{
	struct ofwfb_softc *sc;
        phandle_t chosen;
        ihandle_t stdout;
	phandle_t node;
	uint32_t fb_phys;
	int depth;
	int disable;
	int len;
	int i;
	char type[16];
	static int done = 0;

	disable = 0;
	TUNABLE_INT_FETCH("hw.syscons.disable", &disable);
	if (disable != 0)
		return (0);

	if (done != 0)
		return (0);
	done = 1;

	sc = &ofwfb_softc;

	chosen = OF_finddevice("/chosen");
	OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
        node = OF_instance_to_package(stdout);
	if (node == -1) {
		/*
		 * The "/chosen/stdout" does not exist try
		 * using "screen" directly.
		 */
		node = OF_finddevice("screen");
	}
	OF_getprop(node, "device_type", type, sizeof(type));
	if (strcmp(type, "display") != 0)
		return (0);

	/* Only support 8 and 32-bit framebuffers */
	OF_getprop(node, "depth", &depth, sizeof(depth));
	if (depth == 8) {
		sc->sc_blank = ofwfb_blank_display8;
		sc->sc_putc = ofwfb_putc8;
		sc->sc_putm = ofwfb_putm8;
		sc->sc_set_border = ofwfb_set_border8;
	} else if (depth == 32) {
		sc->sc_blank = ofwfb_blank_display32;
		sc->sc_putc = ofwfb_putc32;
		sc->sc_putm = ofwfb_putm32;
		sc->sc_set_border = ofwfb_set_border32;
	} else
		return (0);

	if (OF_getproplen(node, "height") != sizeof(sc->sc_height) ||
	    OF_getproplen(node, "width") != sizeof(sc->sc_width) ||
	    OF_getproplen(node, "linebytes") != sizeof(sc->sc_stride))
		return (0);

	sc->sc_depth = depth;
	sc->sc_node = node;
	sc->sc_console = 1;
	OF_getprop(node, "height", &sc->sc_height, sizeof(sc->sc_height));
	OF_getprop(node, "width", &sc->sc_width, sizeof(sc->sc_width));
	OF_getprop(node, "linebytes", &sc->sc_stride, sizeof(sc->sc_stride));

	/*
	 * Get the PCI addresses of the adapter. The node may be the
	 * child of the PCI device: in that case, try the parent for
	 * the assigned-addresses property.
	 */
	len = OF_getprop(node, "assigned-addresses", sc->sc_pciaddrs,
	          sizeof(sc->sc_pciaddrs));
	if (len == -1) {
		len = OF_getprop(OF_parent(node), "assigned-addresses",
		    sc->sc_pciaddrs, sizeof(sc->sc_pciaddrs));
	}
	if (len == -1)
		len = 0;
	sc->sc_num_pciaddrs = len / sizeof(struct ofw_pci_register);

	/*
	 * Grab the physical address of the framebuffer, and then map it
	 * into our memory space. If the MMU is not yet up, it will be
	 * remapped for us when relocation turns on.
	 *
	 * XXX We assume #address-cells is 1 at this point.
	 */
	if (OF_getproplen(node, "address") == sizeof(fb_phys)) {
		OF_getprop(node, "address", &fb_phys, sizeof(fb_phys));
		sc->sc_tag = &bs_be_tag;
		bus_space_map(sc->sc_tag, fb_phys, sc->sc_height *
		    sc->sc_stride, BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_addr);
	} else {
		/*
		 * Some IBM systems don't have an address property. Try to
		 * guess the framebuffer region from the assigned addresses.
		 * This is ugly, but there doesn't seem to be an alternative.
		 * Linux does the same thing.
		 */

		fb_phys = sc->sc_num_pciaddrs;
		for (i = 0; i < sc->sc_num_pciaddrs; i++) {
			/* If it is too small, not the framebuffer */
			if (sc->sc_pciaddrs[i].size_lo <
			    sc->sc_stride*sc->sc_height)
				continue;
			/* If it is not memory, it isn't either */
			if (!(sc->sc_pciaddrs[i].phys_hi &
			    OFW_PCI_PHYS_HI_SPACE_MEM32))
				continue;

			/* This could be the framebuffer */
			fb_phys = i;

			/* If it is prefetchable, it certainly is */
			if (sc->sc_pciaddrs[i].phys_hi &
			    OFW_PCI_PHYS_HI_PREFETCHABLE)
				break;
		}
		if (fb_phys == sc->sc_num_pciaddrs)
			return (0);

		OF_decode_addr(node, fb_phys, &sc->sc_tag, &sc->sc_addr);
	}

	ofwfb_init(0, &sc->sc_va, 0);

	return (0);
}
Esempio n. 27
0
void
ofw_memmap(int acells)
{
	struct		ofw_mapping *mapptr;
	struct		ofw_mapping2 *mapptr2;
        phandle_t	mmup;
        int		nmapping, i;
        u_char		mappings[256 * sizeof(struct ofw_mapping2)];
        char		lbuf[80];

	mmup = OF_instance_to_package(mmu);

	bzero(mappings, sizeof(mappings));

	nmapping = OF_getprop(mmup, "translations", mappings, sizeof(mappings));
	if (nmapping == -1) {
		printf("Could not get memory map (%d)\n",
		    nmapping);
		return;
	}

	pager_open();
	if (acells == 1) {
		nmapping /= sizeof(struct ofw_mapping);
		mapptr = (struct ofw_mapping *) mappings;

		printf("%17s\t%17s\t%8s\t%6s\n", "Virtual Range",
		    "Physical Range", "#Pages", "Mode");

		for (i = 0; i < nmapping; i++) {
			sprintf(lbuf, "%08x-%08x\t%08x-%08x\t%8d\t%6x\n",
				mapptr[i].va,
				mapptr[i].va + mapptr[i].len,
				mapptr[i].pa,
				mapptr[i].pa + mapptr[i].len,
				mapptr[i].len / 0x1000,
				mapptr[i].mode);
			if (pager_output(lbuf))
				break;
		}
	} else {
		nmapping /= sizeof(struct ofw_mapping2);
		mapptr2 = (struct ofw_mapping2 *) mappings;

		printf("%17s\t%17s\t%8s\t%6s\n", "Virtual Range",
		       "Physical Range", "#Pages", "Mode");

		for (i = 0; i < nmapping; i++) {
			sprintf(lbuf, "%08x-%08x\t%08x-%08x\t%8d\t%6x\n",
				mapptr2[i].va,
				mapptr2[i].va + mapptr2[i].len,
				mapptr2[i].pa_lo,
				mapptr2[i].pa_lo + mapptr2[i].len,
				mapptr2[i].len / 0x1000,
				mapptr2[i].mode);
			if (pager_output(lbuf))
				break;
		}
	}
	pager_close();
}
Esempio n. 28
0
static int
ofwfb_configure(int flags)
{
    struct ofwfb_softc *sc;
    phandle_t chosen;
    ihandle_t stdout;
    phandle_t node;
    uint32_t fb_phys;
    int depth;
    int disable;
    int len;
    char type[16];
    static int done = 0;

    disable = 0;
    TUNABLE_INT_FETCH("hw.syscons.disable", &disable);
    if (disable != 0)
        return (0);

    if (done != 0)
        return (0);
    done = 1;

    sc = &ofwfb_softc;

    chosen = OF_finddevice("/chosen");
    OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
    node = OF_instance_to_package(stdout);
    if (node == -1) {
        /*
         * The "/chosen/stdout" does not exist try
         * using "screen" directly.
         */
        node = OF_finddevice("screen");
    }
    OF_getprop(node, "device_type", type, sizeof(type));
    if (strcmp(type, "display") != 0)
        return (0);

    /* Only support 8 and 32-bit framebuffers */
    OF_getprop(node, "depth", &depth, sizeof(depth));
    if (depth == 8) {
        sc->sc_blank = ofwfb_blank_display8;
        sc->sc_putc = ofwfb_putc8;
        sc->sc_putm = ofwfb_putm8;
        sc->sc_set_border = ofwfb_set_border8;
    } else if (depth == 32) {
        sc->sc_blank = ofwfb_blank_display32;
        sc->sc_putc = ofwfb_putc32;
        sc->sc_putm = ofwfb_putm32;
        sc->sc_set_border = ofwfb_set_border32;
    } else
        return (0);

    sc->sc_depth = depth;
    sc->sc_node = node;
    sc->sc_console = 1;
    OF_getprop(node, "height", &sc->sc_height, sizeof(sc->sc_height));
    OF_getprop(node, "width", &sc->sc_width, sizeof(sc->sc_width));
    OF_getprop(node, "linebytes", &sc->sc_stride, sizeof(sc->sc_stride));

    /*
     * Grab the physical address of the framebuffer, and then map it
     * into our memory space. If the MMU is not yet up, it will be
     * remapped for us when relocation turns on.
     *
     * XXX We assume #address-cells is 1 at this point.
     */
    OF_getprop(node, "address", &fb_phys, sizeof(fb_phys));

    bus_space_map(&bs_be_tag, fb_phys, sc->sc_height * sc->sc_stride,
                  BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_addr);

    /*
     * Get the PCI addresses of the adapter. The node may be the
     * child of the PCI device: in that case, try the parent for
     * the assigned-addresses property.
     */
    len = OF_getprop(node, "assigned-addresses", sc->sc_pciaddrs,
                     sizeof(sc->sc_pciaddrs));
    if (len == -1) {
        len = OF_getprop(OF_parent(node), "assigned-addresses",
                         sc->sc_pciaddrs, sizeof(sc->sc_pciaddrs));
    }

    if (len != -1) {
        sc->sc_num_pciaddrs = len / sizeof(struct ofw_pci_register);
    }

    ofwfb_init(0, &sc->sc_va, 0);

    return (0);
}
Esempio n. 29
0
/* the backdoor to the keyboard controller! XXX */
int
atkbdc_configure(void)
{
	bus_space_tag_t tag;
	bus_space_handle_t h0;
	bus_space_handle_t h1;
#if defined(__i386__) || defined(__amd64__)
	volatile int i;
	register_t flags;
#endif
#ifdef __sparc64__
	char name[32];
	phandle_t chosen, node;
	ihandle_t stdin;
	bus_addr_t port0;
	bus_addr_t port1;
	int space;
#else
	int port0;
	int port1;
#endif

	/* XXX: tag should be passed from the caller */
#if defined(__amd64__) || defined(__i386__)
	tag = X86_BUS_SPACE_IO;
#elif defined(__sparc64__)
	tag = &atkbdc_bst_store[0];
#else
#error "define tag!"
#endif

#ifdef __sparc64__
	if ((chosen = OF_finddevice("/chosen")) == -1)
		return 0;
	if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1)
		return 0;
	if ((node = OF_instance_to_package(stdin)) == -1)
		return 0;
	if (OF_getprop(node, "name", name, sizeof(name)) == -1)
		return 0;
	name[sizeof(name) - 1] = '\0';
	if (strcmp(name, "kb_ps2") != 0)
		return 0;
	/*
	 * The stdin handle points to an instance of a PS/2 keyboard
	 * package but we want the 8042 controller, which is the parent
	 * of that keyboard node.
	 */
	if ((node = OF_parent(node)) == 0)
		return 0;
	if (OF_decode_addr(node, 0, &space, &port0) != 0)
		return 0;
	h0 = sparc64_fake_bustag(space, port0, tag);
	bus_space_subregion(tag, h0, KBD_DATA_PORT, 1, &h0);
	if (OF_decode_addr(node, 1, &space, &port1) != 0)
		return 0;
	h1 = sparc64_fake_bustag(space, port1, tag);
	bus_space_subregion(tag, h1, KBD_STATUS_PORT, 1, &h1);
#else
	port0 = IO_KBD;
	resource_int_value("atkbdc", 0, "port", &port0);
	port1 = IO_KBD + KBD_STATUS_PORT;
#ifdef notyet
	bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0);
	bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1);
#else
	h0 = (bus_space_handle_t)port0;
	h1 = (bus_space_handle_t)port1;
#endif
#endif

#if defined(__i386__) || defined(__amd64__)
	/*
	 * Check if we really have AT keyboard controller. Poll status
	 * register until we get "all clear" indication. If no such
	 * indication comes, it probably means that there is no AT
	 * keyboard controller present. Give up in such case. Check relies
	 * on the fact that reading from non-existing in/out port returns
	 * 0xff on i386. May or may not be true on other platforms.
	 */
	flags = intr_disable();
	for (i = 0; i != 65535; i++) {
		if ((bus_space_read_1(tag, h1, 0) & 0x2) == 0)
			break;
	}
	intr_restore(flags);
	if (i == 65535)
                return ENXIO;
#endif

	return atkbdc_setup(atkbdc_softc[0], tag, h0, h1);
}
Esempio n. 30
0
int
igsfb_ofbus_cnattach(bus_space_tag_t iot, bus_space_tag_t memt)
{
	struct igsfb_devconfig *dc;
	int ret;
	int chosen_phandle, igs_node;
	int stdout_ihandle, stdout_phandle;
	uint32_t regs[16];
	char mode_buffer[64];

	stdout_phandle = 0;

	/* first find out if there's a CyberPro at all in this machine */
	igs_node = OF_finddevice("/vlbus/display");
	if (igs_node == -1)
		return ENXIO;
	if (of_compatible(igs_node, compat_strings) < 0) 
		return ENXIO;

	/*
	 * now we know there's a CyberPro in this machine so map it into
	 * kernel space, even if it's not the console
	 */
	if (OF_getprop(igs_node, "reg", regs, sizeof(regs)) <= 0)
		return ENXIO;

	igsfb_mem_paddr = be32toh(regs[13]);
	/* 4MB VRAM aperture, bufferable and cacheable */
	igsfb_mem_vaddr = ofw_map(igsfb_mem_paddr, 0x00400000, L2_B);
	/* MMIO registers */
	igsfb_mmio_vaddr = ofw_map(igsfb_mem_paddr + IGS_MEM_MMIO_SELECT,
	    0x00100000, 0);

	memcpy(&igsfb_memt, memt, sizeof(struct bus_space));
	igsfb_memt.bs_cookie = (void *)igsfb_mem_vaddr;
	memcpy(&igsfb_iot, memt, sizeof(struct bus_space));
	igsfb_iot.bs_cookie = (void *)igsfb_mmio_vaddr;

	/*
	 * check if the firmware output device is indeed the CyberPro
	 */
	if ((chosen_phandle = OF_finddevice("/chosen")) == -1 ||
	    OF_getprop(chosen_phandle, "stdout", &stdout_ihandle, 
	    sizeof(stdout_ihandle)) != sizeof(stdout_ihandle)) {
		return ENXIO;
	}
	stdout_ihandle = of_decode_int((void *)&stdout_ihandle);
	stdout_phandle = OF_instance_to_package(stdout_ihandle);

	if (stdout_phandle != igs_node)
		return ENXIO;

	/* ok, now setup and attach the console */
	dc = &igsfb_console_dc;
	ret = igsfb_setup_dc(dc);
	if (ret)
		return ret;

	if (of_get_mode_string(mode_buffer, sizeof(mode_buffer))) {
		strcpy(dc->dc_modestring, mode_buffer);
	}	

	ret = igsfb_cnattach_subr(dc);
	if (ret)
		return ret;

	igsfb_ofbus_console = 1;
	igsfb_ofbus_phandle = stdout_phandle;
#if (NIGSFB_OFBUS > 0) || (NVGA_OFBUS > 0)
	console_ihandle = stdout_ihandle;
#endif
	return 0;
}