Fasm: Fixed a bug when building programs with the length of the included file name...
[kolibrios.git] / drivers / unfinished / cardbus.asm
blobcc1ba6c116b0b1a9fc639230488428544e183385
1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; ;;
3 ;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;;
4 ;; Distributed under terms of the GNU General Public License ;;
5 ;; ;;
6 ;; PCMCIA aka cardbus driver for KolibriOS ;;
7 ;; Written by hidnplayr@gmail.com ;;
8 ;; ;;
9 ;; Many credits go to Paolo Franchetti for his HWTEST program ;;
10 ;; (https://sites.google.com/site/pfranz73/) from which large ;;
11 ;; parts of code have been borrowed. ;;
12 ;; ;;
13 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15 ; This module detects and initialises all Cardbus/pc-card/PCMCIA cards.
17 ; WARNING: Cards must be inserted before the driver starts, and shouldn't be removed.
18 ; This module doesn't handle insertions and removals.
20 ; TODO:
22 ; Use GetPCIList instead of reading directly from PCI bus to detect bridge.
23 ; (See #5544 agp.asm for example).
24 ; Export a function in kernel to re-scan PCI device list (fix 'dirty hack').
25 ; Fix bugs (currently not working on all PCMCIA bridges).
27 format PE DLL native
28 entry START
30 CURRENT_API = 0x0200
31 COMPATIBLE_API = 0x0100
32 API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API
34 CARDBUS_IO_BASE = 0x1400
35 CARDBUS_IO_SIZE = 0x100
36 CARDBUS_IRQ = 0x0A
38 __DEBUG__ = 1
39 __DEBUG_LEVEL__ = 1
41 section '.flat' readable writable executable
43 include '../proc32.inc'
44 include '../struct.inc'
45 include '../macros.inc'
46 include '../pci.inc'
47 include '../fdo.inc'
49 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
50 ;; ;;
51 ;; proc START ;;
52 ;; ;;
53 ;; (standard driver proc) ;;
54 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
56 proc START c, reason:dword, cmdline:dword
58 cmp [reason], DRV_ENTRY
59 jne .fail
61 DEBUGF 1, "Loading cardbus driver\n"
62 invoke RegService, my_service, service_proc
64 call detect
66 ret
68 .fail:
69 xor eax, eax
70 ret
72 endp
76 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
77 ;; ;;
78 ;; proc SERVICE_PROC ;;
79 ;; ;;
80 ;; (standard driver proc) ;;
81 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
83 proc service_proc stdcall, ioctl:dword
85 mov edx, [ioctl]
86 mov eax, [edx + IOCTL.io_code]
88 ;------------------------------------------------------
90 cmp eax, 0 ;SRV_GETVERSION
91 jne .fail
93 cmp [edx + IOCTL.out_size], 4
94 jb .fail
95 mov eax, [edx + IOCTL.output]
96 mov [eax], dword API_VERSION
98 xor eax, eax
99 ret
101 .fail:
102 or eax, -1
105 endp
107 align 4
108 proc detect
110 locals
111 last_bus dd ?
112 card_bus dd ?
113 bus dd ?
114 devfn dd ?
115 endl
117 DEBUGF 1, "Searching for cardbus bridges...\n"
119 xor eax, eax
120 mov [bus], eax
121 inc eax
122 invoke PciApi
123 cmp eax, -1
124 je .err
125 mov [last_bus], eax
127 inc eax
128 mov [card_bus], eax
130 .next_bus:
131 and [devfn], 0
132 .next_dev:
133 invoke PciRead32, [bus], [devfn], PCI_header.vendor_id
134 test eax, eax
135 jz .next
136 cmp eax, -1
137 je .next
139 invoke PciRead16, [bus], [devfn], PCI_header.subclass ; class & subclass
140 cmp ax, 0x0607
141 je .found
143 .next:
144 test [devfn], 7
145 jnz .next_fn
146 invoke PciRead8, [bus], [devfn], PCI_header.header_type
147 test al, al
148 js .next_fn
149 or [devfn], 7
151 .next_fn:
152 inc [devfn]
153 cmp [devfn], 256
154 jb .next_dev
155 mov eax, [bus]
156 inc eax
157 mov [bus], eax
158 cmp eax, [last_bus]
159 jna .next_bus
161 DEBUGF 1, "Search complete\n"
162 xor eax, eax
163 inc eax
166 .found:
167 DEBUGF 1, "Found cardbus bridge: bus=0x%x, dev=0x%x\n", [bus], [devfn]
169 invoke PciRead8, [bus], [devfn], PCI_header.header_type
170 and al, not 0x80 ; Mask the multifunction device bit
171 DEBUGF 1, "Header type=0x%x\n", eax:2
172 cmp al, 2
173 jne .next
175 ; Write PCI and cardbus numbers
177 invoke PciRead32, [bus], [devfn], PCI_header02.pci_bus_nr ; PCcard latency settings + Card bus number, PCI bus number
178 and eax, 0xff000000 ; Keep original latency setting, clear the rest
179 mov al, byte[bus]
180 mov ah, byte[card_bus]
181 mov ebx, [card_bus] ; sub bus nr???
182 shl ebx, 16
183 or eax, ebx
184 DEBUGF 1, "Latency, bus,.. 0x%x\n", eax
185 invoke PciWrite32, [bus], [devfn], PCI_header02.pci_bus_nr, eax
187 ; set ExCA legacy mode base
189 invoke PciWrite32, [bus], [devfn], 0x44, 1
191 ; Enable power
193 invoke PciRead8, [bus], [devfn], PCI_header02.cap_list_offs ; get capabilities offset
194 movzx eax, al ; (A0 for TI bridges)
195 DEBUGF 1, "Capabilities offset=0x%x\n", eax:2
196 add al, 4 ; Power management control/status
197 invoke PciWrite16, [bus], [devfn], eax, 0x0100 ; Enable PME signaling, power state=D0
199 ; Enable Bus master, io space, memory space
201 invoke PciWrite16, [bus], [devfn], PCI_header02.command, PCI_CMD_PIO or PCI_CMD_MMIO or PCI_CMD_MASTER
203 ; Write CardBus Socket/ExCA base address
205 mov eax, 0x7f000000
206 push eax
207 invoke PciWrite32, [bus], [devfn], PCI_header02.base_addr, eax ; base is 4 Kbyte aligned
208 pop ebx
209 invoke MapIoMem, ebx, 4096, PG_SW+PG_NOCACHE
210 mov ecx, eax
212 ; Check if a card is present in the socket
214 mov eax, [ecx + 8] ; Socket present state register
215 DEBUGF 1, "Socket present state reg: 0x%x\n", eax
216 and al, 10110110b ; NotACard | CBCard | 16bitCard | CDetect1 | CDetect2
217 cmp al, 00100000b ; Check for inserted cardbus card
218 je .CardbusInserted
220 ; No card found... set PCI command back to 0
222 invoke PciWrite16, [bus], [devfn], PCI_header02.command, 0 ; To avoid conflicts with other sockets
223 DEBUGF 1, "Cardbus KO\n"
224 jmp .next
226 .CardbusInserted:
227 DEBUGF 1, "Card inserted\n"
228 ;mov word[ecx + 0x802], 0x00F9 ; Assert reset, output enable, vcc=vpp=3.3V
229 mov dword[ecx + 0x10], 0x33 ; Request 3.3V for Vcc and Vpp (Control register)
230 ;push ecx
231 ;mov esi, 1
232 ;invoke Sleep
233 ;pop ecx
234 ;mov byte[ecx + 0x803], 0x40 ; stop reset
235 mov dword[ecx + 0xC], 0x4000 ; force Card CV test (Force register) ;;; WHY???
236 DEBUGF 1, "Resetting card\n"
238 ; Next power up test can be deferred until before writing to Bridge control PCI reg 0x3E
239 .waitpower: ; For TI, you can check that bits 8-11 in PCI reg 80h are all 0
240 test dword[ecx + 8], 1 shl 3 ; Test PWRCYCLE bit
241 jz .waitpower ; Wait for power to go up
243 DEBUGF 1, "Interface is powered up\n"
245 ; Write MemBase-Limit 0 and 1, then IOBase-Limit 0 and 1
246 ; mem0 space limit = base => size is 4 kilobytes
247 ; set to 0 the second interval (mem1 and IO1)
248 ; IO0: size is 256 bytes
250 invoke PciWrite32, [bus], [devfn], PCI_header02.mbar_0, 0x7EFFF000
251 invoke PciWrite32, [bus], [devfn], PCI_header02.mlimit_0, 0x7EFFF000
252 invoke PciWrite32, [bus], [devfn], PCI_header02.mbar_1, 0
253 invoke PciWrite32, [bus], [devfn], PCI_header02.mlimit_1, 0
254 invoke PciWrite32, [bus], [devfn], PCI_header02.iobar_0, CARDBUS_IO
255 invoke PciWrite32, [bus], [devfn], PCI_header02.iolimit_0, CARDBUS_IO + 0xFC
256 invoke PciWrite32, [bus], [devfn], PCI_header02.iobar_1, 0
257 invoke PciWrite32, [bus], [devfn], PCI_header02.iolimit_1, 0
258 invoke PciWrite8, [bus], [devfn], PCI_header02.interrupt_line, CARDBUS_IRQ ; IRQ line
259 invoke PciRead16, [bus], [devfn], PCI_header02.bridge_ctrl ; Bridge control
260 or ax, 0x0700 ; Enable write posting, both memory windows prefetchable
261 invoke PciWrite16, [bus], [devfn], PCI_header02.bridge_ctrl, eax
262 DEBUGF 1, "Write posting enabled\n"
265 DEBUGF 1, "Bridge PCI registers:\n"
266 rept 17 reg
268 invoke PciRead32, [bus], [devfn], 4*(reg-1)
269 DEBUGF 1, "0x%x\n", eax
272 inc byte[0x80009021] ; LAST PCI bus count in kernel (dirty HACK!)
275 mov ecx, 100
276 .waitactive:
277 push ecx
278 invoke PciRead32, [card_bus], 0, PCI_header.vendor_id ; Check if the card is awake yet
279 inc eax
280 jnz .got_it
281 mov esi, 2
282 invoke Sleep
283 pop ecx
284 dec ecx
285 jnz .waitactive
287 DEBUGF 1, "Timeout!\n"
288 ; TODO: disable card/bridge again ?
289 jmp .next
291 .got_it:
292 pop eax
293 DEBUGF 1, "Card is enabled!\n"
295 invoke PciWrite32, [card_bus], 0, PCI_header02.base_addr, CARDBUS_IO ; Supposing it's IO space that is needed
296 invoke PciWrite8, [card_bus], 0, PCI_header02.interrupt_line, 0xC ; FIXME
297 invoke PciWrite16, [card_bus], 0, PCI_header02.command, PCI_CMD_PIO or PCI_CMD_MMIO
299 DEBUGF 1, "done\n"
301 jmp .next
303 .err:
304 DEBUGF 1, "Error\n"
305 xor eax, eax
309 endp
312 ; End of code
314 data fixups
315 end data
317 include '../peimport.inc'
319 my_service db 'CARDBUS',0 ; max 16 chars include zero
321 include_debug_strings ; All data wich FDO uses will be included here