From 40b89c3985a3afa9cd229229343efcaf1a08b4ab Mon Sep 17 00:00:00 2001 From: Eric-Paul Ickhorn Date: Fri, 30 Aug 2024 20:19:07 +0200 Subject: [PATCH] Refactor PCI device enumeration The PCI driver's function 'pci_check_device_exists' can now test for a specific function. There were a few changes connected to that, those have also been done now. --- .../src-asm/drivers/pci/enumerate.asm | 164 +++++++++++------- 1 file changed, 97 insertions(+), 67 deletions(-) diff --git a/i386/legacy-boot/src-asm/drivers/pci/enumerate.asm b/i386/legacy-boot/src-asm/drivers/pci/enumerate.asm index 0b69b45..39405c2 100755 --- a/i386/legacy-boot/src-asm/drivers/pci/enumerate.asm +++ b/i386/legacy-boot/src-asm/drivers/pci/enumerate.asm @@ -1,58 +1,84 @@ ; Arguments: -; ah Bus Number (0 .. 255) -; al Device Number (0 .. 31) +; [Furthest from EBP] +; 2. U16 Function (0 .. 7) +; 1. U16 Device Number (0 .. 31) +; 0. U16 Bus Number (0 .. 255) +; [Nearest to EBP] ; ; Returns: -; - true/false (eax) -pci_device_exists: - push dword esi - sub esp, 8 - mov esi, esp +; eax: If there is NO device at the location: 0 +; If there IS a device at the location: 1 +pci_check_device_exists: +.prolog: + push esi + sub esp, 32 - mov [esi], edx - mov [esi + 4], eax + mov [esi + 24], ebx + mov [esi + 28], edx +.gather_arguments: + mov ax, [ebp - 2] + mov [esi + 4], al + + mov ax, [ebp - 4] + and al, 0x1f + mov [esi + 5], al + + mov ax, [ebp - 6] + and al, 0x07 + mov [esi + 6], al + +; Configuration Space Address (4 bytes): +; [Highest Bit] +; 5. Enable Bit (1) +; 4. Reserved (8) +; 3. Bus Number (8) +; 2. Device Number (4) +; 1. Function Number (3) +; 0. Register Offset (8) +; [Lowest Bit] .make_address: - xor eax, eax - ; Enable Bit - or al, 1 - ; Make space for 8 Reserved Bits and 8 Bytes of bus number. - shl eax, 15 + xor edx, edx + ; Set the Enable Bit + inc edx + ; Make space for 8 Reserved Bits and 8 Bits for the Bus Number. + shl edx, 15 ; Bus Number - mov al, [esi + 5] - ; Device Number - ; Make space for device number - shl eax, 5 mov dl, [esi + 4] - and dl, 0x1f - or al, dl - shl eax, 11 + ; Device Number + shl edx, 5 + or dl, [esi + 5] + ; Function Number + shl edx, 3 + or edx, [esi + 6] + ; Make place for the register offset (which isn't used here). + shl edx, 8 -.input_output: - mov dx, PCI_CONFIG_ADDRESS_PORT - out dx, eax + mov eax, edx - mov dx, PCI_CONFIG_DATA_PORT - in eax, dx + mov dx, PCI_CONFIG_ADDRESS_PORT + out dx, eax - cmp ax, 0xffff - jne .device_found + mov dx, PCI_CONFIG_DATA_PORT + in eax, dx -.not_a_device: - mov edx, [esi] + cmp ax, 0xffff + je .no_device - add esp, 8 - pop dword esi + xor eax, eax + inc eax + jmp .epilog - xor eax, eax - ret -.device_found: - mov edx, [esi] +.no_device: + xor eax, eax - add esp, 8 - pop dword esi - mov eax, 1 +.epilog: + mov ebx, [esi + 24] + mov edx, [esi + 28] + + add esp, 32 + pop esi ret @@ -120,7 +146,7 @@ pci_append_device: ; ; Returns: ; ax PCI Device Class & Subclass -; (Higher byte: Class, lower byte: Subclass) +; (Lower byte: Subclass, Higher byte: Class) pci_get_device_class_at_address: push dword esi sub esp, 64 @@ -163,6 +189,8 @@ pci_get_device_class_at_address: ; PCI class- and subclass-code shr eax, 16 + xchg ah, al + .epilog: mov ebx, [esi + (64 - 8)] mov ecx, [esi + (64 - 12)] @@ -177,7 +205,7 @@ pci_get_device_class_at_address: ; Arguments: ; [FURTHER FROM EBP] -; 2. U32 Bus Number (0 .. 255) +; 2. U16 Bus Number (0 .. 255) ; 1. Ptr32 Pointer to PCI driver area of 65536 bytes ; [NEAREST TO EBP] ; @@ -192,61 +220,61 @@ pci_enumerate_bus: mov [esi + (64 - 12)], ecx mov [esi + (64 - 16)], edx mov [esi + (64 - 20)], edi - ; [esi]: Device-in-bus Index + ; CH: Bus Number + ; CL: Device index within bus ; [esi + 4]: Number of existing devices - ; [esi + 8]: Bus number ; [esi + 12]: PCI driver area pointer mov [esi], dword 0 mov [esi + 4], dword 0 - mov eax, [ebp - 8] - mov [esi + 8], eax - mov eax, [ebp - 4] - mov [esi + 12], eax + .initialize_device_loop: + mov ch, [ebp - 4] + xor cl, cl .device_loop: - cmp [esi], dword 32 + cmp cl, 32 jae .epilog .test_whether_device_exists: - mov ah, [esi + 8] ; Bus Number - mov al, [esi] ; Device Number - mov [esi + 16], ax + mov ax, [ebp - 6] ; Bus Number + mov dx, cx + and dx, 0xff push ebp mov ebp, esp - call pci_device_exists + push ax ; Bus Number + push dx ; Device Index + push word 0 ; Function Number + call pci_check_device_exists mov esp, ebp pop ebp cmp ax, 0 je .no_device -.append_device: - mov al, [esi + 8] - mov ah, [esi] +.call_append_device: - ; Device Number in DX - xor dx, dx - mov dl, ah - xor ah, ah + mov bx, cx + and bx, 0xff + + mov ax, cx + shr ax, 8 push ebp mov ebp, esp - push ax - push dx + push ax ; Bus Number + push bx ; Device Index call pci_get_device_class_at_address mov esp, ebp pop ebp - mov cx, ax - mov ax, [esi + 16] + mov edx, [ebp - 4] push ebp mov ebp, esp - push dword [esi + 12] - push ax - push cx + push edx ; Pointer to PCI Driver Area + push cx ; Device Address + push ax ; Class, Subclass call pci_append_device mov esp, ebp pop ebp @@ -254,7 +282,7 @@ pci_enumerate_bus: mov ebx, [ebp - 4] .no_device: - inc dword [esi] + inc cl jmp .device_loop .epilog: @@ -280,6 +308,7 @@ pci_enumerate_bus: ; Returns: ; eax: Number of devices read pci_enumerate: +.prolog: push dword esi sub esp, 64 mov esi, esp @@ -290,6 +319,7 @@ pci_enumerate: mov [esi + (64 - 16)], edx mov [esi + (64 - 20)], edi +.get_arguments: ; [esi]: Number of devices found ; ecx: Bus Index