kernel: restore setting KTS_NONE
[minix.git] / drivers / amddev / amddev.c
blob8db57527f21222e999410e329eb7e780f64645f4
1 /*
2 amddev.c
4 Driver for the AMD Device Exclusion Vector (DEV)
5 */
7 #include <minix/driver.h>
8 #include <minix/config.h>
9 #include <minix/type.h>
11 #include <errno.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <machine/vm.h>
17 #include <signal.h>
18 #include <minix/com.h>
19 #include <minix/const.h>
20 #include <minix/ipc.h>
21 #include <minix/syslib.h>
22 #include <minix/sysutil.h>
23 #include <minix/endpoint.h>
24 #include <machine/pci.h>
26 /* Offsets from capability pointer */
27 #define DEV_OP 4 /* Selects control/status register to access */
28 #define DEV_OP_FUNC_SHIFT 8 /* Function part in OP reg. */
29 #define DEV_DATA 8 /* Read/write to access reg. selected */
31 /* Functions */
32 #define DEVF_BASE_LO 0
33 #define DEVF_BASE_HI 1
34 #define DEVF_MAP 2
35 #define DEVF_CAP 3
36 #define DEVF_CAP_MAPS_MASK 0x00ff0000
37 #define DEVF_CAP_MAPS_SHIFT 16
38 #define DEVF_CAP_DOMS_MASK 0x0000ff00
39 #define DEVF_CAP_DOMS_SHIFT 8
40 #define DEVF_CAP_REV_MASK 0x000000ff
41 #define DEVF_CAP_REV_SHIFT 0
42 #define DEVF_CR 4
43 #define DEVF_ERR_STATUS 5
44 #define DEVF_ERR_ADDR_LO 6
45 #define DEVF_ERR_ADDR_HI 7
47 static int dev_devind;
48 static u8_t dev_capptr;
49 static u8_t *table;
51 static int find_dev(int *devindp, u8_t *capaddrp);
52 static u32_t read_reg(int function, int index);
53 static void write_reg(int function, int index, u32_t value);
54 static void init_domain(int index);
55 static void init_map(unsigned int ix);
56 static int do_add4pci(const message *m);
57 static void add_range(phys_bytes busaddr, phys_bytes size);
58 #if 0
59 static void del_range(phys_bytes busaddr, phys_bytes size);
60 static void sef_cb_signal_handler(int signo);
61 #endif
62 static void report_exceptions(void);
64 /* SEF functions and variables. */
65 static void sef_local_startup(void);
66 static int sef_cb_init_fresh(int type, sef_init_info_t *info);
68 int main(void)
70 int r;
71 message m;
72 int ipc_status;
74 /* SEF local startup. */
75 sef_local_startup();
77 for(;;)
79 report_exceptions();
81 r= driver_receive(ANY, &m, &ipc_status);
82 if (r != OK)
83 panic("driver_receive failed: %d", r);
84 if (m.m_type == IOMMU_MAP) {
85 r= do_add4pci(&m);
86 m.m_type= r;
87 send(m.m_source, &m);
88 continue;
90 printf("amddev: got message from %d\n", m.m_source);
94 /*===========================================================================*
95 * sef_local_startup *
96 *===========================================================================*/
97 static void sef_local_startup()
99 /* Register init callbacks. */
100 sef_setcb_init_fresh(sef_cb_init_fresh);
101 sef_setcb_init_lu(sef_cb_init_fresh);
102 sef_setcb_init_restart(sef_cb_init_fresh);
104 /* Register live update callbacks. */
105 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
106 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
108 #if 0
109 /* Register signal callbacks. */
110 sef_setcb_signal_handler(sef_cb_signal_handler);
111 #endif
113 /* Let SEF perform startup. */
114 sef_startup();
117 /*===========================================================================*
118 * sef_cb_init_fresh *
119 *===========================================================================*/
120 static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
122 /* Initialize the amddev driver. */
123 int r, n_maps, n_domains, revision;
124 u16_t flags;
125 u32_t bits;
127 printf("amddev: starting\n");
129 r= find_dev(&dev_devind, &dev_capptr);
130 if (!r)
131 return r;
132 flags= pci_attr_r16(dev_devind, dev_capptr+CAP_SD_INFO);
133 printf("amddev`init: flags = 0x%x\n", flags);
135 bits= read_reg(DEVF_CAP, 0);
136 n_maps= ((bits & DEVF_CAP_MAPS_MASK) >> DEVF_CAP_MAPS_SHIFT);
137 n_domains= ((bits & DEVF_CAP_DOMS_MASK) >> DEVF_CAP_DOMS_SHIFT);
138 revision= ((bits & DEVF_CAP_REV_MASK) >> DEVF_CAP_REV_SHIFT);
139 printf("amddev`init: DEVF_CAP = 0x%x (%d maps, %d domains, rev 0x%x)\n",
140 bits, n_maps, n_domains, revision);
142 printf("status = 0x%x, addr-lo = 0x%x, addr-hi = 0x%x\n",
143 read_reg(DEVF_ERR_STATUS, 0),
144 read_reg(DEVF_ERR_ADDR_LO, 0),
145 read_reg(DEVF_ERR_ADDR_HI, 0));
147 init_domain(0);
148 init_map(0);
149 #if 0
150 init_domain(1);
151 #endif
153 write_reg(DEVF_CR, 0, 0x10 | 0x8 | 0x4 | 1);
155 printf("after write: DEVF_CR: 0x%x\n", read_reg(DEVF_CR, 0));
157 return(OK);
161 #if 0
162 /*===========================================================================*
163 * sef_cb_signal_handler *
164 *===========================================================================*/
165 static void sef_cb_signal_handler(int signo)
167 int r;
168 endpoint_t proc_e;
169 phys_bytes base, size;
171 /* Only check for termination signal, ignore anything else. */
172 if (signo != SIGTERM) return;
174 for (;;)
176 r= vm_getdma(&proc_e, &base, &size);
177 if (r == -1)
179 if (errno != -EAGAIN)
181 printf(
182 "amddev: vm_getdma failed: %d\n",
183 errno);
185 break;
188 printf(
189 "amddev: deleting 0x%lx@0x%lx for proc %d\n",
190 size, base, proc_e);
191 del_range(base, size);
192 r= vm_deldma(proc_e, base, size);
193 if (r == -1)
195 printf("amddev: vm_deldma failed: %d\n",
196 errno);
197 break;
201 #endif
203 /* Returns 0 if no device found, or 1 if a device is found. */
204 static int find_dev(devindp, capaddrp)
205 int *devindp;
206 u8_t *capaddrp;
208 int r, devind, first;
209 u8_t capptr, type, next, subtype;
210 u16_t vid, did, status;
212 pci_init();
214 first= 1;
215 for(;;)
217 if (first)
219 first= 0;
220 r= pci_first_dev(&devind, &vid, &did);
221 if (!r)
223 printf("amddev`find_dev: no first dev\n");
224 return 0;
227 else
229 r= pci_next_dev(&devind, &vid, &did);
230 if (!r)
232 printf("amddev`find_dev: no next dev\n");
233 return 0;
237 printf("amddev`find_dev: got devind %d, vid 0x%x, did 0x%x\n",
238 devind, vid, did);
240 /* Check capabilities bit in the device status register */
241 status= pci_attr_r16(devind, PCI_SR);
242 if (!(status & PSR_CAPPTR))
243 continue;
245 capptr= (pci_attr_r8(devind, PCI_CAPPTR) & PCI_CP_MASK);
246 while (capptr != 0)
248 type = pci_attr_r8(devind, capptr+CAP_TYPE);
249 next= (pci_attr_r8(devind, capptr+CAP_NEXT) &
250 PCI_CP_MASK);
251 if (type == CAP_T_SECURE_DEV)
253 printf(
254 "amddev`find_dev: found secure device\n");
255 subtype= (pci_attr_r8(devind, capptr+
256 CAP_SD_INFO) & CAP_SD_SUBTYPE_MASK);
257 if (subtype == CAP_T_SD_DEV)
259 printf("amddev`find_dev: AMD DEV\n");
260 pci_reserve(devind);
261 *devindp= devind;
262 *capaddrp= capptr;
263 return 1;
266 capptr= next;
269 return 0;
272 static u32_t read_reg(int function, int index)
274 pci_attr_w32(dev_devind, dev_capptr + DEV_OP, ((function <<
275 DEV_OP_FUNC_SHIFT) | index));
276 return pci_attr_r32(dev_devind, dev_capptr + DEV_DATA);
279 static void write_reg(int function, int index, u32_t value)
281 pci_attr_w32(dev_devind, dev_capptr + DEV_OP, ((function <<
282 DEV_OP_FUNC_SHIFT) | index));
283 pci_attr_w32(dev_devind, dev_capptr + DEV_DATA, value);
286 static void init_domain(int index)
288 size_t size, memsize;
289 phys_bytes busaddr;
291 size= 0x100000 / 8;
292 table= alloc_contig(size, AC_ALIGN4K, &busaddr);
293 if (table == NULL)
294 panic("malloc failed");
295 if (index == 0)
297 memset(table, 0, size);
298 memsize= 0x37000 / 8;
299 printf("memsize = 0x%x / 8\n", memsize*8);
300 memset(table, 0xff, memsize);
302 else
304 memset(table, 0xff, size);
305 memset(table, 0x00, size);
308 printf("init_domain: busaddr = 0x%lx\n", busaddr);
310 write_reg(DEVF_BASE_HI, index, 0);
311 write_reg(DEVF_BASE_LO, index, busaddr | 3);
313 printf("after write: DEVF_BASE_LO: 0x%x\n",
314 read_reg(DEVF_BASE_LO, index));
317 static void init_map(unsigned int ix)
319 u32_t v, dom, busno, unit0, unit1;
321 dom= 1;
322 busno= 7;
323 unit1= 9;
324 unit0= 9;
325 v= (dom << 26) | (dom << 20) | (busno << 12) |
326 (0 << 11) | (unit1 << 6) |
327 (0 << 5) | (unit0 << 0);
328 write_reg(DEVF_MAP, ix, v);
330 printf("after write: DEVF_MAP: 0x%x\n", read_reg(DEVF_MAP, ix));
333 #if 0
334 static int do_add(message *m)
336 int r;
337 endpoint_t proc;
338 vir_bytes start;
339 size_t size;
340 phys_bytes busaddr;
342 proc= m->m_source;
343 start= m->m2_l1;
344 size= m->m2_l2;
346 #if 0
347 printf("amddev`do_add: got request for 0x%x@0x%x from %d\n",
348 size, start, proc);
349 #endif
351 if (start % I386_PAGE_SIZE)
353 printf("amddev`do_add: bad start 0x%x from proc %d\n",
354 start, proc);
355 return EINVAL;
357 if (size % I386_PAGE_SIZE)
359 printf("amddev`do_add: bad size 0x%x from proc %d\n",
360 size, proc);
361 return EINVAL;
363 r= sys_umap_remote(proc, SELF, VM_D, (vir_bytes)start, size, &busaddr);
364 if (r != OK)
366 printf("amddev`do_add: umap failed for 0x%x@0x%x, proc %d\n",
367 size, start, proc);
368 return r;
370 add_range(busaddr, size);
373 #endif
377 static int do_add4pci(const message *m)
379 int r, pci_bus, pci_dev, pci_func;
380 endpoint_t proc;
381 vir_bytes start;
382 size_t size;
383 phys_bytes busaddr;
385 proc= m->m_source;
386 start= m->m2_l1;
387 size= m->m2_l2;
388 pci_bus= m->m1_i1;
389 pci_dev= m->m1_i2;
390 pci_func= m->m1_i3;
392 printf(
393 "amddev`do_add4pci: got request for 0x%x@0x%lx from %d for pci dev %u.%u.%u\n",
394 size, start, proc, pci_bus, pci_dev, pci_func);
396 if (start % I386_PAGE_SIZE)
398 printf("amddev`do_add4pci: bad start 0x%lx from proc %d\n",
399 start, proc);
400 return EINVAL;
402 if (size % I386_PAGE_SIZE)
404 printf("amddev`do_add4pci: bad size 0x%x from proc %d\n",
405 size, proc);
406 return EINVAL;
409 printf("amddev`do_add4pci: should check with PCI\n");
411 r= sys_umap_remote(proc, SELF, VM_D, (vir_bytes)start, size, &busaddr);
412 if (r != OK)
414 printf(
415 "amddev`do_add4pci: umap failed for 0x%x@0x%lx, proc %d: %d\n",
416 size, start, proc, r);
417 return r;
420 #if 0
421 r= vm_adddma(proc, start, size);
422 if (r != 0)
424 r= -errno;
425 printf("amddev`do_add4pci: vm_adddma failed for 0x%x@0x%lx, "
426 "proc %d: %d\n", size, start, proc, r);
427 return r;
429 #endif
431 add_range(busaddr, size);
433 return OK;
437 static void add_range(phys_bytes busaddr, phys_bytes size)
439 phys_bytes o;
441 #if 0
442 printf("add_range: mapping 0x%x@0x%x\n", size, busaddr);
443 #endif
445 for (o= 0; o<size; o += I386_PAGE_SIZE)
447 u32_t bit= (busaddr+o)/I386_PAGE_SIZE;
448 table[bit/8] &= ~(1U << (bit % 8));
452 #if 0
453 static void del_range(phys_bytes busaddr, phys_bytes size)
455 phys_bytes o;
457 #if 0
458 printf("del_range: mapping 0x%x@0x%x\n", size, busaddr);
459 #endif
461 for (o= 0; o<size; o += I386_PAGE_SIZE)
463 u32_t bit= (busaddr+o)/I386_PAGE_SIZE;
464 table[bit/8] |= (1 << (bit % 8));
467 #endif
469 static void report_exceptions(void)
471 u32_t status;
473 status= read_reg(DEVF_ERR_STATUS, 0);
474 if (!(status & 0x80000000))
475 return;
476 printf("amddev: status = 0x%x, addr-lo = 0x%x, addr-hi = 0x%x\n",
477 status, read_reg(DEVF_ERR_ADDR_LO, 0),
478 read_reg(DEVF_ERR_ADDR_HI, 0));
479 write_reg(DEVF_ERR_STATUS, 0, 0);