xref: /dflybsd-src/sys/dev/misc/dcons/dcons_crom.c (revision 04a3b05a06faf941aa6ec3a48b7ad31d19e75bc0)
1  /*
2   * Copyright (C) 2003
3   * 	Hidetoshi Shimokawa. All rights reserved.
4   *
5   * Redistribution and use in source and binary forms, with or without
6   * modification, are permitted provided that the following conditions
7   * are met:
8   * 1. Redistributions of source code must retain the above copyright
9   *    notice, this list of conditions and the following disclaimer.
10   * 2. Redistributions in binary form must reproduce the above copyright
11   *    notice, this list of conditions and the following disclaimer in the
12   *    documentation and/or other materials provided with the distribution.
13   * 3. All advertising materials mentioning features or use of this software
14   *    must display the following acknowledgement:
15   *
16   *	This product includes software developed by Hidetoshi Shimokawa.
17   *
18   * 4. Neither the name of the author nor the names of its contributors
19   *    may be used to endorse or promote products derived from this software
20   *    without specific prior written permission.
21   *
22   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32   * SUCH DAMAGE.
33   *
34   * $Id: dcons_crom.c,v 1.8 2003/10/23 15:47:21 simokawa Exp $
35   * $FreeBSD: src/sys/dev/dcons/dcons_crom.c,v 1.5 2004/10/13 05:38:42 simokawa Exp $
36   */
37  
38  #include <sys/param.h>
39  #include <sys/kernel.h>
40  #include <sys/module.h>
41  #include <sys/systm.h>
42  #include <sys/types.h>
43  #include <sys/conf.h>
44  #include <sys/malloc.h>
45  #include <sys/bus.h>
46  
47  #ifdef __DragonFly__
48  #include <bus/firewire/firewire.h>
49  #include <bus/firewire/firewirereg.h>
50  #include <bus/firewire/iec13213.h>
51  #include "dcons.h"
52  #include "dcons_os.h"
53  #else
54  #include <dev/firewire/firewire.h>
55  #include <dev/firewire/firewirereg.h>
56  #include <dev/firewire/iec13213.h>
57  #include <dev/dcons/dcons.h>
58  #include <dev/dcons/dcons_os.h>
59  #endif
60  
61  #include <sys/cons.h>
62  
63  static bus_addr_t dcons_paddr;
64  
65  #if 0 /* XXX __FreeBSD_version >= 500000 */
66  static int force_console = 1;
67  TUNABLE_INT("hw.firewire.dcons_crom.force_console", &force_console);
68  #endif
69  
70  #ifndef CSRVAL_VENDOR_PRIVATE
71  #define NEED_NEW_DRIVER
72  #endif
73  
74  #define ADDR_HI(x)	(((x) >> 24) & 0xffffff)
75  #define ADDR_LO(x)	((x) & 0xffffff)
76  
77  struct dcons_crom_softc {
78          struct firewire_dev_comm fd;
79  	struct crom_chunk unit;
80  	struct crom_chunk spec;
81  	struct crom_chunk ver;
82  	bus_dma_tag_t dma_tag;
83  	bus_dmamap_t dma_map;
84  	bus_addr_t bus_addr;
85  };
86  
87  static int
88  dcons_crom_probe(device_t dev)
89  {
90  	device_t pa;
91  
92  	pa = device_get_parent(dev);
93  	if(device_get_unit(dev) != device_get_unit(pa)){
94  		return(ENXIO);
95  	}
96  
97  	device_set_desc(dev, "dcons configuration ROM");
98  	return (0);
99  }
100  
101  #ifndef NEED_NEW_DRIVER
102  static void
103  dcons_crom_post_busreset(void *arg)
104  {
105  	struct dcons_crom_softc *sc;
106  	struct crom_src *src;
107  	struct crom_chunk *root;
108  
109  	sc = (struct dcons_crom_softc *) arg;
110  	src = sc->fd.fc->crom_src;
111  	root = sc->fd.fc->crom_root;
112  
113  	bzero(&sc->unit, sizeof(struct crom_chunk));
114  
115  	crom_add_chunk(src, root, &sc->unit, CROM_UDIR);
116  	crom_add_entry(&sc->unit, CSRKEY_SPEC, CSRVAL_VENDOR_PRIVATE);
117  	crom_add_simple_text(src, &sc->unit, &sc->spec, "FreeBSD");
118  	crom_add_entry(&sc->unit, CSRKEY_VER, DCONS_CSR_VAL_VER);
119  	crom_add_simple_text(src, &sc->unit, &sc->ver, "dcons");
120  	crom_add_entry(&sc->unit, DCONS_CSR_KEY_HI, ADDR_HI(dcons_paddr));
121  	crom_add_entry(&sc->unit, DCONS_CSR_KEY_LO, ADDR_LO(dcons_paddr));
122  }
123  #endif
124  
125  static void
126  dmamap_cb(void *arg, bus_dma_segment_t *segments, int seg, int error)
127  {
128  	struct dcons_crom_softc *sc;
129  
130  	if (error)
131  		kprintf("dcons_dmamap_cb: error=%d\n", error);
132  
133  	sc = (struct dcons_crom_softc *)arg;
134  	sc->bus_addr = segments[0].ds_addr;
135  
136  	bus_dmamap_sync(sc->dma_tag, sc->dma_map, BUS_DMASYNC_PREWRITE);
137  	device_printf(sc->fd.dev, "bus_addr 0x%jx\n",
138  		      (uintmax_t)sc->bus_addr);
139  	if (dcons_paddr != 0) {
140  		/* XXX */
141  		device_printf(sc->fd.dev, "dcons_paddr is already set\n");
142  		return;
143  	}
144  	dcons_conf->dma_tag = sc->dma_tag;
145  	dcons_conf->dma_map = sc->dma_map;
146  	dcons_paddr = sc->bus_addr;
147  
148  #if 0 /* XXX __FreeBSD_version >= 500000 */
149  	/* Force to be the high-level console */
150  	if (force_console)
151  		cnselect(dcons_conf->cdev);
152  #endif
153  }
154  
155  static int
156  dcons_crom_attach(device_t dev)
157  {
158  #ifdef NEED_NEW_DRIVER
159  	kprintf("dcons_crom: you need newer firewire driver\n");
160  	return (-1);
161  #else
162  	struct dcons_crom_softc *sc;
163  
164          sc = (struct dcons_crom_softc *) device_get_softc(dev);
165  	sc->fd.fc = device_get_ivars(dev);
166  	sc->fd.dev = dev;
167  	sc->fd.post_explore = NULL;
168  	sc->fd.post_busreset = (void *) dcons_crom_post_busreset;
169  
170  	/* map dcons buffer */
171  	bus_dma_tag_create(
172  		/*parent*/ sc->fd.fc->dmat,
173  		/*alignment*/ sizeof(u_int32_t),
174  		/*boundary*/ 0,
175  		/*lowaddr*/ BUS_SPACE_MAXADDR,
176  		/*highaddr*/ BUS_SPACE_MAXADDR,
177  		/*maxsize*/ dcons_conf->size,
178  		/*nsegments*/ 1,
179  		/*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
180  		/*flags*/ BUS_DMA_ALLOCNOW,
181  		&sc->dma_tag);
182  	bus_dmamap_create(sc->dma_tag, 0, &sc->dma_map);
183  	bus_dmamap_load(sc->dma_tag, sc->dma_map,
184  	    (void *)dcons_conf->buf, dcons_conf->size,
185  	    dmamap_cb, sc, 0);
186  	return (0);
187  #endif
188  }
189  
190  static int
191  dcons_crom_detach(device_t dev)
192  {
193  	struct dcons_crom_softc *sc;
194  
195          sc = (struct dcons_crom_softc *) device_get_softc(dev);
196  	sc->fd.post_busreset = NULL;
197  
198  	/* XXX */
199  	if (dcons_conf->dma_tag == sc->dma_tag)
200  		dcons_conf->dma_tag = NULL;
201  
202  	bus_dmamap_unload(sc->dma_tag, sc->dma_map);
203  	bus_dmamap_destroy(sc->dma_tag, sc->dma_map);
204  	bus_dma_tag_destroy(sc->dma_tag);
205  
206  	return 0;
207  }
208  
209  /*
210   * Because dcons_crom is a static device that always exists under any attached
211   * firewire device, and not scanned by the firewire device, we need an
212   * identify function to install the device.  For our sanity we want
213   * the sbp device to have the same unit number as the fireweire device.
214   */
215  static devclass_t dcons_crom_devclass;
216  
217  static device_method_t dcons_crom_methods[] = {
218  	/* device interface */
219  	DEVMETHOD(device_identify,	bus_generic_identify_sameunit),
220  	DEVMETHOD(device_probe,		dcons_crom_probe),
221  	DEVMETHOD(device_attach,	dcons_crom_attach),
222  	DEVMETHOD(device_detach,	dcons_crom_detach),
223  	DEVMETHOD_END
224  };
225  
226  static driver_t dcons_crom_driver = {
227  	"dcons_crom",
228  	dcons_crom_methods,
229  	sizeof(struct dcons_crom_softc),
230  };
231  
232  DRIVER_MODULE(dcons_crom, firewire, dcons_crom_driver,
233      dcons_crom_devclass, NULL, NULL);
234  MODULE_VERSION(dcons_crom, 1);
235  MODULE_DEPEND(dcons_crom, dcons,
236  	DCONS_VERSION, DCONS_VERSION, DCONS_VERSION);
237  MODULE_DEPEND(dcons_crom, firewire, 1, 1, 1);
238