xref: /dflybsd-src/sys/dev/misc/dcons/dcons_crom.c (revision 030b0c8c4cf27c560ccec70410c8e21934ae677d)
16265f26aSHidetoshi Shimokawa /*
26265f26aSHidetoshi Shimokawa  * Copyright (C) 2003
36265f26aSHidetoshi Shimokawa  * 	Hidetoshi Shimokawa. All rights reserved.
46265f26aSHidetoshi Shimokawa  *
56265f26aSHidetoshi Shimokawa  * Redistribution and use in source and binary forms, with or without
66265f26aSHidetoshi Shimokawa  * modification, are permitted provided that the following conditions
76265f26aSHidetoshi Shimokawa  * are met:
86265f26aSHidetoshi Shimokawa  * 1. Redistributions of source code must retain the above copyright
96265f26aSHidetoshi Shimokawa  *    notice, this list of conditions and the following disclaimer.
106265f26aSHidetoshi Shimokawa  * 2. Redistributions in binary form must reproduce the above copyright
116265f26aSHidetoshi Shimokawa  *    notice, this list of conditions and the following disclaimer in the
126265f26aSHidetoshi Shimokawa  *    documentation and/or other materials provided with the distribution.
136265f26aSHidetoshi Shimokawa  * 3. All advertising materials mentioning features or use of this software
146265f26aSHidetoshi Shimokawa  *    must display the following acknowledgement:
156265f26aSHidetoshi Shimokawa  *
166265f26aSHidetoshi Shimokawa  *	This product includes software developed by Hidetoshi Shimokawa.
176265f26aSHidetoshi Shimokawa  *
186265f26aSHidetoshi Shimokawa  * 4. Neither the name of the author nor the names of its contributors
196265f26aSHidetoshi Shimokawa  *    may be used to endorse or promote products derived from this software
206265f26aSHidetoshi Shimokawa  *    without specific prior written permission.
216265f26aSHidetoshi Shimokawa  *
226265f26aSHidetoshi Shimokawa  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
236265f26aSHidetoshi Shimokawa  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
246265f26aSHidetoshi Shimokawa  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
256265f26aSHidetoshi Shimokawa  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
266265f26aSHidetoshi Shimokawa  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
276265f26aSHidetoshi Shimokawa  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
286265f26aSHidetoshi Shimokawa  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
296265f26aSHidetoshi Shimokawa  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
306265f26aSHidetoshi Shimokawa  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
316265f26aSHidetoshi Shimokawa  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
326265f26aSHidetoshi Shimokawa  * SUCH DAMAGE.
336265f26aSHidetoshi Shimokawa  *
346265f26aSHidetoshi Shimokawa  * $Id: dcons_crom.c,v 1.8 2003/10/23 15:47:21 simokawa Exp $
35d8d65ecaSHidetoshi Shimokawa  * $FreeBSD: src/sys/dev/dcons/dcons_crom.c,v 1.5 2004/10/13 05:38:42 simokawa Exp $
366265f26aSHidetoshi Shimokawa  */
376265f26aSHidetoshi Shimokawa 
386265f26aSHidetoshi Shimokawa #include <sys/param.h>
396265f26aSHidetoshi Shimokawa #include <sys/kernel.h>
406265f26aSHidetoshi Shimokawa #include <sys/module.h>
416265f26aSHidetoshi Shimokawa #include <sys/systm.h>
426265f26aSHidetoshi Shimokawa #include <sys/types.h>
436265f26aSHidetoshi Shimokawa #include <sys/conf.h>
446265f26aSHidetoshi Shimokawa #include <sys/malloc.h>
456265f26aSHidetoshi Shimokawa #include <sys/bus.h>
466265f26aSHidetoshi Shimokawa 
476265f26aSHidetoshi Shimokawa #ifdef __DragonFly__
486265f26aSHidetoshi Shimokawa #include <bus/firewire/firewire.h>
496265f26aSHidetoshi Shimokawa #include <bus/firewire/firewirereg.h>
506265f26aSHidetoshi Shimokawa #include <bus/firewire/iec13213.h>
516265f26aSHidetoshi Shimokawa #include "dcons.h"
52d8d65ecaSHidetoshi Shimokawa #include "dcons_os.h"
536265f26aSHidetoshi Shimokawa #else
546265f26aSHidetoshi Shimokawa #include <dev/firewire/firewire.h>
556265f26aSHidetoshi Shimokawa #include <dev/firewire/firewirereg.h>
566265f26aSHidetoshi Shimokawa #include <dev/firewire/iec13213.h>
576265f26aSHidetoshi Shimokawa #include <dev/dcons/dcons.h>
58d8d65ecaSHidetoshi Shimokawa #include <dev/dcons/dcons_os.h>
596265f26aSHidetoshi Shimokawa #endif
606265f26aSHidetoshi Shimokawa 
616265f26aSHidetoshi Shimokawa #include <sys/cons.h>
626265f26aSHidetoshi Shimokawa 
636265f26aSHidetoshi Shimokawa static bus_addr_t dcons_paddr;
646265f26aSHidetoshi Shimokawa 
65*20d3070bSSascha Wildner #if 0 /* XXX __FreeBSD_version >= 500000 */
666265f26aSHidetoshi Shimokawa static int force_console = 1;
676265f26aSHidetoshi Shimokawa TUNABLE_INT("hw.firewire.dcons_crom.force_console", &force_console);
686265f26aSHidetoshi Shimokawa #endif
696265f26aSHidetoshi Shimokawa 
706265f26aSHidetoshi Shimokawa #ifndef CSRVAL_VENDOR_PRIVATE
716265f26aSHidetoshi Shimokawa #define NEED_NEW_DRIVER
726265f26aSHidetoshi Shimokawa #endif
736265f26aSHidetoshi Shimokawa 
746265f26aSHidetoshi Shimokawa #define ADDR_HI(x)	(((x) >> 24) & 0xffffff)
756265f26aSHidetoshi Shimokawa #define ADDR_LO(x)	((x) & 0xffffff)
766265f26aSHidetoshi Shimokawa 
776265f26aSHidetoshi Shimokawa struct dcons_crom_softc {
786265f26aSHidetoshi Shimokawa         struct firewire_dev_comm fd;
796265f26aSHidetoshi Shimokawa 	struct crom_chunk unit;
806265f26aSHidetoshi Shimokawa 	struct crom_chunk spec;
816265f26aSHidetoshi Shimokawa 	struct crom_chunk ver;
826265f26aSHidetoshi Shimokawa 	bus_dma_tag_t dma_tag;
836265f26aSHidetoshi Shimokawa 	bus_dmamap_t dma_map;
846265f26aSHidetoshi Shimokawa 	bus_addr_t bus_addr;
856265f26aSHidetoshi Shimokawa };
866265f26aSHidetoshi Shimokawa 
876265f26aSHidetoshi Shimokawa static int
dcons_crom_probe(device_t dev)886265f26aSHidetoshi Shimokawa dcons_crom_probe(device_t dev)
896265f26aSHidetoshi Shimokawa {
906265f26aSHidetoshi Shimokawa 	device_t pa;
916265f26aSHidetoshi Shimokawa 
926265f26aSHidetoshi Shimokawa 	pa = device_get_parent(dev);
936265f26aSHidetoshi Shimokawa 	if(device_get_unit(dev) != device_get_unit(pa)){
946265f26aSHidetoshi Shimokawa 		return(ENXIO);
956265f26aSHidetoshi Shimokawa 	}
966265f26aSHidetoshi Shimokawa 
976265f26aSHidetoshi Shimokawa 	device_set_desc(dev, "dcons configuration ROM");
986265f26aSHidetoshi Shimokawa 	return (0);
996265f26aSHidetoshi Shimokawa }
1006265f26aSHidetoshi Shimokawa 
1016265f26aSHidetoshi Shimokawa #ifndef NEED_NEW_DRIVER
1026265f26aSHidetoshi Shimokawa static void
dcons_crom_post_busreset(void * arg)1036265f26aSHidetoshi Shimokawa dcons_crom_post_busreset(void *arg)
1046265f26aSHidetoshi Shimokawa {
1056265f26aSHidetoshi Shimokawa 	struct dcons_crom_softc *sc;
1066265f26aSHidetoshi Shimokawa 	struct crom_src *src;
1076265f26aSHidetoshi Shimokawa 	struct crom_chunk *root;
1086265f26aSHidetoshi Shimokawa 
1096265f26aSHidetoshi Shimokawa 	sc = (struct dcons_crom_softc *) arg;
1106265f26aSHidetoshi Shimokawa 	src = sc->fd.fc->crom_src;
1116265f26aSHidetoshi Shimokawa 	root = sc->fd.fc->crom_root;
1126265f26aSHidetoshi Shimokawa 
1136265f26aSHidetoshi Shimokawa 	bzero(&sc->unit, sizeof(struct crom_chunk));
1146265f26aSHidetoshi Shimokawa 
1156265f26aSHidetoshi Shimokawa 	crom_add_chunk(src, root, &sc->unit, CROM_UDIR);
1166265f26aSHidetoshi Shimokawa 	crom_add_entry(&sc->unit, CSRKEY_SPEC, CSRVAL_VENDOR_PRIVATE);
1176265f26aSHidetoshi Shimokawa 	crom_add_simple_text(src, &sc->unit, &sc->spec, "FreeBSD");
1186265f26aSHidetoshi Shimokawa 	crom_add_entry(&sc->unit, CSRKEY_VER, DCONS_CSR_VAL_VER);
1196265f26aSHidetoshi Shimokawa 	crom_add_simple_text(src, &sc->unit, &sc->ver, "dcons");
1206265f26aSHidetoshi Shimokawa 	crom_add_entry(&sc->unit, DCONS_CSR_KEY_HI, ADDR_HI(dcons_paddr));
1216265f26aSHidetoshi Shimokawa 	crom_add_entry(&sc->unit, DCONS_CSR_KEY_LO, ADDR_LO(dcons_paddr));
1226265f26aSHidetoshi Shimokawa }
1236265f26aSHidetoshi Shimokawa #endif
1246265f26aSHidetoshi Shimokawa 
1256265f26aSHidetoshi Shimokawa static void
dmamap_cb(void * arg,bus_dma_segment_t * segments,int seg,int error)1266265f26aSHidetoshi Shimokawa dmamap_cb(void *arg, bus_dma_segment_t *segments, int seg, int error)
1276265f26aSHidetoshi Shimokawa {
1286265f26aSHidetoshi Shimokawa 	struct dcons_crom_softc *sc;
1296265f26aSHidetoshi Shimokawa 
1306265f26aSHidetoshi Shimokawa 	if (error)
131e3869ec7SSascha Wildner 		kprintf("dcons_dmamap_cb: error=%d\n", error);
1326265f26aSHidetoshi Shimokawa 
1336265f26aSHidetoshi Shimokawa 	sc = (struct dcons_crom_softc *)arg;
1346265f26aSHidetoshi Shimokawa 	sc->bus_addr = segments[0].ds_addr;
1356265f26aSHidetoshi Shimokawa 
1366265f26aSHidetoshi Shimokawa 	bus_dmamap_sync(sc->dma_tag, sc->dma_map, BUS_DMASYNC_PREWRITE);
137bfc09ba0SMatthew Dillon 	device_printf(sc->fd.dev, "bus_addr 0x%jx\n",
138bfc09ba0SMatthew Dillon 		      (uintmax_t)sc->bus_addr);
1396265f26aSHidetoshi Shimokawa 	if (dcons_paddr != 0) {
1406265f26aSHidetoshi Shimokawa 		/* XXX */
1416265f26aSHidetoshi Shimokawa 		device_printf(sc->fd.dev, "dcons_paddr is already set\n");
1426265f26aSHidetoshi Shimokawa 		return;
1436265f26aSHidetoshi Shimokawa 	}
1446265f26aSHidetoshi Shimokawa 	dcons_conf->dma_tag = sc->dma_tag;
1456265f26aSHidetoshi Shimokawa 	dcons_conf->dma_map = sc->dma_map;
1466265f26aSHidetoshi Shimokawa 	dcons_paddr = sc->bus_addr;
1476265f26aSHidetoshi Shimokawa 
148*20d3070bSSascha Wildner #if 0 /* XXX __FreeBSD_version >= 500000 */
1496265f26aSHidetoshi Shimokawa 	/* Force to be the high-level console */
1506265f26aSHidetoshi Shimokawa 	if (force_console)
1516265f26aSHidetoshi Shimokawa 		cnselect(dcons_conf->cdev);
1526265f26aSHidetoshi Shimokawa #endif
1536265f26aSHidetoshi Shimokawa }
1546265f26aSHidetoshi Shimokawa 
1556265f26aSHidetoshi Shimokawa static int
dcons_crom_attach(device_t dev)1566265f26aSHidetoshi Shimokawa dcons_crom_attach(device_t dev)
1576265f26aSHidetoshi Shimokawa {
1586265f26aSHidetoshi Shimokawa #ifdef NEED_NEW_DRIVER
159e3869ec7SSascha Wildner 	kprintf("dcons_crom: you need newer firewire driver\n");
1606265f26aSHidetoshi Shimokawa 	return (-1);
1616265f26aSHidetoshi Shimokawa #else
1626265f26aSHidetoshi Shimokawa 	struct dcons_crom_softc *sc;
1636265f26aSHidetoshi Shimokawa 
1646265f26aSHidetoshi Shimokawa         sc = (struct dcons_crom_softc *) device_get_softc(dev);
1656265f26aSHidetoshi Shimokawa 	sc->fd.fc = device_get_ivars(dev);
1666265f26aSHidetoshi Shimokawa 	sc->fd.dev = dev;
1676265f26aSHidetoshi Shimokawa 	sc->fd.post_explore = NULL;
1686265f26aSHidetoshi Shimokawa 	sc->fd.post_busreset = (void *) dcons_crom_post_busreset;
1696265f26aSHidetoshi Shimokawa 
1706265f26aSHidetoshi Shimokawa 	/* map dcons buffer */
1716265f26aSHidetoshi Shimokawa 	bus_dma_tag_create(
1726265f26aSHidetoshi Shimokawa 		/*parent*/ sc->fd.fc->dmat,
1736265f26aSHidetoshi Shimokawa 		/*alignment*/ sizeof(u_int32_t),
1746265f26aSHidetoshi Shimokawa 		/*boundary*/ 0,
1756265f26aSHidetoshi Shimokawa 		/*lowaddr*/ BUS_SPACE_MAXADDR,
1766265f26aSHidetoshi Shimokawa 		/*highaddr*/ BUS_SPACE_MAXADDR,
1776265f26aSHidetoshi Shimokawa 		/*maxsize*/ dcons_conf->size,
1786265f26aSHidetoshi Shimokawa 		/*nsegments*/ 1,
1796265f26aSHidetoshi Shimokawa 		/*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
1806265f26aSHidetoshi Shimokawa 		/*flags*/ BUS_DMA_ALLOCNOW,
1816265f26aSHidetoshi Shimokawa 		&sc->dma_tag);
1826265f26aSHidetoshi Shimokawa 	bus_dmamap_create(sc->dma_tag, 0, &sc->dma_map);
1836265f26aSHidetoshi Shimokawa 	bus_dmamap_load(sc->dma_tag, sc->dma_map,
1846265f26aSHidetoshi Shimokawa 	    (void *)dcons_conf->buf, dcons_conf->size,
1856265f26aSHidetoshi Shimokawa 	    dmamap_cb, sc, 0);
1866265f26aSHidetoshi Shimokawa 	return (0);
1876265f26aSHidetoshi Shimokawa #endif
1886265f26aSHidetoshi Shimokawa }
1896265f26aSHidetoshi Shimokawa 
1906265f26aSHidetoshi Shimokawa static int
dcons_crom_detach(device_t dev)1916265f26aSHidetoshi Shimokawa dcons_crom_detach(device_t dev)
1926265f26aSHidetoshi Shimokawa {
1936265f26aSHidetoshi Shimokawa 	struct dcons_crom_softc *sc;
1946265f26aSHidetoshi Shimokawa 
1956265f26aSHidetoshi Shimokawa         sc = (struct dcons_crom_softc *) device_get_softc(dev);
1966265f26aSHidetoshi Shimokawa 	sc->fd.post_busreset = NULL;
1976265f26aSHidetoshi Shimokawa 
1986265f26aSHidetoshi Shimokawa 	/* XXX */
1996265f26aSHidetoshi Shimokawa 	if (dcons_conf->dma_tag == sc->dma_tag)
2006265f26aSHidetoshi Shimokawa 		dcons_conf->dma_tag = NULL;
2016265f26aSHidetoshi Shimokawa 
2026265f26aSHidetoshi Shimokawa 	bus_dmamap_unload(sc->dma_tag, sc->dma_map);
2036265f26aSHidetoshi Shimokawa 	bus_dmamap_destroy(sc->dma_tag, sc->dma_map);
2046265f26aSHidetoshi Shimokawa 	bus_dma_tag_destroy(sc->dma_tag);
2056265f26aSHidetoshi Shimokawa 
2066265f26aSHidetoshi Shimokawa 	return 0;
2076265f26aSHidetoshi Shimokawa }
2086265f26aSHidetoshi Shimokawa 
20939b5d600SMatthew Dillon /*
21039b5d600SMatthew Dillon  * Because dcons_crom is a static device that always exists under any attached
21139b5d600SMatthew Dillon  * firewire device, and not scanned by the firewire device, we need an
21239b5d600SMatthew Dillon  * identify function to install the device.  For our sanity we want
21339b5d600SMatthew Dillon  * the sbp device to have the same unit number as the fireweire device.
21439b5d600SMatthew Dillon  */
2156265f26aSHidetoshi Shimokawa static devclass_t dcons_crom_devclass;
2166265f26aSHidetoshi Shimokawa 
2176265f26aSHidetoshi Shimokawa static device_method_t dcons_crom_methods[] = {
2186265f26aSHidetoshi Shimokawa 	/* device interface */
21939b5d600SMatthew Dillon 	DEVMETHOD(device_identify,	bus_generic_identify_sameunit),
2206265f26aSHidetoshi Shimokawa 	DEVMETHOD(device_probe,		dcons_crom_probe),
2216265f26aSHidetoshi Shimokawa 	DEVMETHOD(device_attach,	dcons_crom_attach),
2226265f26aSHidetoshi Shimokawa 	DEVMETHOD(device_detach,	dcons_crom_detach),
223d3c9c58eSSascha Wildner 	DEVMETHOD_END
2246265f26aSHidetoshi Shimokawa };
2256265f26aSHidetoshi Shimokawa 
2266265f26aSHidetoshi Shimokawa static driver_t dcons_crom_driver = {
2276265f26aSHidetoshi Shimokawa 	"dcons_crom",
2286265f26aSHidetoshi Shimokawa 	dcons_crom_methods,
2296265f26aSHidetoshi Shimokawa 	sizeof(struct dcons_crom_softc),
2306265f26aSHidetoshi Shimokawa };
2316265f26aSHidetoshi Shimokawa 
2326265f26aSHidetoshi Shimokawa DRIVER_MODULE(dcons_crom, firewire, dcons_crom_driver,
233aa6ac96eSSascha Wildner     dcons_crom_devclass, NULL, NULL);
2346265f26aSHidetoshi Shimokawa MODULE_VERSION(dcons_crom, 1);
2356265f26aSHidetoshi Shimokawa MODULE_DEPEND(dcons_crom, dcons,
2366265f26aSHidetoshi Shimokawa 	DCONS_VERSION, DCONS_VERSION, DCONS_VERSION);
2376265f26aSHidetoshi Shimokawa MODULE_DEPEND(dcons_crom, firewire, 1, 1, 1);
238