-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsdhc_disk.inc
220 lines (190 loc) · 6.42 KB
/
sdhc_disk.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
; Functions for this driver
;×òîáû íå ñòàâèòü ïàðíûå push/pop ïðè âõîäå è âûõîäå èç ôóíêöèè, ìîæíî ïèñàòü òàê:
;proc GET_SDSC_SIZE uses ecx edx
;proc GET_SDSC_SIZE uses ecx edx, _param1, _param2
proc GET_SDSC_SIZE
; memory capacity = BLOCKNR * BLOCK_LEN ; shl BSF block_len
; BLOCKNR = (C_SIZE + 1) * MULT ; shl ecx, BSF (C_SIZE_MULT + 2)
; MULT = 2^(C_SIZE_MULT + 2)
; BLOCK_LEN = 2^LEN_BL_READ
push ecx edx
mov ecx, dword[esi + SDHCI_SLOT.card_reg_csd + 4] ; C_SIZE_MULT
shr ecx, 7; 39 - 32 = 7
and ecx, 111b
add ecx, 2
mov edx, dword[esi + SDHCI_SLOT.card_reg_csd + 6] ; C_SIZE 48/8
shr edx, 6 ; 48 + 6
and edx, 0xFFF ; data in 12 low bits
inc edx
shl edx, cl
movzx ecx, byte[esi + SDHCI_SLOT.card_reg_csd + 9] ; LEN_BL_READ 72/8
and ecx, 0x0f
shl edx, cl
; get sectors = edx / 512 <- sectorsize for kernel
shr edx, BSF 512
mov dword[esi + SDHCI_SLOT.sector_count], edx
mov dword[esi + SDHCI_SLOT.sector_count + 4], 0
pop edx ecx
ret
endp
proc GET_SDHC_SIZE
; 22 bit [40:61]
; ((C_SIZE + 1) * 512Kbyte ) / sectorsize
push ebx
mov ebx, dword[esi + SDHCI_SLOT.card_reg_csd + 5]
and ebx, not 0xFFC00000 ; îáíóëÿåì ñòàðøèå áèòû
mov dword[esi + SDHCI_SLOT.sector_count + 4], 0
inc edx ; C_SIZE + 1
shl ebx, 10 ; *512Kbyte / sectorsize(512)
mov dword[esi + SDHCI_SLOT.sector_count], ebx
;bt dword[esi + SDHCI_CONTROLLER.card_reg_csd + 4], 29 ; read 22 bit C_SIZE
adc dword[esi + SDHCI_SLOT.sector_count + 4], 0
pop ebx
ret
endp
proc GET_SDUC_SIZE
; 28 bit [40:67] 40bit=5*8bit
; ((C_SIZE + 1) * 512Kbyte ) / sectorsize
push ebx
mov ebx, dword[esi + SDHCI_SLOT.card_reg_csd + 5]
and ebx, not 0xC0000000 ; îáíóëÿåì ñòàðøèå áèòû
inc edx
mov dword[esi + SDHCI_SLOT.sector_count], ebx
shr ebx, 31-10 ; get hign LBA addr
mov dword[esi + SDHCI_SLOT.card_reg_csd + 4], ebx
shl dword[esi + SDHCI_SLOT.sector_count], 10
pop ebx
ret
endp
proc GET_MMC_SIZE
; òóò æóòü, â æ*ïó
ret
endp
proc add_card_disk stdcall, hd_name:dword
invoke DiskAdd, sdhci_callbacks, [hd_name], esi, 0
test eax, eax
jz .disk_add_fail
mov dword[esi + SDHCI_SLOT.disk_hand], eax
invoke DiskMediaChanged, eax, 1 ; system will scan for partitions on disk
ret
.disk_add_fail:
DEBUGF 1, "Failed to add disk\n"
ret
endp
; Functions for kernel
proc sdhci_read stdcall pdata: dword, buffer: dword, startsector: qword, numsectors_ptr:dword
pusha
mov esi, [pdata]
mov eax, [esi + SDHCI_SLOT.base_reg_map]
mov ebx, dword[startsector]
mov edx, [numsectors_ptr]
mov edx, [edx]
mov edi, [buffer]
;DEBUGF 1,"SDHCI: read sector=%x num=%x \n", ebx, edx
cmp edx, 1
ja .multiple
call READ_SIGLE_BLOCK
popa
mov eax, 0
ret
.multiple:
push edx ebx edi
@@:
mov edx, dword[esp + 8]
mov ebx, dword[esp + 4]
mov edi, dword[esp]
cmp dword[esp + 8], 0xFFFF
jbe .send
mov edx, 0xFFFF
sub dword[esp + 8], edx
add dword[esp + 4], edx
shl edx, 9
add dword[esp], edx
shr edx, 9
.send:
push edx
call READ_MULTIPLE_BLOCK
pop edx
cmp edx, dword[esp + 8]
jnz @b
pop edi ebx edx
popa
mov eax, 0
ret
endp
proc sdhci_write stdcall pdata: dword, buffer: dword, startsector: qword, numsectors_ptr:dword
pusha
mov esi, [pdata]
mov eax, [esi + SDHCI_SLOT.base_reg_map]
mov ebx, dword[startsector]
mov edx, [numsectors_ptr]
mov edx, [edx]
mov edi, [buffer]
;DEBUGF 1,"SDHCI: write sector=%x num=%x \n", ebx, edx
cmp edx, 1
ja .multiple
call WRITE_BLOCK
popa
mov eax, 0
ret
.multiple:
push edx ebx edi
@@:
mov edx, dword[esp + 8]
mov ebx, dword[esp + 4]
mov edi, dword[esp]
cmp dword[esp + 8], 0xFFFF
jbe .send
mov edx, 0xFFFF
sub dword[esp + 8], edx
add dword[esp + 4], edx
shl edx, 9
add dword[esp], edx
shr edx, 9
.send:
push edx
call WRITE_MULTIPLE_BLOCK
pop edx
cmp edx, dword[esp + 8]
jnz @b
pop edi ebx edx
popa
mov eax, 0
ret
endp
struct DISKMEDIAINFO
Flags dd ?
SectorSize dd ?
Capacity dq ?
ends
proc sdhci_querymedia stdcall, pdata, mediainfo
push ecx edx
mov eax, [mediainfo]
mov edx, [pdata]
mov [eax + DISKMEDIAINFO.Flags], 0
mov [eax + DISKMEDIAINFO.SectorSize], SD_BLOCK_SIZE
mov ecx, dword[edx + SDHCI_SLOT.sector_count]
mov dword [eax + DISKMEDIAINFO.Capacity], ecx
mov ecx, dword[edx + SDHCI_SLOT.sector_count + 4]
mov dword [eax + DISKMEDIAINFO.Capacity + 4], ecx
pop edx ecx
xor eax, eax
ret
endp
proc sdhci_close
ret
endp
align 4
sdhci_callbacks:
dd sdhci_callbacks.end - sdhci_callbacks
dd 0 ;sdhci_close ; close function -
dd 0 ; closemedia function
dd sdhci_querymedia ; +
dd sdhci_read ; +
dd sdhci_write ; +
dd 0 ; no flush function
dd 0 ; use default cache size
.end:
; ; /sdhciXXXS/1
;sdhci_disk_name: db 'sdhci0000',0,0 ; xxx - number of controller
; ; s - number slot in select controller