xref: /netbsd-src/sys/arch/hppa/dev/wax.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /*	$NetBSD: wax.c,v 1.4 2021/08/07 16:18:55 thorpej Exp $	*/
26d3ceb1dSskrll 
36d3ceb1dSskrll /*	$OpenBSD: wax.c,v 1.1 1998/11/23 03:04:10 mickey Exp $	*/
46d3ceb1dSskrll 
56d3ceb1dSskrll /*
66d3ceb1dSskrll  * Copyright (c) 1998-2003 Michael Shalayeff
76d3ceb1dSskrll  * All rights reserved.
86d3ceb1dSskrll  *
96d3ceb1dSskrll  * Redistribution and use in source and binary forms, with or without
106d3ceb1dSskrll  * modification, are permitted provided that the following conditions
116d3ceb1dSskrll  * are met:
126d3ceb1dSskrll  * 1. Redistributions of source code must retain the above copyright
136d3ceb1dSskrll  *    notice, this list of conditions and the following disclaimer.
146d3ceb1dSskrll  * 2. Redistributions in binary form must reproduce the above copyright
156d3ceb1dSskrll  *    notice, this list of conditions and the following disclaimer in the
166d3ceb1dSskrll  *    documentation and/or other materials provided with the distribution.
176d3ceb1dSskrll  *
186d3ceb1dSskrll  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
196d3ceb1dSskrll  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
206d3ceb1dSskrll  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
216d3ceb1dSskrll  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
226d3ceb1dSskrll  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
236d3ceb1dSskrll  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
246d3ceb1dSskrll  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
256d3ceb1dSskrll  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
266d3ceb1dSskrll  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
276d3ceb1dSskrll  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
286d3ceb1dSskrll  * THE POSSIBILITY OF SUCH DAMAGE.
296d3ceb1dSskrll  */
306d3ceb1dSskrll 
316d3ceb1dSskrll #include <sys/cdefs.h>
32*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: wax.c,v 1.4 2021/08/07 16:18:55 thorpej Exp $");
336d3ceb1dSskrll 
346d3ceb1dSskrll #include <sys/param.h>
356d3ceb1dSskrll #include <sys/systm.h>
366d3ceb1dSskrll #include <sys/device.h>
376d3ceb1dSskrll #include <sys/reboot.h>
386d3ceb1dSskrll 
396d3ceb1dSskrll #include <machine/iomod.h>
406d3ceb1dSskrll #include <machine/autoconf.h>
416d3ceb1dSskrll 
426d3ceb1dSskrll #include <hppa/dev/cpudevs.h>
436d3ceb1dSskrll 
446d3ceb1dSskrll #include <hppa/gsc/gscbusvar.h>
456d3ceb1dSskrll 
466d3ceb1dSskrll #define	WAX_IOMASK	0xfff00000
476d3ceb1dSskrll #define	WAX_REGS	0xc000
486d3ceb1dSskrll 
496d3ceb1dSskrll struct wax_regs {
506d3ceb1dSskrll 	uint32_t wax_irr;	/* int requset register */
516d3ceb1dSskrll 	uint32_t wax_imr;	/* int mask register */
526d3ceb1dSskrll 	uint32_t wax_ipr;	/* int pending register */
536d3ceb1dSskrll 	uint32_t wax_icr;	/* int control register */
546d3ceb1dSskrll 	uint32_t wax_iar;	/* int address register */
556d3ceb1dSskrll };
566d3ceb1dSskrll 
576d3ceb1dSskrll struct wax_softc {
586d3ceb1dSskrll 	device_t sc_dv;
596d3ceb1dSskrll 	struct hppa_interrupt_register sc_ir;
606d3ceb1dSskrll 	struct wax_regs volatile *sc_regs;
616d3ceb1dSskrll };
626d3ceb1dSskrll 
636d3ceb1dSskrll int	waxmatch(device_t, cfdata_t, void *);
646d3ceb1dSskrll void	waxattach(device_t, device_t, void *);
656d3ceb1dSskrll 
666d3ceb1dSskrll 
676d3ceb1dSskrll CFATTACH_DECL_NEW(wax, sizeof(struct wax_softc),
686d3ceb1dSskrll     waxmatch, waxattach, NULL, NULL);
696d3ceb1dSskrll 
706d3ceb1dSskrll static int wax_attached;
716d3ceb1dSskrll 
726d3ceb1dSskrll /*
736d3ceb1dSskrll  * Before a module is matched, this fixes up its gsc_attach_args.
746d3ceb1dSskrll  */
756d3ceb1dSskrll static void wax_fix_args(void *, struct gsc_attach_args *);
766d3ceb1dSskrll static void
wax_fix_args(void * _sc,struct gsc_attach_args * ga)776d3ceb1dSskrll wax_fix_args(void *_sc, struct gsc_attach_args *ga)
786d3ceb1dSskrll {
796d3ceb1dSskrll 	struct wax_softc *sc = _sc;
806d3ceb1dSskrll 	hppa_hpa_t module_offset;
816d3ceb1dSskrll 
826d3ceb1dSskrll 	/*
836d3ceb1dSskrll 	 * Determine this module's interrupt bit.
846d3ceb1dSskrll 	 */
856d3ceb1dSskrll 	module_offset = ga->ga_hpa - (hppa_hpa_t) sc->sc_regs;
866d3ceb1dSskrll 	ga->ga_irq = HPPACF_IRQ_UNDEF;
876d3ceb1dSskrll 	if (module_offset == 0x1000)	/* hil */
886d3ceb1dSskrll 		ga->ga_irq = 1;
896d3ceb1dSskrll 	if (module_offset == 0x2000)	/* com */
906d3ceb1dSskrll 		ga->ga_irq = 6;
916d3ceb1dSskrll }
926d3ceb1dSskrll 
936d3ceb1dSskrll int
waxmatch(device_t parent,cfdata_t cf,void * aux)946d3ceb1dSskrll waxmatch(device_t parent, cfdata_t cf, void *aux)
956d3ceb1dSskrll {
966d3ceb1dSskrll 	struct confargs *ca = aux;
976d3ceb1dSskrll 
986d3ceb1dSskrll 	/* there will be only one */
996d3ceb1dSskrll 	if (wax_attached ||
1006d3ceb1dSskrll 	    ca->ca_type.iodc_type != HPPA_TYPE_BHA ||
1016d3ceb1dSskrll 	    ca->ca_type.iodc_sv_model != HPPA_BHA_WAX)
1026d3ceb1dSskrll 		return 0;
1036d3ceb1dSskrll 
1046d3ceb1dSskrll 	return 1;
1056d3ceb1dSskrll }
1066d3ceb1dSskrll 
1076d3ceb1dSskrll void
waxattach(device_t parent,device_t self,void * aux)1086d3ceb1dSskrll waxattach(device_t parent, device_t self, void *aux)
1096d3ceb1dSskrll {
1106d3ceb1dSskrll 	struct confargs *ca = aux;
1116d3ceb1dSskrll 	struct wax_softc *sc = device_private(self);
1126d3ceb1dSskrll 	struct gsc_attach_args ga;
1136d3ceb1dSskrll 	struct cpu_info *ci = &cpus[0];
1146d3ceb1dSskrll 	bus_space_handle_t ioh;
1156d3ceb1dSskrll 	int s;
1166d3ceb1dSskrll 
1176d3ceb1dSskrll 	ca->ca_irq = hppa_intr_allocate_bit(&ci->ci_ir, ca->ca_irq);
1186d3ceb1dSskrll 	if (ca->ca_irq == HPPACF_IRQ_UNDEF) {
1196d3ceb1dSskrll 		aprint_error(": can't allocate interrupt\n");
1206d3ceb1dSskrll 		return;
1216d3ceb1dSskrll 	}
1226d3ceb1dSskrll 
1236d3ceb1dSskrll 	sc->sc_dv = self;
1246d3ceb1dSskrll 	wax_attached = 1;
1256d3ceb1dSskrll 
1266d3ceb1dSskrll 	aprint_normal("\n");
1276d3ceb1dSskrll 
1286d3ceb1dSskrll 	/*
1296d3ceb1dSskrll 	 * Map the WAX interrupt registers.
1306d3ceb1dSskrll 	 */
1316d3ceb1dSskrll 	if (bus_space_map(ca->ca_iot, ca->ca_hpa, sizeof(struct wax_regs),
1326d3ceb1dSskrll 	    0, &ioh)) {
1336d3ceb1dSskrll 		aprint_error(": can't map interrupt registers\n");
1346d3ceb1dSskrll 		return;
1356d3ceb1dSskrll 	}
1366d3ceb1dSskrll 	sc->sc_regs = (struct wax_regs *)ca->ca_hpa;
1376d3ceb1dSskrll 
1386d3ceb1dSskrll 	/* interrupts guts */
1396d3ceb1dSskrll 	s = splhigh();
1406d3ceb1dSskrll 	sc->sc_regs->wax_iar = ci->ci_hpa | (31 - ca->ca_irq);
1416d3ceb1dSskrll 	sc->sc_regs->wax_icr = 0;
1426d3ceb1dSskrll 	sc->sc_regs->wax_imr = 0;
143fc85ec4fSskrll 	(void)sc->sc_regs->wax_irr;
1446d3ceb1dSskrll 	splx(s);
1456d3ceb1dSskrll 
1466d3ceb1dSskrll 	/* Establish the interrupt register. */
1476d3ceb1dSskrll 	hppa_interrupt_register_establish(ci, &sc->sc_ir);
1486d3ceb1dSskrll 	sc->sc_ir.ir_name = device_xname(self);
1496d3ceb1dSskrll 	sc->sc_ir.ir_mask = &sc->sc_regs->wax_imr;
1506d3ceb1dSskrll 	sc->sc_ir.ir_req = &sc->sc_regs->wax_irr;
1516d3ceb1dSskrll 
1526d3ceb1dSskrll 	/* Attach the GSC bus. */
1536d3ceb1dSskrll 	ga.ga_ca = *ca;	/* clone from us */
1546d3ceb1dSskrll 	if (strcmp(device_xname(parent), "mainbus0") == 0) {
1556d3ceb1dSskrll 		ga.ga_dp.dp_bc[0] = ga.ga_dp.dp_bc[1];
1566d3ceb1dSskrll 		ga.ga_dp.dp_bc[1] = ga.ga_dp.dp_bc[2];
1576d3ceb1dSskrll 		ga.ga_dp.dp_bc[2] = ga.ga_dp.dp_bc[3];
1586d3ceb1dSskrll 		ga.ga_dp.dp_bc[3] = ga.ga_dp.dp_bc[4];
1596d3ceb1dSskrll 		ga.ga_dp.dp_bc[4] = ga.ga_dp.dp_bc[5];
1606d3ceb1dSskrll 		ga.ga_dp.dp_bc[5] = ga.ga_dp.dp_mod;
1616d3ceb1dSskrll 		ga.ga_dp.dp_mod = 0;
1626d3ceb1dSskrll 	}
1636d3ceb1dSskrll 
1646d3ceb1dSskrll 	ga.ga_name = "gsc";
1656d3ceb1dSskrll 	ga.ga_ir = &sc->sc_ir;
1666d3ceb1dSskrll 	ga.ga_fix_args = wax_fix_args;
1676d3ceb1dSskrll 	ga.ga_fix_args_cookie = sc;
1686d3ceb1dSskrll 	ga.ga_scsi_target = 7; /* XXX */
169*c7fb772bSthorpej 	config_found(self, &ga, gscprint, CFARGS_NONE);
1706d3ceb1dSskrll }
171