diff --git a/i386/loader/src-asm/drivers/pci/utility.asm b/i386/loader/src-asm/drivers/pci/utility.asm new file mode 100644 index 0000000..abe9769 --- /dev/null +++ b/i386/loader/src-asm/drivers/pci/utility.asm @@ -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