diff --git a/Makefile b/Makefile index d163a1c..0413fc8 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ AS = nasm ASFlAGS = -felf32 EMU = qemu-system-x86_64 -EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci +EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci -device usb-mouse BUILD_FOLDER = build diff --git a/Makefile b/Makefile index d163a1c..0413fc8 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ AS = nasm ASFlAGS = -felf32 EMU = qemu-system-x86_64 -EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci +EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci -device usb-mouse BUILD_FOLDER = build diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 3ca7b01..2129d04 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -60,6 +60,6 @@ extern void reservePagesCount(PagingInfo *info, uint32_t startPageId, uint32_t count); extern void mapPage(PagingInfo *info, void *physical, void *virtual, - bool userPage); + bool userPage, bool isVolatile); #endif diff --git a/Makefile b/Makefile index d163a1c..0413fc8 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ AS = nasm ASFlAGS = -felf32 EMU = qemu-system-x86_64 -EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci +EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci -device usb-mouse BUILD_FOLDER = build diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 3ca7b01..2129d04 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -60,6 +60,6 @@ extern void reservePagesCount(PagingInfo *info, uint32_t startPageId, uint32_t count); extern void mapPage(PagingInfo *info, void *physical, void *virtual, - bool userPage); + bool userPage, bool isVolatile); #endif diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 51b034e..cc4619e 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -64,7 +64,8 @@ } } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -128,7 +129,7 @@ reservePagesCount(kernelVirtualPages, virtualPageStart, size); for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, ADDRESS(physicalPageStart + i), - ADDRESS(virtualPageStart + i), false); + ADDRESS(virtualPageStart + i), false, false); } return ADDRESS(virtualPageStart) + PAGE_OFFSET(address); } @@ -139,11 +140,12 @@ uint32_t virtualPageId = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtualPageId); mapPage(kernelVirtualPages, ADDRESS(physicalPageId), ADDRESS(virtualPageId), - false); + false, false); return ADDRESS(virtualPageId) + PAGE_OFFSET(address); } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -163,6 +165,7 @@ pageTable[address->pageTableIndex].targetAddress = PAGE_ID(physical); pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].isVolatile = isVolatile; pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(PAGE_ID(virtual)); } @@ -172,7 +175,8 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false); + mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false, + false); return ADDRESS(virtual); } @@ -183,7 +187,7 @@ uint32_t physical = findPage(kernelPhysicalPages); reservePage(kernelPhysicalPages, physical); mapPage(kernelVirtualPages, ADDRESS(physical), - ADDRESS(virtualPageId + i), false); + ADDRESS(virtualPageId + i), false, false); } return ADDRESS(virtualPageId); } @@ -195,10 +199,10 @@ getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); if (!destinationAddress) { void *target = ADDRESS(findPage(destination)); - mapPage(destination, physicalSource, target, true); + mapPage(destination, physicalSource, target, true, false); return target + PAGE_OFFSET(sourceAddress); } - mapPage(destination, physicalSource, destinationAddress, true); + mapPage(destination, physicalSource, destinationAddress, true, false); return destinationAddress; } diff --git a/Makefile b/Makefile index d163a1c..0413fc8 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ AS = nasm ASFlAGS = -felf32 EMU = qemu-system-x86_64 -EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci +EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci -device usb-mouse BUILD_FOLDER = build diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 3ca7b01..2129d04 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -60,6 +60,6 @@ extern void reservePagesCount(PagingInfo *info, uint32_t startPageId, uint32_t count); extern void mapPage(PagingInfo *info, void *physical, void *virtual, - bool userPage); + bool userPage, bool isVolatile); #endif diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 51b034e..cc4619e 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -64,7 +64,8 @@ } } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -128,7 +129,7 @@ reservePagesCount(kernelVirtualPages, virtualPageStart, size); for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, ADDRESS(physicalPageStart + i), - ADDRESS(virtualPageStart + i), false); + ADDRESS(virtualPageStart + i), false, false); } return ADDRESS(virtualPageStart) + PAGE_OFFSET(address); } @@ -139,11 +140,12 @@ uint32_t virtualPageId = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtualPageId); mapPage(kernelVirtualPages, ADDRESS(physicalPageId), ADDRESS(virtualPageId), - false); + false, false); return ADDRESS(virtualPageId) + PAGE_OFFSET(address); } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -163,6 +165,7 @@ pageTable[address->pageTableIndex].targetAddress = PAGE_ID(physical); pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].isVolatile = isVolatile; pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(PAGE_ID(virtual)); } @@ -172,7 +175,8 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false); + mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false, + false); return ADDRESS(virtual); } @@ -183,7 +187,7 @@ uint32_t physical = findPage(kernelPhysicalPages); reservePage(kernelPhysicalPages, physical); mapPage(kernelVirtualPages, ADDRESS(physical), - ADDRESS(virtualPageId + i), false); + ADDRESS(virtualPageId + i), false, false); } return ADDRESS(virtualPageId); } @@ -195,10 +199,10 @@ getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); if (!destinationAddress) { void *target = ADDRESS(findPage(destination)); - mapPage(destination, physicalSource, target, true); + mapPage(destination, physicalSource, target, true, false); return target + PAGE_OFFSET(sourceAddress); } - mapPage(destination, physicalSource, destinationAddress, true); + mapPage(destination, physicalSource, destinationAddress, true, false); return destinationAddress; } diff --git a/src/kernel/service/memorySyscalls.c b/src/kernel/service/memorySyscalls.c index 1711cb4..ef93d5f 100644 --- a/src/kernel/service/memorySyscalls.c +++ b/src/kernel/service/memorySyscalls.c @@ -20,14 +20,14 @@ uint32_t physicalPage = findPage(kernelPhysicalPages); reservePagesCount(kernelPhysicalPages, physicalPage, 1); mapPage(&service->pagingInfo, ADDRESS(physicalPage), - ADDRESS(virtualStart + i), true); + ADDRESS(virtualStart + i), true, false); } } else { uint32_t physicalPage = PAGE_ID(physical); reservePagesCount(kernelPhysicalPages, physicalPage, pageCount); for (uint32_t i = 0; i < pageCount; i++) { mapPage(&service->pagingInfo, ADDRESS(physicalPage + i), - ADDRESS(virtualStart + i), true); + ADDRESS(virtualStart + i), true, true); } } call->returnValue = U32(ADDRESS(virtualStart)) + (U32(physical) & 0xFFF); diff --git a/Makefile b/Makefile index d163a1c..0413fc8 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ AS = nasm ASFlAGS = -felf32 EMU = qemu-system-x86_64 -EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci +EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci -device usb-mouse BUILD_FOLDER = build diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 3ca7b01..2129d04 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -60,6 +60,6 @@ extern void reservePagesCount(PagingInfo *info, uint32_t startPageId, uint32_t count); extern void mapPage(PagingInfo *info, void *physical, void *virtual, - bool userPage); + bool userPage, bool isVolatile); #endif diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 51b034e..cc4619e 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -64,7 +64,8 @@ } } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -128,7 +129,7 @@ reservePagesCount(kernelVirtualPages, virtualPageStart, size); for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, ADDRESS(physicalPageStart + i), - ADDRESS(virtualPageStart + i), false); + ADDRESS(virtualPageStart + i), false, false); } return ADDRESS(virtualPageStart) + PAGE_OFFSET(address); } @@ -139,11 +140,12 @@ uint32_t virtualPageId = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtualPageId); mapPage(kernelVirtualPages, ADDRESS(physicalPageId), ADDRESS(virtualPageId), - false); + false, false); return ADDRESS(virtualPageId) + PAGE_OFFSET(address); } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -163,6 +165,7 @@ pageTable[address->pageTableIndex].targetAddress = PAGE_ID(physical); pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].isVolatile = isVolatile; pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(PAGE_ID(virtual)); } @@ -172,7 +175,8 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false); + mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false, + false); return ADDRESS(virtual); } @@ -183,7 +187,7 @@ uint32_t physical = findPage(kernelPhysicalPages); reservePage(kernelPhysicalPages, physical); mapPage(kernelVirtualPages, ADDRESS(physical), - ADDRESS(virtualPageId + i), false); + ADDRESS(virtualPageId + i), false, false); } return ADDRESS(virtualPageId); } @@ -195,10 +199,10 @@ getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); if (!destinationAddress) { void *target = ADDRESS(findPage(destination)); - mapPage(destination, physicalSource, target, true); + mapPage(destination, physicalSource, target, true, false); return target + PAGE_OFFSET(sourceAddress); } - mapPage(destination, physicalSource, destinationAddress, true); + mapPage(destination, physicalSource, destinationAddress, true, false); return destinationAddress; } diff --git a/src/kernel/service/memorySyscalls.c b/src/kernel/service/memorySyscalls.c index 1711cb4..ef93d5f 100644 --- a/src/kernel/service/memorySyscalls.c +++ b/src/kernel/service/memorySyscalls.c @@ -20,14 +20,14 @@ uint32_t physicalPage = findPage(kernelPhysicalPages); reservePagesCount(kernelPhysicalPages, physicalPage, 1); mapPage(&service->pagingInfo, ADDRESS(physicalPage), - ADDRESS(virtualStart + i), true); + ADDRESS(virtualStart + i), true, false); } } else { uint32_t physicalPage = PAGE_ID(physical); reservePagesCount(kernelPhysicalPages, physicalPage, pageCount); for (uint32_t i = 0; i < pageCount; i++) { mapPage(&service->pagingInfo, ADDRESS(physicalPage + i), - ADDRESS(virtualStart + i), true); + ADDRESS(virtualStart + i), true, true); } } call->returnValue = U32(ADDRESS(virtualStart)) + (U32(physical) & 0xFFF); diff --git a/src/userland/lspci/main.c b/src/userland/lspci/main.c index 33ac1cd..c66e2a9 100644 --- a/src/userland/lspci/main.c +++ b/src/userland/lspci/main.c @@ -33,74 +33,82 @@ ListElement *pciDevices = NULL; bool initialized = false; -uint8_t pciConfigReadByte(uint32_t bus, uint32_t device, uint32_t function, - uint8_t offset) { +uint32_t pciConfigRead(uint32_t bus, uint32_t device, uint32_t function, + uint8_t offset) { uint32_t address = ((bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC) | 0x80000000); ioOut(0xCF8, address, 4); - uint8_t result = (ioIn(0xCFC, 4) >> ((offset % 4) * 8)); + uint32_t result = ioIn(0xCFC, 4) >> ((offset % 4) * 8); return result; } void pciConfigWriteByte(uint32_t bus, uint32_t device, uint32_t function, - uint8_t offset, uint8_t data) { - uint32_t address = ((bus << 16) | (device << 11) | (function << 8) | - (offset & 0xFC) | 0x80000000); + uint8_t offset, uint32_t data) { + uint32_t address = + (bus << 16) | (device << 11) | (function << 8) | offset | 0x80000000; ioOut(0xCF8, address, 4); - ioOut(0xCFC, data, 1); + ioOut(0xCFC, data, 2); } -uint16_t pciConfigReadWord(uint8_t bus, uint8_t device, uint8_t function, - uint8_t offset) { - return (uint16_t)pciConfigReadByte(bus, device, function, offset) | - ((uint16_t)pciConfigReadByte(bus, device, function, offset + 1) - << 8); +// uint16_t pciConfigReadWord(uint8_t bus, uint8_t device, uint8_t function, +// uint8_t offset) { +// return (uint16_t)pciConfigReadByte(bus, device, function, offset) | +// ((uint16_t)pciConfigReadByte(bus, device, function, offset + 1) +// << 8); +//} + +void pciConfigWriteWord(uint8_t bus, uint8_t device, uint8_t function, + uint8_t offset, uint16_t data) { + pciConfigWriteByte(bus, device, function, offset, (uint8_t)data); + pciConfigWriteByte(bus, device, function, offset + 1, (uint8_t)(data >> 8)); } -uint32_t pciConfigReadInt(uint8_t bus, uint8_t device, uint8_t function, - uint8_t offset) { - return (uint32_t)pciConfigReadWord(bus, device, function, offset) | - ((uint32_t)pciConfigReadWord(bus, device, function, offset + 2) - << 16); -} +// uint32_t pciConfigReadInt(uint8_t bus, uint8_t device, uint8_t function, +// uint8_t offset) { +// return (uint32_t)pciConfigReadWord(bus, device, function, offset) | +// ((uint32_t)pciConfigReadWord(bus, device, function, offset + 2) +// << 16); +//} uint8_t getHeaderType(uint8_t bus, uint8_t device, uint8_t function) { - return pciConfigReadByte(bus, device, function, 0x0E); + return pciConfigRead(bus, device, function, 0x0E) & 0xFF; } uint16_t getVendorID(uint8_t bus, uint8_t device, uint8_t function) { - return pciConfigReadWord(bus, device, function, 0); + return pciConfigRead(bus, device, function, 0) & 0xFFFF; } void checkBus(uint8_t); void checkFunction(uint8_t bus, uint8_t device, uint8_t function) { - uint8_t class = pciConfigReadByte(bus, device, function, 0xB); + uint8_t class = pciConfigRead(bus, device, function, 0xB) & 0xFF; if (!class || class == 0xFF) { return; } - uint8_t subclass = pciConfigReadByte(bus, device, function, 0xA); + uint8_t subclass = pciConfigRead(bus, device, function, 0xA) & 0xFF; PciDevice *pciDevice = malloc(sizeof(PciDevice)); pciDevice->bus = bus; pciDevice->device = device; pciDevice->function = function; pciDevice->class = class; pciDevice->subclass = subclass; - pciDevice->vendorId = pciConfigReadWord(bus, device, function, 0x00); - pciDevice->deviceId = pciConfigReadWord(bus, device, function, 0x02); + pciDevice->vendorId = pciConfigRead(bus, device, function, 0x00) & 0xFFFF; + pciDevice->deviceId = pciConfigRead(bus, device, function, 0x02) & 0xFFFF; pciDevice->programmingInterface = - pciConfigReadByte(bus, device, function, 0x09); - pciDevice->bar0 = pciConfigReadInt(bus, device, function, 0x10); - pciDevice->bar1 = pciConfigReadInt(bus, device, function, 0x14); - pciDevice->bar2 = pciConfigReadInt(bus, device, function, 0x18); - pciDevice->bar3 = pciConfigReadInt(bus, device, function, 0x1C); - pciDevice->bar4 = pciConfigReadInt(bus, device, function, 0x20); - pciDevice->bar5 = pciConfigReadInt(bus, device, function, 0x24); + pciConfigRead(bus, device, function, 0x09) & 0xFF; + pciDevice->configuration = + pciConfigRead(bus, device, function, 0x04) & 0xFFFF; + pciDevice->bar[0] = pciConfigRead(bus, device, function, 0x10); + pciDevice->bar[1] = pciConfigRead(bus, device, function, 0x14); + pciDevice->bar[2] = pciConfigRead(bus, device, function, 0x18); + pciDevice->bar[3] = pciConfigRead(bus, device, function, 0x1C); + pciDevice->bar[4] = pciConfigRead(bus, device, function, 0x20); + pciDevice->bar[5] = pciConfigRead(bus, device, function, 0x24); listAdd(&pciDevices, pciDevice); - printf("device at %i/%i/%i: %s\n", bus, device, function, classNames[class], - subclass); + printf("device at %i/%i/%i: %s/%i bar0: %x\n", bus, device, function, + classNames[class], subclass, pciDevice->bar[0]); if (class == 6 && subclass == 4) { - checkBus(pciConfigReadByte(bus, device, function, 0x19)); + checkBus(pciConfigRead(bus, device, function, 0x19) & 0xFF); } } @@ -132,9 +140,13 @@ } int32_t getDeviceClass(uint32_t deviceId); +int32_t getBaseAddress(uint32_t deviceId, uint32_t n); +int32_t enableBusMaster(uint32_t deviceId); void initializePci() { createFunction("getDeviceClass", (void *)getDeviceClass); + createFunction("getBaseAddress", (void *)getBaseAddress); + createFunction("enableBusMaster", (void *)enableBusMaster); if (!(getHeaderType(0, 0, 0) & 0x80)) { checkBus(0); } else { @@ -146,18 +158,43 @@ initialized = true; } -int32_t getDeviceClass(uint32_t deviceId) { - if (!initialized) { - initializePci(); - } - if (deviceId >= deviceCount) { - return 0; - } +#define GET_HEADER \ + if (!initialized) { \ + initializePci(); \ + } \ + if (deviceId >= deviceCount) { \ + return 0; \ + } \ PciDevice *device = listGet(pciDevices, deviceId); + +int32_t getDeviceClass(uint32_t deviceId) { + GET_HEADER return device->class << 16 | device->subclass << 8 | device->programmingInterface; } +int32_t getBaseAddress(uint32_t deviceId, uint32_t n) { + GET_HEADER + return device->bar[n]; +} + +int32_t enableBusMaster(uint32_t deviceId) { + GET_HEADER + if (!(device->configuration & 0x04)) { + device->configuration |= 0x0006; + uint16_t oldConfig = device->configuration; + pciConfigWriteByte(device->bus, device->device, device->function, 0x04, + device->configuration); + for (uint32_t i = 0; i < 10000; i++) { + ioIn(0, 1); + } + device->configuration = + pciConfigRead(device->bus, device->device, device->function, 0x04) & + 0xFFFF; + } + return 0; +} + int32_t main() { if (!initialized) { initializePci(); diff --git a/Makefile b/Makefile index d163a1c..0413fc8 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ AS = nasm ASFlAGS = -felf32 EMU = qemu-system-x86_64 -EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci +EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci -device usb-mouse BUILD_FOLDER = build diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 3ca7b01..2129d04 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -60,6 +60,6 @@ extern void reservePagesCount(PagingInfo *info, uint32_t startPageId, uint32_t count); extern void mapPage(PagingInfo *info, void *physical, void *virtual, - bool userPage); + bool userPage, bool isVolatile); #endif diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 51b034e..cc4619e 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -64,7 +64,8 @@ } } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -128,7 +129,7 @@ reservePagesCount(kernelVirtualPages, virtualPageStart, size); for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, ADDRESS(physicalPageStart + i), - ADDRESS(virtualPageStart + i), false); + ADDRESS(virtualPageStart + i), false, false); } return ADDRESS(virtualPageStart) + PAGE_OFFSET(address); } @@ -139,11 +140,12 @@ uint32_t virtualPageId = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtualPageId); mapPage(kernelVirtualPages, ADDRESS(physicalPageId), ADDRESS(virtualPageId), - false); + false, false); return ADDRESS(virtualPageId) + PAGE_OFFSET(address); } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -163,6 +165,7 @@ pageTable[address->pageTableIndex].targetAddress = PAGE_ID(physical); pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].isVolatile = isVolatile; pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(PAGE_ID(virtual)); } @@ -172,7 +175,8 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false); + mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false, + false); return ADDRESS(virtual); } @@ -183,7 +187,7 @@ uint32_t physical = findPage(kernelPhysicalPages); reservePage(kernelPhysicalPages, physical); mapPage(kernelVirtualPages, ADDRESS(physical), - ADDRESS(virtualPageId + i), false); + ADDRESS(virtualPageId + i), false, false); } return ADDRESS(virtualPageId); } @@ -195,10 +199,10 @@ getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); if (!destinationAddress) { void *target = ADDRESS(findPage(destination)); - mapPage(destination, physicalSource, target, true); + mapPage(destination, physicalSource, target, true, false); return target + PAGE_OFFSET(sourceAddress); } - mapPage(destination, physicalSource, destinationAddress, true); + mapPage(destination, physicalSource, destinationAddress, true, false); return destinationAddress; } diff --git a/src/kernel/service/memorySyscalls.c b/src/kernel/service/memorySyscalls.c index 1711cb4..ef93d5f 100644 --- a/src/kernel/service/memorySyscalls.c +++ b/src/kernel/service/memorySyscalls.c @@ -20,14 +20,14 @@ uint32_t physicalPage = findPage(kernelPhysicalPages); reservePagesCount(kernelPhysicalPages, physicalPage, 1); mapPage(&service->pagingInfo, ADDRESS(physicalPage), - ADDRESS(virtualStart + i), true); + ADDRESS(virtualStart + i), true, false); } } else { uint32_t physicalPage = PAGE_ID(physical); reservePagesCount(kernelPhysicalPages, physicalPage, pageCount); for (uint32_t i = 0; i < pageCount; i++) { mapPage(&service->pagingInfo, ADDRESS(physicalPage + i), - ADDRESS(virtualStart + i), true); + ADDRESS(virtualStart + i), true, true); } } call->returnValue = U32(ADDRESS(virtualStart)) + (U32(physical) & 0xFFF); diff --git a/src/userland/lspci/main.c b/src/userland/lspci/main.c index 33ac1cd..c66e2a9 100644 --- a/src/userland/lspci/main.c +++ b/src/userland/lspci/main.c @@ -33,74 +33,82 @@ ListElement *pciDevices = NULL; bool initialized = false; -uint8_t pciConfigReadByte(uint32_t bus, uint32_t device, uint32_t function, - uint8_t offset) { +uint32_t pciConfigRead(uint32_t bus, uint32_t device, uint32_t function, + uint8_t offset) { uint32_t address = ((bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC) | 0x80000000); ioOut(0xCF8, address, 4); - uint8_t result = (ioIn(0xCFC, 4) >> ((offset % 4) * 8)); + uint32_t result = ioIn(0xCFC, 4) >> ((offset % 4) * 8); return result; } void pciConfigWriteByte(uint32_t bus, uint32_t device, uint32_t function, - uint8_t offset, uint8_t data) { - uint32_t address = ((bus << 16) | (device << 11) | (function << 8) | - (offset & 0xFC) | 0x80000000); + uint8_t offset, uint32_t data) { + uint32_t address = + (bus << 16) | (device << 11) | (function << 8) | offset | 0x80000000; ioOut(0xCF8, address, 4); - ioOut(0xCFC, data, 1); + ioOut(0xCFC, data, 2); } -uint16_t pciConfigReadWord(uint8_t bus, uint8_t device, uint8_t function, - uint8_t offset) { - return (uint16_t)pciConfigReadByte(bus, device, function, offset) | - ((uint16_t)pciConfigReadByte(bus, device, function, offset + 1) - << 8); +// uint16_t pciConfigReadWord(uint8_t bus, uint8_t device, uint8_t function, +// uint8_t offset) { +// return (uint16_t)pciConfigReadByte(bus, device, function, offset) | +// ((uint16_t)pciConfigReadByte(bus, device, function, offset + 1) +// << 8); +//} + +void pciConfigWriteWord(uint8_t bus, uint8_t device, uint8_t function, + uint8_t offset, uint16_t data) { + pciConfigWriteByte(bus, device, function, offset, (uint8_t)data); + pciConfigWriteByte(bus, device, function, offset + 1, (uint8_t)(data >> 8)); } -uint32_t pciConfigReadInt(uint8_t bus, uint8_t device, uint8_t function, - uint8_t offset) { - return (uint32_t)pciConfigReadWord(bus, device, function, offset) | - ((uint32_t)pciConfigReadWord(bus, device, function, offset + 2) - << 16); -} +// uint32_t pciConfigReadInt(uint8_t bus, uint8_t device, uint8_t function, +// uint8_t offset) { +// return (uint32_t)pciConfigReadWord(bus, device, function, offset) | +// ((uint32_t)pciConfigReadWord(bus, device, function, offset + 2) +// << 16); +//} uint8_t getHeaderType(uint8_t bus, uint8_t device, uint8_t function) { - return pciConfigReadByte(bus, device, function, 0x0E); + return pciConfigRead(bus, device, function, 0x0E) & 0xFF; } uint16_t getVendorID(uint8_t bus, uint8_t device, uint8_t function) { - return pciConfigReadWord(bus, device, function, 0); + return pciConfigRead(bus, device, function, 0) & 0xFFFF; } void checkBus(uint8_t); void checkFunction(uint8_t bus, uint8_t device, uint8_t function) { - uint8_t class = pciConfigReadByte(bus, device, function, 0xB); + uint8_t class = pciConfigRead(bus, device, function, 0xB) & 0xFF; if (!class || class == 0xFF) { return; } - uint8_t subclass = pciConfigReadByte(bus, device, function, 0xA); + uint8_t subclass = pciConfigRead(bus, device, function, 0xA) & 0xFF; PciDevice *pciDevice = malloc(sizeof(PciDevice)); pciDevice->bus = bus; pciDevice->device = device; pciDevice->function = function; pciDevice->class = class; pciDevice->subclass = subclass; - pciDevice->vendorId = pciConfigReadWord(bus, device, function, 0x00); - pciDevice->deviceId = pciConfigReadWord(bus, device, function, 0x02); + pciDevice->vendorId = pciConfigRead(bus, device, function, 0x00) & 0xFFFF; + pciDevice->deviceId = pciConfigRead(bus, device, function, 0x02) & 0xFFFF; pciDevice->programmingInterface = - pciConfigReadByte(bus, device, function, 0x09); - pciDevice->bar0 = pciConfigReadInt(bus, device, function, 0x10); - pciDevice->bar1 = pciConfigReadInt(bus, device, function, 0x14); - pciDevice->bar2 = pciConfigReadInt(bus, device, function, 0x18); - pciDevice->bar3 = pciConfigReadInt(bus, device, function, 0x1C); - pciDevice->bar4 = pciConfigReadInt(bus, device, function, 0x20); - pciDevice->bar5 = pciConfigReadInt(bus, device, function, 0x24); + pciConfigRead(bus, device, function, 0x09) & 0xFF; + pciDevice->configuration = + pciConfigRead(bus, device, function, 0x04) & 0xFFFF; + pciDevice->bar[0] = pciConfigRead(bus, device, function, 0x10); + pciDevice->bar[1] = pciConfigRead(bus, device, function, 0x14); + pciDevice->bar[2] = pciConfigRead(bus, device, function, 0x18); + pciDevice->bar[3] = pciConfigRead(bus, device, function, 0x1C); + pciDevice->bar[4] = pciConfigRead(bus, device, function, 0x20); + pciDevice->bar[5] = pciConfigRead(bus, device, function, 0x24); listAdd(&pciDevices, pciDevice); - printf("device at %i/%i/%i: %s\n", bus, device, function, classNames[class], - subclass); + printf("device at %i/%i/%i: %s/%i bar0: %x\n", bus, device, function, + classNames[class], subclass, pciDevice->bar[0]); if (class == 6 && subclass == 4) { - checkBus(pciConfigReadByte(bus, device, function, 0x19)); + checkBus(pciConfigRead(bus, device, function, 0x19) & 0xFF); } } @@ -132,9 +140,13 @@ } int32_t getDeviceClass(uint32_t deviceId); +int32_t getBaseAddress(uint32_t deviceId, uint32_t n); +int32_t enableBusMaster(uint32_t deviceId); void initializePci() { createFunction("getDeviceClass", (void *)getDeviceClass); + createFunction("getBaseAddress", (void *)getBaseAddress); + createFunction("enableBusMaster", (void *)enableBusMaster); if (!(getHeaderType(0, 0, 0) & 0x80)) { checkBus(0); } else { @@ -146,18 +158,43 @@ initialized = true; } -int32_t getDeviceClass(uint32_t deviceId) { - if (!initialized) { - initializePci(); - } - if (deviceId >= deviceCount) { - return 0; - } +#define GET_HEADER \ + if (!initialized) { \ + initializePci(); \ + } \ + if (deviceId >= deviceCount) { \ + return 0; \ + } \ PciDevice *device = listGet(pciDevices, deviceId); + +int32_t getDeviceClass(uint32_t deviceId) { + GET_HEADER return device->class << 16 | device->subclass << 8 | device->programmingInterface; } +int32_t getBaseAddress(uint32_t deviceId, uint32_t n) { + GET_HEADER + return device->bar[n]; +} + +int32_t enableBusMaster(uint32_t deviceId) { + GET_HEADER + if (!(device->configuration & 0x04)) { + device->configuration |= 0x0006; + uint16_t oldConfig = device->configuration; + pciConfigWriteByte(device->bus, device->device, device->function, 0x04, + device->configuration); + for (uint32_t i = 0; i < 10000; i++) { + ioIn(0, 1); + } + device->configuration = + pciConfigRead(device->bus, device->device, device->function, 0x04) & + 0xFFFF; + } + return 0; +} + int32_t main() { if (!initialized) { initializePci(); diff --git a/src/userland/lspci/pci.h b/src/userland/lspci/pci.h index 4e8d258..b54720c 100644 --- a/src/userland/lspci/pci.h +++ b/src/userland/lspci/pci.h @@ -6,8 +6,9 @@ typedef struct { uint8_t bus, device, function; uint8_t class, subclass; + uint16_t configuration; uint16_t deviceId, vendorId, programmingInterface; - uint32_t bar0, bar1, bar2, bar3, bar4, bar5; + uint32_t bar[6]; } PciDevice; #endif diff --git a/Makefile b/Makefile index d163a1c..0413fc8 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ AS = nasm ASFlAGS = -felf32 EMU = qemu-system-x86_64 -EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci +EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci -device usb-mouse BUILD_FOLDER = build diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 3ca7b01..2129d04 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -60,6 +60,6 @@ extern void reservePagesCount(PagingInfo *info, uint32_t startPageId, uint32_t count); extern void mapPage(PagingInfo *info, void *physical, void *virtual, - bool userPage); + bool userPage, bool isVolatile); #endif diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 51b034e..cc4619e 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -64,7 +64,8 @@ } } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -128,7 +129,7 @@ reservePagesCount(kernelVirtualPages, virtualPageStart, size); for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, ADDRESS(physicalPageStart + i), - ADDRESS(virtualPageStart + i), false); + ADDRESS(virtualPageStart + i), false, false); } return ADDRESS(virtualPageStart) + PAGE_OFFSET(address); } @@ -139,11 +140,12 @@ uint32_t virtualPageId = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtualPageId); mapPage(kernelVirtualPages, ADDRESS(physicalPageId), ADDRESS(virtualPageId), - false); + false, false); return ADDRESS(virtualPageId) + PAGE_OFFSET(address); } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -163,6 +165,7 @@ pageTable[address->pageTableIndex].targetAddress = PAGE_ID(physical); pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].isVolatile = isVolatile; pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(PAGE_ID(virtual)); } @@ -172,7 +175,8 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false); + mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false, + false); return ADDRESS(virtual); } @@ -183,7 +187,7 @@ uint32_t physical = findPage(kernelPhysicalPages); reservePage(kernelPhysicalPages, physical); mapPage(kernelVirtualPages, ADDRESS(physical), - ADDRESS(virtualPageId + i), false); + ADDRESS(virtualPageId + i), false, false); } return ADDRESS(virtualPageId); } @@ -195,10 +199,10 @@ getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); if (!destinationAddress) { void *target = ADDRESS(findPage(destination)); - mapPage(destination, physicalSource, target, true); + mapPage(destination, physicalSource, target, true, false); return target + PAGE_OFFSET(sourceAddress); } - mapPage(destination, physicalSource, destinationAddress, true); + mapPage(destination, physicalSource, destinationAddress, true, false); return destinationAddress; } diff --git a/src/kernel/service/memorySyscalls.c b/src/kernel/service/memorySyscalls.c index 1711cb4..ef93d5f 100644 --- a/src/kernel/service/memorySyscalls.c +++ b/src/kernel/service/memorySyscalls.c @@ -20,14 +20,14 @@ uint32_t physicalPage = findPage(kernelPhysicalPages); reservePagesCount(kernelPhysicalPages, physicalPage, 1); mapPage(&service->pagingInfo, ADDRESS(physicalPage), - ADDRESS(virtualStart + i), true); + ADDRESS(virtualStart + i), true, false); } } else { uint32_t physicalPage = PAGE_ID(physical); reservePagesCount(kernelPhysicalPages, physicalPage, pageCount); for (uint32_t i = 0; i < pageCount; i++) { mapPage(&service->pagingInfo, ADDRESS(physicalPage + i), - ADDRESS(virtualStart + i), true); + ADDRESS(virtualStart + i), true, true); } } call->returnValue = U32(ADDRESS(virtualStart)) + (U32(physical) & 0xFFF); diff --git a/src/userland/lspci/main.c b/src/userland/lspci/main.c index 33ac1cd..c66e2a9 100644 --- a/src/userland/lspci/main.c +++ b/src/userland/lspci/main.c @@ -33,74 +33,82 @@ ListElement *pciDevices = NULL; bool initialized = false; -uint8_t pciConfigReadByte(uint32_t bus, uint32_t device, uint32_t function, - uint8_t offset) { +uint32_t pciConfigRead(uint32_t bus, uint32_t device, uint32_t function, + uint8_t offset) { uint32_t address = ((bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC) | 0x80000000); ioOut(0xCF8, address, 4); - uint8_t result = (ioIn(0xCFC, 4) >> ((offset % 4) * 8)); + uint32_t result = ioIn(0xCFC, 4) >> ((offset % 4) * 8); return result; } void pciConfigWriteByte(uint32_t bus, uint32_t device, uint32_t function, - uint8_t offset, uint8_t data) { - uint32_t address = ((bus << 16) | (device << 11) | (function << 8) | - (offset & 0xFC) | 0x80000000); + uint8_t offset, uint32_t data) { + uint32_t address = + (bus << 16) | (device << 11) | (function << 8) | offset | 0x80000000; ioOut(0xCF8, address, 4); - ioOut(0xCFC, data, 1); + ioOut(0xCFC, data, 2); } -uint16_t pciConfigReadWord(uint8_t bus, uint8_t device, uint8_t function, - uint8_t offset) { - return (uint16_t)pciConfigReadByte(bus, device, function, offset) | - ((uint16_t)pciConfigReadByte(bus, device, function, offset + 1) - << 8); +// uint16_t pciConfigReadWord(uint8_t bus, uint8_t device, uint8_t function, +// uint8_t offset) { +// return (uint16_t)pciConfigReadByte(bus, device, function, offset) | +// ((uint16_t)pciConfigReadByte(bus, device, function, offset + 1) +// << 8); +//} + +void pciConfigWriteWord(uint8_t bus, uint8_t device, uint8_t function, + uint8_t offset, uint16_t data) { + pciConfigWriteByte(bus, device, function, offset, (uint8_t)data); + pciConfigWriteByte(bus, device, function, offset + 1, (uint8_t)(data >> 8)); } -uint32_t pciConfigReadInt(uint8_t bus, uint8_t device, uint8_t function, - uint8_t offset) { - return (uint32_t)pciConfigReadWord(bus, device, function, offset) | - ((uint32_t)pciConfigReadWord(bus, device, function, offset + 2) - << 16); -} +// uint32_t pciConfigReadInt(uint8_t bus, uint8_t device, uint8_t function, +// uint8_t offset) { +// return (uint32_t)pciConfigReadWord(bus, device, function, offset) | +// ((uint32_t)pciConfigReadWord(bus, device, function, offset + 2) +// << 16); +//} uint8_t getHeaderType(uint8_t bus, uint8_t device, uint8_t function) { - return pciConfigReadByte(bus, device, function, 0x0E); + return pciConfigRead(bus, device, function, 0x0E) & 0xFF; } uint16_t getVendorID(uint8_t bus, uint8_t device, uint8_t function) { - return pciConfigReadWord(bus, device, function, 0); + return pciConfigRead(bus, device, function, 0) & 0xFFFF; } void checkBus(uint8_t); void checkFunction(uint8_t bus, uint8_t device, uint8_t function) { - uint8_t class = pciConfigReadByte(bus, device, function, 0xB); + uint8_t class = pciConfigRead(bus, device, function, 0xB) & 0xFF; if (!class || class == 0xFF) { return; } - uint8_t subclass = pciConfigReadByte(bus, device, function, 0xA); + uint8_t subclass = pciConfigRead(bus, device, function, 0xA) & 0xFF; PciDevice *pciDevice = malloc(sizeof(PciDevice)); pciDevice->bus = bus; pciDevice->device = device; pciDevice->function = function; pciDevice->class = class; pciDevice->subclass = subclass; - pciDevice->vendorId = pciConfigReadWord(bus, device, function, 0x00); - pciDevice->deviceId = pciConfigReadWord(bus, device, function, 0x02); + pciDevice->vendorId = pciConfigRead(bus, device, function, 0x00) & 0xFFFF; + pciDevice->deviceId = pciConfigRead(bus, device, function, 0x02) & 0xFFFF; pciDevice->programmingInterface = - pciConfigReadByte(bus, device, function, 0x09); - pciDevice->bar0 = pciConfigReadInt(bus, device, function, 0x10); - pciDevice->bar1 = pciConfigReadInt(bus, device, function, 0x14); - pciDevice->bar2 = pciConfigReadInt(bus, device, function, 0x18); - pciDevice->bar3 = pciConfigReadInt(bus, device, function, 0x1C); - pciDevice->bar4 = pciConfigReadInt(bus, device, function, 0x20); - pciDevice->bar5 = pciConfigReadInt(bus, device, function, 0x24); + pciConfigRead(bus, device, function, 0x09) & 0xFF; + pciDevice->configuration = + pciConfigRead(bus, device, function, 0x04) & 0xFFFF; + pciDevice->bar[0] = pciConfigRead(bus, device, function, 0x10); + pciDevice->bar[1] = pciConfigRead(bus, device, function, 0x14); + pciDevice->bar[2] = pciConfigRead(bus, device, function, 0x18); + pciDevice->bar[3] = pciConfigRead(bus, device, function, 0x1C); + pciDevice->bar[4] = pciConfigRead(bus, device, function, 0x20); + pciDevice->bar[5] = pciConfigRead(bus, device, function, 0x24); listAdd(&pciDevices, pciDevice); - printf("device at %i/%i/%i: %s\n", bus, device, function, classNames[class], - subclass); + printf("device at %i/%i/%i: %s/%i bar0: %x\n", bus, device, function, + classNames[class], subclass, pciDevice->bar[0]); if (class == 6 && subclass == 4) { - checkBus(pciConfigReadByte(bus, device, function, 0x19)); + checkBus(pciConfigRead(bus, device, function, 0x19) & 0xFF); } } @@ -132,9 +140,13 @@ } int32_t getDeviceClass(uint32_t deviceId); +int32_t getBaseAddress(uint32_t deviceId, uint32_t n); +int32_t enableBusMaster(uint32_t deviceId); void initializePci() { createFunction("getDeviceClass", (void *)getDeviceClass); + createFunction("getBaseAddress", (void *)getBaseAddress); + createFunction("enableBusMaster", (void *)enableBusMaster); if (!(getHeaderType(0, 0, 0) & 0x80)) { checkBus(0); } else { @@ -146,18 +158,43 @@ initialized = true; } -int32_t getDeviceClass(uint32_t deviceId) { - if (!initialized) { - initializePci(); - } - if (deviceId >= deviceCount) { - return 0; - } +#define GET_HEADER \ + if (!initialized) { \ + initializePci(); \ + } \ + if (deviceId >= deviceCount) { \ + return 0; \ + } \ PciDevice *device = listGet(pciDevices, deviceId); + +int32_t getDeviceClass(uint32_t deviceId) { + GET_HEADER return device->class << 16 | device->subclass << 8 | device->programmingInterface; } +int32_t getBaseAddress(uint32_t deviceId, uint32_t n) { + GET_HEADER + return device->bar[n]; +} + +int32_t enableBusMaster(uint32_t deviceId) { + GET_HEADER + if (!(device->configuration & 0x04)) { + device->configuration |= 0x0006; + uint16_t oldConfig = device->configuration; + pciConfigWriteByte(device->bus, device->device, device->function, 0x04, + device->configuration); + for (uint32_t i = 0; i < 10000; i++) { + ioIn(0, 1); + } + device->configuration = + pciConfigRead(device->bus, device->device, device->function, 0x04) & + 0xFFFF; + } + return 0; +} + int32_t main() { if (!initialized) { initializePci(); diff --git a/src/userland/lspci/pci.h b/src/userland/lspci/pci.h index 4e8d258..b54720c 100644 --- a/src/userland/lspci/pci.h +++ b/src/userland/lspci/pci.h @@ -6,8 +6,9 @@ typedef struct { uint8_t bus, device, function; uint8_t class, subclass; + uint16_t configuration; uint16_t deviceId, vendorId, programmingInterface; - uint32_t bar0, bar1, bar2, bar3, bar4, bar5; + uint32_t bar[6]; } PciDevice; #endif diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index a6457bd..104e08c 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -3,12 +3,43 @@ #include "usb.h" +#define REQUEST(functionName, service, function) \ + uint32_t functionName(uint32_t data1, uint32_t data2) { \ + static uint32_t serviceId = 0; \ + if (!serviceId) { \ + serviceId = getService(service); \ + } \ + static uint32_t functionId = 0; \ + if (!functionId) { \ + functionId = getFunction(serviceId, function); \ + } \ + return request(serviceId, functionId, data1, data2); \ + } + +REQUEST(getBaseAddress, "lspci", "getBaseAddress"); +REQUEST(getDeviceClass, "lspci", "getDeviceClass"); + +REQUEST(enableBusMaster, "lspci", "enableBusMaster"); + +void initializeUSB(uint32_t deviceId) { + enableBusMaster(deviceId, 0); + uint32_t baseAddress = getBaseAddress(deviceId, 0) & ~0xF; + XHCICapabilities *capabilities = requestMemory(1, NULL, PTR(baseAddress)); + uint32_t *ptr = (void *)capabilities; + printf("%x: capSize: 0x%x, version: 0x%x %x\n", capabilities, + capabilities->capabilitiesSize, capabilities->interfaceVersion, + ptr[0]); +} + int32_t main() { uint32_t pciService = getService("lspci"); uint32_t function = getFunction(pciService, "getDeviceClass"); uint32_t i = 0, class = 0; while ((class = request(pciService, function, i, 0))) { - printf("device %i has class 0x%x\n", i, class); + if (class == 0x0C0330) { + printf("found XHCI host controller at pci no. %i\n", i); + initializeUSB(i); + } i++; } } diff --git a/Makefile b/Makefile index d163a1c..0413fc8 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ AS = nasm ASFlAGS = -felf32 EMU = qemu-system-x86_64 -EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci +EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio -d int -D crashlog.log -s -d int -device qemu-xhci -device usb-mouse BUILD_FOLDER = build diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 3ca7b01..2129d04 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -60,6 +60,6 @@ extern void reservePagesCount(PagingInfo *info, uint32_t startPageId, uint32_t count); extern void mapPage(PagingInfo *info, void *physical, void *virtual, - bool userPage); + bool userPage, bool isVolatile); #endif diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 51b034e..cc4619e 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -64,7 +64,8 @@ } } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -128,7 +129,7 @@ reservePagesCount(kernelVirtualPages, virtualPageStart, size); for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, ADDRESS(physicalPageStart + i), - ADDRESS(virtualPageStart + i), false); + ADDRESS(virtualPageStart + i), false, false); } return ADDRESS(virtualPageStart) + PAGE_OFFSET(address); } @@ -139,11 +140,12 @@ uint32_t virtualPageId = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtualPageId); mapPage(kernelVirtualPages, ADDRESS(physicalPageId), ADDRESS(virtualPageId), - false); + false, false); return ADDRESS(virtualPageId) + PAGE_OFFSET(address); } -void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage, + bool isVolatile) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -163,6 +165,7 @@ pageTable[address->pageTableIndex].targetAddress = PAGE_ID(physical); pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].isVolatile = isVolatile; pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(PAGE_ID(virtual)); } @@ -172,7 +175,8 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false); + mapPage(kernelVirtualPages, ADDRESS(physical), ADDRESS(virtual), false, + false); return ADDRESS(virtual); } @@ -183,7 +187,7 @@ uint32_t physical = findPage(kernelPhysicalPages); reservePage(kernelPhysicalPages, physical); mapPage(kernelVirtualPages, ADDRESS(physical), - ADDRESS(virtualPageId + i), false); + ADDRESS(virtualPageId + i), false, false); } return ADDRESS(virtualPageId); } @@ -195,10 +199,10 @@ getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); if (!destinationAddress) { void *target = ADDRESS(findPage(destination)); - mapPage(destination, physicalSource, target, true); + mapPage(destination, physicalSource, target, true, false); return target + PAGE_OFFSET(sourceAddress); } - mapPage(destination, physicalSource, destinationAddress, true); + mapPage(destination, physicalSource, destinationAddress, true, false); return destinationAddress; } diff --git a/src/kernel/service/memorySyscalls.c b/src/kernel/service/memorySyscalls.c index 1711cb4..ef93d5f 100644 --- a/src/kernel/service/memorySyscalls.c +++ b/src/kernel/service/memorySyscalls.c @@ -20,14 +20,14 @@ uint32_t physicalPage = findPage(kernelPhysicalPages); reservePagesCount(kernelPhysicalPages, physicalPage, 1); mapPage(&service->pagingInfo, ADDRESS(physicalPage), - ADDRESS(virtualStart + i), true); + ADDRESS(virtualStart + i), true, false); } } else { uint32_t physicalPage = PAGE_ID(physical); reservePagesCount(kernelPhysicalPages, physicalPage, pageCount); for (uint32_t i = 0; i < pageCount; i++) { mapPage(&service->pagingInfo, ADDRESS(physicalPage + i), - ADDRESS(virtualStart + i), true); + ADDRESS(virtualStart + i), true, true); } } call->returnValue = U32(ADDRESS(virtualStart)) + (U32(physical) & 0xFFF); diff --git a/src/userland/lspci/main.c b/src/userland/lspci/main.c index 33ac1cd..c66e2a9 100644 --- a/src/userland/lspci/main.c +++ b/src/userland/lspci/main.c @@ -33,74 +33,82 @@ ListElement *pciDevices = NULL; bool initialized = false; -uint8_t pciConfigReadByte(uint32_t bus, uint32_t device, uint32_t function, - uint8_t offset) { +uint32_t pciConfigRead(uint32_t bus, uint32_t device, uint32_t function, + uint8_t offset) { uint32_t address = ((bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC) | 0x80000000); ioOut(0xCF8, address, 4); - uint8_t result = (ioIn(0xCFC, 4) >> ((offset % 4) * 8)); + uint32_t result = ioIn(0xCFC, 4) >> ((offset % 4) * 8); return result; } void pciConfigWriteByte(uint32_t bus, uint32_t device, uint32_t function, - uint8_t offset, uint8_t data) { - uint32_t address = ((bus << 16) | (device << 11) | (function << 8) | - (offset & 0xFC) | 0x80000000); + uint8_t offset, uint32_t data) { + uint32_t address = + (bus << 16) | (device << 11) | (function << 8) | offset | 0x80000000; ioOut(0xCF8, address, 4); - ioOut(0xCFC, data, 1); + ioOut(0xCFC, data, 2); } -uint16_t pciConfigReadWord(uint8_t bus, uint8_t device, uint8_t function, - uint8_t offset) { - return (uint16_t)pciConfigReadByte(bus, device, function, offset) | - ((uint16_t)pciConfigReadByte(bus, device, function, offset + 1) - << 8); +// uint16_t pciConfigReadWord(uint8_t bus, uint8_t device, uint8_t function, +// uint8_t offset) { +// return (uint16_t)pciConfigReadByte(bus, device, function, offset) | +// ((uint16_t)pciConfigReadByte(bus, device, function, offset + 1) +// << 8); +//} + +void pciConfigWriteWord(uint8_t bus, uint8_t device, uint8_t function, + uint8_t offset, uint16_t data) { + pciConfigWriteByte(bus, device, function, offset, (uint8_t)data); + pciConfigWriteByte(bus, device, function, offset + 1, (uint8_t)(data >> 8)); } -uint32_t pciConfigReadInt(uint8_t bus, uint8_t device, uint8_t function, - uint8_t offset) { - return (uint32_t)pciConfigReadWord(bus, device, function, offset) | - ((uint32_t)pciConfigReadWord(bus, device, function, offset + 2) - << 16); -} +// uint32_t pciConfigReadInt(uint8_t bus, uint8_t device, uint8_t function, +// uint8_t offset) { +// return (uint32_t)pciConfigReadWord(bus, device, function, offset) | +// ((uint32_t)pciConfigReadWord(bus, device, function, offset + 2) +// << 16); +//} uint8_t getHeaderType(uint8_t bus, uint8_t device, uint8_t function) { - return pciConfigReadByte(bus, device, function, 0x0E); + return pciConfigRead(bus, device, function, 0x0E) & 0xFF; } uint16_t getVendorID(uint8_t bus, uint8_t device, uint8_t function) { - return pciConfigReadWord(bus, device, function, 0); + return pciConfigRead(bus, device, function, 0) & 0xFFFF; } void checkBus(uint8_t); void checkFunction(uint8_t bus, uint8_t device, uint8_t function) { - uint8_t class = pciConfigReadByte(bus, device, function, 0xB); + uint8_t class = pciConfigRead(bus, device, function, 0xB) & 0xFF; if (!class || class == 0xFF) { return; } - uint8_t subclass = pciConfigReadByte(bus, device, function, 0xA); + uint8_t subclass = pciConfigRead(bus, device, function, 0xA) & 0xFF; PciDevice *pciDevice = malloc(sizeof(PciDevice)); pciDevice->bus = bus; pciDevice->device = device; pciDevice->function = function; pciDevice->class = class; pciDevice->subclass = subclass; - pciDevice->vendorId = pciConfigReadWord(bus, device, function, 0x00); - pciDevice->deviceId = pciConfigReadWord(bus, device, function, 0x02); + pciDevice->vendorId = pciConfigRead(bus, device, function, 0x00) & 0xFFFF; + pciDevice->deviceId = pciConfigRead(bus, device, function, 0x02) & 0xFFFF; pciDevice->programmingInterface = - pciConfigReadByte(bus, device, function, 0x09); - pciDevice->bar0 = pciConfigReadInt(bus, device, function, 0x10); - pciDevice->bar1 = pciConfigReadInt(bus, device, function, 0x14); - pciDevice->bar2 = pciConfigReadInt(bus, device, function, 0x18); - pciDevice->bar3 = pciConfigReadInt(bus, device, function, 0x1C); - pciDevice->bar4 = pciConfigReadInt(bus, device, function, 0x20); - pciDevice->bar5 = pciConfigReadInt(bus, device, function, 0x24); + pciConfigRead(bus, device, function, 0x09) & 0xFF; + pciDevice->configuration = + pciConfigRead(bus, device, function, 0x04) & 0xFFFF; + pciDevice->bar[0] = pciConfigRead(bus, device, function, 0x10); + pciDevice->bar[1] = pciConfigRead(bus, device, function, 0x14); + pciDevice->bar[2] = pciConfigRead(bus, device, function, 0x18); + pciDevice->bar[3] = pciConfigRead(bus, device, function, 0x1C); + pciDevice->bar[4] = pciConfigRead(bus, device, function, 0x20); + pciDevice->bar[5] = pciConfigRead(bus, device, function, 0x24); listAdd(&pciDevices, pciDevice); - printf("device at %i/%i/%i: %s\n", bus, device, function, classNames[class], - subclass); + printf("device at %i/%i/%i: %s/%i bar0: %x\n", bus, device, function, + classNames[class], subclass, pciDevice->bar[0]); if (class == 6 && subclass == 4) { - checkBus(pciConfigReadByte(bus, device, function, 0x19)); + checkBus(pciConfigRead(bus, device, function, 0x19) & 0xFF); } } @@ -132,9 +140,13 @@ } int32_t getDeviceClass(uint32_t deviceId); +int32_t getBaseAddress(uint32_t deviceId, uint32_t n); +int32_t enableBusMaster(uint32_t deviceId); void initializePci() { createFunction("getDeviceClass", (void *)getDeviceClass); + createFunction("getBaseAddress", (void *)getBaseAddress); + createFunction("enableBusMaster", (void *)enableBusMaster); if (!(getHeaderType(0, 0, 0) & 0x80)) { checkBus(0); } else { @@ -146,18 +158,43 @@ initialized = true; } -int32_t getDeviceClass(uint32_t deviceId) { - if (!initialized) { - initializePci(); - } - if (deviceId >= deviceCount) { - return 0; - } +#define GET_HEADER \ + if (!initialized) { \ + initializePci(); \ + } \ + if (deviceId >= deviceCount) { \ + return 0; \ + } \ PciDevice *device = listGet(pciDevices, deviceId); + +int32_t getDeviceClass(uint32_t deviceId) { + GET_HEADER return device->class << 16 | device->subclass << 8 | device->programmingInterface; } +int32_t getBaseAddress(uint32_t deviceId, uint32_t n) { + GET_HEADER + return device->bar[n]; +} + +int32_t enableBusMaster(uint32_t deviceId) { + GET_HEADER + if (!(device->configuration & 0x04)) { + device->configuration |= 0x0006; + uint16_t oldConfig = device->configuration; + pciConfigWriteByte(device->bus, device->device, device->function, 0x04, + device->configuration); + for (uint32_t i = 0; i < 10000; i++) { + ioIn(0, 1); + } + device->configuration = + pciConfigRead(device->bus, device->device, device->function, 0x04) & + 0xFFFF; + } + return 0; +} + int32_t main() { if (!initialized) { initializePci(); diff --git a/src/userland/lspci/pci.h b/src/userland/lspci/pci.h index 4e8d258..b54720c 100644 --- a/src/userland/lspci/pci.h +++ b/src/userland/lspci/pci.h @@ -6,8 +6,9 @@ typedef struct { uint8_t bus, device, function; uint8_t class, subclass; + uint16_t configuration; uint16_t deviceId, vendorId, programmingInterface; - uint32_t bar0, bar1, bar2, bar3, bar4, bar5; + uint32_t bar[6]; } PciDevice; #endif diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index a6457bd..104e08c 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -3,12 +3,43 @@ #include "usb.h" +#define REQUEST(functionName, service, function) \ + uint32_t functionName(uint32_t data1, uint32_t data2) { \ + static uint32_t serviceId = 0; \ + if (!serviceId) { \ + serviceId = getService(service); \ + } \ + static uint32_t functionId = 0; \ + if (!functionId) { \ + functionId = getFunction(serviceId, function); \ + } \ + return request(serviceId, functionId, data1, data2); \ + } + +REQUEST(getBaseAddress, "lspci", "getBaseAddress"); +REQUEST(getDeviceClass, "lspci", "getDeviceClass"); + +REQUEST(enableBusMaster, "lspci", "enableBusMaster"); + +void initializeUSB(uint32_t deviceId) { + enableBusMaster(deviceId, 0); + uint32_t baseAddress = getBaseAddress(deviceId, 0) & ~0xF; + XHCICapabilities *capabilities = requestMemory(1, NULL, PTR(baseAddress)); + uint32_t *ptr = (void *)capabilities; + printf("%x: capSize: 0x%x, version: 0x%x %x\n", capabilities, + capabilities->capabilitiesSize, capabilities->interfaceVersion, + ptr[0]); +} + int32_t main() { uint32_t pciService = getService("lspci"); uint32_t function = getFunction(pciService, "getDeviceClass"); uint32_t i = 0, class = 0; while ((class = request(pciService, function, i, 0))) { - printf("device %i has class 0x%x\n", i, class); + if (class == 0x0C0330) { + printf("found XHCI host controller at pci no. %i\n", i); + initializeUSB(i); + } i++; } } diff --git a/src/userland/usb/usb.h b/src/userland/usb/usb.h index 947aa51..2092c14 100644 --- a/src/userland/usb/usb.h +++ b/src/userland/usb/usb.h @@ -3,4 +3,15 @@ #include +typedef struct { + uint8_t capabilitiesSize; + uint8_t reserved; + uint16_t interfaceVersion; + uint32_t structuralParameters[3]; + uint32_t capabilityParameters1; + uint32_t doorbellOffset; + uint32_t runtimeRegistersSpaceOffset; + uint32_t capabilityParameters2; +} XHCICapabilities; + #endif