mirror of
https://github.com/Doczom/SDHCI_driver_for_Kolibrios.git
synced 2026-03-09 09:13:24 +00:00
Big update
Added support SDIO card Fixed bugs Added support 4-bit mode for sd card Added support all slots on controllers and other
This commit is contained in:
102
README.md
102
README.md
@@ -1,52 +1,50 @@
|
||||
# SDHCI_driver_for_Kolibrios
|
||||
|
||||
Driver for SD host controller on Kolibri OS
|
||||
|
||||
## WARNING!!!
|
||||
The driver is being developed and tested for the controller version 2.0 (integrated into the FCH Bolton D3). On controllers of another version or another manufacturer, it may work unstable and may lead to equipment failure.
|
||||
|
||||
## Information
|
||||
|
||||
Version controller:
|
||||
- 1.0 - no supported
|
||||
- 2.0 - Supported
|
||||
- 3.0 - no supported
|
||||
- 4.0 - no supported
|
||||
|
||||
DMA modes:
|
||||
- no-DMA - not supported
|
||||
- SDMA - Supported
|
||||
- ADMA1 - not supported
|
||||
- ADMA2 32bit - not supported
|
||||
- ADMA2 64bit - not supported
|
||||
|
||||
|
||||
Version OS:
|
||||
* rev 9897
|
||||
|
||||
Bus protocol:
|
||||
- SD Bus protocol - Supported
|
||||
- SPI Bus protocol - no supported
|
||||
- UHS-II Bus protocol - no supported
|
||||
- PCIe/NVMe Bus protocol - no supported
|
||||
|
||||
## TODO:
|
||||
- инициализация контроллера, вывод информации об контроллере
|
||||
- Установка изначальных значений для работы контроллера
|
||||
- ~~регистрация обработчика прерываний~~
|
||||
- документирование и реализация команд контроллера
|
||||
- ~~написание алгоритма инициализации SD карт~~
|
||||
- переписать обнаружение карт при инициализации контроллера
|
||||
- написание алгоритма инициализации SDIO карт
|
||||
- написание алгоритма инициализации MMC карт
|
||||
- написание функций передачи блоков через SDMA и ADMA и без применения DMA
|
||||
- реализация функций card_init и card_destryct
|
||||
- написание алгоритма инициализации для карт с интерфейсом SPI
|
||||
- ~~Получение базовых данных о карте(CID, CSD, RCA)~~
|
||||
- реализовать функции смены частоты
|
||||
- реализовать функции переключения шины SD в 4bit режим и обратно в 1bit режим
|
||||
- реализовать функции смены питания на 1.8V
|
||||
- реализация функций обработки сообщений контроллера
|
||||
- реализация функций SDIO и их экспорт для драйверов и прикладного ПО
|
||||
- реализация встроенного драйвера на SD карты памяти
|
||||
- ~~получение объёма карты в секторах(512 байт)~~
|
||||
# SDHCI_driver_for_Kolibrios
|
||||
|
||||
Driver for SD host controller on Kolibri OS
|
||||
|
||||
## WARNING!!!
|
||||
The driver is being developed and tested for the controller version 2.0 (integrated into the FCH Bolton D3). On controllers of another version or another manufacturer, it may work unstable and may lead to equipment failure.
|
||||
|
||||
## Information
|
||||
|
||||
Version controller:
|
||||
- 1.0 - no supported
|
||||
- 2.0 - Supported
|
||||
- 3.0 - no supported
|
||||
- 4.0 - no supported
|
||||
|
||||
DMA modes:
|
||||
- no-DMA - not supported
|
||||
- SDMA - Supported
|
||||
- ADMA1 - not supported
|
||||
- ADMA2 32bit - not supported
|
||||
- ADMA2 64bit - not supported
|
||||
|
||||
|
||||
Version OS:
|
||||
* rev 9897
|
||||
|
||||
Bus protocol:
|
||||
- SD Bus protocol - Supported
|
||||
- UHS-II Bus protocol - no supported
|
||||
- PCIe/NVMe Bus protocol - no supported
|
||||
|
||||
## TODO:
|
||||
- ~~инициализация контроллера, вывод информации об контроллере~~
|
||||
- ~~Установка изначальных значений для работы контроллера~~
|
||||
- ~~регистрация обработчика прерываний~~
|
||||
- ~~документирование и реализация команд контроллера~~
|
||||
- ~~написание алгоритма инициализации SD карт~~
|
||||
- ~~переписать обнаружение карт при инициализации контроллера~~
|
||||
- написание алгоритма инициализации SDIO карт
|
||||
- написание алгоритма инициализации MMC карт
|
||||
- написание функций передачи блоков через SDMA и ADMA и без применения DMA
|
||||
- ~~реализация функций card_init и card_destryct~~
|
||||
- ~~Получение базовых данных о карте(CID, CSD, RCA)~~
|
||||
- ~~реализовать функции смены частоты~~
|
||||
- ~~реализовать функции переключения шины SD в 4bit режим и обратно в 1bit режим~~
|
||||
- реализовать функции смены питания на 1.8V
|
||||
- ~~реализация функций обработки сообщений контроллера~~
|
||||
- реализация функций SDIO и их экспорт для драйверов и прикладного ПО
|
||||
- ~~реализация встроенного драйвера на SD карты памяти~~
|
||||
- ~~получение объёма карты в секторах(512 байт)~~
|
||||
|
||||
123
SDHC_doc.txt
123
SDHC_doc.txt
@@ -47,7 +47,7 @@
|
||||
;0-11 Transfer Block Size
|
||||
; Этот регистр определяет размер блока передачи данных для CMD17, CMD18, CMD24, CMD25, CMD35.
|
||||
; можно задать значение от 1 до 2048 байт. не изменять и не читать во время транзакции
|
||||
; In case of memory? it shall be set up to 512 bytes( Reffer to Implementation Note in Section 1.7.2)
|
||||
; In case of memory<EFBFBD> it shall be set up to 512 bytes( Reffer to Implementation Note in Section 1.7.2)
|
||||
;12-14 SDMA Buffer Boundary
|
||||
; Размер выделяемой нами физической памяти для SDMA команд.(4кб 8 кб 16 кб и тд. до 512к)
|
||||
; когда контроллер дошёл до конца выделенной нами памяти, вызывается прерывание DMA interrupt
|
||||
@@ -650,3 +650,124 @@
|
||||
;Для обнаружения ошибка таймаута на DAT линии. Установку этого значения делать при любой sd
|
||||
;транзакцией.
|
||||
|
||||
|
||||
|
||||
|
||||
;; CODE FOR TEST WORKING
|
||||
;DEBUGF 1,"SDHCI: TEST1 SDMA - read first sector\n"
|
||||
;call TEST_SDMA_R
|
||||
|
||||
;DEBUGF 1,"SDHCI: TEST2 SDMA - read first sector\n"
|
||||
;call TEST_SDMA_R_MUL
|
||||
|
||||
;proc TEST_SDMA_R
|
||||
; or dword[eax + SDHC_INT_MASK], 0xFFFFFFFF
|
||||
; or dword[eax + SDHC_SOG_MASK], 0xFFFFFFFF
|
||||
; and dword[eax + SDHC_CTRL1], not 11000b ; set SDMA mode
|
||||
; mov byte[eax + 0x2E], 1110b ; set max
|
||||
; mov ebp, eax
|
||||
; invoke KernelAlloc, 4096
|
||||
; push eax
|
||||
; invoke GetPhysAddr ; arg = eax
|
||||
; xchg eax, ebp
|
||||
; mov dword[eax], ebp;phys addr
|
||||
; mov dword[eax + 4], SD_BLOCK_SIZE
|
||||
; ;(block_count shl) 16 + (sdma_buffer_boundary shl 12) + block_size
|
||||
; mov dword[eax + 8], 0 ; arg - num sector
|
||||
; mov dword[eax + 0xC], (((17 shl 8) + DATA_PRSNT + RESP_TYPE.R1 ) shl 16) + 010001b
|
||||
;@@:
|
||||
; cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
; hlt
|
||||
; jz @b
|
||||
; ;DEBUGF 1,"SDHCI: resp1=%x resp2=%x \n", [eax + SDHC_RESP1_0], [eax + SDHC_RESP3_2]
|
||||
;.wait_int:
|
||||
; mov dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
; hlt
|
||||
; cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
; jz .wait_int
|
||||
; ;DEBUGF 1,"SDHCI: resp1=%x resp2=%x \n", [eax + SDHC_RESP1_0], [eax + SDHC_RESP3_2]
|
||||
; pop ebp
|
||||
; test dword[eax + SDHC_RESP1_0], 0x8000
|
||||
; jnz @f
|
||||
; push eax
|
||||
; mov dword[.ptr], ebp
|
||||
; mov ebx, .file_struct
|
||||
; invoke FS_Service
|
||||
; pop eax
|
||||
;@@:
|
||||
; ret
|
||||
;.file_struct:
|
||||
; dd 2
|
||||
; dd 0
|
||||
; dd 0
|
||||
; dd 512
|
||||
;.ptr: dd 0
|
||||
; db '/tmp0/1/dump_first_sector',0
|
||||
;
|
||||
;endp
|
||||
|
||||
; Заметка к SDMA: Прерывание DMA возникает только при пересечении границы блока данных
|
||||
; у меня это граница в 4кб
|
||||
;proc TEST_SDMA_R_MUL
|
||||
; or dword[eax + SDHC_INT_MASK], 0xFFFFFFFF
|
||||
; or dword[eax + SDHC_SOG_MASK], 0xFFFFFFFF
|
||||
; and dword[eax + SDHC_CTRL1], not 11000b ; set SDMA mode
|
||||
; mov byte[eax + 0x2E], 1110b ; set max
|
||||
; mov ebp, eax
|
||||
; invoke KernelAlloc, 4096*0x800;128;4096*512
|
||||
; push eax
|
||||
; push eax
|
||||
; invoke GetPhysAddr ; arg = eax
|
||||
; xchg eax, ebp
|
||||
; mov dword[eax], ebp;phys addr
|
||||
; mov dword[eax + 4], ((8*0x800) shl 16) + SD_BLOCK_SIZE
|
||||
; ;(block_count shl) 16 + (sdma_buffer_boundary shl 12) + block_size
|
||||
; mov dword[eax + 8], 0;0x2000 ; arg - num sector
|
||||
; mov dword[eax + 0xC], (((18 shl 8) + DATA_PRSNT + RESP_TYPE.R1 ) shl 16) + CMD_TYPE.Multiple + 10101b
|
||||
;@@:
|
||||
; cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
; hlt
|
||||
; jz @b
|
||||
; ;DEBUGF 1,"SDHCI: resp1=%x resp2=%x \n", [eax + SDHC_RESP1_0], [eax + SDHC_RESP3_2]
|
||||
;.wait_int:
|
||||
; mov dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
; hlt
|
||||
; cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
; jz .wait_int
|
||||
; test dword[esi + SDHCI_CONTROLLER.int_status], 10b
|
||||
; jnz @f
|
||||
; test dword[esi + SDHCI_CONTROLLER.int_status], 1000b
|
||||
; jz @f
|
||||
;
|
||||
; xchg eax, ebp
|
||||
; mov eax, dword[esp]
|
||||
; add eax, 4096
|
||||
; mov dword[esp], eax
|
||||
; invoke GetPhysAddr
|
||||
; xchg eax, ebp
|
||||
; mov dword[eax], ebp;phys addr
|
||||
;
|
||||
; jmp .wait_int
|
||||
;
|
||||
; ;DEBUGF 1,"SDHCI: resp1=%x resp2=%x \n", [eax + SDHC_RESP1_0], [eax + SDHC_RESP3_2]
|
||||
;@@:
|
||||
; pop ebp
|
||||
; pop ebp
|
||||
; test dword[eax + SDHC_RESP1_0], 0x8000
|
||||
; jnz @f
|
||||
; push eax
|
||||
; mov dword[.ptr], ebp
|
||||
; mov ebx, .file_struct
|
||||
; invoke FS_Service
|
||||
; pop eax
|
||||
;@@:
|
||||
; ret
|
||||
;.file_struct:
|
||||
; dd 2
|
||||
; dd 0
|
||||
; dd 0
|
||||
; dd 4096*0x800;128
|
||||
;.ptr: dd 0
|
||||
; db '/tmp0/1/dump_first_sector_mul',0
|
||||
;
|
||||
;endp
|
||||
263
sdhc_cmd.inc
263
sdhc_cmd.inc
@@ -41,6 +41,16 @@ SD_BLOCK_SIZE = 0x200 ;standart sector = 512
|
||||
R1_APP_CMD = 100000b ; êàðòà îæèäàåò ACMD êîìàíäó
|
||||
R1_READY_FOR_DATA = 100000000b ; 0x100 ñîîòâåòñÿòâóåò ñèãíàëó î ïóñòîì áóôåðå íà øèíå
|
||||
CMD55_VALID_RESP = R1_READY_FOR_DATA + R1_APP_CMD
|
||||
|
||||
|
||||
OCR_REG:
|
||||
.S18A = (1 shl 24)
|
||||
.CO2T = 0x08000000
|
||||
.CCS = 0x40000000
|
||||
.UHSII = 0x20000000
|
||||
.Busy = 0x80000000
|
||||
; sdio
|
||||
.MP = (1 shl 27)
|
||||
; in: eax - reg map, esi - struct controller
|
||||
; ebx - arg 32 bit â ãîòîâîì âèäå edx - 0x0C register ;command reg with flags
|
||||
proc send_sdhc_command
|
||||
@@ -48,12 +58,12 @@ proc send_sdhc_command
|
||||
test dword[eax + SDHC_PRSNT_STATE], 0x07 ; check cmd_inhid_cmd + cmd_inhibit_dat + DAT Line Active
|
||||
jnz @b
|
||||
mov dword[eax + SDHC_CMD_ARG], ebx
|
||||
mov dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
mov dword[esi + SDHCI_SLOT.int_status], 0
|
||||
DEBUGF 1,"SDHCI: Command send\n"
|
||||
mov dword[eax + SDHC_CMD_TRN], edx ; íà÷àëî âûïîëíåíèÿ êîìàíäû
|
||||
@@:
|
||||
hlt
|
||||
cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
cmp dword[esi + SDHCI_SLOT.int_status], 0
|
||||
jz @b
|
||||
DEBUGF 1,"SDHCI: resp1=%x resp2=%x \n", [eax + SDHC_RESP1_0], [eax + SDHC_RESP3_2]
|
||||
ret
|
||||
@@ -63,14 +73,16 @@ endp
|
||||
; ebx - argument 32 bit ecx - 0x0C register
|
||||
; edx - (block_count shl 16) + block_size edi - virtual addr ; save in stack
|
||||
proc send_sdhc_transfer_command
|
||||
;DEBUGF 1,"SDHCI: VIRT ADDR %x\n", edi
|
||||
push edx
|
||||
push edi
|
||||
push edi ; virt addr
|
||||
sub esp, 4 ; for save ADMA2\ADMA1 table
|
||||
@@:
|
||||
test dword[eax + SDHC_PRSNT_STATE], 0x07
|
||||
jnz @b ; check cmd_inhid_cmd + cmd_inhibit_dat + DAT Line Active
|
||||
|
||||
mov dword[esi + SDHCI_SLOT.virt_addr_buff],edi
|
||||
|
||||
; (1) Set Block Size Reg
|
||||
; (2) Set Block Count Reg
|
||||
mov dword[eax + SDHX_BLK_CS], edx
|
||||
@@ -98,65 +110,38 @@ proc send_sdhc_transfer_command
|
||||
mov dword[esp], edi
|
||||
|
||||
.end_set_addr:
|
||||
mov dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
mov dword[esi + SDHCI_SLOT.int_status], 0
|
||||
; (4) Set Transfer Mode Reg
|
||||
; (5) Set Command Reg
|
||||
mov dword[eax + SDHC_CMD_TRN], ecx
|
||||
@@:
|
||||
hlt
|
||||
cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
jz @b
|
||||
|
||||
cmp dword[esi + SDHCI_CONTROLLER.int_status], INT_STATUS.CMD_DONE
|
||||
jnz .err
|
||||
; wait interrupt transfer
|
||||
.wait_int:
|
||||
mov dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
@@:
|
||||
hlt
|
||||
cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
|
||||
jz @b;.wait_int
|
||||
cmp dword[esi + SDHCI_SLOT.int_status], 0
|
||||
jz .wait_int
|
||||
|
||||
test dword[esi + SDHCI_CONTROLLER.int_status], INT_STATUS.ERROR
|
||||
jnz .dat_err
|
||||
|
||||
test dword[esi + SDHCI_CONTROLLER.int_status], INT_STATUS.DAT_DONE ; Transfer complate
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.DAT_DONE \
|
||||
+ INT_STATUS.ERROR \
|
||||
+ INT_STATUS.BUF_WR_RDY \
|
||||
+ INT_STATUS.BUF_RD_RDY
|
||||
jnz @f
|
||||
mov dword[esi + SDHCI_SLOT.int_status], 0
|
||||
jmp .wait_int
|
||||
@@:
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.ERROR
|
||||
jnz .err
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.DAT_DONE
|
||||
jnz .good_transfer
|
||||
|
||||
test dword[esi + SDHCI_CONTROLLER.int_status], INT_STATUS.DMA_EVT ; DMA intr
|
||||
jz .no_sdma
|
||||
; SDMA add addr and set new phys addr
|
||||
and dword[esp + 4], -4096
|
||||
add dword[esp + 4], 4096
|
||||
mov ecx, dword[esp + 4]
|
||||
xchg eax, ecx
|
||||
invoke GetPhysAddr
|
||||
xchg eax, ecx
|
||||
mov dword[eax + SDHC_SYS_ADDR], ecx
|
||||
jmp .wait_int
|
||||
.no_sdma:
|
||||
test dword[esi + SDHCI_CONTROLLER.int_status], INT_STATUS.BUF_WR_RDY ; port write
|
||||
jz .no_w_port
|
||||
|
||||
jmp .wait_int
|
||||
.no_w_port:
|
||||
test dword[esi + SDHCI_CONTROLLER.int_status], INT_STATUS.BUF_RD_RDY ; port read
|
||||
jz .wait_int ; undefined interrupt
|
||||
|
||||
mov ecx, [eax + SDHC_BUFFER]
|
||||
;TODO: add code for cory data in not DMA mode !!!
|
||||
jmp .wait_int
|
||||
|
||||
.good_transfer:
|
||||
DEBUGF 1,"SDHCI: GOOD COMMAND\n"
|
||||
add esp, 4*4
|
||||
ret
|
||||
.dat_err:
|
||||
DEBUGF 1,"SDHCI: ERROR CMD COMMAND\n"
|
||||
add esp, 4*4
|
||||
;DEBUGF 1,"SDHCI: GOOD COMMAND\n"
|
||||
add esp, 4*3
|
||||
ret
|
||||
.err:
|
||||
DEBUGF 1,"SDHCI: ERROR DAT COMMAND\n"
|
||||
add esp, 4*4
|
||||
DEBUGF 1,"SDHCI: ERROR DAT COMMAND %x\n", [esi + SDHCI_SLOT.int_status]
|
||||
add esp, 4*3
|
||||
ret
|
||||
endp
|
||||
|
||||
@@ -180,10 +165,10 @@ macro ALL_SEND_CID {
|
||||
mov ebx, [eax + SDHC_RESP3_2]
|
||||
mov edx, [eax + SDHC_RESP5_4]
|
||||
mov edi, [eax + SDHC_RESP7_6]
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_cid], ecx
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_cid + 4], ebx
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_cid + 8], edx
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_cid + 12], edi
|
||||
mov [esi + SDHCI_SLOT.card_reg_cid], ecx
|
||||
mov [esi + SDHCI_SLOT.card_reg_cid + 4], ebx
|
||||
mov [esi + SDHCI_SLOT.card_reg_cid + 8], edx
|
||||
mov [esi + SDHCI_SLOT.card_reg_cid + 12], edi
|
||||
DEBUGF 1,"SDHCI: resp3=%x resp4=%x \n", [eax + SDHC_RESP5_4], [eax + SDHC_RESP7_6]
|
||||
}
|
||||
;cmd3 - Ask the card to publish a new relative address(RCA)
|
||||
@@ -196,26 +181,52 @@ proc SEND_RCA
|
||||
|
||||
mov ecx, [eax + SDHC_RESP1_0]
|
||||
shr ecx, 16
|
||||
mov word[esi + SDHCI_CONTROLLER.card_reg_rca], cx
|
||||
mov word[esi + SDHCI_SLOT.card_reg_rca], cx
|
||||
ret
|
||||
endp
|
||||
; ÍÅ ÈÑÏÎËÜÇÎÂÀÒÜ, ýòî ÷òî-òî ñ ïèòàíèåì, íó íàôèã
|
||||
;cmd4 - programs the DSR of all cards
|
||||
;resp =
|
||||
;args =
|
||||
proc SET_DSR
|
||||
;proc SET_DSR
|
||||
;
|
||||
; ret
|
||||
;endp
|
||||
|
||||
ret
|
||||
;cmd6 - for class 10 , see chapter 4.3.10
|
||||
;resp = R1 + 512 bit
|
||||
;args = [31] mode 0 - check function 1 - switch function
|
||||
; [30:24] reserved, set "0"
|
||||
; ...
|
||||
; [7:4] Command System
|
||||
; [3:0] Access Mode
|
||||
; if function no switch, set 0xF for skip set set new mode function
|
||||
; 0x80fffff1 for switch on high speed
|
||||
; IN: ebx - arg
|
||||
; edi - ptr to buffer on 64byte(512 bit)
|
||||
proc SWITCH_FUNC
|
||||
and dword[eax + SDHC_CTRL1], not 11000b ; set SDMA mode
|
||||
|
||||
; edi
|
||||
mov edx, 512/8
|
||||
mov ecx, (((6 shl 8) + DATA_PRSNT + RESP_TYPE.R1 ) shl 16) + CMD_TYPE.Single \
|
||||
+ CMD_TYPE.Read \
|
||||
+ DMA_EN
|
||||
call send_sdhc_transfer_command
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.ERROR
|
||||
ret
|
||||
endp
|
||||
|
||||
;cmd7 - select card for switch in transfer state
|
||||
;resp = R1b , ZF - good; not ZF - error
|
||||
;args = RCA in ebx
|
||||
proc SELECT_CARD
|
||||
mov bx, word[esi + SDHCI_CONTROLLER.card_reg_rca]
|
||||
mov bx, word[esi + SDHCI_SLOT.card_reg_rca]
|
||||
shl ebx, 16
|
||||
mov edx, ((7 shl 8) + RESP_TYPE.R1b ) shl 16
|
||||
call send_sdhc_command
|
||||
|
||||
test dword[esi + SDHCI_CONTROLLER.int_status],0x8000
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.ERROR
|
||||
ret
|
||||
endp
|
||||
;cmd7 - switch card in stable state
|
||||
@@ -225,7 +236,7 @@ proc DESELECT_CARD
|
||||
mov edx, ((7 shl 8) + RESP_TYPE.R1b ) shl 16
|
||||
call send_sdhc_command
|
||||
|
||||
test dword[esi + SDHCI_CONTROLLER.int_status],0x8000
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.ERROR
|
||||
ret
|
||||
endp
|
||||
;cmd8 - ïðîâåðêà âîëüòàæà êàðòû äëÿ âåðñèè 2.0 è âûøå. Èñïîëüçóåòñÿ äëÿ îïðåäåëåíèÿ âåðñèè.
|
||||
@@ -236,6 +247,7 @@ endp
|
||||
; òî îøèáêà òàéìàóò
|
||||
; Ïðèìå÷àíèå: Åñëè íå âûçûâàòü ýòó êîìàíäó òî êàðòà âûäàñò îøèáêó èíèöèàëèçàöèè ïðè ACMD41
|
||||
proc SEND_IF_COUND
|
||||
;DEBUGF 1,"SDHCI: CMD8 - check SDHC card\n"
|
||||
mov ebx, (0001b shl 8) + 10101010b
|
||||
|
||||
cmp byte[eax + 0x29],1011b
|
||||
@@ -253,7 +265,7 @@ endp
|
||||
;args = [16:31]RCA card
|
||||
proc SEND_CSD
|
||||
;DEBUGF 1,"SDHCI: get CSD reg\n"
|
||||
mov bx, word[esi + SDHCI_CONTROLLER.card_reg_rca]
|
||||
mov bx, word[esi + SDHCI_SLOT.card_reg_rca]
|
||||
shl ebx, 16
|
||||
mov edx, ((9 shl 8) + RESP_TYPE.R2 ) shl 16
|
||||
call send_sdhc_command
|
||||
@@ -262,10 +274,10 @@ proc SEND_CSD
|
||||
mov ebx, [eax + SDHC_RESP3_2]
|
||||
mov edx, [eax + SDHC_RESP5_4]
|
||||
mov edi, [eax + SDHC_RESP7_6]
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_csd], ecx
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_csd + 4], ebx
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_csd + 8], edx
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_csd + 12], edi
|
||||
mov [esi + SDHCI_SLOT.card_reg_csd], ecx
|
||||
mov [esi + SDHCI_SLOT.card_reg_csd + 4], ebx
|
||||
mov [esi + SDHCI_SLOT.card_reg_csd + 8], edx
|
||||
mov [esi + SDHCI_SLOT.card_reg_csd + 12], edi
|
||||
DEBUGF 1,"SDHCI: resp3=%x resp4=%x \n", [eax + SDHC_RESP5_4], [eax + SDHC_RESP7_6]
|
||||
ret
|
||||
endp
|
||||
@@ -274,7 +286,7 @@ endp
|
||||
;args = [16:31]RCA card
|
||||
proc SEND_CID
|
||||
;DEBUGF 1,"SDHCI: get CID reg\n"
|
||||
mov bx, word[esi + SDHCI_CONTROLLER.card_reg_rca]
|
||||
mov bx, word[esi + SDHCI_SLOT.card_reg_rca]
|
||||
shl ebx, 16
|
||||
mov edx, ((10 shl 8) + RESP_TYPE.R2 ) shl 16
|
||||
call send_sdhc_command
|
||||
@@ -283,33 +295,33 @@ proc SEND_CID
|
||||
mov ebx, [eax + SDHC_RESP3_2]
|
||||
mov edx, [eax + SDHC_RESP5_4]
|
||||
mov edi, [eax + SDHC_RESP7_6]
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_cid], ecx
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_cid + 4], ebx
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_cid + 8], edx
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_cid + 12], edi
|
||||
mov [esi + SDHCI_SLOT.card_reg_cid], ecx
|
||||
mov [esi + SDHCI_SLOT.card_reg_cid + 4], ebx
|
||||
mov [esi + SDHCI_SLOT.card_reg_cid + 8], edx
|
||||
mov [esi + SDHCI_SLOT.card_reg_cid + 12], edi
|
||||
DEBUGF 1,"SDHCI: resp3=%x resp4=%x \n", [eax + SDHC_RESP5_4], [eax + SDHC_RESP7_6]
|
||||
ret
|
||||
endp
|
||||
;cmd55 = switch to ACMD mode command
|
||||
;resp = R1
|
||||
;args = [31:16]RCA [15:0]stuff bits
|
||||
; êîìàíäà ñîîáùàåò êàðòå, ÷òî ñäóäóþùàÿ êîìàíäà áóäåò acmd
|
||||
;OUT: ZF - good ; NO ZF - error timeout
|
||||
; WARNING!!! Ïðè îòêëþ÷åíèè êàðòû èëè äðóãèõ îøèáêàõ âûçûâàåò çàâèñàíèå
|
||||
proc APP_CMD
|
||||
push ecx edx ebx
|
||||
dec esp
|
||||
mov byte[esp], 0
|
||||
@@:
|
||||
inc byte[esp]
|
||||
mov bx, word[esi + SDHCI_CONTROLLER.card_reg_rca]
|
||||
mov bx, word[esi + SDHCI_SLOT.card_reg_rca]
|
||||
shl ebx, 16
|
||||
mov edx, ((55 shl 8) + RESP_TYPE.R1 ) shl 16
|
||||
call send_sdhc_command
|
||||
; òóò êàê ÿ ïîíèìàþ íàäî ïðîâåðÿòü ñîñòîÿíèå
|
||||
cmp dword[eax + SDHC_RESP1_0], CMD55_VALID_RESP
|
||||
jz .good ; ïî ñïåêå(ôèç óðîâåíü, ñòð 63(74))
|
||||
test byte[esp], 0x80 ; ýòî ôëàãè APP_CMD è READY_FOR_DATA
|
||||
|
||||
mov ecx, dword[eax + SDHC_RESP1_0]
|
||||
and ecx, CMD55_VALID_RESP ; clear all bits response
|
||||
cmp ecx, CMD55_VALID_RESP ; check switch in APP mode
|
||||
jz .good ; ïî ñïåêå(ôèç óðîâåíü, ñòð 63(74))
|
||||
test byte[esp], 0x80 ; ýòî ôëàãè APP_CMD è READY_FOR_DATA
|
||||
jz @b
|
||||
.good:
|
||||
lea esp, [esp + 1]
|
||||
@@ -317,19 +329,65 @@ proc APP_CMD
|
||||
ret
|
||||
endp
|
||||
|
||||
;acmd41 -
|
||||
;acmd6 = SET_BUS_WIDTH
|
||||
;resp = R1
|
||||
;args = [1:0]bus width 00 - 1bit; 10 - 4bit
|
||||
; IN: ebx - arg 00-1bit 10-4bit
|
||||
proc SET_BUS_WIDTH
|
||||
call APP_CMD
|
||||
jnz .err
|
||||
|
||||
mov edx, ((6 shl 8) + RESP_TYPE.R1) shl 16
|
||||
call send_sdhc_command
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.ERROR
|
||||
.err:
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
;acmd13 = SD_STATUS
|
||||
;resp = R1 AND 512 bits ˜
|
||||
;args =
|
||||
|
||||
;acmd51 = SEND_SCR
|
||||
;resp = R1 AND 64 bits
|
||||
;args =
|
||||
proc SEND_SCR
|
||||
call APP_CMD
|
||||
jnz .err
|
||||
|
||||
and dword[eax + SDHC_CTRL1], not 11000b ; set SDMA mode
|
||||
xor ebx, ebx
|
||||
lea edi, [esi + SDHCI_SLOT.card_reg_scr]
|
||||
mov edx, 8;64/8
|
||||
mov ecx, (((51 shl 8) + DATA_PRSNT + RESP_TYPE.R1 ) shl 16) + CMD_TYPE.Single \
|
||||
+ CMD_TYPE.Read \
|
||||
+ DMA_EN
|
||||
call send_sdhc_transfer_command
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.ERROR
|
||||
DEBUGF 1,"SDHCI: scr=%x scr+4=%x\n", [esi + SDHCI_SLOT.card_reg_scr],\
|
||||
[esi + SDHCI_SLOT.card_reg_scr + 4]
|
||||
.err:
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
;acmd41 - get OCR and set voltage
|
||||
;resp = R3
|
||||
;args = [31]reserved bit [30]HCS(OCR[30]) [29:24]reserved bits
|
||||
; [23:0]Vdd Voltage Window(OCR[23:0])
|
||||
;IN: ebx - argument command
|
||||
proc SD_SEND_OP_COND
|
||||
;DEBUGF 1,"SDHCI: ACMD41 - get OCR\n"
|
||||
call APP_CMD
|
||||
jnz .err
|
||||
|
||||
mov edx, ((41 shl 8) + RESP_TYPE.R3 ) shl 16
|
||||
call send_sdhc_command
|
||||
mov ecx, [eax + SDHC_RESP1_0]
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_ocr], ecx
|
||||
test dword[esi + SDHCI_CONTROLLER.int_status],0x8000
|
||||
mov [esi + SDHCI_SLOT.card_reg_ocr], ecx
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.ERROR
|
||||
.err:
|
||||
ret
|
||||
endp
|
||||
; block read/write
|
||||
@@ -339,12 +397,12 @@ endp
|
||||
;resp = R1
|
||||
; IN: ebx - 32bit block length
|
||||
proc SET_BLOCKLEN
|
||||
DEBUGF 1,"SDHCI: SET_BLOCKLEN 0x%x\n", ebx
|
||||
;DEBUGF 1,"SDHCI: SET_BLOCKLEN 0x%x\n", ebx
|
||||
mov edx, ((16 shl 8) + RESP_TYPE.R1 ) shl 16
|
||||
call send_sdhc_command
|
||||
mov ecx, [eax + SDHC_RESP1_0]
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_ocr], ecx
|
||||
test dword[esi + SDHCI_CONTROLLER.int_status],0x8000
|
||||
mov [esi + SDHCI_SLOT.card_reg_ocr], ecx
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.ERROR
|
||||
ret
|
||||
endp
|
||||
; block read
|
||||
@@ -395,7 +453,7 @@ proc WRITE_BLOCK
|
||||
and dword[eax + SDHC_CTRL1], not 11000b ; set SDMA mode
|
||||
mov edx, SD_BLOCK_SIZE
|
||||
mov ecx, (((24 shl 8) + DATA_PRSNT + RESP_TYPE.R1 ) shl 16) + CMD_TYPE.Single \
|
||||
+ CMD_TYPE.Read \
|
||||
+ CMD_TYPE.Write \
|
||||
+ DMA_EN
|
||||
call send_sdhc_transfer_command
|
||||
ret
|
||||
@@ -412,7 +470,7 @@ proc WRITE_MULTIPLE_BLOCK
|
||||
shl edx, 16
|
||||
add edx, SD_BLOCK_SIZE
|
||||
mov ecx, (((25 shl 8) + DATA_PRSNT + RESP_TYPE.R1 ) shl 16) + CMD_TYPE.Multiple \
|
||||
+ CMD_TYPE.Read \
|
||||
+ CMD_TYPE.Write \
|
||||
+ ACMD12_EN \
|
||||
+ DMA_EN
|
||||
call send_sdhc_transfer_command
|
||||
@@ -424,6 +482,21 @@ endp
|
||||
; ret
|
||||
;endp
|
||||
|
||||
;cmd42 - works with password and PWD register card
|
||||
;resp = R1
|
||||
;args = -
|
||||
; IN: edi - virt addr data
|
||||
proc LOCK_UNLOCK
|
||||
|
||||
xor ebx, ebx
|
||||
mov ecx, (((42 shl 8) + DATA_PRSNT + RESP_TYPE.R1 ) shl 16) + CMD_TYPE.Single \
|
||||
+ CMD_TYPE.Write \
|
||||
+ DMA_EN
|
||||
call send_sdhc_transfer_command
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
; SDIO mode
|
||||
; Îòëè÷èÿ îò SD memory:
|
||||
; - CID ðåãèñòð îòñóòñòâóåò
|
||||
@@ -439,16 +512,30 @@ proc IO_SEND_OP_COND
|
||||
|
||||
call send_sdhc_command
|
||||
mov ecx, [eax + SDHC_RESP1_0]
|
||||
mov [esi + SDHCI_CONTROLLER.card_reg_ocr], ecx
|
||||
test dword[esi + SDHCI_CONTROLLER.int_status], INT_STATUS.ERROR
|
||||
mov [esi + SDHCI_SLOT.card_reg_ocr], ecx
|
||||
test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.ERROR
|
||||
ret
|
||||
endp
|
||||
;cmd52 -
|
||||
;cmd52 - Read\Write Byte. No using DAT line.
|
||||
;arg =
|
||||
;resp = R5
|
||||
; fastcall i32 IO_RW_DIRECT(i32 arg); esi - rtp SDHCI_SLOT
|
||||
; IN: ecx - data for sending to card
|
||||
proc IO_RW_DIRECT
|
||||
|
||||
ret
|
||||
push ebx
|
||||
mov eax, [esi + SDHCI_SLOT.base_reg_map]
|
||||
mov ebx, ecx
|
||||
mov edx, ((52 shl 8) + RESP_TYPE.R5 ) shl 16
|
||||
call send_sdhc_command
|
||||
|
||||
pop ebx
|
||||
mov eax, [eax + SDHC_RESP1_0]
|
||||
ret
|
||||
endp
|
||||
;cmd53 -
|
||||
;arg =
|
||||
;resp = R5 or R5b
|
||||
proc IO_RW_EXTENDED
|
||||
|
||||
ret
|
||||
|
||||
106
sdhc_disk.inc
106
sdhc_disk.inc
@@ -10,24 +10,24 @@ proc GET_SDSC_SIZE
|
||||
; MULT = 2^(C_SIZE_MULT + 2)
|
||||
; BLOCK_LEN = 2^LEN_BL_READ
|
||||
push ecx edx
|
||||
mov ecx, dword[esi + SDHCI_CONTROLLER.card_reg_csd + 4] ; C_SIZE_MULT
|
||||
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_CONTROLLER.card_reg_csd + 6] ; C_SIZE 48/8
|
||||
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_CONTROLLER.card_reg_csd + 9] ; LEN_BL_READ 72/8
|
||||
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_CONTROLLER.sector_count], edx
|
||||
mov dword[esi + SDHCI_CONTROLLER.sector_count + 4], 0
|
||||
mov dword[esi + SDHCI_SLOT.sector_count], edx
|
||||
mov dword[esi + SDHCI_SLOT.sector_count + 4], 0
|
||||
pop edx ecx
|
||||
ret
|
||||
endp
|
||||
@@ -36,14 +36,14 @@ proc GET_SDHC_SIZE
|
||||
; 22 bit [40:61]
|
||||
; ((C_SIZE + 1) * 512Kbyte ) / sectorsize
|
||||
push ebx
|
||||
mov ebx, dword[esi + SDHCI_CONTROLLER.card_reg_csd + 5]
|
||||
mov ebx, dword[esi + SDHCI_SLOT.card_reg_csd + 5]
|
||||
and ebx, not 0xFFC00000 ; îáíóëÿåì ñòàðøèå áèòû
|
||||
mov dword[esi + SDHCI_CONTROLLER.sector_count + 4], 0
|
||||
mov dword[esi + SDHCI_SLOT.sector_count + 4], 0
|
||||
inc edx ; C_SIZE + 1
|
||||
shl ebx, 10 ; *512Kbyte / sectorsize(512)
|
||||
mov dword[esi + SDHCI_CONTROLLER.sector_count], ebx
|
||||
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_CONTROLLER.sector_count + 4], 0
|
||||
adc dword[esi + SDHCI_SLOT.sector_count + 4], 0
|
||||
pop ebx
|
||||
ret
|
||||
endp
|
||||
@@ -52,13 +52,13 @@ proc GET_SDUC_SIZE
|
||||
; 28 bit [40:67] 40bit=5*8bit
|
||||
; ((C_SIZE + 1) * 512Kbyte ) / sectorsize
|
||||
push ebx
|
||||
mov ebx, dword[esi + SDHCI_CONTROLLER.card_reg_csd + 5]
|
||||
mov ebx, dword[esi + SDHCI_SLOT.card_reg_csd + 5]
|
||||
and ebx, not 0xC0000000 ; îáíóëÿåì ñòàðøèå áèòû
|
||||
inc edx
|
||||
mov dword[esi + SDHCI_CONTROLLER.sector_count], ebx
|
||||
mov dword[esi + SDHCI_SLOT.sector_count], ebx
|
||||
shr ebx, 31-10 ; get hign LBA addr
|
||||
mov dword[esi + SDHCI_CONTROLLER.card_reg_csd + 4], ebx
|
||||
shl dword[esi + SDHCI_CONTROLLER.sector_count], 10
|
||||
mov dword[esi + SDHCI_SLOT.card_reg_csd + 4], ebx
|
||||
shl dword[esi + SDHCI_SLOT.sector_count], 10
|
||||
pop ebx
|
||||
ret
|
||||
endp
|
||||
@@ -75,51 +75,57 @@ 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
|
||||
proc del_card_disk
|
||||
|
||||
ret
|
||||
endp
|
||||
|
||||
; Functions for kernel
|
||||
; Ïîÿñíåíèå ê ðåàëèçàöèè ÷òåíèÿ/çàïèñè ñåêòîðîâ:
|
||||
; Ýòîò äðàéâåð äîëæåí îáðàáàòûâàòü SD êàðòû ðàçíûõ âåðñèé,
|
||||
; SDIO êàðòû(â òîì ÷èñëå è ñîâìåù¸ííûå) è MMC(eMMC) êàðòû.
|
||||
; Âî âñåõ âàðèàíòàõ êàðò ÷òåíèå è çàïèñü ïðîèñõîäèòü ïðè ïîìîùè
|
||||
; îäíèõ è òåõ æå êîìàíä(17,18,24,25), ïðè ÷¸ì ïîñëåäîâàòåëüíîñòü
|
||||
; îñòàëüíûõ êîìàíä òàêæå ñõîæà.
|
||||
; Ïî ýòîìó ðàçëè÷àòüñÿ áóäóò òîëüêî ìåòîäû ðàáîòû ñ êîíòðîëëåðîì,
|
||||
; ýòî ëèáî èñïîëüçîâàíèå SDMA èëè ADMA2 èëè, åñëè ýòîãî íåò, òî
|
||||
; ðàáîòà ÷åðåç ïîðò áóôåðà
|
||||
proc sdhci_read stdcall pdata: dword, buffer: dword, startsector: qword, numsectors_ptr:dword
|
||||
pusha
|
||||
|
||||
mov esi, [pdata]
|
||||
mov eax, [esi + SDHCI_CONTROLLER.base_reg_map]
|
||||
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
|
||||
;DEBUGF 1,"SDHCI: read sector=%x num=%x \n", ebx, edx
|
||||
cmp edx, 1
|
||||
ja .multiple
|
||||
|
||||
; send CMD 17
|
||||
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
|
||||
|
||||
; send CMD 18
|
||||
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
|
||||
@@ -128,26 +134,44 @@ endp
|
||||
proc sdhci_write stdcall pdata: dword, buffer: dword, startsector: qword, numsectors_ptr:dword
|
||||
pusha
|
||||
mov esi, [pdata]
|
||||
mov eax, [esi + SDHCI_CONTROLLER.base_reg_map]
|
||||
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
|
||||
;DEBUGF 1,"SDHCI: write sector=%x num=%x \n", ebx, edx
|
||||
cmp edx, 1
|
||||
ja .multiple
|
||||
|
||||
; send CMD 24
|
||||
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
|
||||
|
||||
; send CMD 25
|
||||
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
|
||||
@@ -166,9 +190,9 @@ proc sdhci_querymedia stdcall, pdata, mediainfo
|
||||
mov edx, [pdata]
|
||||
mov [eax + DISKMEDIAINFO.Flags], 0
|
||||
mov [eax + DISKMEDIAINFO.SectorSize], SD_BLOCK_SIZE
|
||||
mov ecx, dword[edx + SDHCI_CONTROLLER.sector_count]
|
||||
mov ecx, dword[edx + SDHCI_SLOT.sector_count]
|
||||
mov dword [eax + DISKMEDIAINFO.Capacity], ecx
|
||||
mov ecx, dword[edx + SDHCI_CONTROLLER.sector_count + 4]
|
||||
mov ecx, dword[edx + SDHCI_SLOT.sector_count + 4]
|
||||
mov dword [eax + DISKMEDIAINFO.Capacity + 4], ecx
|
||||
pop edx ecx
|
||||
xor eax, eax
|
||||
@@ -186,11 +210,11 @@ sdhci_callbacks:
|
||||
dd 0 ;sdhci_close ; close function -
|
||||
dd 0 ; closemedia function
|
||||
dd sdhci_querymedia ; +
|
||||
dd sdhci_read ; -
|
||||
dd sdhci_write ; -
|
||||
dd sdhci_read ; +
|
||||
dd sdhci_write ; +
|
||||
dd 0 ; no flush function
|
||||
dd 0 ; use default cache size
|
||||
.end:
|
||||
|
||||
sdcard_disk_name: db 'sdcard00',0
|
||||
mmccard_disk_name: db 'MMC00',0
|
||||
; ; /sdhciXXXS/1
|
||||
;sdhci_disk_name: db 'sdhci0000',0,0 ; xxx - number of controller
|
||||
; ; s - number slot in select controller
|
||||
118
sdio-test.asm
Normal file
118
sdio-test.asm
Normal file
@@ -0,0 +1,118 @@
|
||||
format PE native
|
||||
entry START
|
||||
use32
|
||||
DEBUG = 1
|
||||
__DEBUG__ = 1
|
||||
__DEBUG_LEVEL__ = 1 ; 1 = verbose, 2 = errors only
|
||||
|
||||
section '.flat' code readable writable executable
|
||||
|
||||
include 'drivers/proc32.inc'
|
||||
include 'drivers/struct.inc'
|
||||
include 'drivers/macros.inc'
|
||||
include 'drivers/peimport.inc'
|
||||
include 'drivers/fdo.inc'
|
||||
|
||||
struct IMPORT_SDIO_FUNC
|
||||
reg_sdio rd 1
|
||||
unreg_sdio rd 1
|
||||
scan_dev rd 1
|
||||
cmd52 rd 1
|
||||
cmd53 rd 1
|
||||
ends
|
||||
|
||||
proc START c, state:dword, cmdline:dword
|
||||
cmp [state], DRV_ENTRY
|
||||
jne .stop_drv
|
||||
DEBUGF 1,"SDIO-TEST: Loading driver\n"
|
||||
|
||||
invoke GetService, sdhci_str
|
||||
DEBUGF 1,"SDIO-TEST: Get service %x\n", eax
|
||||
test eax, eax
|
||||
jz .err
|
||||
mov [sdhci_handle], eax
|
||||
; get import sdio func
|
||||
invoke ServiceHandler, ioctl_get_export
|
||||
; reg sdio
|
||||
test eax, eax
|
||||
jnz .err
|
||||
DEBUGF 1,"SDIO-TEST: import table %x\n", [ptr_import_table]
|
||||
mov eax, [ptr_import_table]
|
||||
stdcall [eax + IMPORT_SDIO_FUNC.reg_sdio], drv_table_func
|
||||
DEBUGF 1,"SDIO-TEST: Reg sdio %x\n", eax
|
||||
test eax, eax
|
||||
jz .err
|
||||
mov [sdio_hand], eax
|
||||
; TODO: scan dev
|
||||
; reg driver
|
||||
invoke RegService, drv_name, 0
|
||||
ret
|
||||
.stop_drv:
|
||||
; unreg
|
||||
.err:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
proc check_dev stdcall ptr_slot: dword
|
||||
push esi ebx edi
|
||||
; Âûâîä ñîîáùåíèÿ îá îáíàðóæåíèè SDIO óñòðîéñòâà
|
||||
DEBUGF 1,"SDIO-TEST: Check SDIO dev\n"
|
||||
mov esi, [ptr_slot]
|
||||
mov edi, [ptr_import_table]
|
||||
; âûâîä âåðñèè SDIO èíòåðôåéñà
|
||||
mov ecx, 0
|
||||
call [edi + IMPORT_SDIO_FUNC.cmd52]
|
||||
mov ecx, eax
|
||||
shr al, 4
|
||||
and cl, 0x0F
|
||||
and al, 0x0f
|
||||
DEBUGF 1,"SDIO-TEST: SDIO ver= %d CCCR ver = %d\n", al, cl
|
||||
; âûâîä êëàññà FBR1
|
||||
mov ecx, (0x100 shl 9)
|
||||
call [edi + IMPORT_SDIO_FUNC.cmd52]
|
||||
and al, 0x0f
|
||||
DEBUGF 1,"SDIO-TEST: FBR interface code= %d\n", cl
|
||||
|
||||
pop edi ebx esi
|
||||
mov eax,[ptr_slot]
|
||||
ret
|
||||
endp
|
||||
|
||||
proc int_handle stdcall pdata: dword
|
||||
|
||||
ret
|
||||
endp
|
||||
|
||||
proc close_dev stdcall pdata: dword
|
||||
DEBUGF 1,"SDIO-TEST: Close sdio device\n"
|
||||
ret
|
||||
endp
|
||||
|
||||
ioctl_get_export:
|
||||
sdhci_handle: dd 0
|
||||
dd 3
|
||||
dd 0
|
||||
dd 0
|
||||
dd ptr_import_table
|
||||
dd 4
|
||||
|
||||
ptr_import_table: dd 0
|
||||
sdio_hand: dd 0
|
||||
PDATA_STRUCT: dd 0
|
||||
|
||||
drv_table_func:
|
||||
dd check_dev
|
||||
dd int_handle
|
||||
dd close_dev
|
||||
sdhci_str: db 'SDHCI',0
|
||||
|
||||
drv_name: db 'SDIO-TEST',0
|
||||
|
||||
|
||||
|
||||
align 4
|
||||
data fixups
|
||||
end data
|
||||
|
||||
include_debug_strings
|
||||
BIN
sdio-test.sys
Normal file
BIN
sdio-test.sys
Normal file
Binary file not shown.
83
sdio.inc
Normal file
83
sdio.inc
Normal file
@@ -0,0 +1,83 @@
|
||||
;; Copyright (C) 2022, Michael Frolov(aka Doczom)
|
||||
;; SDIO subsystem SDHCI driver. Base functons for working.
|
||||
|
||||
|
||||
; Ñïèñîê âíåøíèõ SDIO ìîäóëåé ÿäðà
|
||||
sdio_drv_list:
|
||||
dd sdio_drv_list
|
||||
dd sdio_drv_list
|
||||
|
||||
|
||||
struct SDIO_SERVICE
|
||||
next rd 1
|
||||
prev rd 1
|
||||
sdio_func rd 1 ;ptr
|
||||
ends
|
||||
|
||||
|
||||
struct SDIO_SERVICE_FUNC
|
||||
check_fbr rd 1
|
||||
; stdcall void* check_fbr(SDHCI_SLOT* slot_str)
|
||||
; Called for find driver to this card. Function rerturning
|
||||
; DWORD or zero. Return value - pdata for calling func
|
||||
int_handler rd 1
|
||||
; stdcall int int_handler(void* pdata)
|
||||
; This function calling in sdhc_irq() when geting
|
||||
; card interrupt
|
||||
close_card rd 1
|
||||
; stdcall int close_card(void* pdata)
|
||||
; Calling when card removed.
|
||||
ends
|
||||
|
||||
|
||||
export_sdio_api:
|
||||
dd REG_SDIO_SERVICE
|
||||
dd UNREG_SDIO_SERVICE
|
||||
dd SCAN_SDIO_DEV
|
||||
dd IO_RW_DIRECT ;cmd52
|
||||
dd IO_RW_EXTENDED ; cmd53
|
||||
|
||||
|
||||
proc REG_SDIO_SERVICE stdcall sdio_func: dword
|
||||
; alloc new item list
|
||||
mov eax, sizeof.SDIO_SERVICE
|
||||
invoke Kmalloc
|
||||
test eax, eax
|
||||
jz .exit
|
||||
|
||||
mov ecx, [sdio_func]
|
||||
mov [eax + SDIO_SERVICE.sdio_func], ecx
|
||||
cli
|
||||
|
||||
mov ecx, [sdio_drv_list]
|
||||
mov [eax], ecx
|
||||
mov [eax + SDIO_SERVICE.prev], sdio_drv_list
|
||||
mov [ecx + SDIO_SERVICE.prev], eax
|
||||
mov [sdio_drv_list], eax
|
||||
sti
|
||||
.exit:
|
||||
ret
|
||||
endp
|
||||
|
||||
proc UNREG_SDIO_SERVICE stdcall sdio_hand: dword
|
||||
|
||||
; del in list
|
||||
mov eax, [sdio_hand]
|
||||
mov edx, [eax]
|
||||
mov ecx, [eax + SDIO_SERVICE.prev]
|
||||
mov [edx + SDIO_SERVICE.prev], ecx
|
||||
mov [ecx], edx
|
||||
|
||||
; find all slots, using this service
|
||||
|
||||
; free struct
|
||||
mov eax, [sdio_hand]
|
||||
invoke Kfree
|
||||
ret
|
||||
endp
|
||||
|
||||
proc SCAN_SDIO_DEV stdcall sdio_hand: dword
|
||||
|
||||
|
||||
ret
|
||||
endp
|
||||
Reference in New Issue
Block a user