xref: /openbsd/sys/arch/sparc64/dev/bbc.c (revision 4bdff4be)
1 /*	$OpenBSD: bbc.c,v 1.4 2021/10/24 17:05:03 mpi Exp $	*/
2 
3 /*
4  * Copyright (c) 2007 Mark Kettenis
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
20 #include <sys/kernel.h>
21 #include <sys/device.h>
22 #include <sys/malloc.h>
23 #include <sys/systm.h>
24 
25 #include <machine/bus.h>
26 #include <machine/autoconf.h>
27 
28 #ifdef DDB
29 #include <machine/db_machdep.h>
30 #endif
31 
32 #include <sparc64/dev/ebusreg.h>
33 #include <sparc64/dev/ebusvar.h>
34 
35 /* Agent ID */
36 #define BBC_AID			0x00000
37 
38 /* Watchdog Action */
39 #define BBC_WATCHDOG_ACTION	0x00004
40 
41 /* Perform system reset when watchdog timer expires. */
42 #define	BBC_WATCHDOG_RESET	0x01
43 
44 /* Soft_XIR_GEN */
45 #define BBC_SOFT_XIR_GEN	0x00007
46 
47 struct bbc_softc {
48 	struct device		sc_dv;
49 	bus_space_tag_t		sc_iot;
50 	bus_space_handle_t	sc_ioh;
51 
52 	int			sc_aid;
53 };
54 
55 int	bbc_match(struct device *, void *, void *);
56 void	bbc_attach(struct device *, struct device *, void *);
57 
58 const struct cfattach bbc_ca = {
59 	sizeof(struct bbc_softc), bbc_match, bbc_attach
60 };
61 
62 struct cfdriver bbc_cd = {
63 	NULL, "bbc", DV_DULL
64 };
65 
66 #ifdef DDB
67 void	bbc_xir(void *, int);
68 #endif
69 
70 int
71 bbc_match(struct device *parent, void *cf, void *aux)
72 {
73 	struct ebus_attach_args *ea = aux;
74 
75 	if (strcmp("bbc", ea->ea_name) == 0)
76 		return (1);
77 	return (0);
78 }
79 
80 void
81 bbc_attach(struct device *parent, struct device *self, void *aux)
82 {
83 	struct bbc_softc *sc = (void *)self;
84 	struct ebus_attach_args *ea = aux;
85 
86 	/* Use prom address if available, otherwise map it. */
87 	if (ea->ea_nvaddrs) {
88 		if (bus_space_map(ea->ea_memtag, ea->ea_vaddrs[0], 0,
89 		    BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh)) {
90 			printf(": can't map PROM register space\n");
91 			return;
92 		}
93 		sc->sc_iot = ea->ea_memtag;
94 	} else if (ebus_bus_map(ea->ea_iotag, 0,
95 	    EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
96 	    ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
97 		sc->sc_iot = ea->ea_iotag;
98 	} else if (ebus_bus_map(ea->ea_memtag, 0,
99 	    EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
100 	    ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
101 		sc->sc_iot = ea->ea_memtag;
102 	} else {
103 		printf(": can't map register space\n");
104 		return;
105 	}
106 
107 	sc->sc_aid = bus_space_read_1(sc->sc_iot, sc->sc_ioh, BBC_AID);
108 	printf(": AID 0x%02x\n", sc->sc_aid);
109 
110 	/*
111 	 * Make sure we actually reset the system when the watchdog
112 	 * timer expires.
113 	 */
114 	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
115 	    BBC_WATCHDOG_ACTION, BBC_WATCHDOG_RESET);
116 
117 #ifdef DDB
118 	db_register_xir(bbc_xir, sc);
119 #endif
120 }
121 
122 #ifdef DDB
123 void
124 bbc_xir(void *arg, int cpu)
125 {
126 	struct bbc_softc *sc = arg;
127 
128 	/* Redirect a request to reset all processors to Processor 0. */
129 	if (cpu == -1)
130 		cpu = 0;
131 
132 	/* Check whether we're handling the requested processor. */
133 	if ((cpu & ~0x7) != sc->sc_aid)
134 		return;
135 
136 	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
137 	    BBC_SOFT_XIR_GEN, 1 << (cpu & 0x7));
138 }
139 #endif
140