uint32_t PCI::read_dword(uint32_t bus, uint32_t slot, uint32_t func, uint32_t offset) { uint32_t id = ((bus) << 16) | ((slot) << 11) | ((func) << 8); uint32_t addr = 0x80000000 | id | (offset & 0xfc); outportd(0xCF8, addr); uint32 val = inportd(0xCFC); return val; }
uint32_t PCI_READ_DATA(uint32_t addr){ uint32_t data; asm volatile("cli\n"); outportd(0x0CF8,addr); data=inportd(0x0CFC); asm volatile("sti\n"); return data; }
// PCI Enumerator Device int devcall_PCIENUM(CALLFS_PARAM* param){ CALLFS_IOCTL* ioctl=(CALLFS_IOCTL*)param; CALLFS_DTX* dtx=(CALLFS_DTX*)param; switch(param->fscmd){ // always through case devcall_open: case devcall_close: return 0; // IOCTL case devcall_ioctl: { switch(ioctl->ioctl_cmd){ case ioctl_get_information: *(volume_info*)ioctl->data=volume; return 0; case ioctl_read_toc: case ioctl_reset_device: case ioctl_check_read_status: case ioctl_check_write_status: case ioctl_nop: return 0; case ioctl_fast_find: { fastfind_t* ff=(fastfind_t*)ioctl->data; if(!::strcmp(ff->name,"/")){ ::memset(ff->result,0,sizeof(readdir_t)); ff->result->raw[0]='/'; ff->result->filename[0]='/'; ff->result->devid=ioctl->device; return 0; } } return -ENOENT; default: return -EINVAL; } } // read case devcall_read: { int i=dtx->index; if(i<=pcidevices){ uint32_t addr=pci_devices[i-1].addr; uint32_t* buff=(uint32_t*)dtx->data; asm volatile("cli"); for(int c=0;c<64;c++){ outportd(0x0CF8,addr+(c<<2)); buff[c]=inportd(0x0CFC); } asm volatile("sti"); dtx->count--; return 0; } return -ENOENT; } // write case devcall_write: return -EROFS; // read dir case devcall_read_dir: { int i=dtx->offset; readdir_t* rd=(readdir_t*)dtx->data; if(i < pcidevices){ ::memset(rd,0,sizeof(readdir_t)); rd->raw[0]='?'; ::strcpy(rd->filename,pci_devices[i].name); rd->devid=ioctl->device; rd->index=1+i; rd->size=256; return 0; } return -EINVAL; } // otherwise not supported default: return -EINVAL; }