Annotation of sys/dev/ic/am79c930.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: am79c930.c,v 1.4 2002/03/14 01:26:54 millert Exp $ */
2: /* $NetBSD: am79c930.c,v 1.5 2000/03/23 13:57:58 onoe Exp $ */
3:
4: /*-
5: * Copyright (c) 1999 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to The NetBSD Foundation
9: * by Bill Sommerfeld
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
38: */
39:
40: /*
41: * Am79c930 chip driver.
42: *
43: * This is used by the awi driver to use the shared
44: * memory attached to the 79c930 to communicate with the firmware running
45: * in the 930's on-board 80188 core.
46: *
47: * The 79c930 can be mapped into just I/O space, or also have a
48: * memory mapping; the mapping must be set up by the bus front-end
49: * before am79c930_init is called.
50: */
51:
52: /*
53: * operations:
54: *
55: * read_8, read_16, read_32, read_64, read_bytes
56: * write_8, write_16, write_32, write_64, write_bytes
57: * (two versions, depending on whether memory-space or i/o space is in use).
58: *
59: * interrupt E.C.
60: * start isr
61: * end isr
62: */
63:
64: #include <sys/param.h>
65: #include <sys/systm.h>
66: #ifndef __FreeBSD__
67: #include <sys/device.h>
68: #endif
69:
70: #include <machine/cpu.h>
71: #ifdef __FreeBSD__
72: #include <machine/bus_pio.h>
73: #include <machine/bus_memio.h>
74: #endif
75: #include <machine/bus.h>
76: #ifdef __NetBSD__
77: #include <machine/intr.h>
78: #endif
79:
80: #if defined(__NetBSD__) || defined(__OpenBSD__)
81: #include <dev/ic/am79c930reg.h>
82: #include <dev/ic/am79c930var.h>
83: #endif
84: #ifdef __FreeBSD__
85: #include <dev/awi/am79c930reg.h>
86: #include <dev/awi/am79c930var.h>
87: #endif
88:
89: #define AM930_DELAY(x) /*nothing*/
90:
91: void am79c930_regdump(struct am79c930_softc *sc);
92:
93: static void io_write_1(struct am79c930_softc *, u_int32_t, u_int8_t);
94: static void io_write_2(struct am79c930_softc *, u_int32_t, u_int16_t);
95: static void io_write_4(struct am79c930_softc *, u_int32_t, u_int32_t);
96: static void io_write_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t);
97:
98: static u_int8_t io_read_1(struct am79c930_softc *, u_int32_t);
99: static u_int16_t io_read_2(struct am79c930_softc *, u_int32_t);
100: static u_int32_t io_read_4(struct am79c930_softc *, u_int32_t);
101: static void io_read_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t);
102:
103: static void mem_write_1(struct am79c930_softc *, u_int32_t, u_int8_t);
104: static void mem_write_2(struct am79c930_softc *, u_int32_t, u_int16_t);
105: static void mem_write_4(struct am79c930_softc *, u_int32_t, u_int32_t);
106: static void mem_write_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t);
107:
108: static u_int8_t mem_read_1(struct am79c930_softc *, u_int32_t);
109: static u_int16_t mem_read_2(struct am79c930_softc *, u_int32_t);
110: static u_int32_t mem_read_4(struct am79c930_softc *, u_int32_t);
111: static void mem_read_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t);
112:
113: static struct am79c930_ops iospace_ops = {
114: io_write_1,
115: io_write_2,
116: io_write_4,
117: io_write_bytes,
118: io_read_1,
119: io_read_2,
120: io_read_4,
121: io_read_bytes
122: };
123:
124: struct am79c930_ops memspace_ops = {
125: mem_write_1,
126: mem_write_2,
127: mem_write_4,
128: mem_write_bytes,
129: mem_read_1,
130: mem_read_2,
131: mem_read_4,
132: mem_read_bytes
133: };
134:
135: static void io_write_1 (sc, off, val)
136: struct am79c930_softc *sc;
137: u_int32_t off;
138: u_int8_t val;
139: {
140: AM930_DELAY(1);
141: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
142: ((off>>8)& 0x7f));
143: AM930_DELAY(1);
144: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
145: AM930_DELAY(1);
146: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA, val);
147: AM930_DELAY(1);
148: }
149:
150: static void io_write_2 (sc, off, val)
151: struct am79c930_softc *sc;
152: u_int32_t off;
153: u_int16_t val;
154: {
155: AM930_DELAY(1);
156: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
157: ((off>>8)& 0x7f));
158: AM930_DELAY(1);
159: bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff));
160: AM930_DELAY(1);
161: bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA, val & 0xff);
162: AM930_DELAY(1);
163: bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA, (val>>8)&0xff);
164: AM930_DELAY(1);
165: }
166:
167: static void io_write_4 (sc, off, val)
168: struct am79c930_softc *sc;
169: u_int32_t off;
170: u_int32_t val;
171: {
172: AM930_DELAY(1);
173: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
174: ((off>>8)& 0x7f));
175: AM930_DELAY(1);
176: bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff));
177: AM930_DELAY(1);
178: bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,val & 0xff);
179: AM930_DELAY(1);
180: bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>8)&0xff);
181: AM930_DELAY(1);
182: bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>16)&0xff);
183: AM930_DELAY(1);
184: bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>24)&0xff);
185: AM930_DELAY(1);
186: }
187:
188: static void io_write_bytes (sc, off, ptr, len)
189: struct am79c930_softc *sc;
190: u_int32_t off;
191: u_int8_t *ptr;
192: size_t len;
193: {
194: int i;
195:
196: AM930_DELAY(1);
197: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
198: ((off>>8)& 0x7f));
199: AM930_DELAY(1);
200: bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff));
201: AM930_DELAY(1);
202: for (i=0; i<len; i++)
203: bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,ptr[i]);
204: }
205:
206: static u_int8_t io_read_1 (sc, off)
207: struct am79c930_softc *sc;
208: u_int32_t off;
209: {
210: u_int8_t val;
211:
212: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
213: ((off>>8)& 0x7f));
214: AM930_DELAY(1);
215: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
216: AM930_DELAY(1);
217: val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA);
218: AM930_DELAY(1);
219: return val;
220: }
221:
222: static u_int16_t io_read_2 (sc, off)
223: struct am79c930_softc *sc;
224: u_int32_t off;
225: {
226: u_int16_t val;
227:
228: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
229: ((off>>8)& 0x7f));
230: AM930_DELAY(1);
231: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
232: AM930_DELAY(1);
233: val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA);
234: AM930_DELAY(1);
235: val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 8;
236: AM930_DELAY(1);
237: return val;
238: }
239:
240: static u_int32_t io_read_4 (sc, off)
241: struct am79c930_softc *sc;
242: u_int32_t off;
243: {
244: u_int32_t val;
245:
246: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
247: ((off>>8)& 0x7f));
248: AM930_DELAY(1);
249: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
250: AM930_DELAY(1);
251: val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA);
252: AM930_DELAY(1);
253: val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 8;
254: AM930_DELAY(1);
255: val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 16;
256: AM930_DELAY(1);
257: val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 24;
258: AM930_DELAY(1);
259: return val;
260: }
261:
262: static void io_read_bytes (sc, off, ptr, len)
263: struct am79c930_softc *sc;
264: u_int32_t off;
265: u_int8_t *ptr;
266: size_t len;
267: {
268: int i;
269:
270: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
271: ((off>>8)& 0x7f));
272: AM930_DELAY(1);
273: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
274: AM930_DELAY(1);
275: for (i=0; i<len; i++)
276: ptr[i] = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
277: AM79C930_IODPA);
278: }
279:
280: static void mem_write_1 (sc, off, val)
281: struct am79c930_softc *sc;
282: u_int32_t off;
283: u_int8_t val;
284: {
285: bus_space_write_1(sc->sc_memt, sc->sc_memh, off, val);
286: }
287:
288: static void mem_write_2 (sc, off, val)
289: struct am79c930_softc *sc;
290: u_int32_t off;
291: u_int16_t val;
292: {
293: bus_space_tag_t t = sc->sc_memt;
294: bus_space_handle_t h = sc->sc_memh;
295:
296: /* could be unaligned */
297: if ((off & 0x1) == 0)
298: bus_space_write_2(t, h, off, val);
299: else {
300: bus_space_write_1(t, h, off, val & 0xff);
301: bus_space_write_1(t, h, off+1, (val >> 8) & 0xff);
302: }
303: }
304:
305: static void mem_write_4 (sc, off, val)
306: struct am79c930_softc *sc;
307: u_int32_t off;
308: u_int32_t val;
309: {
310: bus_space_tag_t t = sc->sc_memt;
311: bus_space_handle_t h = sc->sc_memh;
312:
313: /* could be unaligned */
314: if ((off & 0x3) == 0)
315: bus_space_write_4(t, h, off, val);
316: else {
317: bus_space_write_1(t, h, off, val & 0xff);
318: bus_space_write_1(t, h, off+1, (val >> 8) & 0xff);
319: bus_space_write_1(t, h, off+2, (val >> 16) & 0xff);
320: bus_space_write_1(t, h, off+3, (val >> 24) & 0xff);
321: }
322: }
323:
324: static void mem_write_bytes (sc, off, ptr, len)
325: struct am79c930_softc *sc;
326: u_int32_t off;
327: u_int8_t *ptr;
328: size_t len;
329: {
330: bus_space_write_region_1 (sc->sc_memt, sc->sc_memh, off, ptr, len);
331: }
332:
333:
334: static u_int8_t mem_read_1 (sc, off)
335: struct am79c930_softc *sc;
336: u_int32_t off;
337: {
338: return bus_space_read_1(sc->sc_memt, sc->sc_memh, off);
339: }
340:
341: static u_int16_t mem_read_2 (sc, off)
342: struct am79c930_softc *sc;
343: u_int32_t off;
344: {
345: /* could be unaligned */
346: if ((off & 0x1) == 0)
347: return bus_space_read_2(sc->sc_memt, sc->sc_memh, off);
348: else
349: return
350: bus_space_read_1(sc->sc_memt, sc->sc_memh, off ) |
351: (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+1) << 8);
352: }
353:
354: static u_int32_t mem_read_4 (sc, off)
355: struct am79c930_softc *sc;
356: u_int32_t off;
357: {
358: /* could be unaligned */
359: if ((off & 0x3) == 0)
360: return bus_space_read_4(sc->sc_memt, sc->sc_memh, off);
361: else
362: return
363: bus_space_read_1(sc->sc_memt, sc->sc_memh, off ) |
364: (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+1) << 8) |
365: (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+2) <<16) |
366: (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+3) <<24);
367: }
368:
369:
370:
371: static void mem_read_bytes (sc, off, ptr, len)
372: struct am79c930_softc *sc;
373: u_int32_t off;
374: u_int8_t *ptr;
375: size_t len;
376: {
377: bus_space_read_region_1 (sc->sc_memt, sc->sc_memh, off, ptr, len);
378: }
379:
380:
381:
382:
383: /*
384: * Set bits in GCR.
385: */
386:
387: void am79c930_gcr_setbits (sc, bits)
388: struct am79c930_softc *sc;
389: u_int8_t bits;
390: {
391: u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
392:
393: gcr |= bits;
394:
395: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_GCR, gcr);
396: }
397:
398: /*
399: * Clear bits in GCR.
400: */
401:
402: void am79c930_gcr_clearbits (sc, bits)
403: struct am79c930_softc *sc;
404: u_int8_t bits;
405: {
406: u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
407:
408: gcr &= ~bits;
409:
410: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_GCR, gcr);
411: }
412:
413: u_int8_t am79c930_gcr_read (sc)
414: struct am79c930_softc *sc;
415: {
416: return bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
417: }
418:
419: #if 0
420: void am79c930_regdump (sc)
421: struct am79c930_softc *sc;
422: {
423: u_int8_t buf[8];
424: int i;
425:
426: AM930_DELAY(5);
427: for (i=0; i<8; i++) {
428: buf[i] = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, i);
429: AM930_DELAY(5);
430: }
431: printf("am79c930: regdump:");
432: for (i=0; i<8; i++) {
433: printf(" %02x", buf[i]);
434: }
435: printf("\n");
436: }
437: #endif
438:
439: void am79c930_chip_init (sc, how)
440: struct am79c930_softc *sc;
441: {
442: /* zero the bank select register, and leave it that way.. */
443: bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_BSS, 0);
444: if (how)
445: sc->sc_ops = &memspace_ops;
446: else
447: sc->sc_ops = &iospace_ops;
448: }
449:
450:
CVSweb