1 #include <malloc.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 6 #include <AGP.h> 7 #include <PCI.h> 8 #include <KernelExport.h> 9 10 11 extern "C" status_t _add_builtin_module(module_info *info); 12 13 extern module_info* modules[]; 14 static agp_gart_module_info* sGART; 15 static pci_module_info sPCI; 16 static void* sApertureBase; 17 18 19 // #pragma mark - Kernel & PCI emulation 20 21 22 static long 23 pci_get_nth_pci_info(long index, pci_info* info) 24 { 25 return B_ENTRY_NOT_FOUND; 26 } 27 28 29 static status_t 30 pci_std_ops(int32, ...) 31 { 32 return B_OK; 33 } 34 35 36 extern "C" status_t 37 get_memory_map(const void* address, ulong numBytes, physical_entry* table, 38 long numEntries) 39 { 40 table[0].address = (void *)((addr_t)address - 0x100000); 41 table[0].size = numBytes; 42 //dprintf("GET_MEMORY_MAP: %p -> %p\n", address, table[0].address); 43 return B_OK; 44 } 45 46 47 // #pragma mark - GART bus module 48 49 50 status_t 51 gart_create_aperture(uint8 bus, uint8 device, uint8 function, size_t size, 52 void **_aperture) 53 { 54 dprintf(" gart_create_aperture(%d.%d.%d, %lu bytes)\n", bus, device, 55 function, size); 56 57 sApertureBase = memalign(65536, B_PAGE_SIZE); 58 *_aperture = (void *)0x42; 59 return B_OK; 60 } 61 62 63 void 64 gart_delete_aperture(void *aperture) 65 { 66 dprintf(" gart_delete_aperture(%p)\n", aperture); 67 } 68 69 70 static status_t 71 gart_get_aperture_info(void *aperture, aperture_info *info) 72 { 73 dprintf(" gart_get_aperture_info(%p)\n", aperture); 74 75 info->base = (addr_t)sApertureBase; 76 info->physical_base = 0x800000; 77 info->size = 65536; 78 info->reserved_size = 3 * 4096; 79 80 return B_OK; 81 } 82 83 84 status_t 85 gart_set_aperture_size(void *aperture, size_t size) 86 { 87 dprintf(" gart_set_aperture_size(%p, %lu)\n", aperture, size); 88 return B_ERROR; 89 } 90 91 92 static status_t 93 gart_bind_page(void *aperture, uint32 offset, addr_t physicalAddress) 94 { 95 dprintf(" gart_bind_page(%p, offset %lx, physical %lx)\n", aperture, 96 offset, physicalAddress); 97 return B_OK; 98 } 99 100 101 static status_t 102 gart_unbind_page(void *aperture, uint32 offset) 103 { 104 dprintf(" gart_unbind_page(%p, offset %lx)\n", aperture, offset); 105 return B_OK; 106 } 107 108 109 void 110 gart_flush_tlbs(void *aperture) 111 { 112 dprintf(" gart_flush_tlbs(%p)\n", aperture); 113 } 114 115 116 static int32 117 gart_std_ops(int32 op, ...) 118 { 119 switch (op) { 120 case B_MODULE_INIT: 121 dprintf("GART init\n"); 122 return B_OK; 123 case B_MODULE_UNINIT: 124 dprintf("GART uninit\n"); 125 return B_OK; 126 } 127 128 return B_BAD_VALUE; 129 } 130 131 132 static struct agp_gart_bus_module_info sGARTModuleInfo = { 133 { 134 "busses/agp_gart/test/v0", 135 0, 136 gart_std_ops 137 }, 138 139 gart_create_aperture, 140 gart_delete_aperture, 141 142 gart_get_aperture_info, 143 gart_set_aperture_size, 144 gart_bind_page, 145 gart_unbind_page, 146 gart_flush_tlbs 147 }; 148 149 150 // #pragma mark - Tests 151 152 153 void 154 allocate(aperture_id aperture, size_t size, size_t alignment, uint32 flags, 155 addr_t& base, addr_t& physical) 156 { 157 printf("Alloc %lu bytes, alignment %ld%s\n", size, alignment, 158 flags & B_APERTURE_NEED_PHYSICAL ? ", need-physical" 159 : flags & B_APERTURE_NON_RESERVED ? ", non-reserved" : ""); 160 161 status_t status = sGART->allocate_memory(aperture, size, alignment, flags, 162 &base, &physical); 163 if (status == B_OK) 164 printf(" -> base %lx, physical %lx\n", base, physical); 165 else 166 printf(" -> failed: %s\n", strerror(status)); 167 } 168 169 170 void 171 test_gart() 172 { 173 addr_t apertureBase; 174 aperture_id aperture = sGART->map_aperture(0, 0, 0, 0, &apertureBase); 175 printf("Map Aperture: %ld, base %lx\n", aperture, apertureBase); 176 177 aperture_info info; 178 sGART->get_aperture_info(aperture, &info); 179 printf("Aperture: base %lx, physical base %lx, size %ld, reserved %ld\n", 180 info.base, info.physical_base, info.size, info.reserved_size); 181 182 addr_t base[5], physical[5]; 183 allocate(aperture, 2 * B_PAGE_SIZE, 0, 0, base[0], physical[0]); 184 allocate(aperture, 4 * B_PAGE_SIZE, 0, B_APERTURE_NON_RESERVED, base[1], 185 physical[1]); 186 allocate(aperture, 1 * B_PAGE_SIZE, 0, B_APERTURE_NEED_PHYSICAL, base[2], 187 physical[2]); 188 sGART->deallocate_memory(aperture, base[2]); 189 allocate(aperture, 1 * B_PAGE_SIZE, 4 * B_PAGE_SIZE, 0, base[2], 190 physical[2]); 191 192 sGART->deallocate_memory(aperture, base[1]); 193 194 allocate(aperture, 5 * B_PAGE_SIZE, 0, 0, base[1], physical[1]); 195 196 sGART->deallocate_memory(aperture, base[2]); 197 sGART->deallocate_memory(aperture, base[0]); 198 if (sGART->deallocate_memory(aperture, 0x12345) == B_OK) 199 debugger("Non-allocated succeeded to be freed!\n"); 200 201 void *buffer = memalign(3 * B_PAGE_SIZE, B_PAGE_SIZE); 202 status_t status = sGART->bind_aperture(aperture, -1, (addr_t)buffer, 203 3 * B_PAGE_SIZE, 0, false, 0, &base[3]); 204 if (status < B_OK) 205 printf("binding memory failed: %s\n", strerror(status)); 206 207 allocate(aperture, 25 * B_PAGE_SIZE, 0, 0, base[0], physical[0]); 208 // will fail 209 allocate(aperture, 4 * B_PAGE_SIZE, 0, 0, base[0], physical[0]); 210 211 void *address; 212 area_id area = create_area("test", &address, B_ANY_ADDRESS, 2 * B_PAGE_SIZE, 213 B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); 214 printf("Area %ld, address %p\n", area, address); 215 status = sGART->bind_aperture(aperture, area, 0, 0, 0, false, 0, &base[4]); 216 if (status < B_OK) 217 printf("binding area failed: %s\n", strerror(status)); 218 219 sGART->unbind_aperture(aperture, base[3]); 220 sGART->unbind_aperture(aperture, base[4]); 221 // sGART->deallocate_memory(aperture, base[0]); 222 223 free(buffer); 224 delete_area(area); 225 226 sGART->unmap_aperture(aperture); 227 } 228 229 230 int 231 main(int argc, char** argv) 232 { 233 sPCI.binfo.minfo.name = B_PCI_MODULE_NAME; 234 sPCI.binfo.minfo.std_ops = pci_std_ops; 235 sPCI.get_nth_pci_info = pci_get_nth_pci_info; 236 237 _add_builtin_module(modules[0]); 238 _add_builtin_module((module_info*)&sPCI); 239 _add_builtin_module((module_info*)&sGARTModuleInfo); 240 241 if (get_module(B_AGP_GART_MODULE_NAME, (module_info**)&sGART) != B_OK) 242 return 1; 243 244 test_gart(); 245 246 put_module(B_AGP_GART_MODULE_NAME); 247 return 0; 248 } 249 250