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
bbc_match(struct device * parent,void * cf,void * aux)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
bbc_attach(struct device * parent,struct device * self,void * aux)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
bbc_xir(void * arg,int cpu)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