Deleted Added
full compact
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}