amdsmn.c (343323) | amdsmn.c (343325) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2017 Conrad Meyer | 2 * Copyright (c) 2017-2019 Conrad Meyer <cem@FreeBSD.org> |
3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright --- 9 unchanged lines hidden (view full) --- 20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 23 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 * POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27/* | 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright --- 9 unchanged lines hidden (view full) --- 20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 23 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 * POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27/* |
28 * Driver for the AMD Family 17h CPU System Management Network. | 28 * Driver for the AMD Family 15h and 17h CPU System Management Network. |
29 */ 30 31#include <sys/cdefs.h> | 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: stable/11/sys/dev/amdsmn/amdsmn.c 343323 2019-01-22 21:33:14Z mav $"); | 32__FBSDID("$FreeBSD: stable/11/sys/dev/amdsmn/amdsmn.c 343325 2019-01-22 21:35:25Z mav $"); |
33 34#include <sys/param.h> 35#include <sys/bus.h> 36#include <sys/conf.h> 37#include <sys/lock.h> 38#include <sys/kernel.h> 39#include <sys/module.h> 40#include <sys/mutex.h> --- 5 unchanged lines hidden (view full) --- 46#include <machine/md_var.h> 47#include <machine/specialreg.h> 48 49#include <dev/pci/pcivar.h> 50#include <x86/pci_cfgreg.h> 51 52#include <dev/amdsmn/amdsmn.h> 53 | 33 34#include <sys/param.h> 35#include <sys/bus.h> 36#include <sys/conf.h> 37#include <sys/lock.h> 38#include <sys/kernel.h> 39#include <sys/module.h> 40#include <sys/mutex.h> --- 5 unchanged lines hidden (view full) --- 46#include <machine/md_var.h> 47#include <machine/specialreg.h> 48 49#include <dev/pci/pcivar.h> 50#include <x86/pci_cfgreg.h> 51 52#include <dev/amdsmn/amdsmn.h> 53 |
54#define SMN_ADDR_REG 0x60 55#define SMN_DATA_REG 0x64 | 54#define F15H_SMN_ADDR_REG 0xb8 55#define F15H_SMN_DATA_REG 0xbc 56#define F17H_SMN_ADDR_REG 0x60 57#define F17H_SMN_DATA_REG 0x64 |
56 | 58 |
59#define PCI_DEVICE_ID_AMD_15H_M60H_ROOT 0x1576 |
|
57#define PCI_DEVICE_ID_AMD_17H_ROOT 0x1450 | 60#define PCI_DEVICE_ID_AMD_17H_ROOT 0x1450 |
58#define PCI_DEVICE_ID_AMD_17H_ROOT_DF_F3 0x1463 | |
59#define PCI_DEVICE_ID_AMD_17H_M10H_ROOT 0x15d0 | 61#define PCI_DEVICE_ID_AMD_17H_M10H_ROOT 0x15d0 |
60#define PCI_DEVICE_ID_AMD_17H_M10H_ROOT_DF_F3 0x15eb | |
61 | 62 |
63struct pciid; |
|
62struct amdsmn_softc { 63 struct mtx smn_lock; | 64struct amdsmn_softc { 65 struct mtx smn_lock; |
66 const struct pciid *smn_pciid; |
|
64}; 65 | 67}; 68 |
66static struct pciid { | 69static const struct pciid { |
67 uint16_t amdsmn_vendorid; 68 uint16_t amdsmn_deviceid; | 70 uint16_t amdsmn_vendorid; 71 uint16_t amdsmn_deviceid; |
72 uint8_t amdsmn_addr_reg; 73 uint8_t amdsmn_data_reg; |
|
69} amdsmn_ids[] = { | 74} amdsmn_ids[] = { |
70 { CPU_VENDOR_AMD, PCI_DEVICE_ID_AMD_17H_ROOT }, 71 { CPU_VENDOR_AMD, PCI_DEVICE_ID_AMD_17H_M10H_ROOT }, | 75 { 76 .amdsmn_vendorid = CPU_VENDOR_AMD, 77 .amdsmn_deviceid = PCI_DEVICE_ID_AMD_15H_M60H_ROOT, 78 .amdsmn_addr_reg = F15H_SMN_ADDR_REG, 79 .amdsmn_data_reg = F15H_SMN_DATA_REG, 80 }, 81 { 82 .amdsmn_vendorid = CPU_VENDOR_AMD, 83 .amdsmn_deviceid = PCI_DEVICE_ID_AMD_17H_ROOT, 84 .amdsmn_addr_reg = F17H_SMN_ADDR_REG, 85 .amdsmn_data_reg = F17H_SMN_DATA_REG, 86 }, 87 { 88 .amdsmn_vendorid = CPU_VENDOR_AMD, 89 .amdsmn_deviceid = PCI_DEVICE_ID_AMD_17H_M10H_ROOT, 90 .amdsmn_addr_reg = F17H_SMN_ADDR_REG, 91 .amdsmn_data_reg = F17H_SMN_DATA_REG, 92 }, |
72}; 73 74/* 75 * Device methods. 76 */ 77static void amdsmn_identify(driver_t *driver, device_t parent); 78static int amdsmn_probe(device_t dev); 79static int amdsmn_attach(device_t dev); --- 14 unchanged lines hidden (view full) --- 94 sizeof(struct amdsmn_softc), 95}; 96 97static devclass_t amdsmn_devclass; 98DRIVER_MODULE(amdsmn, hostb, amdsmn_driver, amdsmn_devclass, NULL, NULL); 99MODULE_VERSION(amdsmn, 1); 100 101static bool | 93}; 94 95/* 96 * Device methods. 97 */ 98static void amdsmn_identify(driver_t *driver, device_t parent); 99static int amdsmn_probe(device_t dev); 100static int amdsmn_attach(device_t dev); --- 14 unchanged lines hidden (view full) --- 115 sizeof(struct amdsmn_softc), 116}; 117 118static devclass_t amdsmn_devclass; 119DRIVER_MODULE(amdsmn, hostb, amdsmn_driver, amdsmn_devclass, NULL, NULL); 120MODULE_VERSION(amdsmn, 1); 121 122static bool |
102amdsmn_match(device_t parent) | 123amdsmn_match(device_t parent, const struct pciid **pciid_out) |
103{ 104 uint16_t vendor, device; 105 size_t i; 106 107 vendor = pci_get_vendor(parent); 108 device = pci_get_device(parent); 109 | 124{ 125 uint16_t vendor, device; 126 size_t i; 127 128 vendor = pci_get_vendor(parent); 129 device = pci_get_device(parent); 130 |
110 for (i = 0; i < nitems(amdsmn_ids); i++) | 131 for (i = 0; i < nitems(amdsmn_ids); i++) { |
111 if (vendor == amdsmn_ids[i].amdsmn_vendorid && | 132 if (vendor == amdsmn_ids[i].amdsmn_vendorid && |
112 device == amdsmn_ids[i].amdsmn_deviceid) | 133 device == amdsmn_ids[i].amdsmn_deviceid) { 134 if (pciid_out != NULL) 135 *pciid_out = &amdsmn_ids[i]; |
113 return (true); | 136 return (true); |
137 } 138 } |
|
114 return (false); 115} 116 117static void 118amdsmn_identify(driver_t *driver, device_t parent) 119{ 120 device_t child; 121 122 /* Make sure we're not being doubly invoked. */ 123 if (device_find_child(parent, "amdsmn", -1) != NULL) 124 return; | 139 return (false); 140} 141 142static void 143amdsmn_identify(driver_t *driver, device_t parent) 144{ 145 device_t child; 146 147 /* Make sure we're not being doubly invoked. */ 148 if (device_find_child(parent, "amdsmn", -1) != NULL) 149 return; |
125 if (!amdsmn_match(parent)) | 150 if (!amdsmn_match(parent, NULL)) |
126 return; 127 128 child = device_add_child(parent, "amdsmn", -1); 129 if (child == NULL) 130 device_printf(parent, "add amdsmn child failed\n"); 131} 132 133static int 134amdsmn_probe(device_t dev) 135{ 136 uint32_t family; | 151 return; 152 153 child = device_add_child(parent, "amdsmn", -1); 154 if (child == NULL) 155 device_printf(parent, "add amdsmn child failed\n"); 156} 157 158static int 159amdsmn_probe(device_t dev) 160{ 161 uint32_t family; |
162 char buf[64]; |
|
137 138 if (resource_disabled("amdsmn", 0)) 139 return (ENXIO); | 163 164 if (resource_disabled("amdsmn", 0)) 165 return (ENXIO); |
140 if (!amdsmn_match(device_get_parent(dev))) | 166 if (!amdsmn_match(device_get_parent(dev), NULL)) |
141 return (ENXIO); 142 143 family = CPUID_TO_FAMILY(cpu_id); 144 145 switch (family) { | 167 return (ENXIO); 168 169 family = CPUID_TO_FAMILY(cpu_id); 170 171 switch (family) { |
172 case 0x15: |
|
146 case 0x17: 147 break; 148 default: 149 return (ENXIO); 150 } | 173 case 0x17: 174 break; 175 default: 176 return (ENXIO); 177 } |
151 device_set_desc(dev, "AMD Family 17h System Management Network"); | 178 snprintf(buf, sizeof(buf), "AMD Family %xh System Management Network", 179 family); 180 device_set_desc_copy(dev, buf); |
152 153 return (BUS_PROBE_GENERIC); 154} 155 156static int 157amdsmn_attach(device_t dev) 158{ 159 struct amdsmn_softc *sc = device_get_softc(dev); 160 | 181 182 return (BUS_PROBE_GENERIC); 183} 184 185static int 186amdsmn_attach(device_t dev) 187{ 188 struct amdsmn_softc *sc = device_get_softc(dev); 189 |
190 if (!amdsmn_match(device_get_parent(dev), &sc->smn_pciid)) 191 return (ENXIO); 192 |
|
161 mtx_init(&sc->smn_lock, "SMN mtx", "SMN", MTX_DEF); 162 return (0); 163} 164 165int 166amdsmn_detach(device_t dev) 167{ 168 struct amdsmn_softc *sc = device_get_softc(dev); --- 6 unchanged lines hidden (view full) --- 175amdsmn_read(device_t dev, uint32_t addr, uint32_t *value) 176{ 177 struct amdsmn_softc *sc = device_get_softc(dev); 178 device_t parent; 179 180 parent = device_get_parent(dev); 181 182 mtx_lock(&sc->smn_lock); | 193 mtx_init(&sc->smn_lock, "SMN mtx", "SMN", MTX_DEF); 194 return (0); 195} 196 197int 198amdsmn_detach(device_t dev) 199{ 200 struct amdsmn_softc *sc = device_get_softc(dev); --- 6 unchanged lines hidden (view full) --- 207amdsmn_read(device_t dev, uint32_t addr, uint32_t *value) 208{ 209 struct amdsmn_softc *sc = device_get_softc(dev); 210 device_t parent; 211 212 parent = device_get_parent(dev); 213 214 mtx_lock(&sc->smn_lock); |
183 pci_write_config(parent, SMN_ADDR_REG, addr, 4); 184 *value = pci_read_config(parent, SMN_DATA_REG, 4); | 215 pci_write_config(parent, sc->smn_pciid->amdsmn_addr_reg, addr, 4); 216 *value = pci_read_config(parent, sc->smn_pciid->amdsmn_data_reg, 4); |
185 mtx_unlock(&sc->smn_lock); 186 187 return (0); 188} 189 190int 191amdsmn_write(device_t dev, uint32_t addr, uint32_t value) 192{ 193 struct amdsmn_softc *sc = device_get_softc(dev); 194 device_t parent; 195 196 parent = device_get_parent(dev); 197 198 mtx_lock(&sc->smn_lock); | 217 mtx_unlock(&sc->smn_lock); 218 219 return (0); 220} 221 222int 223amdsmn_write(device_t dev, uint32_t addr, uint32_t value) 224{ 225 struct amdsmn_softc *sc = device_get_softc(dev); 226 device_t parent; 227 228 parent = device_get_parent(dev); 229 230 mtx_lock(&sc->smn_lock); |
199 pci_write_config(parent, SMN_ADDR_REG, addr, 4); 200 pci_write_config(parent, SMN_DATA_REG, value, 4); | 231 pci_write_config(parent, sc->smn_pciid->amdsmn_addr_reg, addr, 4); 232 pci_write_config(parent, sc->smn_pciid->amdsmn_data_reg, value, 4); |
201 mtx_unlock(&sc->smn_lock); 202 203 return (0); 204} | 233 mtx_unlock(&sc->smn_lock); 234 235 return (0); 236} |