DMPAPI(bool) io_Free(void* handle) { bool result = true; IO_BASE_t* base; if ((base = (IO_BASE_t*)handle) == NULL) return false; switch (base->iotype) { case IO_USE_PORTIO: // TODO: for WinXP or Linux Kernel Mode, free Port-I/O region here break; case IO_USE_MMIO: #if defined DMP_DOS_DJGPP dpmi_LinMapFree(base->addr); dpmi_SelFree(base->mmio_selector); #elif defined USE_WINIO3 UnmapPhysicalMemory(base->mmio_info); #elif defined USE_PHYMEM UnmapPhyMem((void*)base->addr, base->size); #else // TODO: for WinXP or Linux Kernel Mode, free MMIO region here #endif break; default: err_print((char*)"%s: unknown io-type!\n", __FUNCTION__); result = false; break; } free_io_base(base); return result; }
DMPAPI(bool) io_Free(void* handle) { bool result = true; IO_BASE_t* base; if ((base = (IO_BASE_t*)handle) == NULL) return false; switch (base->iotype) { case IO_USE_PORTIO: // do nothing ... break; case IO_USE_MMIO: #if defined DMP_DOS_DJGPP dpmi_LinMapFree(base->addr); dpmi_SelFree(base->mmio_selector); #elif defined DMP_LINUX if ((IO_mmioFD != -1) && ((void*)base->addr != (void *)-1)) //&& if (munmap((void*)(base->mmio_realaddr), base->size) == -1) { err_print("%s: fail to free MMIO region (%d)!\n", __FUNCTION__, errno); result = false; } #elif defined USE_WINIO3 UnmapPhysicalMemory(base->mmio_info); #elif defined USE_PHYMEM UnmapPhyMem((void*)base->addr, base->size); #endif break; default: err_print("%s: unknown io-type!\n", __FUNCTION__); result = false; break; } free_io_base(base); return result; }
DMPAPI(void*) io_Alloc(int io_type, unsigned long io_phyaddr, unsigned long io_size) { IO_BASE_t* base; if ((base = get_io_base()) == NULL) { err_print((char*)"%s: no free I/O handle!\n", __FUNCTION__); return NULL; } base->iotype = io_type; base->addr = io_phyaddr; base->size = io_size; switch (base->iotype) { case IO_USE_PORTIO: if ((base->addr > 0xffffL) || ((0xffffL - base->addr) < (base->size - 1L))) { err_print((char*)"%s: infeasible port-I/O region!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } // TODO: for WinXP or Linux Kernel Mode, alloc Port-I/O region here break; case IO_USE_MMIO: if ((0xffffffffL - base->addr) < (base->size - 1L)) { err_print((char*)"%s: infeasible MMIO region!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } #if defined DMP_DOS_DJGPP if ((base->addr = dpmi_LinMapAlloc(base->addr, base->size)) != 0L) //&& if ((base->mmio_selector = dpmi_SelAlloc(base->addr, base->size)) < 0) dpmi_LinMapFree(base->addr); if ((base->addr == 0L) || (base->mmio_selector < 0)) { err_print((char*)"%s: fail to map MMIO region!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } #elif defined USE_WINIO3 base->mmio_info.pvPhysAddress = (DWORD64)(DWORD32)(base->addr); base->mmio_info.dwPhysMemSizeInBytes = (DWORD64)(DWORD32)(base->size); base->addr = (unsigned long)MapPhysToLin(base->mmio_info); if ((unsigned char*)(base->addr) == NULL) { err_print((char*)"%s: fail to map MMIO region!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } #elif defined USE_PHYMEM base->addr = (unsigned long)MapPhyMem(base->addr, base->size); if ((unsigned char*)(base->addr) == NULL) { err_print((char*)"%s: fail to map MMIO region!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } #elif defined(DMP_DOS_WATCOM) || defined(USE_PCIDEBUG) // do nothing ... #else err_print((char*)"%s: MMIO is not supported!\n", __FUNCTION__); goto FAIL_IO_ALLOC; #endif // TODO: for WinXP or Linux Kernel Mode, alloc MMIO region here break; default: err_print((char*)"%s: unknown io_type!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } return (void*)base; FAIL_IO_ALLOC: free_io_base(base); return NULL; }
DMPAPI(void*) io_Alloc(int io_type, unsigned long io_phyaddr, unsigned long io_size) { IO_BASE_t* base; if ((base = get_io_base()) == NULL) { err_print("%s: no free I/O handle!\n", __FUNCTION__); return NULL; } base->iotype = io_type; base->addr = io_phyaddr; base->size = io_size; switch (base->iotype) { case IO_USE_PORTIO: if ((base->addr > 0xffffL) || ((0xffffL - base->addr) < (base->size - 1L))) { err_print("%s: infeasible port-I/O region!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } break; case IO_USE_MMIO: if ((0xffffffffL - base->addr) < (base->size - 1L)) { err_print("%s: infeasible MMIO region!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } #if defined DMP_DOS_DJGPP if ((base->addr = dpmi_LinMapAlloc(base->addr, base->size)) != 0L) //&& if ((base->mmio_selector = dpmi_SelAlloc(base->addr, base->size)) < 0) dpmi_LinMapFree(base->addr); if ((base->addr == 0L) || (base->mmio_selector < 0)) { err_print("%s: fail to map MMIO region!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } #elif defined DMP_LINUX if (IO_mmioFD != -1) { unsigned long offset_in_page = base->addr % sysconf(_SC_PAGE_SIZE); base->addr = base->addr - offset_in_page; // ensure the base address is page-aligned base->size = base->size + offset_in_page; base->mmio_realaddr = (unsigned long)mmap(NULL, base->size, PROT_READ | PROT_WRITE, MAP_SHARED, IO_mmioFD, base->addr); base->addr = ((void*)(base->mmio_realaddr) == (void *)-1)? base->mmio_realaddr : base->mmio_realaddr + offset_in_page; } if ((IO_mmioFD == -1) || ((void*)(base->addr) == (void *)-1)) { err_print("%s: fail to map MMIO region (%d)!\n", __FUNCTION__, errno); goto FAIL_IO_ALLOC; } #elif defined USE_WINIO3 base->mmio_info.pvPhysAddress = (DWORD64)(DWORD32)(base->addr); base->mmio_info.dwPhysMemSizeInBytes = (DWORD64)(DWORD32)(base->size); base->addr = (unsigned long)MapPhysToLin(base->mmio_info); if ((unsigned char*)(base->addr) == NULL) { err_print("%s: fail to map MMIO region!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } #elif defined USE_PHYMEM base->addr = (unsigned long)MapPhyMem(base->addr, base->size); if ((unsigned char*)(base->addr) == NULL) { err_print("%s: fail to map MMIO region!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } #elif defined(DMP_DOS_WATCOM) || defined(USE_PCIDEBUG) // do nothing ... #else err_print("%s: MMIO is not supported!\n", __FUNCTION__); goto FAIL_IO_ALLOC; #endif break; default: err_print("%s: unknown io_type!\n", __FUNCTION__); goto FAIL_IO_ALLOC; } return (void*)base; FAIL_IO_ALLOC: free_io_base(base); return NULL; }