1 /* $NetBSD: isa_machdep.c,v 1.13 2009/08/18 17:02:00 dyoung Exp $ */
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: isa_machdep.c,v 1.13 2009/08/18 17:02:00 dyoung Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38 #include <sys/malloc.h>
39 #include <sys/queue.h>
41 #include <machine/sysconf.h>
42 #include <machine/autoconf.h>
43 #include <machine/mainboard.h>
44 #include <machine/bus.h>
46 #include <dev/isa/isavar.h>
47 #include <dev/isa/isareg.h>
49 static int mipscoisabusprint(void *auxp
, const char *);
50 static int isabusmatch(struct device
*, struct cfdata
*, void *);
51 static void isabusattach(struct device
*, struct device
*, void *);
55 struct mipsco_isa_chipset sc_isa_ic
;
58 CFATTACH_DECL(isabus
, sizeof(struct isabus_softc
),
59 isabusmatch
, isabusattach
, NULL
, NULL
);
61 extern struct cfdriver isabus_cd
;
63 static struct mipsco_bus_space isa_io_bst
, isa_mem_bst
, isa_ctl_bst
;
64 static struct mipsco_bus_dma_tag isa_dmatag
;
66 static void isa_bus_space_init(struct mipsco_bus_space
*, const char *,
72 isabusmatch(struct device
*pdp
, struct cfdata
*cfp
, void *aux
)
74 struct confargs
*ca
= aux
;
76 if (strcmp(ca
->ca_name
, isabus_cd
.cd_name
) != 0)
82 isa_bus_space_init(struct mipsco_bus_space
*bst
, const char *type
, paddr_t paddr
, size_t len
)
84 vaddr_t vaddr
= MIPS_PHYS_TO_KSEG1(paddr
); /* XXX */
86 /* Setup default bus_space */
87 mipsco_bus_space_init(bst
, type
, paddr
, vaddr
, 0x0, len
);
89 /* ISA bus maps 1 word for every byte, therefore stride = 2 */
90 mipsco_bus_space_set_aligned_stride(bst
, 2);
93 * ISA bus will do an automatic byte swap, but when accessing
94 * memory using bus_space_stream functions we need to byte swap
95 * to reverse the one performed in hardware
99 bst
->bs_intr_establish
= (void *)isa_intr_establish
;
101 printf(" %s %p", type
, (void *)vaddr
);
106 isabusattach(struct device
*pdp
, struct device
*dp
, void *aux
)
108 struct isabus_softc
*sc
= (struct isabus_softc
*)dp
;
109 struct mipsco_isa_chipset
*ic
= &sc
->sc_isa_ic
;
110 struct isabus_attach_args iba
;
114 iba
.iba_iot
= &isa_io_bst
;
115 iba
.iba_memt
= &isa_mem_bst
;
116 iba
.iba_dmat
= &isa_dmatag
;
119 isa_bus_space_init(&isa_io_bst
, "isa_io", PIZAZZ_ISA_IOBASE
,
122 isa_bus_space_init(&isa_mem_bst
, "isa_mem", PIZAZZ_ISA_MEMBASE
,
125 isa_bus_space_init(&isa_ctl_bst
, "isa_intr", PIZAZZ_ISA_INTRLATCH
,
128 _bus_dma_tag_init(&isa_dmatag
);
130 ic
->ic_bst
= &isa_ctl_bst
;
132 if (bus_space_map(ic
->ic_bst
, 0x00000, sizeof(u_int32_t
),
133 BUS_SPACE_MAP_LINEAR
, &ic
->ic_bsh
) != 0) {
134 printf(": can't map intrreg\n");
138 /* Clear ISA interrupt latch */
139 bus_space_write_4(ic
->ic_bst
, ic
->ic_bsh
, 0, 0);
141 evcnt_attach_dynamic(&ic
->ic_intrcnt
, EVCNT_TYPE_INTR
, NULL
,
142 dp
->dv_xname
, "intr");
144 LIST_INIT(&ic
->intr_q
);
145 (*platform
.intr_establish
)(SYS_INTR_ATBUS
, isa_intr
, ic
);
148 config_found_ia(dp
, "isabus", &iba
, mipscoisabusprint
);
152 mipscoisabusprint(void *auxp
, const char *name
)
160 isa_attach_hook(struct device
*parent
, struct device
*self
, struct isabus_attach_args
*iba
)
165 isa_detach_hook(isa_chipset_tag_t ic
, device_t self
)
170 isa_intr_evcnt(isa_chipset_tag_t ic
, int irq
)
172 /* XXX for now, no evcnt parent reported */
177 isa_intr_establish(isa_chipset_tag_t ic
, int intr
, int type
, int level
, int (*ih_fun
)(void*), void *ih_arg
)
178 /* type: XXX not yet */
179 /* level: XXX not yet */
181 struct mipsco_intrhand
*ih
;
183 ih
= malloc(sizeof *ih
, M_DEVBUF
, M_NOWAIT
);
185 panic("isa_intr_establish: malloc failed");
189 LIST_INSERT_HEAD(&ic
->intr_q
, ih
, ih_q
);
194 isa_intr_disestablish(isa_chipset_tag_t ic
, void *cookie
)
196 struct mipsco_intrhand
*ih
= cookie
;
198 LIST_REMOVE(ih
, ih_q
);
203 isa_intr_alloc(isa_chipset_tag_t ic
, int mask
, int type
, int *irq
)
211 struct mipsco_isa_chipset
*ic
= (struct mipsco_isa_chipset
*)arg
;
212 struct mipsco_intrhand
*ih
;
215 ic
->ic_intrcnt
.ev_count
++;
218 LIST_FOREACH(ih
, &ic
->intr_q
, ih_q
) {
220 * The handler returns one of three values:
221 * 0: This interrupt wasn't for me.
222 * 1: This interrupt was for me.
223 * -1: This interrupt might have been for me, but I can't say
226 rv
= (*ih
->ih_fun
)(ih
->ih_arg
);
227 handled
|= (rv
!= 0);
230 /* Clear ISA interrupt latch */
231 bus_space_write_4(ic
->ic_bst
, ic
->ic_bsh
, 0, 0);