1*433d6423SLionel Sambuc /*
2*433d6423SLionel Sambuc amddev.c
3*433d6423SLionel Sambuc
4*433d6423SLionel Sambuc Driver for the AMD Device Exclusion Vector (DEV)
5*433d6423SLionel Sambuc */
6*433d6423SLionel Sambuc
7*433d6423SLionel Sambuc #include <minix/driver.h>
8*433d6423SLionel Sambuc #include <minix/config.h>
9*433d6423SLionel Sambuc #include <minix/type.h>
10*433d6423SLionel Sambuc
11*433d6423SLionel Sambuc #include <errno.h>
12*433d6423SLionel Sambuc #include <stdio.h>
13*433d6423SLionel Sambuc #include <stdlib.h>
14*433d6423SLionel Sambuc #include <string.h>
15*433d6423SLionel Sambuc #include <unistd.h>
16*433d6423SLionel Sambuc #include <machine/vm.h>
17*433d6423SLionel Sambuc #include <machine/vmparam.h>
18*433d6423SLionel Sambuc #include <signal.h>
19*433d6423SLionel Sambuc #include <minix/com.h>
20*433d6423SLionel Sambuc #include <minix/const.h>
21*433d6423SLionel Sambuc #include <minix/ipc.h>
22*433d6423SLionel Sambuc #include <minix/syslib.h>
23*433d6423SLionel Sambuc #include <minix/sysutil.h>
24*433d6423SLionel Sambuc #include <minix/endpoint.h>
25*433d6423SLionel Sambuc #include <machine/pci.h>
26*433d6423SLionel Sambuc
27*433d6423SLionel Sambuc /* Offsets from capability pointer */
28*433d6423SLionel Sambuc #define DEV_OP 4 /* Selects control/status register to access */
29*433d6423SLionel Sambuc #define DEV_OP_FUNC_SHIFT 8 /* Function part in OP reg. */
30*433d6423SLionel Sambuc #define DEV_DATA 8 /* Read/write to access reg. selected */
31*433d6423SLionel Sambuc
32*433d6423SLionel Sambuc /* Functions */
33*433d6423SLionel Sambuc #define DEVF_BASE_LO 0
34*433d6423SLionel Sambuc #define DEVF_BASE_HI 1
35*433d6423SLionel Sambuc #define DEVF_MAP 2
36*433d6423SLionel Sambuc #define DEVF_CAP 3
37*433d6423SLionel Sambuc #define DEVF_CAP_MAPS_MASK 0x00ff0000
38*433d6423SLionel Sambuc #define DEVF_CAP_MAPS_SHIFT 16
39*433d6423SLionel Sambuc #define DEVF_CAP_DOMS_MASK 0x0000ff00
40*433d6423SLionel Sambuc #define DEVF_CAP_DOMS_SHIFT 8
41*433d6423SLionel Sambuc #define DEVF_CAP_REV_MASK 0x000000ff
42*433d6423SLionel Sambuc #define DEVF_CAP_REV_SHIFT 0
43*433d6423SLionel Sambuc #define DEVF_CR 4
44*433d6423SLionel Sambuc #define DEVF_ERR_STATUS 5
45*433d6423SLionel Sambuc #define DEVF_ERR_ADDR_LO 6
46*433d6423SLionel Sambuc #define DEVF_ERR_ADDR_HI 7
47*433d6423SLionel Sambuc
48*433d6423SLionel Sambuc static int dev_devind;
49*433d6423SLionel Sambuc static u8_t dev_capptr;
50*433d6423SLionel Sambuc static u8_t *table;
51*433d6423SLionel Sambuc
52*433d6423SLionel Sambuc static int find_dev(int *devindp, u8_t *capaddrp);
53*433d6423SLionel Sambuc static u32_t read_reg(int function, int index);
54*433d6423SLionel Sambuc static void write_reg(int function, int index, u32_t value);
55*433d6423SLionel Sambuc static void init_domain(int index);
56*433d6423SLionel Sambuc static void init_map(unsigned int ix);
57*433d6423SLionel Sambuc static int do_add4pci(const message *m);
58*433d6423SLionel Sambuc static void add_range(phys_bytes busaddr, phys_bytes size);
59*433d6423SLionel Sambuc #if 0
60*433d6423SLionel Sambuc static void del_range(phys_bytes busaddr, phys_bytes size);
61*433d6423SLionel Sambuc static void sef_cb_signal_handler(int signo);
62*433d6423SLionel Sambuc #endif
63*433d6423SLionel Sambuc static void report_exceptions(void);
64*433d6423SLionel Sambuc
65*433d6423SLionel Sambuc /* SEF functions and variables. */
66*433d6423SLionel Sambuc static void sef_local_startup(void);
67*433d6423SLionel Sambuc static int sef_cb_init_fresh(int type, sef_init_info_t *info);
68*433d6423SLionel Sambuc
main(void)69*433d6423SLionel Sambuc int main(void)
70*433d6423SLionel Sambuc {
71*433d6423SLionel Sambuc int r;
72*433d6423SLionel Sambuc message m;
73*433d6423SLionel Sambuc int ipc_status;
74*433d6423SLionel Sambuc
75*433d6423SLionel Sambuc /* SEF local startup. */
76*433d6423SLionel Sambuc sef_local_startup();
77*433d6423SLionel Sambuc
78*433d6423SLionel Sambuc for(;;)
79*433d6423SLionel Sambuc {
80*433d6423SLionel Sambuc report_exceptions();
81*433d6423SLionel Sambuc
82*433d6423SLionel Sambuc r= driver_receive(ANY, &m, &ipc_status);
83*433d6423SLionel Sambuc if (r != OK)
84*433d6423SLionel Sambuc panic("driver_receive failed: %d", r);
85*433d6423SLionel Sambuc if (m.m_type == IOMMU_MAP) {
86*433d6423SLionel Sambuc r= do_add4pci(&m);
87*433d6423SLionel Sambuc m.m_type= r;
88*433d6423SLionel Sambuc ipc_send(m.m_source, &m);
89*433d6423SLionel Sambuc continue;
90*433d6423SLionel Sambuc }
91*433d6423SLionel Sambuc printf("amddev: got message from %d\n", m.m_source);
92*433d6423SLionel Sambuc }
93*433d6423SLionel Sambuc }
94*433d6423SLionel Sambuc
95*433d6423SLionel Sambuc /*===========================================================================*
96*433d6423SLionel Sambuc * sef_local_startup *
97*433d6423SLionel Sambuc *===========================================================================*/
sef_local_startup()98*433d6423SLionel Sambuc static void sef_local_startup()
99*433d6423SLionel Sambuc {
100*433d6423SLionel Sambuc /* Register init callbacks. */
101*433d6423SLionel Sambuc sef_setcb_init_fresh(sef_cb_init_fresh);
102*433d6423SLionel Sambuc sef_setcb_init_lu(sef_cb_init_fresh);
103*433d6423SLionel Sambuc sef_setcb_init_restart(sef_cb_init_fresh);
104*433d6423SLionel Sambuc
105*433d6423SLionel Sambuc #if 0
106*433d6423SLionel Sambuc /* Register signal callbacks. */
107*433d6423SLionel Sambuc sef_setcb_signal_handler(sef_cb_signal_handler);
108*433d6423SLionel Sambuc #endif
109*433d6423SLionel Sambuc
110*433d6423SLionel Sambuc /* Let SEF perform startup. */
111*433d6423SLionel Sambuc sef_startup();
112*433d6423SLionel Sambuc }
113*433d6423SLionel Sambuc
114*433d6423SLionel Sambuc /*===========================================================================*
115*433d6423SLionel Sambuc * sef_cb_init_fresh *
116*433d6423SLionel Sambuc *===========================================================================*/
sef_cb_init_fresh(int UNUSED (type),sef_init_info_t * UNUSED (info))117*433d6423SLionel Sambuc static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
118*433d6423SLionel Sambuc {
119*433d6423SLionel Sambuc /* Initialize the amddev driver. */
120*433d6423SLionel Sambuc int r, n_maps, n_domains, revision;
121*433d6423SLionel Sambuc u16_t flags;
122*433d6423SLionel Sambuc u32_t bits;
123*433d6423SLionel Sambuc
124*433d6423SLionel Sambuc printf("amddev: starting\n");
125*433d6423SLionel Sambuc
126*433d6423SLionel Sambuc r= find_dev(&dev_devind, &dev_capptr);
127*433d6423SLionel Sambuc if (!r)
128*433d6423SLionel Sambuc return r;
129*433d6423SLionel Sambuc flags= pci_attr_r16(dev_devind, dev_capptr+CAP_SD_INFO);
130*433d6423SLionel Sambuc printf("amddev`init: flags = 0x%x\n", flags);
131*433d6423SLionel Sambuc
132*433d6423SLionel Sambuc bits= read_reg(DEVF_CAP, 0);
133*433d6423SLionel Sambuc n_maps= ((bits & DEVF_CAP_MAPS_MASK) >> DEVF_CAP_MAPS_SHIFT);
134*433d6423SLionel Sambuc n_domains= ((bits & DEVF_CAP_DOMS_MASK) >> DEVF_CAP_DOMS_SHIFT);
135*433d6423SLionel Sambuc revision= ((bits & DEVF_CAP_REV_MASK) >> DEVF_CAP_REV_SHIFT);
136*433d6423SLionel Sambuc printf("amddev`init: DEVF_CAP = 0x%x (%d maps, %d domains, rev 0x%x)\n",
137*433d6423SLionel Sambuc bits, n_maps, n_domains, revision);
138*433d6423SLionel Sambuc
139*433d6423SLionel Sambuc printf("status = 0x%x, addr-lo = 0x%x, addr-hi = 0x%x\n",
140*433d6423SLionel Sambuc read_reg(DEVF_ERR_STATUS, 0),
141*433d6423SLionel Sambuc read_reg(DEVF_ERR_ADDR_LO, 0),
142*433d6423SLionel Sambuc read_reg(DEVF_ERR_ADDR_HI, 0));
143*433d6423SLionel Sambuc
144*433d6423SLionel Sambuc init_domain(0);
145*433d6423SLionel Sambuc init_map(0);
146*433d6423SLionel Sambuc #if 0
147*433d6423SLionel Sambuc init_domain(1);
148*433d6423SLionel Sambuc #endif
149*433d6423SLionel Sambuc
150*433d6423SLionel Sambuc write_reg(DEVF_CR, 0, 0x10 | 0x8 | 0x4 | 1);
151*433d6423SLionel Sambuc
152*433d6423SLionel Sambuc printf("after write: DEVF_CR: 0x%x\n", read_reg(DEVF_CR, 0));
153*433d6423SLionel Sambuc
154*433d6423SLionel Sambuc return(OK);
155*433d6423SLionel Sambuc }
156*433d6423SLionel Sambuc
157*433d6423SLionel Sambuc
158*433d6423SLionel Sambuc #if 0
159*433d6423SLionel Sambuc /*===========================================================================*
160*433d6423SLionel Sambuc * sef_cb_signal_handler *
161*433d6423SLionel Sambuc *===========================================================================*/
162*433d6423SLionel Sambuc static void sef_cb_signal_handler(int signo)
163*433d6423SLionel Sambuc {
164*433d6423SLionel Sambuc int r;
165*433d6423SLionel Sambuc endpoint_t proc_e;
166*433d6423SLionel Sambuc phys_bytes base, size;
167*433d6423SLionel Sambuc
168*433d6423SLionel Sambuc /* Only check for termination signal, ignore anything else. */
169*433d6423SLionel Sambuc if (signo != SIGTERM) return;
170*433d6423SLionel Sambuc
171*433d6423SLionel Sambuc for (;;)
172*433d6423SLionel Sambuc {
173*433d6423SLionel Sambuc r= vm_getdma(&proc_e, &base, &size);
174*433d6423SLionel Sambuc if (r == -1)
175*433d6423SLionel Sambuc {
176*433d6423SLionel Sambuc if (errno != -EAGAIN)
177*433d6423SLionel Sambuc {
178*433d6423SLionel Sambuc printf(
179*433d6423SLionel Sambuc "amddev: vm_getdma failed: %d\n",
180*433d6423SLionel Sambuc errno);
181*433d6423SLionel Sambuc }
182*433d6423SLionel Sambuc break;
183*433d6423SLionel Sambuc }
184*433d6423SLionel Sambuc
185*433d6423SLionel Sambuc printf(
186*433d6423SLionel Sambuc "amddev: deleting 0x%lx@0x%lx for proc %d\n",
187*433d6423SLionel Sambuc size, base, proc_e);
188*433d6423SLionel Sambuc del_range(base, size);
189*433d6423SLionel Sambuc r= vm_deldma(proc_e, base, size);
190*433d6423SLionel Sambuc if (r == -1)
191*433d6423SLionel Sambuc {
192*433d6423SLionel Sambuc printf("amddev: vm_deldma failed: %d\n",
193*433d6423SLionel Sambuc errno);
194*433d6423SLionel Sambuc break;
195*433d6423SLionel Sambuc }
196*433d6423SLionel Sambuc }
197*433d6423SLionel Sambuc }
198*433d6423SLionel Sambuc #endif
199*433d6423SLionel Sambuc
200*433d6423SLionel Sambuc /* Returns 0 if no device found, or 1 if a device is found. */
find_dev(devindp,capaddrp)201*433d6423SLionel Sambuc static int find_dev(devindp, capaddrp)
202*433d6423SLionel Sambuc int *devindp;
203*433d6423SLionel Sambuc u8_t *capaddrp;
204*433d6423SLionel Sambuc {
205*433d6423SLionel Sambuc int r, devind, first;
206*433d6423SLionel Sambuc u8_t capptr, type, next, subtype;
207*433d6423SLionel Sambuc u16_t vid, did, status;
208*433d6423SLionel Sambuc
209*433d6423SLionel Sambuc pci_init();
210*433d6423SLionel Sambuc
211*433d6423SLionel Sambuc first= 1;
212*433d6423SLionel Sambuc for(;;)
213*433d6423SLionel Sambuc {
214*433d6423SLionel Sambuc if (first)
215*433d6423SLionel Sambuc {
216*433d6423SLionel Sambuc first= 0;
217*433d6423SLionel Sambuc r= pci_first_dev(&devind, &vid, &did);
218*433d6423SLionel Sambuc if (!r)
219*433d6423SLionel Sambuc {
220*433d6423SLionel Sambuc printf("amddev`find_dev: no first dev\n");
221*433d6423SLionel Sambuc return 0;
222*433d6423SLionel Sambuc }
223*433d6423SLionel Sambuc }
224*433d6423SLionel Sambuc else
225*433d6423SLionel Sambuc {
226*433d6423SLionel Sambuc r= pci_next_dev(&devind, &vid, &did);
227*433d6423SLionel Sambuc if (!r)
228*433d6423SLionel Sambuc {
229*433d6423SLionel Sambuc printf("amddev`find_dev: no next dev\n");
230*433d6423SLionel Sambuc return 0;
231*433d6423SLionel Sambuc }
232*433d6423SLionel Sambuc }
233*433d6423SLionel Sambuc
234*433d6423SLionel Sambuc printf("amddev`find_dev: got devind %d, vid 0x%x, did 0x%x\n",
235*433d6423SLionel Sambuc devind, vid, did);
236*433d6423SLionel Sambuc
237*433d6423SLionel Sambuc /* Check capabilities bit in the device status register */
238*433d6423SLionel Sambuc status= pci_attr_r16(devind, PCI_SR);
239*433d6423SLionel Sambuc if (!(status & PSR_CAPPTR))
240*433d6423SLionel Sambuc continue;
241*433d6423SLionel Sambuc
242*433d6423SLionel Sambuc capptr= (pci_attr_r8(devind, PCI_CAPPTR) & PCI_CP_MASK);
243*433d6423SLionel Sambuc while (capptr != 0)
244*433d6423SLionel Sambuc {
245*433d6423SLionel Sambuc type = pci_attr_r8(devind, capptr+CAP_TYPE);
246*433d6423SLionel Sambuc next= (pci_attr_r8(devind, capptr+CAP_NEXT) &
247*433d6423SLionel Sambuc PCI_CP_MASK);
248*433d6423SLionel Sambuc if (type == CAP_T_SECURE_DEV)
249*433d6423SLionel Sambuc {
250*433d6423SLionel Sambuc printf(
251*433d6423SLionel Sambuc "amddev`find_dev: found secure device\n");
252*433d6423SLionel Sambuc subtype= (pci_attr_r8(devind, capptr+
253*433d6423SLionel Sambuc CAP_SD_INFO) & CAP_SD_SUBTYPE_MASK);
254*433d6423SLionel Sambuc if (subtype == CAP_T_SD_DEV)
255*433d6423SLionel Sambuc {
256*433d6423SLionel Sambuc printf("amddev`find_dev: AMD DEV\n");
257*433d6423SLionel Sambuc pci_reserve(devind);
258*433d6423SLionel Sambuc *devindp= devind;
259*433d6423SLionel Sambuc *capaddrp= capptr;
260*433d6423SLionel Sambuc return 1;
261*433d6423SLionel Sambuc }
262*433d6423SLionel Sambuc }
263*433d6423SLionel Sambuc capptr= next;
264*433d6423SLionel Sambuc }
265*433d6423SLionel Sambuc }
266*433d6423SLionel Sambuc return 0;
267*433d6423SLionel Sambuc }
268*433d6423SLionel Sambuc
read_reg(int function,int index)269*433d6423SLionel Sambuc static u32_t read_reg(int function, int index)
270*433d6423SLionel Sambuc {
271*433d6423SLionel Sambuc pci_attr_w32(dev_devind, dev_capptr + DEV_OP, ((function <<
272*433d6423SLionel Sambuc DEV_OP_FUNC_SHIFT) | index));
273*433d6423SLionel Sambuc return pci_attr_r32(dev_devind, dev_capptr + DEV_DATA);
274*433d6423SLionel Sambuc }
275*433d6423SLionel Sambuc
write_reg(int function,int index,u32_t value)276*433d6423SLionel Sambuc static void write_reg(int function, int index, u32_t value)
277*433d6423SLionel Sambuc {
278*433d6423SLionel Sambuc pci_attr_w32(dev_devind, dev_capptr + DEV_OP, ((function <<
279*433d6423SLionel Sambuc DEV_OP_FUNC_SHIFT) | index));
280*433d6423SLionel Sambuc pci_attr_w32(dev_devind, dev_capptr + DEV_DATA, value);
281*433d6423SLionel Sambuc }
282*433d6423SLionel Sambuc
init_domain(int index)283*433d6423SLionel Sambuc static void init_domain(int index)
284*433d6423SLionel Sambuc {
285*433d6423SLionel Sambuc size_t size, memsize;
286*433d6423SLionel Sambuc phys_bytes busaddr;
287*433d6423SLionel Sambuc
288*433d6423SLionel Sambuc size= 0x100000 / 8;
289*433d6423SLionel Sambuc table= alloc_contig(size, AC_ALIGN4K, &busaddr);
290*433d6423SLionel Sambuc if (table == NULL)
291*433d6423SLionel Sambuc panic("malloc failed");
292*433d6423SLionel Sambuc if (index == 0)
293*433d6423SLionel Sambuc {
294*433d6423SLionel Sambuc memset(table, 0, size);
295*433d6423SLionel Sambuc memsize= 0x37000 / 8;
296*433d6423SLionel Sambuc printf("memsize = 0x%x / 8\n", memsize*8);
297*433d6423SLionel Sambuc memset(table, 0xff, memsize);
298*433d6423SLionel Sambuc }
299*433d6423SLionel Sambuc else
300*433d6423SLionel Sambuc {
301*433d6423SLionel Sambuc memset(table, 0xff, size);
302*433d6423SLionel Sambuc memset(table, 0x00, size);
303*433d6423SLionel Sambuc }
304*433d6423SLionel Sambuc
305*433d6423SLionel Sambuc printf("init_domain: busaddr = 0x%lx\n", busaddr);
306*433d6423SLionel Sambuc
307*433d6423SLionel Sambuc write_reg(DEVF_BASE_HI, index, 0);
308*433d6423SLionel Sambuc write_reg(DEVF_BASE_LO, index, busaddr | 3);
309*433d6423SLionel Sambuc
310*433d6423SLionel Sambuc printf("after write: DEVF_BASE_LO: 0x%x\n",
311*433d6423SLionel Sambuc read_reg(DEVF_BASE_LO, index));
312*433d6423SLionel Sambuc }
313*433d6423SLionel Sambuc
init_map(unsigned int ix)314*433d6423SLionel Sambuc static void init_map(unsigned int ix)
315*433d6423SLionel Sambuc {
316*433d6423SLionel Sambuc u32_t v, dom, busno, unit0, unit1;
317*433d6423SLionel Sambuc
318*433d6423SLionel Sambuc dom= 1;
319*433d6423SLionel Sambuc busno= 7;
320*433d6423SLionel Sambuc unit1= 9;
321*433d6423SLionel Sambuc unit0= 9;
322*433d6423SLionel Sambuc v= (dom << 26) | (dom << 20) | (busno << 12) |
323*433d6423SLionel Sambuc (0 << 11) | (unit1 << 6) |
324*433d6423SLionel Sambuc (0 << 5) | (unit0 << 0);
325*433d6423SLionel Sambuc write_reg(DEVF_MAP, ix, v);
326*433d6423SLionel Sambuc
327*433d6423SLionel Sambuc printf("after write: DEVF_MAP: 0x%x\n", read_reg(DEVF_MAP, ix));
328*433d6423SLionel Sambuc }
329*433d6423SLionel Sambuc
330*433d6423SLionel Sambuc #if 0
331*433d6423SLionel Sambuc static int do_add(message *m)
332*433d6423SLionel Sambuc {
333*433d6423SLionel Sambuc int r;
334*433d6423SLionel Sambuc endpoint_t proc;
335*433d6423SLionel Sambuc vir_bytes start;
336*433d6423SLionel Sambuc size_t size;
337*433d6423SLionel Sambuc phys_bytes busaddr;
338*433d6423SLionel Sambuc
339*433d6423SLionel Sambuc proc= m->m_source;
340*433d6423SLionel Sambuc start= m->m2_l1;
341*433d6423SLionel Sambuc size= m->m2_l2;
342*433d6423SLionel Sambuc
343*433d6423SLionel Sambuc #if 0
344*433d6423SLionel Sambuc printf("amddev`do_add: got request for 0x%x@0x%x from %d\n",
345*433d6423SLionel Sambuc size, start, proc);
346*433d6423SLionel Sambuc #endif
347*433d6423SLionel Sambuc
348*433d6423SLionel Sambuc if (start % PAGE_SIZE)
349*433d6423SLionel Sambuc {
350*433d6423SLionel Sambuc printf("amddev`do_add: bad start 0x%x from proc %d\n",
351*433d6423SLionel Sambuc start, proc);
352*433d6423SLionel Sambuc return EINVAL;
353*433d6423SLionel Sambuc }
354*433d6423SLionel Sambuc if (size % PAGE_SIZE)
355*433d6423SLionel Sambuc {
356*433d6423SLionel Sambuc printf("amddev`do_add: bad size 0x%x from proc %d\n",
357*433d6423SLionel Sambuc size, proc);
358*433d6423SLionel Sambuc return EINVAL;
359*433d6423SLionel Sambuc }
360*433d6423SLionel Sambuc r= sys_umap_remote(proc, SELF, VM_D, (vir_bytes)start, size, &busaddr);
361*433d6423SLionel Sambuc if (r != OK)
362*433d6423SLionel Sambuc {
363*433d6423SLionel Sambuc printf("amddev`do_add: umap failed for 0x%x@0x%x, proc %d\n",
364*433d6423SLionel Sambuc size, start, proc);
365*433d6423SLionel Sambuc return r;
366*433d6423SLionel Sambuc }
367*433d6423SLionel Sambuc add_range(busaddr, size);
368*433d6423SLionel Sambuc
369*433d6423SLionel Sambuc }
370*433d6423SLionel Sambuc #endif
371*433d6423SLionel Sambuc
372*433d6423SLionel Sambuc
373*433d6423SLionel Sambuc
do_add4pci(const message * m)374*433d6423SLionel Sambuc static int do_add4pci(const message *m)
375*433d6423SLionel Sambuc {
376*433d6423SLionel Sambuc int r, pci_bus, pci_dev, pci_func;
377*433d6423SLionel Sambuc endpoint_t proc;
378*433d6423SLionel Sambuc vir_bytes start;
379*433d6423SLionel Sambuc size_t size;
380*433d6423SLionel Sambuc phys_bytes busaddr;
381*433d6423SLionel Sambuc
382*433d6423SLionel Sambuc proc= m->m_source;
383*433d6423SLionel Sambuc start= m->m2_l1;
384*433d6423SLionel Sambuc size= m->m2_l2;
385*433d6423SLionel Sambuc pci_bus= m->m1_i1;
386*433d6423SLionel Sambuc pci_dev= m->m1_i2;
387*433d6423SLionel Sambuc pci_func= m->m1_i3;
388*433d6423SLionel Sambuc
389*433d6423SLionel Sambuc printf(
390*433d6423SLionel Sambuc "amddev`do_add4pci: got request for 0x%x@0x%lx from %d for pci dev %u.%u.%u\n",
391*433d6423SLionel Sambuc size, start, proc, pci_bus, pci_dev, pci_func);
392*433d6423SLionel Sambuc
393*433d6423SLionel Sambuc if (start % PAGE_SIZE)
394*433d6423SLionel Sambuc {
395*433d6423SLionel Sambuc printf("amddev`do_add4pci: bad start 0x%lx from proc %d\n",
396*433d6423SLionel Sambuc start, proc);
397*433d6423SLionel Sambuc return EINVAL;
398*433d6423SLionel Sambuc }
399*433d6423SLionel Sambuc if (size % PAGE_SIZE)
400*433d6423SLionel Sambuc {
401*433d6423SLionel Sambuc printf("amddev`do_add4pci: bad size 0x%x from proc %d\n",
402*433d6423SLionel Sambuc size, proc);
403*433d6423SLionel Sambuc return EINVAL;
404*433d6423SLionel Sambuc }
405*433d6423SLionel Sambuc
406*433d6423SLionel Sambuc printf("amddev`do_add4pci: should check with PCI\n");
407*433d6423SLionel Sambuc
408*433d6423SLionel Sambuc r= sys_umap_remote(proc, SELF, VM_D, (vir_bytes)start, size, &busaddr);
409*433d6423SLionel Sambuc if (r != OK)
410*433d6423SLionel Sambuc {
411*433d6423SLionel Sambuc printf(
412*433d6423SLionel Sambuc "amddev`do_add4pci: umap failed for 0x%x@0x%lx, proc %d: %d\n",
413*433d6423SLionel Sambuc size, start, proc, r);
414*433d6423SLionel Sambuc return r;
415*433d6423SLionel Sambuc }
416*433d6423SLionel Sambuc
417*433d6423SLionel Sambuc #if 0
418*433d6423SLionel Sambuc r= vm_adddma(proc, start, size);
419*433d6423SLionel Sambuc if (r != 0)
420*433d6423SLionel Sambuc {
421*433d6423SLionel Sambuc r= -errno;
422*433d6423SLionel Sambuc printf("amddev`do_add4pci: vm_adddma failed for 0x%x@0x%lx, "
423*433d6423SLionel Sambuc "proc %d: %d\n", size, start, proc, r);
424*433d6423SLionel Sambuc return r;
425*433d6423SLionel Sambuc }
426*433d6423SLionel Sambuc #endif
427*433d6423SLionel Sambuc
428*433d6423SLionel Sambuc add_range(busaddr, size);
429*433d6423SLionel Sambuc
430*433d6423SLionel Sambuc return OK;
431*433d6423SLionel Sambuc }
432*433d6423SLionel Sambuc
433*433d6423SLionel Sambuc
add_range(phys_bytes busaddr,phys_bytes size)434*433d6423SLionel Sambuc static void add_range(phys_bytes busaddr, phys_bytes size)
435*433d6423SLionel Sambuc {
436*433d6423SLionel Sambuc phys_bytes o;
437*433d6423SLionel Sambuc
438*433d6423SLionel Sambuc #if 0
439*433d6423SLionel Sambuc printf("add_range: mapping 0x%x@0x%x\n", size, busaddr);
440*433d6423SLionel Sambuc #endif
441*433d6423SLionel Sambuc
442*433d6423SLionel Sambuc for (o= 0; o<size; o += PAGE_SIZE)
443*433d6423SLionel Sambuc {
444*433d6423SLionel Sambuc u32_t bit= (busaddr+o)/PAGE_SIZE;
445*433d6423SLionel Sambuc table[bit/8] &= ~(1U << (bit % 8));
446*433d6423SLionel Sambuc }
447*433d6423SLionel Sambuc }
448*433d6423SLionel Sambuc
449*433d6423SLionel Sambuc #if 0
450*433d6423SLionel Sambuc static void del_range(phys_bytes busaddr, phys_bytes size)
451*433d6423SLionel Sambuc {
452*433d6423SLionel Sambuc phys_bytes o;
453*433d6423SLionel Sambuc
454*433d6423SLionel Sambuc #if 0
455*433d6423SLionel Sambuc printf("del_range: mapping 0x%x@0x%x\n", size, busaddr);
456*433d6423SLionel Sambuc #endif
457*433d6423SLionel Sambuc
458*433d6423SLionel Sambuc for (o= 0; o<size; o += PAGE_SIZE)
459*433d6423SLionel Sambuc {
460*433d6423SLionel Sambuc u32_t bit= (busaddr+o)/PAGE_SIZE;
461*433d6423SLionel Sambuc table[bit/8] |= (1 << (bit % 8));
462*433d6423SLionel Sambuc }
463*433d6423SLionel Sambuc }
464*433d6423SLionel Sambuc #endif
465*433d6423SLionel Sambuc
report_exceptions(void)466*433d6423SLionel Sambuc static void report_exceptions(void)
467*433d6423SLionel Sambuc {
468*433d6423SLionel Sambuc u32_t status;
469*433d6423SLionel Sambuc
470*433d6423SLionel Sambuc status= read_reg(DEVF_ERR_STATUS, 0);
471*433d6423SLionel Sambuc if (!(status & 0x80000000))
472*433d6423SLionel Sambuc return;
473*433d6423SLionel Sambuc printf("amddev: status = 0x%x, addr-lo = 0x%x, addr-hi = 0x%x\n",
474*433d6423SLionel Sambuc status, read_reg(DEVF_ERR_ADDR_LO, 0),
475*433d6423SLionel Sambuc read_reg(DEVF_ERR_ADDR_HI, 0));
476*433d6423SLionel Sambuc write_reg(DEVF_ERR_STATUS, 0, 0);
477*433d6423SLionel Sambuc }
478