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
pci_get_nth_pci_info(long index,pci_info * info)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
pci_std_ops(int32,...)30 pci_std_ops(int32, ...)
31 {
32 return B_OK;
33 }
34
35
36 extern "C" status_t
get_memory_map(const void * address,ulong numBytes,physical_entry * table,long numEntries)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
gart_create_aperture(uint8 bus,uint8 device,uint8 function,size_t size,void ** _aperture)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
gart_delete_aperture(void * aperture)64 gart_delete_aperture(void *aperture)
65 {
66 dprintf(" gart_delete_aperture(%p)\n", aperture);
67 }
68
69
70 static status_t
gart_get_aperture_info(void * aperture,aperture_info * info)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
gart_set_aperture_size(void * aperture,size_t size)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
gart_bind_page(void * aperture,uint32 offset,addr_t physicalAddress)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
gart_unbind_page(void * aperture,uint32 offset)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
gart_flush_tlbs(void * aperture)110 gart_flush_tlbs(void *aperture)
111 {
112 dprintf(" gart_flush_tlbs(%p)\n", aperture);
113 }
114
115
116 static int32
gart_std_ops(int32 op,...)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
allocate(aperture_id aperture,size_t size,size_t alignment,uint32 flags,addr_t & base,addr_t & physical)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
test_gart()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
main(int argc,char ** argv)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