;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; simple AGP driver for KolibriOS ;; ;; ;; ;; Written by hidnplayr@kolibrios.org ;; ;; ;; ;; GNU GENERAL PUBLIC LICENSE ;; ;; Version 2, June 1991 ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; format PE DLL native entry START CURRENT_API = 0x0200 COMPATIBLE_API = 0x0100 API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API FAST_WRITE = 0 ; may cause problems with some motherboards section '.flat' readable writable executable include '../proc32.inc' include '../struct.inc' include '../macros.inc' include '../pci_pe.inc' ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; proc START ;; ;; ;; ;; (standard driver proc) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;; proc START c, reason:dword, cmdline:dword cmp [reason], DRV_ENTRY jne .fail mov esi, msgInit invoke SysMsgBoardStr invoke RegService, my_service, service_proc call detect ret .fail: xor eax, eax ret endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; proc SERVICE_PROC ;; ;; ;; ;; (standard driver proc) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;; proc service_proc stdcall, ioctl:dword mov edx, [ioctl] mov eax, [edx + IOCTL.io_code] ;------------------------------------------------------ cmp eax, 0 ;SRV_GETVERSION jne .fail cmp [edx + IOCTL.out_size], 4 jb .fail mov eax, [edx + IOCTL.output] mov [eax], dword API_VERSION xor eax, eax ret .fail: or eax, -1 ret endp align 4 proc detect locals last_bus dd ? endl mov esi, msgSearch invoke SysMsgBoardStr xor eax, eax mov [bus], eax inc eax invoke PciApi ; get last bus cmp eax, -1 je .error mov [last_bus], eax .next_bus: and [devfn], 0 .next_dev: invoke PciRead16, [bus], [devfn], PCI_header.subclass ; subclass/vendor cmp ax, 0x0300 ; display controller - vga compatable controller je .found cmp ax, 0x0302 ; display controller - 3d controller je .found cmp ax, 0x0380 ; display controller - other display controller je .found .next: inc [devfn] cmp [devfn], 256 jb .next_dev mov eax, [bus] inc eax mov [bus], eax cmp eax, [last_bus] jna .next_bus .error: mov esi, msgFail invoke SysMsgBoardStr xor eax, eax inc eax ret .found: invoke PciRead8, [bus], [devfn], PCI_header00.prog_if test al, 1 shl 4 ; got capabilities list? jnz .got_capabilities_list ; TODO: Do it the old way: detect device and check with a list of known capabilities ; stupid pre PCI 2.2 board.... jmp .next .got_capabilities_list: invoke PciRead8, [bus], [devfn], PCI_header00.cap_ptr and eax, 11111100b ; always dword aligned mov edi, eax .read_capability: invoke PciRead32, [bus], [devfn], edi ; read capability cmp al, 0x02 ; AGP je .got_agp movzx edi, ah ; pointer to next capability test edi, edi jnz .read_capability jmp .next .got_agp: shr eax, 16 mov [revision], al ; high nibble = major revision ; low nibble = minor revision add edi, 4 and al, 0xf0 cmp al, 0x30 je .agp_3 .agp_2: mov esi, msgAGP2 invoke SysMsgBoardStr invoke PciRead32, [bus], [devfn], edi ; read AGP status .agp_2_: test al, 100b jnz .100b test al, 10b jnz .010b test al, 1b jz .error .001b: mov [cmd], 001b mov esi, msg1 invoke SysMsgBoardStr jmp .agp_go .010b: mov [cmd], 010b mov esi, msg2 invoke SysMsgBoardStr jmp .agp_go .100b: mov [cmd], 100b mov esi, msg4 invoke SysMsgBoardStr jmp .agp_go .agp_2m: mov esi, msgAGP2m invoke SysMsgBoardStr jmp .agp_2_ .agp_3: mov esi, msgAGP3 invoke SysMsgBoardStr invoke PciRead32, [bus], [devfn], edi ; read AGP status test al, 1 shl 3 jz .agp_2m test eax, 10b jnz .8x mov [cmd], 01b mov esi, msg4 invoke SysMsgBoardStr jmp .agp_go .8x: mov [cmd], 10b mov esi, msg8 invoke SysMsgBoardStr .agp_go: if FAST_WRITE test ax, 1 shl 4 jz @f or [cmd], 1 shl 4 mov esi, msgfast invoke SysMsgBoardStr @@: end if test ax, 1 shl 9 ; Side band addressing jz @f or [cmd], 1 shl 9 mov esi, msgside invoke SysMsgBoardStr @@: add edi, 4 mov eax, [cmd] or eax, 1 shl 8 ; enable AGP invoke PciWrite32, [bus], [devfn], edi, eax ; write AGP cmd mov esi, msgOK invoke SysMsgBoardStr ret endp ; End of code data fixups end data include '../peimport.inc' my_service db 'AGP', 0 ; max 16 chars include zero msgInit db 'AGP driver loaded.', 13, 10, 0 msgSearch db 'Searching for AGP card...', 13, 10, 0 msgFail db 'device not found', 13, 10, 0 msgOK db 'AGP device enabled', 13, 10, 0 msgAGP2 db 'AGP2 device found', 13, 10, 0 msgAGP3 db 'AGP3 device found', 13, 10, 0 msgAGP2m db 'Running in AGP2 mode', 13, 10, 0 msg8 db '8x speed', 13, 10, 0 msg4 db '4x speed', 13, 10, 0 msg2 db '2x speed', 13, 10, 0 msg1 db '1x speed', 13, 10, 0 msgfast db 'Fast Write', 13, 10, 0 msgside db 'Side band addressing', 13, 10, 0 ; uninitialized data revision db ? cmd dd ? bus dd ? devfn dd ?