Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}