From 4d9b1e390d14c73e49f35a753cac67438111333a Mon Sep 17 00:00:00 2001 From: Eric-Paul Ickhorn Date: Sun, 21 Jul 2024 10:26:32 +0200 Subject: [PATCH] Make PCI enumeration write more information The PCI enumeration did, until now, only write a PCI device's address into the device area. Now, it also writes the class and subclass. --- i386/loader/src-asm/drivers/pci/enumerate.asm | 132 +++++++++++++++--- 1 file changed, 114 insertions(+), 18 deletions(-) diff --git a/i386/loader/src-asm/drivers/pci/enumerate.asm b/i386/loader/src-asm/drivers/pci/enumerate.asm index 6a17bf9..14424e0 100755 --- a/i386/loader/src-asm/drivers/pci/enumerate.asm +++ b/i386/loader/src-asm/drivers/pci/enumerate.asm @@ -58,9 +58,11 @@ pci_device_exists: ; Arguments: ; [FURTHEST FROM EBP] -; 3. U32 PCI Device Class & Subclass +; 3. U16 PCI Device Class & Subclass ; (Higher byte: Class, lower byte: Subclass) -; 2. U32 PCI Device Address +; 2. U16 PCI Device Address +; (Higher byte: Bus Address, +; lower byte: Device Address) ; 1. Ptr32 Pointer to PCI driver area of 65536 bytes ; [NEAREST TO EBP] pci_append_device: @@ -81,19 +83,21 @@ pci_append_device: .calculate_device_offset: ; Every device slot has 16 bytes, multiply index with 16 - shl cx, 4 + shl ecx, 4 ; Point into driver device area (add device area start on top) - add ecx, ebx - add ecx, PCI_DEVICE_COUNT_OFFSET - mov ebx, ecx + mov ebx, [ebp - 4] + add ebx, PCI_DEVICE_AREA_OFFSET + add ebx, ecx .set_device: - mov ecx, [ebp - 8] - mov [ebx], ecx - mov ecx, [ebp - 12] - mov [ebx + 4], ecx + mov cx, [ebp - 6] + mov [ebx], cx + mov cx, [ebp - 8] + mov [ebx + 2], cx -increment_device_count: +.increment_device_count: + mov ebx, [ebp - 4] + inc word [ebx + PCI_DEVICE_COUNT_OFFSET] .epilog: mov eax, [esi + (64 - 4)] @@ -107,6 +111,68 @@ increment_device_count: +; Arguments: +; [FURTHER FROM EBP] +; 2. U16 Device Number +; 1. U16 Bus Number +; [NEAREST TO EBP] +; +; Returns: +; ax PCI Device Class & Subclass +; (Higher byte: Class, lower byte: Subclass) +pci_get_device_class_at_address: + push dword esi + sub esp, 64 + mov esi, esp + + mov [esi + (64 - 8)], ebx + mov [esi + (64 - 12)], ecx + mov [esi + (64 - 16)], edx + mov [esi + (64 - 20)], edi + +.create_address: + xor eax, eax + ; Enable Bit + or al, 1 + ; Make space for 8 Reserved Bits and 8 Bytes of bus number. + shl eax, 15 + ; Bus Number + mov al, [ebp - 2] + ; Device Number + shl eax, 5 ; Make space for device number + mov dl, [ebp - 4] + and dl, 0x1f + or al, dl + shl eax, 11 + + ; Include the register offset of the configuration space + ; register which contains the class and subclass + or eax, 8 + +.input_output: + + mov dx, PCI_CONFIG_ADDRESS_PORT + out dx, eax + + mov dx, PCI_CONFIG_DATA_PORT + in eax, dx + + ; Remove the parts of the register which aren't part of the + ; PCI class- and subclass-code + shr eax, 16 + +.epilog: + mov ebx, [esi + (64 - 8)] + mov ecx, [esi + (64 - 12)] + mov edx, [esi + (64 - 16)] + mov edi, [esi + (64 - 20)] + + add esp, 64 + pop dword esi + ret + + + ; Arguments: ; [FURTHER FROM EBP] ; 2. U32 Bus Number (0 .. 255) @@ -130,6 +196,8 @@ pci_enumerate_bus: mov [esi + 4], dword 0 mov eax, [ebp - 8] mov [esi + 8], eax + mov eax, [ebp - 4] + mov [esi + 12], eax .initialize_device_loop: .device_loop: @@ -137,10 +205,12 @@ pci_enumerate_bus: jae .epilog .test_whether_device_exists: - push ebp - mov ebp, esp mov ah, [esi + 8] ; Bus Number mov al, [esi] ; Device Number + mov [esi + 16], ax + + push ebp + mov ebp, esp call pci_device_exists mov esp, ebp pop ebp @@ -148,12 +218,32 @@ pci_enumerate_bus: cmp ax, 0 je .no_device -.call_append_device: +.append_device: + mov al, [esi + 8] + mov ah, [esi] + + ; Device Number in DX + xor dx, dx + mov dl, ah + xor ah, ah + + push ebp mov ebp, esp - push dword [esi + 8] - push dword 0xcafebabe - push dword 0xdeadbeef + push ax + push dx + call pci_get_device_class_at_address + mov esp, ebp + pop ebp + + mov cx, ax + mov ax, [esi + 16] + + push ebp + mov ebp, esp + push dword [esi + 12] + push ax + push cx call pci_append_device mov esp, ebp pop ebp @@ -172,6 +262,7 @@ pci_enumerate_bus: mov ebx, [esi + (64 - 8)] mov ecx, [esi + (64 - 12)] mov edi, [esi + (64 - 20)] + mov eax, [esi + 4] add esp, 64 @@ -203,6 +294,11 @@ pci_enumerate: mov edx, [ebp - 4] mov [esi + 4], edx + ; Set the device count to 0 explicitly, just for safety. + mov ebx, [ebp - 4] + add ebx, PCI_DEVICE_COUNT_OFFSET + mov [ebx], word 0 + .bus_loop: xor ecx, ecx mov [esi], dword 0 @@ -247,4 +343,4 @@ pci_enumerate: add esp, 64 pop dword esi - ret \ No newline at end of file + ret