Compare commits

..

2 Commits

Author SHA1 Message Date
Eric-Paul Ickhorn 18e5b049a4
Add PCI register read utility
The newly added utility routine reads the content of a known PCI
device's register given the index assigned to the device during
enumeration and the index of the register (and the PCI driver area,
but that is implied).
2024-07-23 01:01:20 +02:00
Eric-Paul Ickhorn 1285994cbf
Improve coding style of PCI device enumerator
The arguments of all of the statements are now indented and one or two
comments have been rewritten partially, improving readability.
2024-07-23 00:51:04 +02:00
2 changed files with 238 additions and 170 deletions

View File

@ -6,52 +6,53 @@
; Returns: ; Returns:
; - true/false (eax) ; - true/false (eax)
pci_device_exists: pci_device_exists:
push dword esi push dword esi
sub esp, 8 sub esp, 8
mov esi, esp mov esi, esp
mov [esi], edx mov [esi], edx
mov [esi + 4], eax mov [esi + 4], eax
.make_address: .make_address:
xor eax, eax xor eax, eax
; Enable Bit ; Enable Bit
or al, 1 or al, 1
; Make space for 8 Reserved Bits and 8 Bytes of bus number. ; Make space for 8 Reserved Bits and 8 Bytes of bus number.
shl eax, 15 shl eax, 15
; Bus Number ; Bus Number
mov al, [esi + 5] mov al, [esi + 5]
; Device Number ; Device Number
shl eax, 5 ; Make space for device number ; Make space for device number
mov dl, [esi + 4] shl eax, 5
and dl, 0x1f mov dl, [esi + 4]
or al, dl and dl, 0x1f
shl eax, 11 or al, dl
shl eax, 11
.io_task: .input_output:
mov dx, PCI_CONFIG_ADDRESS_PORT mov dx, PCI_CONFIG_ADDRESS_PORT
out dx, eax out dx, eax
mov dx, PCI_CONFIG_DATA_PORT mov dx, PCI_CONFIG_DATA_PORT
in eax, dx in eax, dx
cmp ax, 0xffff cmp ax, 0xffff
jne .device_found jne .device_found
.not_a_device: .not_a_device:
mov edx, [esi] mov edx, [esi]
add esp, 8 add esp, 8
pop dword esi pop dword esi
xor eax, eax xor eax, eax
ret ret
.device_found: .device_found:
mov edx, [esi] mov edx, [esi]
add esp, 8 add esp, 8
pop dword esi pop dword esi
mov eax, 1 mov eax, 1
ret ret
@ -66,26 +67,26 @@ pci_device_exists:
; 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]
pci_append_device: pci_append_device:
push dword esi push dword esi
sub esp, 64 sub esp, 64
mov esi, esp mov esi, esp
mov [esi + (64 - 4)], eax mov [esi + (64 - 4)], eax
mov [esi + (64 - 8)], ebx mov [esi + (64 - 8)], ebx
mov [esi + (64 - 12)], ecx mov [esi + (64 - 12)], ecx
mov [esi + (64 - 20)], edi mov [esi + (64 - 20)], edi
.get_device_count: .get_device_count:
mov ebx, [ebp - 4] mov ebx, [ebp - 4]
xor ecx, ecx xor ecx, ecx
mov cx, [ebx + PCI_DEVICE_COUNT_OFFSET] mov cx, [ebx + PCI_DEVICE_COUNT_OFFSET]
mov [esi + 4], cx mov [esi + 4], cx
.calculate_device_offset: .calculate_device_offset:
; Every device slot has 16 bytes, multiply index with 16 ; Every device slot has 16 bytes, multiply index with 16
shl ecx, 4 shl ecx, 4
; Point into driver device area (add device area start on top) ; Point into driver device area (add device area start on top)
mov ebx, [ebp - 4] mov ebx, [ebp - 4]
add ebx, PCI_DEVICE_AREA_OFFSET add ebx, PCI_DEVICE_AREA_OFFSET
add ebx, ecx add ebx, ecx
@ -96,7 +97,7 @@ pci_append_device:
mov [ebx + 2], cx mov [ebx + 2], cx
.increment_device_count: .increment_device_count:
mov ebx, [ebp - 4] mov ebx, [ebp - 4]
inc word [ebx + PCI_DEVICE_COUNT_OFFSET] inc word [ebx + PCI_DEVICE_COUNT_OFFSET]
.epilog: .epilog:
@ -121,54 +122,55 @@ pci_append_device:
; ax PCI Device Class & Subclass ; ax PCI Device Class & Subclass
; (Higher byte: Class, lower byte: Subclass) ; (Higher byte: Class, lower byte: Subclass)
pci_get_device_class_at_address: pci_get_device_class_at_address:
push dword esi push dword esi
sub esp, 64 sub esp, 64
mov esi, esp mov esi, esp
mov [esi + (64 - 8)], ebx mov [esi + (64 - 8)], ebx
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
.create_address: .create_address:
xor eax, eax xor eax, eax
; Enable Bit ; Enable Bit
or al, 1 or al, 1
; Make space for 8 Reserved Bits and 8 Bytes of bus number. ; Make space for 8 Reserved Bits and 8 Bytes of bus number.
shl eax, 15 shl eax, 15
; Bus Number ; Bus Number
mov al, [ebp - 2] mov al, [ebp - 2]
; Device Number ; Device Number
shl eax, 5 ; Make space for device number ; Make space for device number
mov dl, [ebp - 4] shl eax, 5
and dl, 0x1f mov dl, [ebp - 4]
or al, dl and dl, 0x1f
shl eax, 11 or al, dl
shl eax, 11
; Include the register offset of the configuration space ; Include the register offset of the configuration space
; register which contains the class and subclass ; register which contains the class and subclass
or eax, 8 or eax, 8
.input_output: .input_output:
mov dx, PCI_CONFIG_ADDRESS_PORT mov dx, PCI_CONFIG_ADDRESS_PORT
out dx, eax out dx, eax
mov dx, PCI_CONFIG_DATA_PORT mov dx, PCI_CONFIG_DATA_PORT
in eax, dx in eax, dx
; Remove the parts of the register which aren't part of the ; Remove the parts of the register which aren't part of the
; PCI class- and subclass-code ; PCI class- and subclass-code
shr eax, 16 shr eax, 16
.epilog: .epilog:
mov ebx, [esi + (64 - 8)] mov ebx, [esi + (64 - 8)]
mov ecx, [esi + (64 - 12)] mov ecx, [esi + (64 - 12)]
mov edx, [esi + (64 - 16)] mov edx, [esi + (64 - 16)]
mov edi, [esi + (64 - 20)] mov edi, [esi + (64 - 20)]
add esp, 64 add esp, 64
pop dword esi pop dword esi
ret ret
@ -182,91 +184,87 @@ pci_get_device_class_at_address:
; Returns: ; Returns:
; - Number of devics on the bus (eax) ; - Number of devics on the bus (eax)
pci_enumerate_bus: pci_enumerate_bus:
push dword esi push dword esi
sub esp, 64 sub esp, 64
mov esi, esp mov esi, esp
mov [esi + (64 - 8)], ebx mov [esi + (64 - 8)], ebx
mov [esi + (64 - 12)], ecx mov [esi + (64 - 12)], ecx
mov [esi + (64 - 20)], edi mov [esi + (64 - 20)], edi
; [esi]: Device-in-bus Index ; [esi]: Device-in-bus Index
; [esi + 4]: Number of existing devices ; [esi + 4]: Number of existing devices
; [esi + 8]: Bus number ; [esi + 8]: Bus number
mov [esi], dword 0 ; [esi + 12]:
mov [esi + 4], dword 0 mov [esi], dword 0
mov eax, [ebp - 8] mov [esi + 4], dword 0
mov [esi + 8], eax mov eax, [ebp - 8]
mov eax, [ebp - 4] mov [esi + 8], eax
mov [esi + 12], eax mov eax, [ebp - 4]
mov [esi + 12], eax
.initialize_device_loop: .initialize_device_loop:
.device_loop: .device_loop:
cmp [esi], dword 32 cmp [esi], dword 32
jae .epilog jae .epilog
.test_whether_device_exists: .test_whether_device_exists:
mov ah, [esi + 8] ; Bus Number mov ah, [esi + 8] ; Bus Number
mov al, [esi] ; Device Number mov al, [esi] ; Device Number
mov [esi + 16], ax mov [esi + 16], ax
push ebp push ebp
mov ebp, esp mov ebp, esp
call pci_device_exists call pci_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: .append_device:
mov al, [esi + 8] mov al, [esi + 8]
mov ah, [esi] mov ah, [esi]
; Device Number in DX ; Device Number in DX
xor dx, dx xor dx, dx
mov dl, ah mov dl, ah
xor ah, ah xor ah, ah
push ebp
mov ebp, esp
push ax
push dx
call pci_get_device_class_at_address
mov esp, ebp
pop ebp
push ebp mov cx, ax
mov ebp, esp mov ax, [esi + 16]
push ax
push dx
call pci_get_device_class_at_address
mov esp, ebp
pop ebp
mov cx, ax push ebp
mov ax, [esi + 16] mov ebp, esp
push dword [esi + 12]
push ax
push cx
call pci_append_device
mov esp, ebp
pop ebp
push ebp mov ebx, [ebp - 4]
mov ebp, esp
push dword [esi + 12]
push ax
push cx
call pci_append_device
mov esp, ebp
pop ebp
mov eax, [esi + 4]
inc eax
mov [esi + 4], eax
.no_device: .no_device:
mov ecx, [esi] inc dword [esi]
inc ecx jmp .device_loop
mov [esi], ecx
jmp .device_loop
.epilog: .epilog:
mov ebx, [esi + (64 - 8)] mov ebx, [esi + (64 - 8)]
mov ecx, [esi + (64 - 12)] mov ecx, [esi + (64 - 12)]
mov edi, [esi + (64 - 20)] mov edi, [esi + (64 - 20)]
mov eax, [esi + 4] mov eax, [esi + 4]
add esp, 64 add esp, 64
pop dword esi pop dword esi
ret ret
@ -277,70 +275,72 @@ pci_enumerate_bus:
; (0 to eliminate limit) ; (0 to eliminate limit)
; 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]
; Returns:
; eax: Number of devices read
pci_enumerate: pci_enumerate:
push dword esi push dword esi
sub esp, 64 sub esp, 64
mov esi, esp mov esi, esp
mov [esi + (64 - 4)], eax mov [esi + (64 - 4)], eax
mov [esi + (64 - 8)], ebx mov [esi + (64 - 8)], ebx
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]: Number of devices found ; [esi]: Number of devices found
; ecx: Bus Index ; ecx: Bus Index
mov edx, [ebp - 4] mov edx, [ebp - 4]
mov [esi + 4], edx mov [esi + 4], edx
; Set the device count to 0 explicitly, just for safety. ; Set the device count to 0 explicitly, just for safety.
mov ebx, [ebp - 4] mov ebx, [ebp - 4]
add ebx, PCI_DEVICE_COUNT_OFFSET add ebx, PCI_DEVICE_COUNT_OFFSET
mov [ebx], word 0 mov [ebx], word 0
.bus_loop: .bus_loop:
xor ecx, ecx xor ecx, ecx
mov [esi], dword 0 mov [esi], dword 0
.bus_loop_body: .bus_loop_body:
; Test whether the device count is unlimited, ; Test whether the device count is unlimited,
; ignore the device count check if it is. ; ignore the device count check if it is.
cmp [ebp - 8], dword 0 cmp [ebp - 8], dword 0
je .call_bus_enumerator je .call_bus_enumerator
mov edx, [esi] mov edx, [esi]
cmp edx, [ebp - 8] cmp edx, [ebp - 8]
jae .epilog jae .epilog
.call_bus_enumerator: .call_bus_enumerator:
push ebp push ebp
mov ebp, esp mov ebp, esp
push dword [esi + 4] push dword [esi + 4]
push ecx push ecx
call pci_enumerate_bus call pci_enumerate_bus
mov esp, ebp mov esp, ebp
pop ebp pop ebp
; Add the number of devices found on the bus ; Add the number of devices found on the bus
; to the number of devices found in total. ; to the number of devices found in total.
add [esi], eax add [esi], eax
mov ebx, [esi + 4] mov ebx, [esi + 4]
add [ebx + PCI_DEVICE_COUNT_OFFSET], ax add [ebx + PCI_DEVICE_COUNT_OFFSET], ax
; Go to the next bus (if there is one) ; Go to the next bus (if there is one)
inc ecx inc ecx
cmp ecx, 256 cmp ecx, 256
jb .bus_loop_body jb .bus_loop_body
.epilog: .epilog:
mov ebx, [esi + (64 - 8)] mov ebx, [esi + (64 - 8)]
mov ecx, [esi + (64 - 12)] mov ecx, [esi + (64 - 12)]
mov edx, [esi + (64 - 16)] mov edx, [esi + (64 - 16)]
mov edi, [esi + (64 - 20)] mov edi, [esi + (64 - 20)]
mov eax, [esi] mov eax, [esi]
add esp, 64 add esp, 64
pop dword esi pop dword esi
ret ret

View File

@ -0,0 +1,68 @@
; Arguments:
; [FURTHER FROM EBP]
; 3. U16 Register Index
; 2. U16 Device Index in device list
; 1. Ptr32 Pointer to PCI driver area
; [NEAREST TO EBP]
pci_read_register:
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
.check_device_index:
; todo: Boundary checks
.get_device:
xor ebx, ebx
mov bx, [ebp - 6]
shl ebx, 4
; Point into the driver's device area
add ebx, [ebp - 4]
add ebx, PCI_DEVICE_AREA_OFFSET
mov [esi], ebx
xor eax, eax
mov ax, [ebx]
mov [esi + 4], ah
mov [esi + 5], al
.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, 9
or al, [ebp - 8]
shl eax, 2
.input_output:
mov dx, PCI_CONFIG_ADDRESS_PORT
out dx, eax
mov dx, PCI_CONFIG_DATA_PORT
in eax, dx
.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