c1f96ec4d4
git-svn-id: svn://kolibrios.org@5544 a494cfbc-eb01-0410-851d-a64ba20cac60
277 lines
7.1 KiB
NASM
277 lines
7.1 KiB
NASM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2004-2015. 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.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
|
|
|
|
mov esi, msgSearch
|
|
invoke SysMsgBoardStr
|
|
|
|
invoke GetPCIList
|
|
mov edx, eax
|
|
|
|
.loop:
|
|
mov ebx, [eax + PCIDEV.class]
|
|
cmp bx, 0x0300 ; display controller - vga compatible controller
|
|
je .found
|
|
cmp bx, 0x0302 ; display controller - 3d controller
|
|
je .found
|
|
cmp bx, 0x0380 ; display controller - other display controller
|
|
je .found
|
|
|
|
.next:
|
|
mov eax, [eax + PCIDEV.fd]
|
|
cmp eax, edx
|
|
jne .loop
|
|
|
|
mov esi, msgDone
|
|
invoke SysMsgBoardStr
|
|
|
|
or eax, -1
|
|
ret
|
|
|
|
.found:
|
|
push eax edx
|
|
movzx ebx, [eax + PCIDEV.bus]
|
|
mov [bus], ebx
|
|
movzx ebx, [eax + PCIDEV.devfn]
|
|
mov [devfn], ebx
|
|
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....
|
|
|
|
pop edx eax
|
|
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
|
|
|
|
pop edx eax
|
|
jz .next
|
|
|
|
.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
|
|
|
|
pop edx eax
|
|
jmp .next
|
|
|
|
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
|
|
msgDone db 'Done', 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 ?
|
|
|