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