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.
This commit is contained in:
Eric-Paul Ickhorn 2024-08-30 20:19:07 +02:00
parent 8127c67d30
commit 40b89c3985
Signed by: epickh
GPG Key ID: 1358818BAA38B104
1 changed files with 97 additions and 67 deletions

View File

@ -1,58 +1,84 @@
; Arguments: ; Arguments:
; ah Bus Number (0 .. 255) ; [Furthest from EBP]
; al Device Number (0 .. 31) ; 2. U16 Function (0 .. 7)
; 1. U16 Device Number (0 .. 31)
; 0. U16 Bus Number (0 .. 255)
; [Nearest to EBP]
; ;
; Returns: ; Returns:
; - true/false (eax) ; eax: If there is NO device at the location: 0
pci_device_exists: ; If there IS a device at the location: 1
push dword esi pci_check_device_exists:
sub esp, 8 .prolog:
mov esi, esp push esi
sub esp, 32
mov [esi], edx mov [esi + 24], ebx
mov [esi + 4], eax 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: .make_address:
xor eax, eax xor edx, edx
; Enable Bit ; Set the Enable Bit
or al, 1 inc edx
; Make space for 8 Reserved Bits and 8 Bytes of bus number. ; Make space for 8 Reserved Bits and 8 Bits for the Bus Number.
shl eax, 15 shl edx, 15
; Bus Number ; Bus Number
mov al, [esi + 5]
; Device Number
; Make space for device number
shl eax, 5
mov dl, [esi + 4] mov dl, [esi + 4]
and dl, 0x1f ; Device Number
or al, dl shl edx, 5
shl eax, 11 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 eax, edx
mov dx, PCI_CONFIG_ADDRESS_PORT
out dx, eax
mov dx, PCI_CONFIG_DATA_PORT mov dx, PCI_CONFIG_ADDRESS_PORT
in eax, dx out dx, eax
cmp ax, 0xffff mov dx, PCI_CONFIG_DATA_PORT
jne .device_found in eax, dx
.not_a_device: cmp ax, 0xffff
mov edx, [esi] je .no_device
add esp, 8 xor eax, eax
pop dword esi inc eax
jmp .epilog
xor eax, eax .no_device:
ret xor eax, eax
.device_found:
mov edx, [esi]
add esp, 8 .epilog:
pop dword esi mov ebx, [esi + 24]
mov eax, 1 mov edx, [esi + 28]
add esp, 32
pop esi
ret ret
@ -120,7 +146,7 @@ pci_append_device:
; ;
; Returns: ; Returns:
; ax PCI Device Class & Subclass ; ax PCI Device Class & Subclass
; (Higher byte: Class, lower byte: Subclass) ; (Lower byte: Subclass, Higher byte: Class)
pci_get_device_class_at_address: pci_get_device_class_at_address:
push dword esi push dword esi
sub esp, 64 sub esp, 64
@ -163,6 +189,8 @@ pci_get_device_class_at_address:
; PCI class- and subclass-code ; PCI class- and subclass-code
shr eax, 16 shr eax, 16
xchg ah, al
.epilog: .epilog:
mov ebx, [esi + (64 - 8)] mov ebx, [esi + (64 - 8)]
mov ecx, [esi + (64 - 12)] mov ecx, [esi + (64 - 12)]
@ -177,7 +205,7 @@ pci_get_device_class_at_address:
; Arguments: ; Arguments:
; [FURTHER FROM EBP] ; [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 ; 1. Ptr32 Pointer to PCI driver area of 65536 bytes
; [NEAREST TO EBP] ; [NEAREST TO EBP]
; ;
@ -192,61 +220,61 @@ pci_enumerate_bus:
mov [esi + (64 - 12)], ecx mov [esi + (64 - 12)], ecx
mov [esi + (64 - 16)], edx mov [esi + (64 - 16)], edx
mov [esi + (64 - 20)], edi 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 + 4]: Number of existing devices
; [esi + 8]: Bus number
; [esi + 12]: PCI driver area pointer ; [esi + 12]: PCI driver area pointer
mov [esi], dword 0 mov [esi], dword 0
mov [esi + 4], 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: .initialize_device_loop:
mov ch, [ebp - 4]
xor cl, cl
.device_loop: .device_loop:
cmp [esi], dword 32 cmp cl, 32
jae .epilog jae .epilog
.test_whether_device_exists: .test_whether_device_exists:
mov ah, [esi + 8] ; Bus Number mov ax, [ebp - 6] ; Bus Number
mov al, [esi] ; Device Number mov dx, cx
mov [esi + 16], ax and dx, 0xff
push ebp push ebp
mov ebp, esp 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 mov esp, ebp
pop ebp pop ebp
cmp ax, 0 cmp ax, 0
je .no_device je .no_device
.append_device: .call_append_device:
mov al, [esi + 8]
mov ah, [esi]
; Device Number in DX mov bx, cx
xor dx, dx and bx, 0xff
mov dl, ah
xor ah, ah mov ax, cx
shr ax, 8
push ebp push ebp
mov ebp, esp mov ebp, esp
push ax push ax ; Bus Number
push dx push bx ; Device Index
call pci_get_device_class_at_address call pci_get_device_class_at_address
mov esp, ebp mov esp, ebp
pop ebp pop ebp
mov cx, ax mov edx, [ebp - 4]
mov ax, [esi + 16]
push ebp push ebp
mov ebp, esp mov ebp, esp
push dword [esi + 12] push edx ; Pointer to PCI Driver Area
push ax push cx ; Device Address
push cx push ax ; Class, Subclass
call pci_append_device call pci_append_device
mov esp, ebp mov esp, ebp
pop ebp pop ebp
@ -254,7 +282,7 @@ pci_enumerate_bus:
mov ebx, [ebp - 4] mov ebx, [ebp - 4]
.no_device: .no_device:
inc dword [esi] inc cl
jmp .device_loop jmp .device_loop
.epilog: .epilog:
@ -280,6 +308,7 @@ pci_enumerate_bus:
; Returns: ; Returns:
; eax: Number of devices read ; eax: Number of devices read
pci_enumerate: pci_enumerate:
.prolog:
push dword esi push dword esi
sub esp, 64 sub esp, 64
mov esi, esp mov esi, esp
@ -290,6 +319,7 @@ pci_enumerate:
mov [esi + (64 - 16)], edx mov [esi + (64 - 16)], edx
mov [esi + (64 - 20)], edi mov [esi + (64 - 20)], edi
.get_arguments:
; [esi]: Number of devices found ; [esi]: Number of devices found
; ecx: Bus Index ; ecx: Bus Index