Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4476 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2014. 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
15
; This module detects and initialises all Cardbus/pc-card/PCMCIA cards.
16
 
17
; WARNING: Cards must be inserted before the driver starts, and shouldn't be removed.
18
; This module doesn't handle insertions and removals.
19
 
20
format MS COFF
21
 
22
        API_VERSION             = 0x01000100
23
        DRIVER_VERSION          = 5
24
 
25
        CARDBUS_IO              = 0xFC00
26
 
27
        DEBUG                   = 1
28
        __DEBUG__               = 1
29
        __DEBUG_LEVEL__         = 1
30
 
31
 
32
include '../struct.inc'
33
include '../macros.inc'
34
include '../proc32.inc'
35
include '../imports.inc'
36
include '../pci.inc'
37
include '../fdo.inc'
38
 
39
public START
40
public service_proc
41
public version
42
 
43
section '.flat' code readable align 16
44
 
45
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
46
;;                        ;;
47
;; proc START             ;;
48
;;                        ;;
49
;; (standard driver proc) ;;
50
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
51
 
52
align 4
53
proc START stdcall, state:dword
54
 
55
        cmp [state], 1
56
        jne .exit
57
 
58
  .entry:
59
 
60
        DEBUGF  1, "Loading cardbus driver\n"
61
        stdcall RegService, my_service, service_proc
62
 
63
        call    detect
64
 
65
        ret
66
 
67
  .fail:
68
  .exit:
69
        xor     eax, eax
70
        ret
71
 
72
endp
73
 
74
 
75
 
76
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
77
;;                        ;;
78
;; proc SERVICE_PROC      ;;
79
;;                        ;;
80
;; (standard driver proc) ;;
81
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
82
 
83
align 4
84
proc service_proc stdcall, ioctl:dword
85
 
86
        mov     edx, [ioctl]
87
        mov     eax, [edx + IOCTL.io_code]
88
 
89
;------------------------------------------------------
90
 
91
        cmp     eax, 0 ;SRV_GETVERSION
92
        jne     .fail
93
 
94
        cmp     [edx + IOCTL.out_size], 4
95
        jb      .fail
96
        mov     eax, [edx + IOCTL.output]
97
        mov     [eax], dword API_VERSION
98
 
99
        xor     eax, eax
100
        ret
101
 
102
  .fail:
103
        or      eax, -1
104
        ret
105
 
106
endp
107
 
108
align 4
109
proc detect
110
 
111
           locals
112
             last_bus dd ?
113
             card_bus dd ?
114
             bus      dd ?
115
             devfn    dd ?
116
           endl
117
 
118
        DEBUGF  1, "Searching for cardbus bridges...\n"
119
 
120
        xor     eax, eax
121
        mov     [bus], eax
122
        inc     eax
123
        call    PciApi
124
        cmp     eax, -1
125
        je      .err
126
        mov     [last_bus], eax
127
 
128
        inc     eax
129
        mov     [card_bus], eax
130
 
131
  .next_bus:
132
        and     [devfn], 0
133
  .next_dev:
134
        stdcall PciRead32, [bus], [devfn], PCI_VENDOR_ID
135
        test    eax, eax
136
        jz      .next
137
        cmp     eax, -1
138
        je      .next
139
 
140
        stdcall PciRead16, [bus], [devfn], 0x0a ; class & subclass
141
        cmp     ax, 0x0607
142
        je      .found
143
 
144
  .next:
145
        inc     [devfn]
146
        cmp     [devfn], 256
147
        jb      .next_dev
148
        mov     eax, [bus]
149
        inc     eax
150
        mov     [bus], eax
151
        cmp     eax, [last_bus]
152
        jna     .next_bus
153
 
154
        DEBUGF  1, "Search complete\n"
155
        xor     eax, eax
156
        inc     eax
157
        ret
158
 
159
  .found:
160
        DEBUGF  1, "Found cardbus bridge: bus=0x%x, dev=0x%x\n", [bus], [devfn]
161
 
162
        stdcall PciRead8, [bus], [devfn], 0x0e                  ; get header type
163
        DEBUGF  1, "Header type=0x%x\n", eax:2
164
 
165
        test    al, al
166
        jz      .next
167
 
168
; Write PCI and cardbus numbers
169
 
170
        stdcall PciRead32, [bus], [devfn], 0x18                 ; PCcard latency settings + Card bus number, PCI bus number
171
        and     eax, 0xff000000                                 ; Keep original latency setting, clear the rest
172
        mov     al, byte[bus]
173
        mov     ah, byte[card_bus]
174
        mov     ebx, [card_bus]
175
        shl     ebx, 16
176
        or      eax, ebx
177
        DEBUGF  1, "Latency, bus,.. 0x%x\n", eax
178
        stdcall PciWrite32, [bus], [devfn], 0x18, eax
179
 
180
; set ExCA legacy mode base
181
 
182
        stdcall PciWrite32, [bus], [devfn], 0x44, 1
183
 
184
; Enable power
185
 
186
        stdcall PciRead8, [bus], [devfn], 0x14                  ; get capabilities offset
187
        movzx   eax, al                                         ; (A0 for TI bridges)
188
        DEBUGF  1, "Capabilities offset=0x%x\n", eax:2
189
        add     al, 4                                           ; Power management control/status
190
        stdcall PciWrite16, [bus], [devfn], eax, 0x0100         ; Enable PME signaling, power state=D0
191
 
192
; Enable Bus master, io space, memory space
193
 
194
        stdcall PciWrite16, [bus], [devfn], PCI_REG_COMMAND, 0x0007
195
 
196
; Write CardBus Socket/ExCA base address
197
 
198
        mov     eax, 0x7f000000
199
        push    eax
200
        stdcall PciWrite32, [bus], [devfn], 0x10, eax           ; base is 4 Kbyte aligned
201
        pop     ebx
202
        stdcall MapIoMem, ebx, 4096, 0x1b
203
        mov     ecx, eax
204
 
205
; Check if a card is present in the socket
206
 
207
        mov     eax, [ecx + 8]                                  ; Socket present state register
208
        DEBUGF  1, "Socket present state reg: 0x%x\n", eax
209
        and     al, 10110110b                                   ; NotACard | CBCard | 16bitCard | CDetect1 | CDetect2
210
        cmp     al, 00100000b                                   ; Check for inserted cardbus card
211
        je      .CardbusInserted
212
 
213
; No card found... set PCI command back to 0
214
 
215
        stdcall PciWrite16, [bus], [devfn], PCI_REG_COMMAND, 0  ; To avoid conflicts with other sockets
216
        DEBUGF  1, "Cardbus KO\n"
217
        jmp     .next
218
 
219
  .CardbusInserted:
220
        DEBUGF  1, "Card inserted\n"
221
        ;mov     word[ecx + 0x802], 0x00F9       ; Assert reset, output enable, vcc=vpp=3.3V
222
        mov     dword[ecx + 0x10], 0x33         ; Request 3.3V for Vcc and Vpp (Control register)
223
        ;push    ecx
224
        ;mov     esi, 10
225
        ;call    Sleep
226
        ;pop     ecx
227
        ;mov     byte[ecx + 0x803], 0x40         ; stop reset
228
        mov     dword[ecx + 0xC], 0x4000        ; force Card CV test (Force register)   ;;; WHY???
229
        DEBUGF  1, "Resetting card\n"
230
 
231
; Next power up test can be deferred until before writing to Bridge control PCI reg 0x3E
232
  .waitpower:                                   ; For TI, you can check that bits 8-11 in PCI reg 80h are all 0
233
        test    dword[ecx + 8], 1 shl 3         ; Test PWRCYCLE bit
234
        jz      .waitpower                      ; Wait for power to go up
235
 
236
        DEBUGF  1, "Interface is powered up\n"
237
 
238
; Write MemBase-Limit 0 and 1, then IOBase-Limit 0 and 1
239
; mem0 space limit = base => size is 4 kilobytes
240
; set to 0 the second interval (mem1 and IO1)
241
; IO0: size is 256 bytes
242
 
243
irp     regvalue,   0x7efff000, 0x7effffff, 0x7effe000, 0x7effe000, CARDBUS_IO, CARDBUS_IO + 0xFF, 0, 0
244
{
245
common
246
        reg = 0x1C
247
forward
248
        stdcall PciWrite32, [bus], [devfn], reg, regvalue
249
        DEBUGF  1, "Writing 0x%x to 0x%x\n", regvalue, reg
250
        reg = reg + 4
251
}
252
 
253
        stdcall PciWrite8, [bus], [devfn], 0x3c, 0xc    ; IRQ line
254
 
255
        stdcall PciRead16, [bus], [devfn], 0x3e                 ; Bridge control
256
        or      ax, 0x0700                                      ; Enable write posting, both memory windows prefetchable
257
        stdcall PciWrite16, [bus], [devfn], 0x3e, eax
258
        DEBUGF  1, "Write posting enabled\n"
259
 
260
 
261
        DEBUGF  1, "Bridge PCI registers:\n"
262
rept    17 reg
263
{
264
        stdcall PciRead32, [bus], [devfn], 4*(reg-1)
265
        DEBUGF  1, "0x%x\n", eax
266
}
267
 
268
        inc     byte[0x80009021]                                ; LAST PCI bus count in kernel (dirty HACK!)
269
 
270
 
271
        mov     ecx, 100
272
  .waitactive:
273
        push    ecx
274
        stdcall PciRead32, [card_bus], 0, PCI_VENDOR_ID         ; Check if the card is awake yet
275
        inc     eax
276
        jnz     .got_it
277
        mov     esi, 2
278
        call    Sleep
279
        pop     ecx
280
        dec     ecx
281
        jnz     .waitactive
282
 
283
        DEBUGF  1, "Timeout!\n"
284
        ; TODO: disable card/bridge again ?
285
        jmp     .next
286
 
287
  .got_it:
288
        pop     eax
289
        DEBUGF  1, "Card is enabled!\n"
290
 
291
        stdcall PciWrite32, [card_bus], 0, PCI_BASE_ADDRESS_0, CARDBUS_IO       ; Supposing it's IO space that is needed
292
        stdcall PciWrite8, [card_bus], 0, PCI_REG_IRQ, 0xC                      ; FIXME
293
        stdcall PciWrite16, [card_bus], 0, PCI_REG_COMMAND, PCI_BIT_PIO or PCI_BIT_MMIO
294
 
295
        DEBUGF  1, "done\n"
296
 
297
        jmp     .next
298
 
299
  .err:
300
        DEBUGF  1, "Error\n"
301
        xor     eax, eax
302
 
303
        ret
304
 
305
 
306
 
307
endp
308
 
309
 
310
 
311
 
312
; End of code
313
 
314
section '.data' data readable writable align 16
315
 
316
version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
317
my_service      db 'CARDBUS',0                  ; max 16 chars include zero
318
 
319
include_debug_strings                           ; All data wich FDO uses will be included here