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 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 *===========================================================================*/ 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 /* Register live update callbacks. */ 106*433d6423SLionel Sambuc sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); 107*433d6423SLionel Sambuc sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard); 108*433d6423SLionel Sambuc 109*433d6423SLionel Sambuc #if 0 110*433d6423SLionel Sambuc /* Register signal callbacks. */ 111*433d6423SLionel Sambuc sef_setcb_signal_handler(sef_cb_signal_handler); 112*433d6423SLionel Sambuc #endif 113*433d6423SLionel Sambuc 114*433d6423SLionel Sambuc /* Let SEF perform startup. */ 115*433d6423SLionel Sambuc sef_startup(); 116*433d6423SLionel Sambuc } 117*433d6423SLionel Sambuc 118*433d6423SLionel Sambuc /*===========================================================================* 119*433d6423SLionel Sambuc * sef_cb_init_fresh * 120*433d6423SLionel Sambuc *===========================================================================*/ 121*433d6423SLionel Sambuc static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) 122*433d6423SLionel Sambuc { 123*433d6423SLionel Sambuc /* Initialize the amddev driver. */ 124*433d6423SLionel Sambuc int r, n_maps, n_domains, revision; 125*433d6423SLionel Sambuc u16_t flags; 126*433d6423SLionel Sambuc u32_t bits; 127*433d6423SLionel Sambuc 128*433d6423SLionel Sambuc printf("amddev: starting\n"); 129*433d6423SLionel Sambuc 130*433d6423SLionel Sambuc r= find_dev(&dev_devind, &dev_capptr); 131*433d6423SLionel Sambuc if (!r) 132*433d6423SLionel Sambuc return r; 133*433d6423SLionel Sambuc flags= pci_attr_r16(dev_devind, dev_capptr+CAP_SD_INFO); 134*433d6423SLionel Sambuc printf("amddev`init: flags = 0x%x\n", flags); 135*433d6423SLionel Sambuc 136*433d6423SLionel Sambuc bits= read_reg(DEVF_CAP, 0); 137*433d6423SLionel Sambuc n_maps= ((bits & DEVF_CAP_MAPS_MASK) >> DEVF_CAP_MAPS_SHIFT); 138*433d6423SLionel Sambuc n_domains= ((bits & DEVF_CAP_DOMS_MASK) >> DEVF_CAP_DOMS_SHIFT); 139*433d6423SLionel Sambuc revision= ((bits & DEVF_CAP_REV_MASK) >> DEVF_CAP_REV_SHIFT); 140*433d6423SLionel Sambuc printf("amddev`init: DEVF_CAP = 0x%x (%d maps, %d domains, rev 0x%x)\n", 141*433d6423SLionel Sambuc bits, n_maps, n_domains, revision); 142*433d6423SLionel Sambuc 143*433d6423SLionel Sambuc printf("status = 0x%x, addr-lo = 0x%x, addr-hi = 0x%x\n", 144*433d6423SLionel Sambuc read_reg(DEVF_ERR_STATUS, 0), 145*433d6423SLionel Sambuc read_reg(DEVF_ERR_ADDR_LO, 0), 146*433d6423SLionel Sambuc read_reg(DEVF_ERR_ADDR_HI, 0)); 147*433d6423SLionel Sambuc 148*433d6423SLionel Sambuc init_domain(0); 149*433d6423SLionel Sambuc init_map(0); 150*433d6423SLionel Sambuc #if 0 151*433d6423SLionel Sambuc init_domain(1); 152*433d6423SLionel Sambuc #endif 153*433d6423SLionel Sambuc 154*433d6423SLionel Sambuc write_reg(DEVF_CR, 0, 0x10 | 0x8 | 0x4 | 1); 155*433d6423SLionel Sambuc 156*433d6423SLionel Sambuc printf("after write: DEVF_CR: 0x%x\n", read_reg(DEVF_CR, 0)); 157*433d6423SLionel Sambuc 158*433d6423SLionel Sambuc return(OK); 159*433d6423SLionel Sambuc } 160*433d6423SLionel Sambuc 161*433d6423SLionel Sambuc 162*433d6423SLionel Sambuc #if 0 163*433d6423SLionel Sambuc /*===========================================================================* 164*433d6423SLionel Sambuc * sef_cb_signal_handler * 165*433d6423SLionel Sambuc *===========================================================================*/ 166*433d6423SLionel Sambuc static void sef_cb_signal_handler(int signo) 167*433d6423SLionel Sambuc { 168*433d6423SLionel Sambuc int r; 169*433d6423SLionel Sambuc endpoint_t proc_e; 170*433d6423SLionel Sambuc phys_bytes base, size; 171*433d6423SLionel Sambuc 172*433d6423SLionel Sambuc /* Only check for termination signal, ignore anything else. */ 173*433d6423SLionel Sambuc if (signo != SIGTERM) return; 174*433d6423SLionel Sambuc 175*433d6423SLionel Sambuc for (;;) 176*433d6423SLionel Sambuc { 177*433d6423SLionel Sambuc r= vm_getdma(&proc_e, &base, &size); 178*433d6423SLionel Sambuc if (r == -1) 179*433d6423SLionel Sambuc { 180*433d6423SLionel Sambuc if (errno != -EAGAIN) 181*433d6423SLionel Sambuc { 182*433d6423SLionel Sambuc printf( 183*433d6423SLionel Sambuc "amddev: vm_getdma failed: %d\n", 184*433d6423SLionel Sambuc errno); 185*433d6423SLionel Sambuc } 186*433d6423SLionel Sambuc break; 187*433d6423SLionel Sambuc } 188*433d6423SLionel Sambuc 189*433d6423SLionel Sambuc printf( 190*433d6423SLionel Sambuc "amddev: deleting 0x%lx@0x%lx for proc %d\n", 191*433d6423SLionel Sambuc size, base, proc_e); 192*433d6423SLionel Sambuc del_range(base, size); 193*433d6423SLionel Sambuc r= vm_deldma(proc_e, base, size); 194*433d6423SLionel Sambuc if (r == -1) 195*433d6423SLionel Sambuc { 196*433d6423SLionel Sambuc printf("amddev: vm_deldma failed: %d\n", 197*433d6423SLionel Sambuc errno); 198*433d6423SLionel Sambuc break; 199*433d6423SLionel Sambuc } 200*433d6423SLionel Sambuc } 201*433d6423SLionel Sambuc } 202*433d6423SLionel Sambuc #endif 203*433d6423SLionel Sambuc 204*433d6423SLionel Sambuc /* Returns 0 if no device found, or 1 if a device is found. */ 205*433d6423SLionel Sambuc static int find_dev(devindp, capaddrp) 206*433d6423SLionel Sambuc int *devindp; 207*433d6423SLionel Sambuc u8_t *capaddrp; 208*433d6423SLionel Sambuc { 209*433d6423SLionel Sambuc int r, devind, first; 210*433d6423SLionel Sambuc u8_t capptr, type, next, subtype; 211*433d6423SLionel Sambuc u16_t vid, did, status; 212*433d6423SLionel Sambuc 213*433d6423SLionel Sambuc pci_init(); 214*433d6423SLionel Sambuc 215*433d6423SLionel Sambuc first= 1; 216*433d6423SLionel Sambuc for(;;) 217*433d6423SLionel Sambuc { 218*433d6423SLionel Sambuc if (first) 219*433d6423SLionel Sambuc { 220*433d6423SLionel Sambuc first= 0; 221*433d6423SLionel Sambuc r= pci_first_dev(&devind, &vid, &did); 222*433d6423SLionel Sambuc if (!r) 223*433d6423SLionel Sambuc { 224*433d6423SLionel Sambuc printf("amddev`find_dev: no first dev\n"); 225*433d6423SLionel Sambuc return 0; 226*433d6423SLionel Sambuc } 227*433d6423SLionel Sambuc } 228*433d6423SLionel Sambuc else 229*433d6423SLionel Sambuc { 230*433d6423SLionel Sambuc r= pci_next_dev(&devind, &vid, &did); 231*433d6423SLionel Sambuc if (!r) 232*433d6423SLionel Sambuc { 233*433d6423SLionel Sambuc printf("amddev`find_dev: no next dev\n"); 234*433d6423SLionel Sambuc return 0; 235*433d6423SLionel Sambuc } 236*433d6423SLionel Sambuc } 237*433d6423SLionel Sambuc 238*433d6423SLionel Sambuc printf("amddev`find_dev: got devind %d, vid 0x%x, did 0x%x\n", 239*433d6423SLionel Sambuc devind, vid, did); 240*433d6423SLionel Sambuc 241*433d6423SLionel Sambuc /* Check capabilities bit in the device status register */ 242*433d6423SLionel Sambuc status= pci_attr_r16(devind, PCI_SR); 243*433d6423SLionel Sambuc if (!(status & PSR_CAPPTR)) 244*433d6423SLionel Sambuc continue; 245*433d6423SLionel Sambuc 246*433d6423SLionel Sambuc capptr= (pci_attr_r8(devind, PCI_CAPPTR) & PCI_CP_MASK); 247*433d6423SLionel Sambuc while (capptr != 0) 248*433d6423SLionel Sambuc { 249*433d6423SLionel Sambuc type = pci_attr_r8(devind, capptr+CAP_TYPE); 250*433d6423SLionel Sambuc next= (pci_attr_r8(devind, capptr+CAP_NEXT) & 251*433d6423SLionel Sambuc PCI_CP_MASK); 252*433d6423SLionel Sambuc if (type == CAP_T_SECURE_DEV) 253*433d6423SLionel Sambuc { 254*433d6423SLionel Sambuc printf( 255*433d6423SLionel Sambuc "amddev`find_dev: found secure device\n"); 256*433d6423SLionel Sambuc subtype= (pci_attr_r8(devind, capptr+ 257*433d6423SLionel Sambuc CAP_SD_INFO) & CAP_SD_SUBTYPE_MASK); 258*433d6423SLionel Sambuc if (subtype == CAP_T_SD_DEV) 259*433d6423SLionel Sambuc { 260*433d6423SLionel Sambuc printf("amddev`find_dev: AMD DEV\n"); 261*433d6423SLionel Sambuc pci_reserve(devind); 262*433d6423SLionel Sambuc *devindp= devind; 263*433d6423SLionel Sambuc *capaddrp= capptr; 264*433d6423SLionel Sambuc return 1; 265*433d6423SLionel Sambuc } 266*433d6423SLionel Sambuc } 267*433d6423SLionel Sambuc capptr= next; 268*433d6423SLionel Sambuc } 269*433d6423SLionel Sambuc } 270*433d6423SLionel Sambuc return 0; 271*433d6423SLionel Sambuc } 272*433d6423SLionel Sambuc 273*433d6423SLionel Sambuc static u32_t read_reg(int function, int index) 274*433d6423SLionel Sambuc { 275*433d6423SLionel Sambuc pci_attr_w32(dev_devind, dev_capptr + DEV_OP, ((function << 276*433d6423SLionel Sambuc DEV_OP_FUNC_SHIFT) | index)); 277*433d6423SLionel Sambuc return pci_attr_r32(dev_devind, dev_capptr + DEV_DATA); 278*433d6423SLionel Sambuc } 279*433d6423SLionel Sambuc 280*433d6423SLionel Sambuc static void write_reg(int function, int index, u32_t value) 281*433d6423SLionel Sambuc { 282*433d6423SLionel Sambuc pci_attr_w32(dev_devind, dev_capptr + DEV_OP, ((function << 283*433d6423SLionel Sambuc DEV_OP_FUNC_SHIFT) | index)); 284*433d6423SLionel Sambuc pci_attr_w32(dev_devind, dev_capptr + DEV_DATA, value); 285*433d6423SLionel Sambuc } 286*433d6423SLionel Sambuc 287*433d6423SLionel Sambuc static void init_domain(int index) 288*433d6423SLionel Sambuc { 289*433d6423SLionel Sambuc size_t size, memsize; 290*433d6423SLionel Sambuc phys_bytes busaddr; 291*433d6423SLionel Sambuc 292*433d6423SLionel Sambuc size= 0x100000 / 8; 293*433d6423SLionel Sambuc table= alloc_contig(size, AC_ALIGN4K, &busaddr); 294*433d6423SLionel Sambuc if (table == NULL) 295*433d6423SLionel Sambuc panic("malloc failed"); 296*433d6423SLionel Sambuc if (index == 0) 297*433d6423SLionel Sambuc { 298*433d6423SLionel Sambuc memset(table, 0, size); 299*433d6423SLionel Sambuc memsize= 0x37000 / 8; 300*433d6423SLionel Sambuc printf("memsize = 0x%x / 8\n", memsize*8); 301*433d6423SLionel Sambuc memset(table, 0xff, memsize); 302*433d6423SLionel Sambuc } 303*433d6423SLionel Sambuc else 304*433d6423SLionel Sambuc { 305*433d6423SLionel Sambuc memset(table, 0xff, size); 306*433d6423SLionel Sambuc memset(table, 0x00, size); 307*433d6423SLionel Sambuc } 308*433d6423SLionel Sambuc 309*433d6423SLionel Sambuc printf("init_domain: busaddr = 0x%lx\n", busaddr); 310*433d6423SLionel Sambuc 311*433d6423SLionel Sambuc write_reg(DEVF_BASE_HI, index, 0); 312*433d6423SLionel Sambuc write_reg(DEVF_BASE_LO, index, busaddr | 3); 313*433d6423SLionel Sambuc 314*433d6423SLionel Sambuc printf("after write: DEVF_BASE_LO: 0x%x\n", 315*433d6423SLionel Sambuc read_reg(DEVF_BASE_LO, index)); 316*433d6423SLionel Sambuc } 317*433d6423SLionel Sambuc 318*433d6423SLionel Sambuc static void init_map(unsigned int ix) 319*433d6423SLionel Sambuc { 320*433d6423SLionel Sambuc u32_t v, dom, busno, unit0, unit1; 321*433d6423SLionel Sambuc 322*433d6423SLionel Sambuc dom= 1; 323*433d6423SLionel Sambuc busno= 7; 324*433d6423SLionel Sambuc unit1= 9; 325*433d6423SLionel Sambuc unit0= 9; 326*433d6423SLionel Sambuc v= (dom << 26) | (dom << 20) | (busno << 12) | 327*433d6423SLionel Sambuc (0 << 11) | (unit1 << 6) | 328*433d6423SLionel Sambuc (0 << 5) | (unit0 << 0); 329*433d6423SLionel Sambuc write_reg(DEVF_MAP, ix, v); 330*433d6423SLionel Sambuc 331*433d6423SLionel Sambuc printf("after write: DEVF_MAP: 0x%x\n", read_reg(DEVF_MAP, ix)); 332*433d6423SLionel Sambuc } 333*433d6423SLionel Sambuc 334*433d6423SLionel Sambuc #if 0 335*433d6423SLionel Sambuc static int do_add(message *m) 336*433d6423SLionel Sambuc { 337*433d6423SLionel Sambuc int r; 338*433d6423SLionel Sambuc endpoint_t proc; 339*433d6423SLionel Sambuc vir_bytes start; 340*433d6423SLionel Sambuc size_t size; 341*433d6423SLionel Sambuc phys_bytes busaddr; 342*433d6423SLionel Sambuc 343*433d6423SLionel Sambuc proc= m->m_source; 344*433d6423SLionel Sambuc start= m->m2_l1; 345*433d6423SLionel Sambuc size= m->m2_l2; 346*433d6423SLionel Sambuc 347*433d6423SLionel Sambuc #if 0 348*433d6423SLionel Sambuc printf("amddev`do_add: got request for 0x%x@0x%x from %d\n", 349*433d6423SLionel Sambuc size, start, proc); 350*433d6423SLionel Sambuc #endif 351*433d6423SLionel Sambuc 352*433d6423SLionel Sambuc if (start % PAGE_SIZE) 353*433d6423SLionel Sambuc { 354*433d6423SLionel Sambuc printf("amddev`do_add: bad start 0x%x from proc %d\n", 355*433d6423SLionel Sambuc start, proc); 356*433d6423SLionel Sambuc return EINVAL; 357*433d6423SLionel Sambuc } 358*433d6423SLionel Sambuc if (size % PAGE_SIZE) 359*433d6423SLionel Sambuc { 360*433d6423SLionel Sambuc printf("amddev`do_add: bad size 0x%x from proc %d\n", 361*433d6423SLionel Sambuc size, proc); 362*433d6423SLionel Sambuc return EINVAL; 363*433d6423SLionel Sambuc } 364*433d6423SLionel Sambuc r= sys_umap_remote(proc, SELF, VM_D, (vir_bytes)start, size, &busaddr); 365*433d6423SLionel Sambuc if (r != OK) 366*433d6423SLionel Sambuc { 367*433d6423SLionel Sambuc printf("amddev`do_add: umap failed for 0x%x@0x%x, proc %d\n", 368*433d6423SLionel Sambuc size, start, proc); 369*433d6423SLionel Sambuc return r; 370*433d6423SLionel Sambuc } 371*433d6423SLionel Sambuc add_range(busaddr, size); 372*433d6423SLionel Sambuc 373*433d6423SLionel Sambuc } 374*433d6423SLionel Sambuc #endif 375*433d6423SLionel Sambuc 376*433d6423SLionel Sambuc 377*433d6423SLionel Sambuc 378*433d6423SLionel Sambuc static int do_add4pci(const message *m) 379*433d6423SLionel Sambuc { 380*433d6423SLionel Sambuc int r, pci_bus, pci_dev, pci_func; 381*433d6423SLionel Sambuc endpoint_t proc; 382*433d6423SLionel Sambuc vir_bytes start; 383*433d6423SLionel Sambuc size_t size; 384*433d6423SLionel Sambuc phys_bytes busaddr; 385*433d6423SLionel Sambuc 386*433d6423SLionel Sambuc proc= m->m_source; 387*433d6423SLionel Sambuc start= m->m2_l1; 388*433d6423SLionel Sambuc size= m->m2_l2; 389*433d6423SLionel Sambuc pci_bus= m->m1_i1; 390*433d6423SLionel Sambuc pci_dev= m->m1_i2; 391*433d6423SLionel Sambuc pci_func= m->m1_i3; 392*433d6423SLionel Sambuc 393*433d6423SLionel Sambuc printf( 394*433d6423SLionel Sambuc "amddev`do_add4pci: got request for 0x%x@0x%lx from %d for pci dev %u.%u.%u\n", 395*433d6423SLionel Sambuc size, start, proc, pci_bus, pci_dev, pci_func); 396*433d6423SLionel Sambuc 397*433d6423SLionel Sambuc if (start % PAGE_SIZE) 398*433d6423SLionel Sambuc { 399*433d6423SLionel Sambuc printf("amddev`do_add4pci: bad start 0x%lx from proc %d\n", 400*433d6423SLionel Sambuc start, proc); 401*433d6423SLionel Sambuc return EINVAL; 402*433d6423SLionel Sambuc } 403*433d6423SLionel Sambuc if (size % PAGE_SIZE) 404*433d6423SLionel Sambuc { 405*433d6423SLionel Sambuc printf("amddev`do_add4pci: bad size 0x%x from proc %d\n", 406*433d6423SLionel Sambuc size, proc); 407*433d6423SLionel Sambuc return EINVAL; 408*433d6423SLionel Sambuc } 409*433d6423SLionel Sambuc 410*433d6423SLionel Sambuc printf("amddev`do_add4pci: should check with PCI\n"); 411*433d6423SLionel Sambuc 412*433d6423SLionel Sambuc r= sys_umap_remote(proc, SELF, VM_D, (vir_bytes)start, size, &busaddr); 413*433d6423SLionel Sambuc if (r != OK) 414*433d6423SLionel Sambuc { 415*433d6423SLionel Sambuc printf( 416*433d6423SLionel Sambuc "amddev`do_add4pci: umap failed for 0x%x@0x%lx, proc %d: %d\n", 417*433d6423SLionel Sambuc size, start, proc, r); 418*433d6423SLionel Sambuc return r; 419*433d6423SLionel Sambuc } 420*433d6423SLionel Sambuc 421*433d6423SLionel Sambuc #if 0 422*433d6423SLionel Sambuc r= vm_adddma(proc, start, size); 423*433d6423SLionel Sambuc if (r != 0) 424*433d6423SLionel Sambuc { 425*433d6423SLionel Sambuc r= -errno; 426*433d6423SLionel Sambuc printf("amddev`do_add4pci: vm_adddma failed for 0x%x@0x%lx, " 427*433d6423SLionel Sambuc "proc %d: %d\n", size, start, proc, r); 428*433d6423SLionel Sambuc return r; 429*433d6423SLionel Sambuc } 430*433d6423SLionel Sambuc #endif 431*433d6423SLionel Sambuc 432*433d6423SLionel Sambuc add_range(busaddr, size); 433*433d6423SLionel Sambuc 434*433d6423SLionel Sambuc return OK; 435*433d6423SLionel Sambuc } 436*433d6423SLionel Sambuc 437*433d6423SLionel Sambuc 438*433d6423SLionel Sambuc static void add_range(phys_bytes busaddr, phys_bytes size) 439*433d6423SLionel Sambuc { 440*433d6423SLionel Sambuc phys_bytes o; 441*433d6423SLionel Sambuc 442*433d6423SLionel Sambuc #if 0 443*433d6423SLionel Sambuc printf("add_range: mapping 0x%x@0x%x\n", size, busaddr); 444*433d6423SLionel Sambuc #endif 445*433d6423SLionel Sambuc 446*433d6423SLionel Sambuc for (o= 0; o<size; o += PAGE_SIZE) 447*433d6423SLionel Sambuc { 448*433d6423SLionel Sambuc u32_t bit= (busaddr+o)/PAGE_SIZE; 449*433d6423SLionel Sambuc table[bit/8] &= ~(1U << (bit % 8)); 450*433d6423SLionel Sambuc } 451*433d6423SLionel Sambuc } 452*433d6423SLionel Sambuc 453*433d6423SLionel Sambuc #if 0 454*433d6423SLionel Sambuc static void del_range(phys_bytes busaddr, phys_bytes size) 455*433d6423SLionel Sambuc { 456*433d6423SLionel Sambuc phys_bytes o; 457*433d6423SLionel Sambuc 458*433d6423SLionel Sambuc #if 0 459*433d6423SLionel Sambuc printf("del_range: mapping 0x%x@0x%x\n", size, busaddr); 460*433d6423SLionel Sambuc #endif 461*433d6423SLionel Sambuc 462*433d6423SLionel Sambuc for (o= 0; o<size; o += PAGE_SIZE) 463*433d6423SLionel Sambuc { 464*433d6423SLionel Sambuc u32_t bit= (busaddr+o)/PAGE_SIZE; 465*433d6423SLionel Sambuc table[bit/8] |= (1 << (bit % 8)); 466*433d6423SLionel Sambuc } 467*433d6423SLionel Sambuc } 468*433d6423SLionel Sambuc #endif 469*433d6423SLionel Sambuc 470*433d6423SLionel Sambuc static void report_exceptions(void) 471*433d6423SLionel Sambuc { 472*433d6423SLionel Sambuc u32_t status; 473*433d6423SLionel Sambuc 474*433d6423SLionel Sambuc status= read_reg(DEVF_ERR_STATUS, 0); 475*433d6423SLionel Sambuc if (!(status & 0x80000000)) 476*433d6423SLionel Sambuc return; 477*433d6423SLionel Sambuc printf("amddev: status = 0x%x, addr-lo = 0x%x, addr-hi = 0x%x\n", 478*433d6423SLionel Sambuc status, read_reg(DEVF_ERR_ADDR_LO, 0), 479*433d6423SLionel Sambuc read_reg(DEVF_ERR_ADDR_HI, 0)); 480*433d6423SLionel Sambuc write_reg(DEVF_ERR_STATUS, 0, 0); 481*433d6423SLionel Sambuc } 482