#include #include #include #include #include #include #include extern "C" status_t _add_builtin_module(module_info *info); extern module_info* modules[]; static agp_gart_module_info* sGART; static pci_module_info sPCI; static void* sApertureBase; // #pragma mark - Kernel & PCI emulation static long pci_get_nth_pci_info(long index, pci_info* info) { return B_ENTRY_NOT_FOUND; } static status_t pci_std_ops(int32, ...) { return B_OK; } extern "C" status_t get_memory_map(const void* address, ulong numBytes, physical_entry* table, long numEntries) { table[0].address = (void *)((addr_t)address - 0x100000); table[0].size = numBytes; //dprintf("GET_MEMORY_MAP: %p -> %p\n", address, table[0].address); return B_OK; } // #pragma mark - GART bus module status_t gart_create_aperture(uint8 bus, uint8 device, uint8 function, size_t size, void **_aperture) { dprintf(" gart_create_aperture(%d.%d.%d, %lu bytes)\n", bus, device, function, size); sApertureBase = memalign(65536, B_PAGE_SIZE); *_aperture = (void *)0x42; return B_OK; } void gart_delete_aperture(void *aperture) { dprintf(" gart_delete_aperture(%p)\n", aperture); } static status_t gart_get_aperture_info(void *aperture, aperture_info *info) { dprintf(" gart_get_aperture_info(%p)\n", aperture); info->base = (addr_t)sApertureBase; info->physical_base = 0x800000; info->size = 65536; info->reserved_size = 3 * 4096; return B_OK; } status_t gart_set_aperture_size(void *aperture, size_t size) { dprintf(" gart_set_aperture_size(%p, %lu)\n", aperture, size); return B_ERROR; } static status_t gart_bind_page(void *aperture, uint32 offset, addr_t physicalAddress) { dprintf(" gart_bind_page(%p, offset %lx, physical %lx)\n", aperture, offset, physicalAddress); return B_OK; } static status_t gart_unbind_page(void *aperture, uint32 offset) { dprintf(" gart_unbind_page(%p, offset %lx)\n", aperture, offset); return B_OK; } void gart_flush_tlbs(void *aperture) { dprintf(" gart_flush_tlbs(%p)\n", aperture); } static int32 gart_std_ops(int32 op, ...) { switch (op) { case B_MODULE_INIT: dprintf("GART init\n"); return B_OK; case B_MODULE_UNINIT: dprintf("GART uninit\n"); return B_OK; } return B_BAD_VALUE; } static struct agp_gart_bus_module_info sGARTModuleInfo = { { "busses/agp_gart/test/v0", 0, gart_std_ops }, gart_create_aperture, gart_delete_aperture, gart_get_aperture_info, gart_set_aperture_size, gart_bind_page, gart_unbind_page, gart_flush_tlbs }; // #pragma mark - Tests void allocate(aperture_id aperture, size_t size, size_t alignment, uint32 flags, addr_t& base, addr_t& physical) { printf("Alloc %lu bytes, alignment %ld%s\n", size, alignment, flags & B_APERTURE_NEED_PHYSICAL ? ", need-physical" : flags & B_APERTURE_NON_RESERVED ? ", non-reserved" : ""); status_t status = sGART->allocate_memory(aperture, size, alignment, flags, &base, &physical); if (status == B_OK) printf(" -> base %lx, physical %lx\n", base, physical); else printf(" -> failed: %s\n", strerror(status)); } void test_gart() { addr_t apertureBase; aperture_id aperture = sGART->map_aperture(0, 0, 0, 0, &apertureBase); printf("Map Aperture: %ld, base %lx\n", aperture, apertureBase); aperture_info info; sGART->get_aperture_info(aperture, &info); printf("Aperture: base %lx, physical base %lx, size %ld, reserved %ld\n", info.base, info.physical_base, info.size, info.reserved_size); addr_t base[5], physical[5]; allocate(aperture, 2 * B_PAGE_SIZE, 0, 0, base[0], physical[0]); allocate(aperture, 4 * B_PAGE_SIZE, 0, B_APERTURE_NON_RESERVED, base[1], physical[1]); allocate(aperture, 1 * B_PAGE_SIZE, 0, B_APERTURE_NEED_PHYSICAL, base[2], physical[2]); sGART->deallocate_memory(aperture, base[2]); allocate(aperture, 1 * B_PAGE_SIZE, 4 * B_PAGE_SIZE, 0, base[2], physical[2]); sGART->deallocate_memory(aperture, base[1]); allocate(aperture, 5 * B_PAGE_SIZE, 0, 0, base[1], physical[1]); sGART->deallocate_memory(aperture, base[2]); sGART->deallocate_memory(aperture, base[0]); if (sGART->deallocate_memory(aperture, 0x12345) == B_OK) debugger("Non-allocated succeeded to be freed!\n"); void *buffer = memalign(3 * B_PAGE_SIZE, B_PAGE_SIZE); status_t status = sGART->bind_aperture(aperture, -1, (addr_t)buffer, 3 * B_PAGE_SIZE, 0, false, 0, &base[3]); if (status < B_OK) printf("binding memory failed: %s\n", strerror(status)); allocate(aperture, 25 * B_PAGE_SIZE, 0, 0, base[0], physical[0]); // will fail allocate(aperture, 4 * B_PAGE_SIZE, 0, 0, base[0], physical[0]); void *address; area_id area = create_area("test", &address, B_ANY_ADDRESS, 2 * B_PAGE_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); printf("Area %ld, address %p\n", area, address); status = sGART->bind_aperture(aperture, area, 0, 0, 0, false, 0, &base[4]); if (status < B_OK) printf("binding area failed: %s\n", strerror(status)); sGART->unbind_aperture(aperture, base[3]); sGART->unbind_aperture(aperture, base[4]); // sGART->deallocate_memory(aperture, base[0]); free(buffer); delete_area(area); sGART->unmap_aperture(aperture); } int main(int argc, char** argv) { sPCI.binfo.minfo.name = B_PCI_MODULE_NAME; sPCI.binfo.minfo.std_ops = pci_std_ops; sPCI.get_nth_pci_info = pci_get_nth_pci_info; _add_builtin_module(modules[0]); _add_builtin_module((module_info*)&sPCI); _add_builtin_module((module_info*)&sGARTModuleInfo); if (get_module(B_AGP_GART_MODULE_NAME, (module_info**)&sGART) != B_OK) return 1; test_gart(); put_module(B_AGP_GART_MODULE_NAME); return 0; }