/drivers/bus/cardbus.asm |
---|
File deleted |
\ No newline at end of file |
/drivers/ethernet/bcm57xx.asm |
---|
File deleted |
Property changes: |
Deleted: svn:eol-style |
-native |
\ No newline at end of property |
/drivers/pci_pe.inc |
---|
10,42 → 10,97 |
struct PCI_header |
vendor_id dw ? |
device_id dw ? |
command dw ? |
status dw ? |
revision_id db ? |
prog_if db ? |
subclass db ? |
class_code db ? |
cache_line_size db ? |
latency_timer db ? |
header_type db ? |
bist db ? |
vendor_id dw ? ; 0x00 |
device_id dw ? ; 0x02 |
command dw ? ; 0x04 |
status dw ? ; 0x06 |
revision_id db ? ; 0x08 |
prog_if db ? ; 0x09 |
subclass db ? ; 0x0A |
class_code db ? ; 0x0B |
cache_line_size db ? ; 0x0C |
latency_timer db ? ; 0x0D |
header_type db ? ; 0x0E |
bist db ? ; 0x0F |
ends |
struct PCI_header00 PCI_header |
base_addr_0 dd ? |
base_addr_1 dd ? |
base_addr_2 dd ? |
base_addr_3 dd ? |
base_addr_4 dd ? |
base_addr_5 dd ? |
cardbus_cis_ptr dd ? |
subsys_vendor dw ? |
subsys_id dw ? |
exp_rom_addr dd ? |
cap_ptr db ? |
reserved rb 7 |
interrupt_line db ? |
interrupt_pin db ? |
min_grant db ? |
max_latency db ? |
base_addr_0 dd ? ; 0x10 |
base_addr_1 dd ? ; 0x14 |
base_addr_2 dd ? ; 0x18 |
base_addr_3 dd ? ; 0x1C |
base_addr_4 dd ? ; 0x20 |
base_addr_5 dd ? ; 0x24 |
cardbus_cis_ptr dd ? ; 0x28 |
subsys_vendor dw ? ; 0x2C |
subsys_id dw ? ; 0x2E |
exp_rom_addr dd ? ; 0x30 |
cap_ptr db ? ; 0x34 |
rb 7 ; reserved |
interrupt_line db ? ; 0x3C |
interrupt_pin db ? ; 0x3D |
min_grant db ? ; 0x3E |
max_latency db ? ; 0x3F |
ends |
struct PCI_header01 PCI_header |
base_addr_0 dd ? ; 0x10 |
base_addr_1 dd ? ; 0x14 |
prim_bus_nr db ? ; 0x18 |
sec_bus_nr db ? ; 0x19 |
sub_bus_nr db ? ; 0x1A |
sec_lat_tmr db ? ; 0x1B |
io_base db ? ; 0x1C |
io_limit db ? ; 0x1D |
sec_status dw ? ; 0x1E |
mem_base dw ? ; 0x20 |
mem_limit dw ? ; 0x22 |
pref_mem_base dw ? ; 0x24 |
pref_mem_limit dw ? ; 0x26 |
pref_base_up dd ? ; 0x28 |
pref_limit_up dd ? ; 0x2C |
io_base_up dw ? ; 0x30 |
io_limit_up dw ? ; 0x32 |
cap_ptr db ? ; 0x34 |
rb 3 ; reserved |
exp_rom_addr dd ? ; 0x38 |
interrupt_line db ? ; 0x3C |
interrupt_pin db ? ; 0x3E |
bridge_ctrl dw ? ; 0x3F |
ends |
struct PCI_header02 PCI_header |
base_addr dd ? ; 0x10 |
cap_list_offs db ? ; 0x14 |
rb 1 ; reserved |
sec_stat dw ? ; 0x16 |
pci_bus_nr db ? ; 0x18 |
cardbus_bus_nr db ? ; 0x19 |
sub_bus_nr db ? ; 0x1A |
cardbus_lat_tmr db ? ; 0x1B |
mbar_0 dd ? ; 0x1C |
mlimit_0 dd ? ; 0x20 |
mbar_1 dd ? ; 0x24 |
mlimit_1 dd ? ; 0x28 |
iobar_0 dd ? ; 0x2C |
iolimit_0 dd ? ; 0x30 |
iobar_1 dd ? ; 0x34 |
iolimit_1 dd ? ; 0x38 |
interrupt_line db ? ; 0x3C |
interrupt_pin db ? ; 0x3D |
bridge_ctrl dw ? ; 0x3E |
subs_did dw ? ; 0x40 |
subs_vid dw ? ; 0x42 |
legacy_bar dd ? ; 0x44 |
ends |
; Base address bits |
PCI_BASE_ADDRESS_SPACE_IO = 0x01 |
PCI_BASE_ADDRESS_IO_MASK = 0xFFFFFFFC |
/drivers/unfinished/agp.asm |
---|
0,0 → 1,284 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ? |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/drivers/unfinished/bcm57xx.asm |
---|
0,0 → 1,424 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; Broadcom NetXtreme 57xx driver for KolibriOS ;; |
;; ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; Broadcom's programmers's manual for the BCM57xx ;; |
;; http://www.broadcom.com/collateral/pg/57XX-PG105-R.pdf ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
format PE DLL native |
entry START |
CURRENT_API = 0x0200 |
COMPATIBLE_API = 0x0100 |
API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API |
MAX_DEVICES = 16 |
__DEBUG__ = 1 |
__DEBUG_LEVEL__ = 2 |
section '.flat' readable writable executable |
include '../proc32.inc' |
include '../struct.inc' |
include '../macros.inc' |
include '../fdo.inc' |
include '../netdrv_pe.inc' |
struct device ETH_DEVICE |
mmio_addr dd ? |
pci_bus dd ? |
pci_dev dd ? |
irq_line db ? |
cur_tx dd ? |
last_tx dd ? |
rb 0x100 - ($ and 0xff) ; align 256 |
rx_desc rd 256/8 |
rb 0x100 - ($ and 0xff) ; align 256 |
tx_desc rd 256/8 |
ends |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; proc START ;; |
;; ;; |
;; (standard driver proc) ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc START c, reason:dword, cmdline:dword |
cmp [reason], DRV_ENTRY |
jne .fail |
DEBUGF 1,"Loading driver\n" |
invoke RegService, my_service, service_proc |
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 @F |
cmp [edx + IOCTL.out_size], 4 |
jb .fail |
mov eax, [edx + IOCTL.output] |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
;------------------------------------------------------ |
@@: |
cmp eax, 1 ;SRV_HOOK |
jne .fail |
cmp [edx + IOCTL.inp_size], 3 ; Data input must be at least 3 bytes |
jb .fail |
mov eax, [edx + IOCTL.input] |
cmp byte [eax], 1 ; 1 means device number and bus number (pci) are given |
jne .fail ; other types arent supported for this card yet |
; check if the device is already listed |
mov esi, device_list |
mov ecx, [devices] |
test ecx, ecx |
jz .firstdevice |
; mov eax, [edx + IOCTL.input] ; get the pci bus and device numbers |
mov ax, [eax+1] ; |
.nextdevice: |
mov ebx, [esi] |
cmp al, byte [ebx + device.pci_bus] |
jne .next |
cmp ah, byte [ebx + device.pci_dev] |
je .find_devicenum ; Device is already loaded, let's find it's device number |
.next: |
add esi, 4 |
loop .nextdevice |
; This device doesnt have its own eth_device structure yet, lets create one |
.firstdevice: |
cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card |
jae .fail |
allocate_and_clear ebx, sizeof.device, .fail ; Allocate the buffer for device structure |
; Fill in the direct call addresses into the struct |
mov [ebx + device.reset], reset |
mov [ebx + device.transmit], transmit |
mov [ebx + device.unload], unload |
mov [ebx + device.name], my_service |
; save the pci bus and device numbers |
mov eax, [edx + IOCTL.input] |
movzx ecx, byte [eax+1] |
mov [ebx + device.pci_bus], ecx |
movzx ecx, byte [eax+2] |
mov [ebx + device.pci_dev], ecx |
; Now, it's time to find the base mmio addres of the PCI device |
stdcall PCI_find_mmio32, [ebx + device.pci_bus], [ebx + device.pci_dev] |
; Create virtual mapping of the physical memory |
push 1Bh ; PG_SW+PG_NOCACHE |
push 10000h ; size of the map |
push eax |
invoke MapIoMem |
mov [ebx + device.mmio_addr], eax |
; We've found the mmio address, find IRQ now |
invoke PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line |
mov [ebx + device.irq_line], al |
DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ |
[ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.mmio_addr]:8 |
; Ok, the eth_device structure is ready, let's probe the device |
call probe ; this function will output in eax |
test eax, eax |
jnz .err ; If an error occured, exit |
mov eax, [devices] ; Add the device structure to our device list |
mov [device_list+4*eax], ebx ; (IRQ handler uses this list to find device) |
inc [devices] ; |
mov [ebx + device.type], NET_TYPE_ETH |
invoke NetRegDev |
cmp eax, -1 |
je .destroy |
ret |
; If the device was already loaded, find the device number and return it in eax |
.find_devicenum: |
DEBUGF 1,"Trying to find device number of already registered device\n" |
invoke NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx |
; into a device number in edi |
mov eax, edi ; Application wants it in eax instead |
DEBUGF 1,"Kernel says: %u\n", eax |
ret |
; If an error occured, remove all allocated data and exit (returning -1 in eax) |
.destroy: |
; todo: reset device into virgin state |
.err: |
invoke KernelFree, ebx |
.fail: |
or eax, -1 |
ret |
;------------------------------------------------------ |
endp |
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
;; ;; |
;; Actual Hardware dependent code starts here ;; |
;; ;; |
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
unload: |
; TODO: (in this particular order) |
; |
; - Stop the device |
; - Detach int handler |
; - Remove device from local list (device_list) |
; - call unregister function in kernel |
; - Remove all allocated structures and buffers the card used |
or eax, -1 |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; |
;; probe: enables the device (if it really is BCM57XX) |
;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
probe: |
DEBUGF 1,"Probe\n" |
; Make the device a bus master |
invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command |
or al, PCI_CMD_MASTER |
invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax |
; TODO: validate the device |
reset: |
DEBUGF 1,"Reset\n" |
movzx eax, [ebx + device.irq_line] |
DEBUGF 1,"Attaching int handler to irq %x\n", eax:1 |
invoke AttachIntHandler, eax, int_handler, ebx |
test eax, eax |
jnz @f |
DEBUGF 1,"\nCould not attach int handler!\n" |
; or eax, -1 |
; ret |
@@: |
call read_mac |
; Set the mtu, kernel will be able to send now |
mov [ebx + device.mtu], 1514 |
; Set link state to unknown |
mov [ebx + device.state], ETH_LINK_UNKNOWN |
ret |
align 4 |
read_mac: |
DEBUGF 1,"Read MAC\n" |
mov esi, [ebx + device.mmio_addr] |
lea edi, [ebx + device.mac] |
movsd |
movsw |
.mac_ok: |
DEBUGF 1,"MAC = %x-%x-%x-%x-%x-%x\n",\ |
[ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2 |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Transmit ;; |
;; ;; |
;; In: buffer pointer in [esp+4] ;; |
;; size of buffer in [esp+8] ;; |
;; pointer to device structure in ebx ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ |
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ |
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ |
[eax+13]:2,[eax+12]:2 |
cmp [buffersize], 1514 |
ja .fail |
cmp [buffersize], 60 |
jb .fail |
; Update stats |
inc [ebx + device.packets_tx] |
mov eax, [buffersize] |
add dword[ebx + device.bytes_tx], eax |
adc dword[ebx + device.bytes_tx + 4], 0 |
DEBUGF 1,"Transmit OK\n" |
popf |
xor eax, eax |
ret |
.fail: |
DEBUGF 2,"Transmit failed\n" |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Interrupt handler ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
int_handler: |
push ebx esi edi |
DEBUGF 1,"INT\n" |
;------------------------------------------- |
; Find pointer of device wich made IRQ occur |
mov ecx, [devices] |
test ecx, ecx |
jz .nothing |
mov esi, device_list |
.nextdevice: |
mov ebx, [esi] |
; mov edi, [ebx + device.mmio_addr] |
; mov eax, [edi + REG_ICR] |
test eax, eax |
jnz .got_it |
.continue: |
add esi, 4 |
dec ecx |
jnz .nextdevice |
.nothing: |
pop edi esi ebx |
xor eax, eax |
ret |
.got_it: |
DEBUGF 1,"Device: %x Status: %x ", ebx, eax |
pop edi esi ebx |
xor eax, eax |
inc eax |
ret |
; End of code |
data fixups |
end data |
include '../peimport.inc' |
my_service db 'BCM57XX',0 ; max 16 chars include zero |
include_debug_strings ; All data wich FDO uses will be included here |
align 4 |
devices dd 0 |
device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/drivers/unfinished/cardbus.asm |
---|
0,0 → 1,306 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; PCMCIA aka cardbus driver for KolibriOS ;; |
;; Written by hidnplayr@gmail.com ;; |
;; ;; |
;; Many credits go to Paolo Franchetti for his HWTEST program ;; |
;; (https://sites.google.com/site/pfranz73/) from which large ;; |
;; parts of code have been borrowed. ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; This module detects and initialises all Cardbus/pc-card/PCMCIA cards. |
; WARNING: Cards must be inserted before the driver starts, and shouldn't be removed. |
; This module doesn't handle insertions and removals. |
format PE DLL native |
entry START |
CURRENT_API = 0x0200 |
COMPATIBLE_API = 0x0100 |
API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API |
CARDBUS_IO = 0xFC00 |
__DEBUG__ = 1 |
__DEBUG_LEVEL__ = 1 |
section '.flat' readable writable executable |
include '../proc32.inc' |
include '../struct.inc' |
include '../macros.inc' |
include '../pci_pe.inc' |
include '../fdo.inc' |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; proc START ;; |
;; ;; |
;; (standard driver proc) ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc START c, reason:dword, cmdline:dword |
cmp [reason], DRV_ENTRY |
jne .fail |
DEBUGF 1, "Loading cardbus driver\n" |
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 ? |
card_bus dd ? |
bus dd ? |
devfn dd ? |
endl |
DEBUGF 1, "Searching for cardbus bridges...\n" |
xor eax, eax |
mov [bus], eax |
inc eax |
invoke PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
inc eax |
mov [card_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
invoke PciRead32, [bus], [devfn], PCI_header02.vendor_id |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
invoke PciRead16, [bus], [devfn], 0x0a ; class & subclass |
cmp ax, 0x0607 |
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 |
DEBUGF 1, "Search complete\n" |
xor eax, eax |
inc eax |
ret |
.found: |
DEBUGF 1, "Found cardbus bridge: bus=0x%x, dev=0x%x\n", [bus], [devfn] |
invoke PciRead8, [bus], [devfn], PCI_header.header_type |
DEBUGF 1, "Header type=0x%x\n", eax:2 |
cmp al, 2 |
jne .next |
; Write PCI and cardbus numbers |
invoke PciRead32, [bus], [devfn], PCI_header02.pci_bus_nr ; PCcard latency settings + Card bus number, PCI bus number |
and eax, 0xff000000 ; Keep original latency setting, clear the rest |
mov al, byte[bus] |
mov ah, byte[card_bus] |
mov ebx, [card_bus] |
shl ebx, 16 |
or eax, ebx |
DEBUGF 1, "Latency, bus,.. 0x%x\n", eax |
invoke PciWrite32, [bus], [devfn], PCI_header02.pci_bus_nr, eax |
; set ExCA legacy mode base |
invoke PciWrite32, [bus], [devfn], 0x44, 1 |
; Enable power |
invoke PciRead8, [bus], [devfn], 0x14 ; get capabilities offset |
movzx eax, al ; (A0 for TI bridges) |
DEBUGF 1, "Capabilities offset=0x%x\n", eax:2 |
add al, 4 ; Power management control/status |
invoke PciWrite16, [bus], [devfn], eax, 0x0100 ; Enable PME signaling, power state=D0 |
; Enable Bus master, io space, memory space |
invoke PciWrite16, [bus], [devfn], PCI_header02.command, 0x0007 |
; Write CardBus Socket/ExCA base address |
mov eax, 0x7f000000 |
push eax |
invoke PciWrite32, [bus], [devfn], PCI_header02.base_addr, eax ; base is 4 Kbyte aligned |
pop ebx |
invoke MapIoMem, ebx, 4096, 0x1b |
mov ecx, eax |
; Check if a card is present in the socket |
mov eax, [ecx + 8] ; Socket present state register |
DEBUGF 1, "Socket present state reg: 0x%x\n", eax |
and al, 10110110b ; NotACard | CBCard | 16bitCard | CDetect1 | CDetect2 |
cmp al, 00100000b ; Check for inserted cardbus card |
je .CardbusInserted |
; No card found... set PCI command back to 0 |
invoke PciWrite16, [bus], [devfn], PCI_header02.command, 0 ; To avoid conflicts with other sockets |
DEBUGF 1, "Cardbus KO\n" |
jmp .next |
.CardbusInserted: |
DEBUGF 1, "Card inserted\n" |
;mov word[ecx + 0x802], 0x00F9 ; Assert reset, output enable, vcc=vpp=3.3V |
mov dword[ecx + 0x10], 0x33 ; Request 3.3V for Vcc and Vpp (Control register) |
;push ecx |
;mov esi, 10 |
;invoke Sleep |
;pop ecx |
;mov byte[ecx + 0x803], 0x40 ; stop reset |
mov dword[ecx + 0xC], 0x4000 ; force Card CV test (Force register) ;;; WHY??? |
DEBUGF 1, "Resetting card\n" |
; Next power up test can be deferred until before writing to Bridge control PCI reg 0x3E |
.waitpower: ; For TI, you can check that bits 8-11 in PCI reg 80h are all 0 |
test dword[ecx + 8], 1 shl 3 ; Test PWRCYCLE bit |
jz .waitpower ; Wait for power to go up |
DEBUGF 1, "Interface is powered up\n" |
; Write MemBase-Limit 0 and 1, then IOBase-Limit 0 and 1 |
; mem0 space limit = base => size is 4 kilobytes |
; set to 0 the second interval (mem1 and IO1) |
; IO0: size is 256 bytes |
irp regvalue, 0x7efff000, 0x7effffff, 0x7effe000, 0x7effe000, CARDBUS_IO, CARDBUS_IO + 0xFF, 0, 0 |
{ |
common |
reg = 0x1C |
forward |
invoke PciWrite32, [bus], [devfn], reg, regvalue |
DEBUGF 1, "Writing 0x%x to 0x%x\n", regvalue, reg |
reg = reg + 4 |
} |
invoke PciWrite8, [bus], [devfn], PCI_header02.interrupt_line, 0xc ; IRQ line |
invoke PciRead16, [bus], [devfn], PCI_header02.bridge_ctrl ; Bridge control |
or ax, 0x0700 ; Enable write posting, both memory windows prefetchable |
invoke PciWrite16, [bus], [devfn], PCI_header02.bridge_ctrl, eax |
DEBUGF 1, "Write posting enabled\n" |
DEBUGF 1, "Bridge PCI registers:\n" |
rept 17 reg |
{ |
invoke PciRead32, [bus], [devfn], 4*(reg-1) |
DEBUGF 1, "0x%x\n", eax |
} |
inc byte[0x80009021] ; LAST PCI bus count in kernel (dirty HACK!) |
mov ecx, 100 |
.waitactive: |
push ecx |
invoke PciRead32, [card_bus], 0, PCI_header02.vendor_id ; Check if the card is awake yet |
inc eax |
jnz .got_it |
mov esi, 2 |
invoke Sleep |
pop ecx |
dec ecx |
jnz .waitactive |
DEBUGF 1, "Timeout!\n" |
; TODO: disable card/bridge again ? |
jmp .next |
.got_it: |
pop eax |
DEBUGF 1, "Card is enabled!\n" |
invoke PciWrite32, [card_bus], 0, PCI_header02.base_addr, CARDBUS_IO ; Supposing it's IO space that is needed |
invoke PciWrite8, [card_bus], 0, PCI_header02.interrupt_line, 0xC ; FIXME |
invoke PciWrite16, [card_bus], 0, PCI_header02.command, PCI_CMD_PIO or PCI_CMD_MMIO |
DEBUGF 1, "done\n" |
jmp .next |
.err: |
DEBUGF 1, "Error\n" |
xor eax, eax |
ret |
endp |
; End of code |
data fixups |
end data |
include '../peimport.inc' |
my_service db 'CARDBUS',0 ; max 16 chars include zero |
include_debug_strings ; All data wich FDO uses will be included here |
/kernel/trunk/drivers/agp.asm |
---|
File deleted |
Property changes: |
Deleted: svn:eol-style |
-native |
\ No newline at end of property |