xref: /haiku/src/tests/add-ons/kernel/bus_managers/agp_gart/gart_tester.cpp (revision aa3083e086e5a929c061c72983e09d916c548a38)
102998a5dSAxel Dörfler #include <malloc.h>
202998a5dSAxel Dörfler #include <stdio.h>
302998a5dSAxel Dörfler #include <stdlib.h>
402998a5dSAxel Dörfler #include <string.h>
502998a5dSAxel Dörfler 
602998a5dSAxel Dörfler #include <AGP.h>
702998a5dSAxel Dörfler #include <PCI.h>
802998a5dSAxel Dörfler #include <KernelExport.h>
902998a5dSAxel Dörfler 
1002998a5dSAxel Dörfler 
1102998a5dSAxel Dörfler extern "C" status_t _add_builtin_module(module_info *info);
1202998a5dSAxel Dörfler 
1302998a5dSAxel Dörfler extern module_info* modules[];
1402998a5dSAxel Dörfler static agp_gart_module_info* sGART;
1502998a5dSAxel Dörfler static pci_module_info sPCI;
1602998a5dSAxel Dörfler static void* sApertureBase;
1702998a5dSAxel Dörfler 
1802998a5dSAxel Dörfler 
1902998a5dSAxel Dörfler //	#pragma mark - Kernel & PCI emulation
2002998a5dSAxel Dörfler 
2102998a5dSAxel Dörfler 
2202998a5dSAxel Dörfler static long
pci_get_nth_pci_info(long index,pci_info * info)2302998a5dSAxel Dörfler pci_get_nth_pci_info(long index, pci_info* info)
2402998a5dSAxel Dörfler {
2502998a5dSAxel Dörfler 	return B_ENTRY_NOT_FOUND;
2602998a5dSAxel Dörfler }
2702998a5dSAxel Dörfler 
2802998a5dSAxel Dörfler 
2902998a5dSAxel Dörfler static status_t
pci_std_ops(int32,...)3002998a5dSAxel Dörfler pci_std_ops(int32, ...)
3102998a5dSAxel Dörfler {
3202998a5dSAxel Dörfler 	return B_OK;
3302998a5dSAxel Dörfler }
3402998a5dSAxel Dörfler 
3502998a5dSAxel Dörfler 
3602998a5dSAxel Dörfler extern "C" status_t
get_memory_map(const void * address,ulong numBytes,physical_entry * table,long numEntries)3702998a5dSAxel Dörfler get_memory_map(const void* address, ulong numBytes, physical_entry* table,
3802998a5dSAxel Dörfler 	long numEntries)
3902998a5dSAxel Dörfler {
4002998a5dSAxel Dörfler 	table[0].address = (void *)((addr_t)address - 0x100000);
4102998a5dSAxel Dörfler 	table[0].size = numBytes;
4202998a5dSAxel Dörfler 	//dprintf("GET_MEMORY_MAP: %p -> %p\n", address, table[0].address);
4302998a5dSAxel Dörfler 	return B_OK;
4402998a5dSAxel Dörfler }
4502998a5dSAxel Dörfler 
4602998a5dSAxel Dörfler 
4702998a5dSAxel Dörfler //	#pragma mark - GART bus module
4802998a5dSAxel Dörfler 
4902998a5dSAxel Dörfler 
5002998a5dSAxel Dörfler status_t
gart_create_aperture(uint8 bus,uint8 device,uint8 function,size_t size,void ** _aperture)5102998a5dSAxel Dörfler gart_create_aperture(uint8 bus, uint8 device, uint8 function, size_t size,
5202998a5dSAxel Dörfler 	void **_aperture)
5302998a5dSAxel Dörfler {
5402998a5dSAxel Dörfler 	dprintf("  gart_create_aperture(%d.%d.%d, %lu bytes)\n", bus, device,
5502998a5dSAxel Dörfler 		function, size);
5602998a5dSAxel Dörfler 
5702998a5dSAxel Dörfler 	sApertureBase = memalign(65536, B_PAGE_SIZE);
5802998a5dSAxel Dörfler 	*_aperture = (void *)0x42;
5902998a5dSAxel Dörfler 	return B_OK;
6002998a5dSAxel Dörfler }
6102998a5dSAxel Dörfler 
6202998a5dSAxel Dörfler 
6302998a5dSAxel Dörfler void
gart_delete_aperture(void * aperture)6402998a5dSAxel Dörfler gart_delete_aperture(void *aperture)
6502998a5dSAxel Dörfler {
6602998a5dSAxel Dörfler 	dprintf("  gart_delete_aperture(%p)\n", aperture);
6702998a5dSAxel Dörfler }
6802998a5dSAxel Dörfler 
6902998a5dSAxel Dörfler 
7002998a5dSAxel Dörfler static status_t
gart_get_aperture_info(void * aperture,aperture_info * info)7102998a5dSAxel Dörfler gart_get_aperture_info(void *aperture, aperture_info *info)
7202998a5dSAxel Dörfler {
7302998a5dSAxel Dörfler 	dprintf("  gart_get_aperture_info(%p)\n", aperture);
7402998a5dSAxel Dörfler 
7502998a5dSAxel Dörfler 	info->base = (addr_t)sApertureBase;
7602998a5dSAxel Dörfler 	info->physical_base = 0x800000;
7702998a5dSAxel Dörfler 	info->size = 65536;
7802998a5dSAxel Dörfler 	info->reserved_size = 3 * 4096;
7902998a5dSAxel Dörfler 
8002998a5dSAxel Dörfler 	return B_OK;
8102998a5dSAxel Dörfler }
8202998a5dSAxel Dörfler 
8302998a5dSAxel Dörfler 
8402998a5dSAxel Dörfler status_t
gart_set_aperture_size(void * aperture,size_t size)8502998a5dSAxel Dörfler gart_set_aperture_size(void *aperture, size_t size)
8602998a5dSAxel Dörfler {
8702998a5dSAxel Dörfler 	dprintf("  gart_set_aperture_size(%p, %lu)\n", aperture, size);
8802998a5dSAxel Dörfler 	return B_ERROR;
8902998a5dSAxel Dörfler }
9002998a5dSAxel Dörfler 
9102998a5dSAxel Dörfler 
9202998a5dSAxel Dörfler static status_t
gart_bind_page(void * aperture,uint32 offset,addr_t physicalAddress)9302998a5dSAxel Dörfler gart_bind_page(void *aperture, uint32 offset, addr_t physicalAddress)
9402998a5dSAxel Dörfler {
9502998a5dSAxel Dörfler 	dprintf("  gart_bind_page(%p, offset %lx, physical %lx)\n", aperture,
9602998a5dSAxel Dörfler 		offset, physicalAddress);
9702998a5dSAxel Dörfler 	return B_OK;
9802998a5dSAxel Dörfler }
9902998a5dSAxel Dörfler 
10002998a5dSAxel Dörfler 
10102998a5dSAxel Dörfler static status_t
gart_unbind_page(void * aperture,uint32 offset)10202998a5dSAxel Dörfler gart_unbind_page(void *aperture, uint32 offset)
10302998a5dSAxel Dörfler {
10402998a5dSAxel Dörfler 	dprintf("  gart_unbind_page(%p, offset %lx)\n", aperture, offset);
10502998a5dSAxel Dörfler 	return B_OK;
10602998a5dSAxel Dörfler }
10702998a5dSAxel Dörfler 
10802998a5dSAxel Dörfler 
10902998a5dSAxel Dörfler void
gart_flush_tlbs(void * aperture)11002998a5dSAxel Dörfler gart_flush_tlbs(void *aperture)
11102998a5dSAxel Dörfler {
11202998a5dSAxel Dörfler 	dprintf("  gart_flush_tlbs(%p)\n", aperture);
11302998a5dSAxel Dörfler }
11402998a5dSAxel Dörfler 
11502998a5dSAxel Dörfler 
11602998a5dSAxel Dörfler static int32
gart_std_ops(int32 op,...)11702998a5dSAxel Dörfler gart_std_ops(int32 op, ...)
11802998a5dSAxel Dörfler {
11902998a5dSAxel Dörfler 	switch (op) {
12002998a5dSAxel Dörfler 		case B_MODULE_INIT:
12102998a5dSAxel Dörfler 			dprintf("GART init\n");
12202998a5dSAxel Dörfler 			return B_OK;
12302998a5dSAxel Dörfler 		case B_MODULE_UNINIT:
12402998a5dSAxel Dörfler 			dprintf("GART uninit\n");
12502998a5dSAxel Dörfler 			return B_OK;
12602998a5dSAxel Dörfler 	}
12702998a5dSAxel Dörfler 
12802998a5dSAxel Dörfler 	return B_BAD_VALUE;
12902998a5dSAxel Dörfler }
13002998a5dSAxel Dörfler 
13102998a5dSAxel Dörfler 
13202998a5dSAxel Dörfler static struct agp_gart_bus_module_info sGARTModuleInfo = {
13302998a5dSAxel Dörfler 	{
13402998a5dSAxel Dörfler 		"busses/agp_gart/test/v0",
13502998a5dSAxel Dörfler 		0,
13602998a5dSAxel Dörfler 		gart_std_ops
13702998a5dSAxel Dörfler 	},
13802998a5dSAxel Dörfler 
13902998a5dSAxel Dörfler 	gart_create_aperture,
14002998a5dSAxel Dörfler 	gart_delete_aperture,
14102998a5dSAxel Dörfler 
14202998a5dSAxel Dörfler 	gart_get_aperture_info,
14302998a5dSAxel Dörfler 	gart_set_aperture_size,
14402998a5dSAxel Dörfler 	gart_bind_page,
14502998a5dSAxel Dörfler 	gart_unbind_page,
14602998a5dSAxel Dörfler 	gart_flush_tlbs
14702998a5dSAxel Dörfler };
14802998a5dSAxel Dörfler 
14902998a5dSAxel Dörfler 
15002998a5dSAxel Dörfler //	#pragma mark - Tests
15102998a5dSAxel Dörfler 
15202998a5dSAxel Dörfler 
15302998a5dSAxel Dörfler void
allocate(aperture_id aperture,size_t size,size_t alignment,uint32 flags,addr_t & base,addr_t & physical)15402998a5dSAxel Dörfler allocate(aperture_id aperture, size_t size, size_t alignment, uint32 flags,
15502998a5dSAxel Dörfler 	addr_t& base, addr_t& physical)
15602998a5dSAxel Dörfler {
15702998a5dSAxel Dörfler 	printf("Alloc %lu bytes, alignment %ld%s\n", size, alignment,
15802998a5dSAxel Dörfler 		flags & B_APERTURE_NEED_PHYSICAL ? ", need-physical"
15902998a5dSAxel Dörfler 		: flags & B_APERTURE_NON_RESERVED ? ", non-reserved" : "");
16002998a5dSAxel Dörfler 
16102998a5dSAxel Dörfler 	status_t status = sGART->allocate_memory(aperture, size, alignment, flags,
16202998a5dSAxel Dörfler 		&base, &physical);
16302998a5dSAxel Dörfler 	if (status == B_OK)
16402998a5dSAxel Dörfler 		printf("  -> base %lx, physical %lx\n", base, physical);
16502998a5dSAxel Dörfler 	else
16602998a5dSAxel Dörfler 		printf("  -> failed: %s\n", strerror(status));
16702998a5dSAxel Dörfler }
16802998a5dSAxel Dörfler 
16902998a5dSAxel Dörfler 
17002998a5dSAxel Dörfler void
test_gart()17102998a5dSAxel Dörfler test_gart()
17202998a5dSAxel Dörfler {
17302998a5dSAxel Dörfler 	addr_t apertureBase;
17402998a5dSAxel Dörfler 	aperture_id aperture = sGART->map_aperture(0, 0, 0, 0, &apertureBase);
17502998a5dSAxel Dörfler 	printf("Map Aperture: %ld, base %lx\n", aperture, apertureBase);
17602998a5dSAxel Dörfler 
17702998a5dSAxel Dörfler 	aperture_info info;
17802998a5dSAxel Dörfler 	sGART->get_aperture_info(aperture, &info);
17902998a5dSAxel Dörfler 	printf("Aperture: base %lx, physical base %lx, size %ld, reserved %ld\n",
18002998a5dSAxel Dörfler 		info.base, info.physical_base, info.size, info.reserved_size);
18102998a5dSAxel Dörfler 
18202998a5dSAxel Dörfler 	addr_t base[5], physical[5];
18302998a5dSAxel Dörfler 	allocate(aperture, 2 * B_PAGE_SIZE, 0, 0, base[0], physical[0]);
184*aa3083e0SFreeman Lou 	allocate(aperture, 4 * B_PAGE_SIZE, 0, B_APERTURE_NON_RESERVED, base[1],
185*aa3083e0SFreeman Lou 		physical[1]);
186*aa3083e0SFreeman Lou 	allocate(aperture, 1 * B_PAGE_SIZE, 0, B_APERTURE_NEED_PHYSICAL, base[2],
187*aa3083e0SFreeman Lou 		physical[2]);
18802998a5dSAxel Dörfler 	sGART->deallocate_memory(aperture, base[2]);
189*aa3083e0SFreeman Lou 	allocate(aperture, 1 * B_PAGE_SIZE, 4 * B_PAGE_SIZE, 0, base[2],
190*aa3083e0SFreeman Lou 		physical[2]);
19102998a5dSAxel Dörfler 
19202998a5dSAxel Dörfler 	sGART->deallocate_memory(aperture, base[1]);
19302998a5dSAxel Dörfler 
19402998a5dSAxel Dörfler 	allocate(aperture, 5 * B_PAGE_SIZE, 0, 0, base[1], physical[1]);
19502998a5dSAxel Dörfler 
19602998a5dSAxel Dörfler 	sGART->deallocate_memory(aperture, base[2]);
19702998a5dSAxel Dörfler 	sGART->deallocate_memory(aperture, base[0]);
19802998a5dSAxel Dörfler 	if (sGART->deallocate_memory(aperture, 0x12345) == B_OK)
19902998a5dSAxel Dörfler 		debugger("Non-allocated succeeded to be freed!\n");
20002998a5dSAxel Dörfler 
20102998a5dSAxel Dörfler 	void *buffer = memalign(3 * B_PAGE_SIZE, B_PAGE_SIZE);
20202998a5dSAxel Dörfler 	status_t status = sGART->bind_aperture(aperture, -1, (addr_t)buffer,
20302998a5dSAxel Dörfler 		3 * B_PAGE_SIZE, 0, false, 0, &base[3]);
20402998a5dSAxel Dörfler 	if (status < B_OK)
20502998a5dSAxel Dörfler 		printf("binding memory failed: %s\n", strerror(status));
20602998a5dSAxel Dörfler 
20702998a5dSAxel Dörfler 	allocate(aperture, 25 * B_PAGE_SIZE, 0, 0, base[0], physical[0]);
20802998a5dSAxel Dörfler 		// will fail
20902998a5dSAxel Dörfler 	allocate(aperture, 4 * B_PAGE_SIZE, 0, 0, base[0], physical[0]);
21002998a5dSAxel Dörfler 
21102998a5dSAxel Dörfler 	void *address;
21202998a5dSAxel Dörfler 	area_id area = create_area("test", &address, B_ANY_ADDRESS, 2 * B_PAGE_SIZE,
21302998a5dSAxel Dörfler 		B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
21402998a5dSAxel Dörfler 	printf("Area %ld, address %p\n", area, address);
21502998a5dSAxel Dörfler 	status = sGART->bind_aperture(aperture, area, 0, 0, 0, false, 0, &base[4]);
21602998a5dSAxel Dörfler 	if (status < B_OK)
21702998a5dSAxel Dörfler 		printf("binding area failed: %s\n", strerror(status));
21802998a5dSAxel Dörfler 
21902998a5dSAxel Dörfler 	sGART->unbind_aperture(aperture, base[3]);
22002998a5dSAxel Dörfler 	sGART->unbind_aperture(aperture, base[4]);
22102998a5dSAxel Dörfler //	sGART->deallocate_memory(aperture, base[0]);
22202998a5dSAxel Dörfler 
22302998a5dSAxel Dörfler 	free(buffer);
22402998a5dSAxel Dörfler 	delete_area(area);
22502998a5dSAxel Dörfler 
22602998a5dSAxel Dörfler 	sGART->unmap_aperture(aperture);
22702998a5dSAxel Dörfler }
22802998a5dSAxel Dörfler 
22902998a5dSAxel Dörfler 
23002998a5dSAxel Dörfler int
main(int argc,char ** argv)23102998a5dSAxel Dörfler main(int argc, char** argv)
23202998a5dSAxel Dörfler {
23302998a5dSAxel Dörfler 	sPCI.binfo.minfo.name = B_PCI_MODULE_NAME;
23402998a5dSAxel Dörfler 	sPCI.binfo.minfo.std_ops = pci_std_ops;
23502998a5dSAxel Dörfler 	sPCI.get_nth_pci_info = pci_get_nth_pci_info;
23602998a5dSAxel Dörfler 
23702998a5dSAxel Dörfler 	_add_builtin_module(modules[0]);
23802998a5dSAxel Dörfler 	_add_builtin_module((module_info*)&sPCI);
23902998a5dSAxel Dörfler 	_add_builtin_module((module_info*)&sGARTModuleInfo);
24002998a5dSAxel Dörfler 
24102998a5dSAxel Dörfler 	if (get_module(B_AGP_GART_MODULE_NAME, (module_info**)&sGART) != B_OK)
24202998a5dSAxel Dörfler 		return 1;
24302998a5dSAxel Dörfler 
24402998a5dSAxel Dörfler 	test_gart();
24502998a5dSAxel Dörfler 
24602998a5dSAxel Dörfler 	put_module(B_AGP_GART_MODULE_NAME);
24702998a5dSAxel Dörfler 	return 0;
24802998a5dSAxel Dörfler }
24902998a5dSAxel Dörfler 
250