2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
; Arguments:
|
|
|
|
; ah Bus Number (0 .. 255)
|
|
|
|
; al Device Number (0 .. 31)
|
|
|
|
;
|
|
|
|
; Returns:
|
|
|
|
; - true/false (eax)
|
|
|
|
pci_device_exists:
|
2024-07-22 22:51:04 +00:00
|
|
|
push dword esi
|
|
|
|
sub esp, 8
|
|
|
|
mov esi, esp
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
mov [esi], edx
|
|
|
|
mov [esi + 4], eax
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.make_address:
|
2024-07-22 22:51:04 +00:00
|
|
|
xor eax, eax
|
2024-07-20 16:54:10 +00:00
|
|
|
; Enable Bit
|
2024-07-22 22:51:04 +00:00
|
|
|
or al, 1
|
2024-07-20 16:54:10 +00:00
|
|
|
; Make space for 8 Reserved Bits and 8 Bytes of bus number.
|
2024-07-22 22:51:04 +00:00
|
|
|
shl eax, 15
|
2024-07-20 16:54:10 +00:00
|
|
|
; Bus Number
|
2024-07-22 22:51:04 +00:00
|
|
|
mov al, [esi + 5]
|
2024-07-20 16:54:10 +00:00
|
|
|
; Device Number
|
2024-07-22 22:51:04 +00:00
|
|
|
; Make space for device number
|
|
|
|
shl eax, 5
|
|
|
|
mov dl, [esi + 4]
|
|
|
|
and dl, 0x1f
|
|
|
|
or al, dl
|
|
|
|
shl eax, 11
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
.input_output:
|
|
|
|
mov dx, PCI_CONFIG_ADDRESS_PORT
|
|
|
|
out dx, eax
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
mov dx, PCI_CONFIG_DATA_PORT
|
|
|
|
in eax, dx
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
cmp ax, 0xffff
|
|
|
|
jne .device_found
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.not_a_device:
|
2024-07-22 22:51:04 +00:00
|
|
|
mov edx, [esi]
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
add esp, 8
|
|
|
|
pop dword esi
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
xor eax, eax
|
2024-07-20 16:54:10 +00:00
|
|
|
ret
|
|
|
|
.device_found:
|
2024-07-22 22:51:04 +00:00
|
|
|
mov edx, [esi]
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
add esp, 8
|
|
|
|
pop dword esi
|
|
|
|
mov eax, 1
|
2024-07-20 16:54:10 +00:00
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Arguments:
|
|
|
|
; [FURTHEST FROM EBP]
|
2024-07-21 08:26:32 +00:00
|
|
|
; 3. U16 PCI Device Class & Subclass
|
2024-07-20 16:54:10 +00:00
|
|
|
; (Higher byte: Class, lower byte: Subclass)
|
2024-07-21 08:26:32 +00:00
|
|
|
; 2. U16 PCI Device Address
|
|
|
|
; (Higher byte: Bus Address,
|
|
|
|
; lower byte: Device Address)
|
2024-07-20 16:54:10 +00:00
|
|
|
; 1. Ptr32 Pointer to PCI driver area of 65536 bytes
|
|
|
|
; [NEAREST TO EBP]
|
|
|
|
pci_append_device:
|
2024-07-22 22:51:04 +00:00
|
|
|
push dword esi
|
|
|
|
sub esp, 64
|
|
|
|
mov esi, esp
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
mov [esi + (64 - 4)], eax
|
|
|
|
mov [esi + (64 - 8)], ebx
|
|
|
|
mov [esi + (64 - 12)], ecx
|
|
|
|
mov [esi + (64 - 20)], edi
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.get_device_count:
|
2024-07-22 22:51:04 +00:00
|
|
|
mov ebx, [ebp - 4]
|
|
|
|
xor ecx, ecx
|
|
|
|
mov cx, [ebx + PCI_DEVICE_COUNT_OFFSET]
|
|
|
|
mov [esi + 4], cx
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.calculate_device_offset:
|
|
|
|
; Every device slot has 16 bytes, multiply index with 16
|
2024-07-21 08:26:32 +00:00
|
|
|
shl ecx, 4
|
2024-07-20 16:54:10 +00:00
|
|
|
; Point into driver device area (add device area start on top)
|
2024-07-22 22:51:04 +00:00
|
|
|
mov ebx, [ebp - 4]
|
2024-07-21 08:26:32 +00:00
|
|
|
add ebx, PCI_DEVICE_AREA_OFFSET
|
|
|
|
add ebx, ecx
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.set_device:
|
2024-07-21 08:26:32 +00:00
|
|
|
mov cx, [ebp - 6]
|
|
|
|
mov [ebx], cx
|
|
|
|
mov cx, [ebp - 8]
|
|
|
|
mov [ebx + 2], cx
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-21 08:26:32 +00:00
|
|
|
.increment_device_count:
|
2024-07-22 22:51:04 +00:00
|
|
|
mov ebx, [ebp - 4]
|
2024-07-21 08:26:32 +00:00
|
|
|
inc word [ebx + PCI_DEVICE_COUNT_OFFSET]
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.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
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-07-21 08:26:32 +00:00
|
|
|
; 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:
|
2024-07-22 22:51:04 +00:00
|
|
|
push dword esi
|
|
|
|
sub esp, 64
|
|
|
|
mov esi, esp
|
2024-07-21 08:26:32 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
mov [esi + (64 - 8)], ebx
|
|
|
|
mov [esi + (64 - 12)], ecx
|
|
|
|
mov [esi + (64 - 16)], edx
|
|
|
|
mov [esi + (64 - 20)], edi
|
2024-07-21 08:26:32 +00:00
|
|
|
|
|
|
|
.create_address:
|
2024-07-22 22:51:04 +00:00
|
|
|
xor eax, eax
|
2024-07-21 08:26:32 +00:00
|
|
|
; Enable Bit
|
2024-07-22 22:51:04 +00:00
|
|
|
or al, 1
|
2024-07-21 08:26:32 +00:00
|
|
|
; Make space for 8 Reserved Bits and 8 Bytes of bus number.
|
2024-07-22 22:51:04 +00:00
|
|
|
shl eax, 15
|
2024-07-21 08:26:32 +00:00
|
|
|
; Bus Number
|
2024-07-22 22:51:04 +00:00
|
|
|
mov al, [ebp - 2]
|
2024-07-21 08:26:32 +00:00
|
|
|
; Device Number
|
2024-07-22 22:51:04 +00:00
|
|
|
; Make space for device number
|
|
|
|
shl eax, 5
|
|
|
|
mov dl, [ebp - 4]
|
|
|
|
and dl, 0x1f
|
|
|
|
or al, dl
|
|
|
|
shl eax, 11
|
2024-07-21 08:26:32 +00:00
|
|
|
|
|
|
|
; Include the register offset of the configuration space
|
|
|
|
; register which contains the class and subclass
|
2024-07-22 22:51:04 +00:00
|
|
|
or eax, 8
|
2024-07-21 08:26:32 +00:00
|
|
|
|
|
|
|
.input_output:
|
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
mov dx, PCI_CONFIG_ADDRESS_PORT
|
|
|
|
out dx, eax
|
2024-07-21 08:26:32 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
mov dx, PCI_CONFIG_DATA_PORT
|
|
|
|
in eax, dx
|
2024-07-21 08:26:32 +00:00
|
|
|
|
|
|
|
; Remove the parts of the register which aren't part of the
|
|
|
|
; PCI class- and subclass-code
|
2024-07-22 22:51:04 +00:00
|
|
|
shr eax, 16
|
2024-07-21 08:26:32 +00:00
|
|
|
|
|
|
|
.epilog:
|
2024-07-22 22:51:04 +00:00
|
|
|
mov ebx, [esi + (64 - 8)]
|
|
|
|
mov ecx, [esi + (64 - 12)]
|
|
|
|
mov edx, [esi + (64 - 16)]
|
|
|
|
mov edi, [esi + (64 - 20)]
|
2024-07-21 08:26:32 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
add esp, 64
|
|
|
|
pop dword esi
|
2024-07-21 08:26:32 +00:00
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-07-20 16:54:10 +00:00
|
|
|
; 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:
|
2024-07-22 22:51:04 +00:00
|
|
|
push dword esi
|
|
|
|
sub esp, 64
|
|
|
|
mov esi, esp
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
mov [esi + (64 - 8)], ebx
|
|
|
|
mov [esi + (64 - 12)], ecx
|
|
|
|
mov [esi + (64 - 20)], edi
|
2024-07-20 16:54:10 +00:00
|
|
|
; [esi]: Device-in-bus Index
|
|
|
|
; [esi + 4]: Number of existing devices
|
|
|
|
; [esi + 8]: Bus number
|
2024-07-22 22:51:04 +00:00
|
|
|
; [esi + 12]:
|
|
|
|
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
|
2024-07-20 16:54:10 +00:00
|
|
|
.initialize_device_loop:
|
|
|
|
|
|
|
|
.device_loop:
|
2024-07-22 22:51:04 +00:00
|
|
|
cmp [esi], dword 32
|
|
|
|
jae .epilog
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.test_whether_device_exists:
|
2024-07-22 22:51:04 +00:00
|
|
|
mov ah, [esi + 8] ; Bus Number
|
|
|
|
mov al, [esi] ; Device Number
|
|
|
|
mov [esi + 16], ax
|
2024-07-21 08:26:32 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
push ebp
|
|
|
|
mov ebp, esp
|
|
|
|
call pci_device_exists
|
|
|
|
mov esp, ebp
|
|
|
|
pop ebp
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
cmp ax, 0
|
|
|
|
je .no_device
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-21 08:26:32 +00:00
|
|
|
.append_device:
|
2024-07-22 22:51:04 +00:00
|
|
|
mov al, [esi + 8]
|
|
|
|
mov ah, [esi]
|
2024-07-21 08:26:32 +00:00
|
|
|
|
|
|
|
; Device Number in DX
|
2024-07-22 22:51:04 +00:00
|
|
|
xor dx, dx
|
|
|
|
mov dl, 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
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
mov ebx, [ebp - 4]
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.no_device:
|
2024-07-22 22:51:04 +00:00
|
|
|
inc dword [esi]
|
|
|
|
jmp .device_loop
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.epilog:
|
2024-07-22 22:51:04 +00:00
|
|
|
mov ebx, [esi + (64 - 8)]
|
|
|
|
mov ecx, [esi + (64 - 12)]
|
|
|
|
mov edi, [esi + (64 - 20)]
|
2024-07-21 08:26:32 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
mov eax, [esi + 4]
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
add esp, 64
|
|
|
|
pop dword esi
|
2024-07-20 16:54:10 +00:00
|
|
|
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]
|
2024-07-22 22:51:04 +00:00
|
|
|
; Returns:
|
|
|
|
; eax: Number of devices read
|
2024-07-20 16:54:10 +00:00
|
|
|
pci_enumerate:
|
2024-07-22 22:51:04 +00:00
|
|
|
push dword esi
|
|
|
|
sub esp, 64
|
|
|
|
mov esi, esp
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
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
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
; [esi]: Number of devices found
|
|
|
|
; ecx: Bus Index
|
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
mov edx, [ebp - 4]
|
|
|
|
mov [esi + 4], edx
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-21 08:26:32 +00:00
|
|
|
; Set the device count to 0 explicitly, just for safety.
|
2024-07-22 22:51:04 +00:00
|
|
|
mov ebx, [ebp - 4]
|
|
|
|
add ebx, PCI_DEVICE_COUNT_OFFSET
|
|
|
|
mov [ebx], word 0
|
2024-07-21 08:26:32 +00:00
|
|
|
|
2024-07-20 16:54:10 +00:00
|
|
|
.bus_loop:
|
2024-07-22 22:51:04 +00:00
|
|
|
xor ecx, ecx
|
|
|
|
mov [esi], dword 0
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.bus_loop_body:
|
|
|
|
; Test whether the device count is unlimited,
|
|
|
|
; ignore the device count check if it is.
|
2024-07-22 22:51:04 +00:00
|
|
|
cmp [ebp - 8], dword 0
|
|
|
|
je .call_bus_enumerator
|
2024-07-20 16:54:10 +00:00
|
|
|
|
2024-07-22 22:51:04 +00:00
|
|
|
mov edx, [esi]
|
|
|
|
cmp edx, [ebp - 8]
|
|
|
|
jae .epilog
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
.call_bus_enumerator:
|
2024-07-22 22:51:04 +00:00
|
|
|
push ebp
|
|
|
|
mov ebp, esp
|
|
|
|
push dword [esi + 4]
|
|
|
|
push ecx
|
|
|
|
call pci_enumerate_bus
|
|
|
|
mov esp, ebp
|
|
|
|
pop ebp
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
; Add the number of devices found on the bus
|
|
|
|
; to the number of devices found in total.
|
2024-07-22 22:51:04 +00:00
|
|
|
add [esi], eax
|
|
|
|
mov ebx, [esi + 4]
|
|
|
|
add [ebx + PCI_DEVICE_COUNT_OFFSET], ax
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
; Go to the next bus (if there is one)
|
2024-07-22 22:51:04 +00:00
|
|
|
inc ecx
|
|
|
|
cmp ecx, 256
|
|
|
|
jb .bus_loop_body
|
2024-07-20 16:54:10 +00:00
|
|
|
|
|
|
|
.epilog:
|
2024-07-22 22:51:04 +00:00
|
|
|
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
|
2024-07-21 08:26:32 +00:00
|
|
|
ret
|