Add main PCI driver file and device enumeration

In this commit, the PCI driver can finally enumerate the devices in
the system. Some other things are still not pushed.
This commit is contained in:
Eric-Paul Ickhorn 2024-07-20 18:54:10 +02:00
parent 3a778fee44
commit 6342b433b4
Signed by: epickh
GPG Key ID: 1358818BAA38B104
2 changed files with 314 additions and 0 deletions

View File

@ -0,0 +1,64 @@
PCI_CONFIG_ADDRESS_PORT equ 0x0cf8
PCI_CONFIG_DATA_PORT equ 0x0cfc
PCI_DEVICE_COUNT_OFFSET equ 0xffe
PCI_DEVICE_AREA_OFFSET equ 0x1000
; [FURTHEST FROM BP]
; 0. Ptr32 Pointer to 65536B slot for PCI driver
; [NEAREST TO BP]
initialize_pci_driver:
push dword esi
sub esp, 64
mov esi, esp
mov [esi + (64 - 4)], eax
mov [esi + (64 - 8)], ebx
mov [esi + (64 - 12)], ecx
mov [esi + (64 - 16)], edx
mov [esi + (64 - 20)], edi
.body:
mov ebx, [ebp - 4]
push ebp
mov ebp, esp
push ebx
push dword 0 ; No Maximum Device Limit
call pci_enumerate
mov esp, ebp
pop ebp
mov ebx, [ebp - 4]
add ebx, PCI_DEVICE_COUNT_OFFSET
push ebp
mov ebp, esp
push ebx
push dword 2
push dword 0
push dword 0
call write_hexadecimal_string
mov esp, ebp
pop ebp
; todo(wip): Remove this once the PCI Driver
; is debugged completely.
cli
hlt
.epilog:
mov eax, [esi + (64 - 4)]
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
.storage:
dd 0
%include "drivers/pci/enumerate.asm"

View File

@ -0,0 +1,250 @@
; Arguments:
; ah Bus Number (0 .. 255)
; al Device Number (0 .. 31)
;
; Returns:
; - true/false (eax)
pci_device_exists:
push dword esi
sub esp, 8
mov esi, esp
mov [esi], edx
mov [esi + 4], eax
.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
; Bus Number
mov al, [esi + 5]
; Device Number
shl eax, 5 ; Make space for device number
mov dl, [esi + 4]
and dl, 0x1f
or al, dl
shl eax, 11
.io_task:
mov dx, PCI_CONFIG_ADDRESS_PORT
out dx, eax
mov dx, PCI_CONFIG_DATA_PORT
in eax, dx
cmp ax, 0xffff
jne .device_found
.not_a_device:
mov edx, [esi]
add esp, 8
pop dword esi
xor eax, eax
ret
.device_found:
mov edx, [esi]
add esp, 8
pop dword esi
mov eax, 1
ret
; Arguments:
; [FURTHEST FROM EBP]
; 3. U32 PCI Device Class & Subclass
; (Higher byte: Class, lower byte: Subclass)
; 2. U32 PCI Device Address
; 1. Ptr32 Pointer to PCI driver area of 65536 bytes
; [NEAREST TO EBP]
pci_append_device:
push dword esi
sub esp, 64
mov esi, esp
mov [esi + (64 - 4)], eax
mov [esi + (64 - 8)], ebx
mov [esi + (64 - 12)], ecx
mov [esi + (64 - 20)], edi
.get_device_count:
mov ebx, [ebp - 4]
xor ecx, ecx
mov cx, [ebx + PCI_DEVICE_COUNT_OFFSET]
mov [esi + 4], cx
.calculate_device_offset:
; Every device slot has 16 bytes, multiply index with 16
shl cx, 4
; Point into driver device area (add device area start on top)
add ecx, ebx
add ecx, PCI_DEVICE_COUNT_OFFSET
mov ebx, ecx
.set_device:
mov ecx, [ebp - 8]
mov [ebx], ecx
mov ecx, [ebp - 12]
mov [ebx + 4], ecx
increment_device_count:
.epilog:
mov eax, [esi + (64 - 4)]
mov ebx, [esi + (64 - 8)]
mov ecx, [esi + (64 - 12)]
mov edi, [esi + (64 - 20)]
add esp, 64
pop dword esi
ret
; Arguments:
; [FURTHER FROM EBP]
; 2. U32 Bus Number (0 .. 255)
; 1. Ptr32 Pointer to PCI driver area of 65536 bytes
; [NEAREST TO EBP]
;
; Returns:
; - Number of devics on the bus (eax)
pci_enumerate_bus:
push dword esi
sub esp, 64
mov esi, esp
mov [esi + (64 - 8)], ebx
mov [esi + (64 - 12)], ecx
mov [esi + (64 - 20)], edi
; [esi]: Device-in-bus Index
; [esi + 4]: Number of existing devices
; [esi + 8]: Bus number
mov [esi], dword 0
mov [esi + 4], dword 0
mov eax, [ebp - 8]
mov [esi + 8], eax
.initialize_device_loop:
.device_loop:
cmp [esi], dword 32
jae .epilog
.test_whether_device_exists:
push ebp
mov ebp, esp
mov ah, [esi + 8] ; Bus Number
mov al, [esi] ; Device Number
call pci_device_exists
mov esp, ebp
pop ebp
cmp ax, 0
je .no_device
.call_append_device:
push ebp
mov ebp, esp
push dword [esi + 8]
push dword 0xcafebabe
push dword 0xdeadbeef
call pci_append_device
mov esp, ebp
pop ebp
mov eax, [esi + 4]
inc eax
mov [esi + 4], eax
.no_device:
mov ecx, [esi]
inc ecx
mov [esi], ecx
jmp .device_loop
.epilog:
mov ebx, [esi + (64 - 8)]
mov ecx, [esi + (64 - 12)]
mov edi, [esi + (64 - 20)]
mov eax, [esi + 4]
add esp, 64
pop dword esi
ret
; Arguments:
; [FURTHEST FROM EBP]
; 2. U32 Maximum number of devices to enumerate
; (0 to eliminate limit)
; 1. Ptr32 Pointer to PCI driver area of 65536 bytes
; [NEAREST TO EBP]
pci_enumerate:
push dword esi
sub esp, 64
mov esi, esp
mov [esi + (64 - 4)], eax
mov [esi + (64 - 8)], ebx
mov [esi + (64 - 12)], ecx
mov [esi + (64 - 16)], edx
mov [esi + (64 - 20)], edi
; [esi]: Number of devices found
; ecx: Bus Index
mov edx, [ebp - 4]
mov [esi + 4], edx
.bus_loop:
xor ecx, ecx
mov [esi], dword 0
.bus_loop_body:
; Test whether the device count is unlimited,
; ignore the device count check if it is.
cmp [ebp - 8], dword 0
je .call_bus_enumerator
mov edx, [esi]
cmp edx, [ebp - 8]
jae .epilog
.call_bus_enumerator:
push ebp
mov ebp, esp
push dword [esi + 4]
push ecx
call pci_enumerate_bus
mov esp, ebp
pop ebp
; Add the number of devices found on the bus
; to the number of devices found in total.
add [esi], eax
mov ebx, [esi + 4]
add [ebx + PCI_DEVICE_COUNT_OFFSET], ax
; Go to the next bus (if there is one)
inc ecx
cmp ecx, 256
jb .bus_loop_body
.epilog:
mov ebx, [esi + (64 - 8)]
mov ecx, [esi + (64 - 12)]
mov edx, [esi + (64 - 16)]
mov edi, [esi + (64 - 20)]
mov eax, [esi]
add esp, 64
pop dword esi
ret