From 519942fec457823124d3d66df09028604cbd471a Mon Sep 17 00:00:00 2001 From: Doczom <78043169+Doczom@users.noreply.github.com> Date: Mon, 5 Jun 2023 11:11:13 +0500 Subject: [PATCH] Big update Added support SDIO card Fixed bugs Added support 4-bit mode for sd card Added support all slots on controllers and other --- README.md | 102 +++-- SDHC_doc.txt | 123 +++++- sdhc_cmd.inc | 263 ++++++++---- sdhc_disk.inc | 106 +++-- sdhci.asm | 1127 ++++++++++++++++++++++++++++++------------------- sdhci.sys | Bin 7008 -> 7264 bytes sdio-test.asm | 118 ++++++ sdio-test.sys | Bin 0 -> 1600 bytes sdio.inc | 83 ++++ 9 files changed, 1307 insertions(+), 615 deletions(-) create mode 100644 sdio-test.asm create mode 100644 sdio-test.sys create mode 100644 sdio.inc diff --git a/README.md b/README.md index 4225524..d27a7d2 100644 --- a/README.md +++ b/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 байт)~~ diff --git a/SDHC_doc.txt b/SDHC_doc.txt index 8f8d931..c549587 100644 --- a/SDHC_doc.txt +++ b/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 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 \ No newline at end of file diff --git a/sdhc_cmd.inc b/sdhc_cmd.inc index 8ccb811..53f7616 100644 --- a/sdhc_cmd.inc +++ b/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 diff --git a/sdhc_disk.inc b/sdhc_disk.inc index 8af6302..bff4acc 100644 --- a/sdhc_disk.inc +++ b/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 \ No newline at end of file +; ; /sdhciXXXS/1 +;sdhci_disk_name: db 'sdhci0000',0,0 ; xxx - number of controller +; ; s - number slot in select controller \ No newline at end of file diff --git a/sdhci.asm b/sdhci.asm index c56d621..e518088 100644 --- a/sdhci.asm +++ b/sdhci.asm @@ -1,30 +1,43 @@ ;; Copyright (C) 2022-2023, Michael Frolov aka Doczom ;; SD host controller driver. ;; -;; !!!!!!!! +;; !!!!WARNING!!!! ;; 2.0 ;; . ;; 2.0. ;; . +;; TODO list: +;; - fix output error read/write sectors +;; - add switch in High speed +;; - add API for SDIO +;; - EXPORT cmd52 ? +;; - EXPORT cmd53 ? +;; - EXPORT and creat sdio_atached_irq +;; - EXPORT function for set card and host param +;; - EXPORT function for add listen on detect insert sdio card +;; ( ) +;; - +;; - add exit in erase exec function (jnz .err) +;; - add API for usermode programm +;; - add ADMA2 +;; - add SDUC support + format PE native entry START use32 DEBUG = 1 __DEBUG__ = 1 - __DEBUG_LEVEL__ = 1 ; 1 = verbose, 2 = errors only + __DEBUG_LEVEL__ = 1 ; 1 = verbose, 2 = errors only - API_VERSION = 0 ;debug - STRIDE = 4 ;size of row in devices table - - SRV_GETVERSION = 0 + DRIVER_VERSION = 1 ;debug ; base SD registers SDHC_SYS_ADDR = 0x00 SDHX_BLK_CS = 0x04 -; SD , + SDHC_CMD_ARG = 0x08 SDHC_CMD_TRN = 0x0c @@ -36,10 +49,10 @@ SDHC_RESP7_6 = 0x1C SDHC_BUFFER = 0x20 -SDHC_PRSNT_STATE = 0x24 ;word (12-15 , 26 Rsvd) +SDHC_PRSNT_STATE = 0x24 ;word (12-15 , 26 Rsvd) PRSNT_STATE: - .CMD_INHIB_CMD = 0x01 ; for test [eax + SDHC_PRSNT_STATE], SDHC_PRSNT_STATE.CMD_INHIB_CMD - .CMD_INHIB_DAT = 0x02 + .CMD_INHIB_CMD = 0x01 ; for test [eax + SDHC_PRSNT_STATE], SDHC_PRSNT_STATE.CMD_INHIB_CMD + .CMD_INHIB_DAT = 0x02 .DAT_LINE_ACTIVE = 0x04 .WR_TX_ACTIVE = 0x100 .RD_TX_ACTIVE = 0x200 @@ -57,13 +70,13 @@ SDHC_CTRL1 = 0x28 block_gap_control = 0x2a ;byte (using 0-3 bits) Wekeup_control = 0x2b ;byte (using 0-2 bits) -SDHC_CTRL2 = 0x2C - clock_control = 0x2c ;word +SDHC_CTRL2 = 0x2C + clock_control = 0x2c ;word timeout_control = 0x2e ;byte (using 0-3 bits) - software_reset = 0x2f ;byte (using 0-2 bits) - .software_reset_for_all = 0x01 ;1-reset 0-work - .saftware_reset_for_cmd_line = 0x02 ;1-reset 0-work - .software_reset_for_dat_line = 0x04 ;1-reset 0-work + software_reset = 0x2f ;byte (using 0-2 bits) + .software_reset_for_all = 0x01 ;1-reset 0-work + .saftware_reset_for_cmd_line = 0x02 ;1-reset 0-work + .software_reset_for_dat_line = 0x04 ;1-reset 0-work ;0x30-0x3d - Interrupt Controls SDHC_INT_STATUS = 0x30 @@ -76,19 +89,19 @@ INT_STATUS: .DMA_EVT = 0x08 .BUF_WR_RDY = 0x10 .BUF_RD_RDY = 0x20 - ; , 0x24 . + ; , 0x24 ; ( or ). .CARD_INS = 0x40 .CARD_REM = 0x80 .SDIO = 0x0100 - .INT_A = 0x0200 ; in 2 version not used - .INT_B = 0x0400 ; in 2 version not used - .INT_C = 0x0800 ; in 2 version not used + .INT_A = 0x0200 ; in 2 version spec not used + .INT_B = 0x0400 ; in 2 version spec not used + .INT_C = 0x0800 ; in 2 version spec not used ;.re_tuning_event = 0x1000 ;.FX_event = 0x2000 ; 14 bit reserved - .ERROR = 0x8000 ; - ; error interupt + .ERROR = 0x8000 ; in all version specifications + ; error interrupt .ALL_ERROR = 0xFFFF0000 ; set all type error .CMD_TO_ERR = 0x01 ; (SD mode only) .CMD_CRC_ERR = 0x02 ; 1=crc error generation 0=no error (sd mode only) @@ -99,7 +112,7 @@ INT_STATUS: .DAT_END_ERR = 0x40 ; (SD mode only) ;.current_limit_error = 0x80 ; 1=Power_fail 0=no_error .ACMD12_ERR = 0x0100 ; (SD mode only) - .ADMA_ERR = 0x0200 ; 2 + .ADMA_ERR = 0x0200 ; added in 2 version spec ;.tuning_error = 0x0400 ; 1=error 0=no error (UHS-I only) ;.response_error = 0x0800 ; (SD mode only) in 4.00 version ;.vendor_specific_error_status = 0xf000 @@ -118,6 +131,16 @@ ACMD12_ERR: SDHC_HOST_CONTROL_2_REG = 0x3e ; word SDHC_CAPABILITY = 0x40 ;qword + TO_CLK_UNIT = (1 shl 7) + MMC8_SUPPORT = (1 shl 18) + ADMA2_SUPPORT = (1 shl 19) + ADMA_SUPPORT = (1 shl 20) + HISPEED_SUPPORT = (1 shl 21) + DMA_SUPPORT = (1 shl 22) + SUS_RES_SUPPORT = (1 shl 23) + SUPPORT_3_3V = (1 shl 24) + SUPPORT_3_0V = (1 shl 25) + SUPPORT_1_8V = (1 shl 26) SDHC_CURR_CAPABILITY = 0x48 ; qword (using 0-23 32-39) SDHC_FORCE_EVT = 0x50 @@ -128,12 +151,12 @@ SDHC_ADMA_ERR = 0x54 ; byte (using 0-2 bits) SDHC_ADMA_SAD = 0x58 SDHC_VER_SLOT = 0xfc ; block data - SLOT_INTRPT = 0xfc ;Slot interapt status register 1 byte; 0xfd - reserved - SPEC_VERSION = 0xfe ; in map register controller(15-8 - vendor version; 7-0 - spec version) + SLOT_INTRPT = 0xfc ;Slot interrupt status register 1 byte; 0xfd - reserved + SPEC_VERSION = 0xfe ; in map register controller(15-8 - vendor version; 7-0 - spec version) VENDOR_VERSION = 0xff ; PCI reg -pci_class_sdhc = 0x0805 ;basic_class=0x08 sub_class=05 +PCI_CLASS_SDHCI = 0x0805 ;basic_class=0x08 sub_class=05 PCI_BAR0 = 0x10 PCI_BAR1 = 0x14 PCI_BAR2 = 0x18 @@ -142,7 +165,10 @@ PCI_BAR4 = 0x20 PCI_BAR5 = 0x14 PCI_IRQ_LINE = 0x3C -PCI_slot_information = 0x40 ;0-2 first BAR 4-6 - number of Slots(counter BAR?) +PCI_slot_information = 0x40 ;0-2 first BAR 4-6 - number of Slots(counter BAR) +PCI_SDHCI_NO_DMA = 0 +PCI_SDHCI_DMA = 1 +PCI_SDHCI_VEND_IF = 2 section '.flat' code readable writable executable @@ -157,48 +183,74 @@ include 'drivers/fdo.inc' include 'sdhc_cmd.inc' include 'sdhc_disk.inc' include 'sdhci_adma.inc' +include 'sdio.inc' ; structures -struct SDHCI_CONTROLLER - fd rd 1 ; next controller - bk rd 1 ; pref controller +struct RW_FUNC + singe_read rd 1 + multiple_read rd 1 + singe_write rd 1 + multiple_write rd 1 +ends - dev rd 1 ; - bus rd 1 ; +struct SDHCI_DEVICE + next rd 1 + prev rd 1 + dev rd 1 ; + bus rd 1 ; + state rd 1 ; bit flags + irq_line rd 1 ; rb + dma_support rd 1 ; rb + slot_0 rd 1 ; ptr SDHCI_SLOT + slot_1 rd 1 + slot_2 rd 1 + slot_3 rd 1 + slot_4 rd 1 + slot_5 rd 1 +ends +struct SDHCI_SLOT base_reg_map rd 1 ;pointer to registers controller - base_sdhc_reg rd 1 ; offset for BAR - count_bar_reg rd 1 ; count BAR for this register - + ;base_sdhc_reg rd 1 ; offset for BAR + ;count_bar_reg rd 1 ; count BAR for this register + state rd 1 ; bit flags ver_spec rb 1 ; using 0 - 4 bits - flag_pci_dma rb 1 ; 0 - no DMA, 1 - yes DMA + dma_support rb 1 ; 0 - no DMA, 1 - yes DMA 2 - Vendor unique SD hoet controller - irq_line rd 1 ;rb + ;irq_line rd 1 Capabilities rd 2 ; qword - save Capabilities max_slot_amper rd 2 divider400KHz rd 1 ; for SDCLK frequency Select divider25MHz rd 1 divider50MHz rd 1 - timeout_reg rd 1 ; offset 0x2e in reg map - type_card rd 1 ; 0 - no card 1 - SDIO 2 - MMC(eMMC) 4 - standart flash card 5+ - other - card_mode rd 1 ; 1 - spi 2 - sd bus 3+ - other - dma_mode rd 1 ; 0-no dma 1-sdma 2-adma1 3 adma2 + type_card rd 1 ; 0 - no card 1 - SD 2 - SDIO 4 - MMC(eMMC) 5+ - other + ;dma_mode rd 1 ; 0-sdma 1-adma1 2-adma2-32 3-adma2-64 - card_reg_ocr rd 1 ; 32 bit card voltage + ; card data + card_reg_ocr rd 1 ; 32 bit + SDIO_reg_ocr rd 1 ; 32 bit card_reg_cid rd 4 ; 128 bit 120 bit - card_reg_csd rd 4 ; 128 bit ( 2 ) + card_reg_csd rd 4 ; 128 bit card_reg_rca rw 1 ; rw 1 ; 16 bit - card_reg_dsr rw 1 ; rw 1 ;16 bit (optional) + card_reg_dsr rw 1 ; rw 1 ;16 bit (optional) ; not using!!! card_reg_scr rd 2 ; 64 bits card_reg_ssr rd 16 ; 512bit + pwd_leb rb 1 + pwd rb 512 sector_count rq 1 ; count rw sectors on SD\SDIO\MMC card + disk_hand rd 1 ; DISK* + disk_name rd 4 ; 16 byte for save path disk, example, 'sdhci0001',0 + memory_rw RW_FUNC - program_id rd 1 ; tid thread for working with no memory cards + ; for working SDIO card + sdio_service rd 1 ; ptr to SDIO_SERVICE + sdio_pdata rd 1 ; DWORD for SDIO functions + ;program_id rd 1 ; tid thread for working with no memory cards - flag_command_copmlate rd 1 ; flag interrapt command complate 00 - interrapt is geting - flag_transfer_copmlate rd 1 ; flag interrapt transfer complate 00 -interrapt is geting + ; to execute the command + virt_addr_buff rd 1 ; addr buffer for data int_status rd 1 ; copy SDHC_INT_STATUS rd 4 ; reserved status_control rd 1 ; flags status controller(0x01 - get irq AND int_status good) @@ -206,18 +258,18 @@ struct SDHCI_CONTROLLER ends -struct SDHCI_SLOT - reg_map rd 1; pointer to register map - Capabilities rd 2 ; qword - save Capabilities - divider400KHz rd 1 ; for SDCLK frequency Select - divider25MHz rd 1 - divider50MHz rd 1 - max_slot_amper rd 2 -ends; +;struct SDHCI_SLOT +; reg_map rd 1; pointer to register map +; Capabilities rd 2 ; qword - save Capabilities +; divider400KHz rd 1 ; for SDCLK frequency Select +; divider25MHz rd 1 +; divider50MHz rd 1 +; max_slot_amper rd 2 +;ends; count_controller: dd 0 list_controllers: -.fd: dd list_controllers ; pointer to first item list -.bk: dd list_controllers ; pointer to last item list +.next: dd list_controllers ; pointer to first item list +.prev: dd list_controllers ; pointer to last item list root_PCIList: dd 0 @@ -238,40 +290,12 @@ proc START c, state:dword, cmdline:dword push eax jz .end_find - cmp word[eax + PCIDEV.class + 1], 0x0805 + cmp word[eax + PCIDEV.class + 1], PCI_CLASS_SDHCI jnz .next_dev - mov esi, eax - invoke KernelAlloc, sizeof.SDHCI_CONTROLLER - test eax, eax - jz .not_memory - - mov ecx, [list_controllers.bk] - mov [eax + SDHCI_CONTROLLER.bk], ecx - mov [ecx + SDHCI_CONTROLLER.fd], eax - mov [eax + SDHCI_CONTROLLER.fd], list_controllers - - ;push eax - push eax - call sdhci_init ; in: eax - structure esi - pointer to PCIDEV ;return 0 - good ; other - error code - pop esi - DEBUGF 1,"SDHCI_INIT: error code =%d bus: %d devfn: %d \n", eax, [esi + SDHCI_CONTROLLER.bus], [esi + SDHCI_CONTROLLER.dev] - inc dword[count_controller] - test eax, eax - mov eax, esi;pop eax ; structure SDHCI_CONTROLLER - jz .next_dev - - DEBUGF 1,"ERROR: Contriller not init\n" - mov ecx, [eax + SDHCI_CONTROLLER.fd] - mov edx, [eax + SDHCI_CONTROLLER.bk] - mov [ecx + SDHCI_CONTROLLER.bk], edx - mov [edx + SDHCI_CONTROLLER.fd], ecx - dec dword[count_controller] - - invoke KernelFree, eax ; free structure when error code not zero - jmp .next_dev -.not_memory: - DEBUGF 1,"ERROR: can't alloc memory for structure SDHC_CONTROLLER\n" + pusha + call sdhci_init + popa jmp .next_dev .end_find: pop eax @@ -280,7 +304,7 @@ proc START c, state:dword, cmdline:dword jz .not_found DEBUGF 1,"SDHCI: Found %d controllers\n", [count_controller] - invoke RegService, drv_name, 0 ;service_proc + invoke RegService, drv_name, service_proc pop ebp edi esi ebx ret .not_found: @@ -288,12 +312,12 @@ proc START c, state:dword, cmdline:dword mov eax, 0 pop ebp edi esi ebx ret + .stop_drv: ; deattach irq ; stop power devise ; free struct ; free reg_map - ; free memory for DMA DEBUGF 1, "SDHCI: Stop working driver\n" xor eax, eax @@ -301,23 +325,41 @@ proc START c, state:dword, cmdline:dword ret endp -;init controller, set base value, add interrupt function, set stucture for controller -; in: eax - pointer to structure controller; esi - pointer to PCIDEV structure -; out: eax - error code 0 - good; other - error init +; args: eax - ptr PCIDEV +; no return +; NO SAVE REGISTERS proc sdhci_init - ;set base data in SDHCI_CONTROLLER structure - movzx ebx, [esi + PCIDEV.devfn] - mov [eax + SDHCI_CONTROLLER.dev], ebx - movzx ebx, [esi + PCIDEV.bus] - mov [eax + SDHCI_CONTROLLER.bus], ebx - ;controller found and init - mov bl, byte [esi + PCIDEV.class] ; get interface code - mov [eax + SDHCI_CONTROLLER.flag_pci_dma], bl ; 0-not use dma 1-use dma 2 -Vendor unique SD hoet controller - DEBUGF 1,"DMA using: %x \n",[eax + SDHCI_CONTROLLER.flag_pci_dma] - mov esi, eax + ; alloc memory for structure SDHCI_DEVICE + invoke KernelAlloc, sizeof.SDHCI_DEVICE + test eax, eax + jz .err_mem - invoke PciRead32, [esi + SDHCI_CONTROLLER.bus], [esi + SDHCI_CONTROLLER.dev], dword 4 + movzx edx, [esi + PCIDEV.devfn] + mov [eax + SDHCI_DEVICE.dev], edx + movzx edx, [esi + PCIDEV.bus] + mov [eax + SDHCI_DEVICE.bus], edx + mov esi, eax ;save ptr SDHCI_DEVICE + ; clear SDHCI_DEVICE.slotX items + xor edx, edx + mov ecx, 5 + 1 +@@: + mov [eax + SDHCI_DEVICE.slot_0 + ecx*4 - 4], edx + loop @b + + ; add list + ; TODO: add and use macro list_add_tail + mov edx, [list_controllers.prev] + mov [list_controllers.prev], esi + mov [eax + SDHCI_DEVICE.next], list_controllers + mov [eax + SDHCI_DEVICE.prev], edx + mov [edx], eax + + inc dword[count_controller] + + ; Set Master and Memory bits, dunkaist + pusha + invoke PciRead32, [esi + SDHCI_DEVICE.bus], [esi + SDHCI_DEVICE.dev], dword 4 test eax, 0x4 ; Test Master bit jnz @f or eax, 0x4 ; Set Master bit @@ -326,87 +368,177 @@ proc sdhci_init cmp ebx, 0x6 ; Test Master and Memory bits jz @f or eax, 0x6 ; Set Master and Memory bits - invoke PciWrite32, [esi + SDHCI_CONTROLLER.bus], [esi + SDHCI_CONTROLLER.dev], dword 4, eax - invoke PciRead32, [esi + SDHCI_CONTROLLER.bus], [esi + SDHCI_CONTROLLER.dev], dword 4 + invoke PciWrite32, [esi + SDHCI_DEVICE.bus], [esi + SDHCI_DEVICE.dev], dword 4, eax + ;invoke PciRead32, [esi + SDHCI_DEVICE.bus], [esi + SDHCI_DEVICE.dev], dword 4 @@: - DEBUGF 1,"Status: %x \n", eax + popa + ; get DMA support in pci reg + invoke PciRead8, [esi + SDHCI_DEVICE.bus], [esi + SDHCI_DEVICE.dev], dword 9 + mov byte[esi + SDHCI_DEVICE.dma_support], al + cmp al, PCI_SDHCI_VEND_IF + ja .err_interface - ;get slot information and get base register sd host controller - invoke PciRead8, [esi + SDHCI_CONTROLLER.bus], dword[esi + SDHCI_CONTROLLER.dev], PCI_slot_information + ;create name for controller (/sdhciXXX0) + sub esp, 4*4 ; for name + + mov dword[esp], 'sdhc' + mov dword[esp + 4], 'i000' ; controller number + mov dword[esp + 8], '0' ; slot number + mov eax, dword[count_controller] + mov ecx, 3 + mov edi, 10 ; for div instruction +@@: + xor edx, edx + div edi + add byte[esp + 4 + ecx], dl + dec ecx + test eax, eax + jnz @b + + + ;get count slot + + invoke PciRead8, [esi + SDHCI_DEVICE.bus], dword[esi + SDHCI_DEVICE.dev], PCI_slot_information movzx edx, al and edx, 111b - mov [esi + SDHCI_CONTROLLER.base_sdhc_reg], edx ;save offset base register sdhc - ;mov ebx, edx ;save offset for get base addr reg sdhc shr eax, 4 and eax, 111b - mov [esi + SDHCI_CONTROLLER.count_bar_reg], eax ;save count working basical addres register - DEBUGF 1,"SDHCI: base BAR: %x count BAR: %x\n",[esi + SDHCI_CONTROLLER.base_sdhc_reg], [esi + SDHCI_CONTROLLER.count_bar_reg] + ;cmp edx, 5 ; check bar, if bar > 5 + ;ja .err_first_bar + mov ecx, edx + add ecx, eax + cmp ecx, 5 + ja .err_count_slots + push edx ; save first BAR ;save offset base register sdhc + push eax ;save count ;save count working basical addres register - ;get base addr reg sdhc and open mmio on 256 byte(standart size for sdhc) - add edx, PCI_BAR0 ; get base pci_bar controller - invoke PciRead32, dword [esi + SDHCI_CONTROLLER.bus], dword [esi + SDHCI_CONTROLLER.dev], edx - and al, not 0Fh ;? not 0xff - invoke MapIoMem, eax, 0x100, PG_SW+PG_NOCACHE ;? + DEBUGF 1,"SDHCI: base BAR: %x count BAR: %x\n", eax, edx + + xor ecx, ecx +.add_new_slot: + push ecx + ; get BAR addr to slots(all slots) + add ecx, [esp + 4 + 4] + add ecx, PCI_BAR0 + invoke PciRead32, dword [esi + SDHCI_DEVICE.bus], dword [esi + SDHCI_DEVICE.dev], ecx + and al, not 0Fh ; not 0xff + ; check BAR + test eax, eax + jz .no_mmio + + ; mapped mmio space + invoke MapIoMem, eax, 0x100, PG_SW+PG_NOCACHE ; test eax, eax - jz .fail + jz .no_mmio DEBUGF 1,"SDHCI: base address = %x \n", eax - mov [esi + SDHCI_CONTROLLER.base_reg_map], eax - mov cl, [eax + SPEC_VERSION] ; get specification version - mov [esi + SDHCI_CONTROLLER.ver_spec], cl - DEBUGF 1,"Version specification: %x \n",[esi + SDHCI_CONTROLLER.ver_spec] + push eax + ; alloc memory for structure SDHCI_SLOT + invoke KernelAlloc, sizeof.SDHCI_SLOT + test eax, eax + pop ecx ; ecx - reg map + jz .not_memory + mov [eax + SDHCI_SLOT.base_reg_map], ecx + mov edx, [esp] + mov [esi + SDHCI_DEVICE.slot_0 + edx*4], eax - DEBUGF 1,"SLOT_INTRPT: %x \n", [eax + SLOT_INTRPT] + ; create name for slot (/sdhci000X) + mov edx, [esp + 4 + 4*2] + mov [eax + SDHCI_SLOT.disk_name], edx + mov edx, [esp + 4 + 4*2 + 4] + mov [eax + SDHCI_SLOT.disk_name + 4], edx + mov edx, [esp + 4 + 4*2 + 8] + mov [eax + SDHCI_SLOT.disk_name + 8], edx + mov edx, [esp + 4 + 4*2 + 12] + mov [eax + SDHCI_SLOT.disk_name + 12], edx + mov edx, [esp] + add byte[eax + SDHCI_SLOT.disk_name + 8], dl ; set slot in name + ; copy dma_support in SDHCI_SLOT - ;reset controller (all) - mov eax, [esi + SDHCI_CONTROLLER.base_reg_map] - inc byte[eax + software_reset] + mov edx, [esi + SDHCI_DEVICE.dma_support] + mov [esi + SDHCI_SLOT.dma_support], dl + + ; ALL RESET slots(all slots) + mov edx, [eax + SDHCI_SLOT.base_reg_map] + inc byte[edx + software_reset] @@: - test byte[eax + software_reset], 0xFF + test byte[edx + software_reset], 0xFF jnz @b - ;TODO: add settings controller + DEBUGF 1,"SDHCI: slot resetting \n" - ; Capabiliti max Current Capabilities + pop ecx + inc ecx + cmp ecx, dword[esp] + ja .end_reset +.not_memory: ; TODO , +.no_mmio: + pop ecx + mov [esi + SDHCI_DEVICE.slot_0 + ecx*4], 0 + inc ecx + cmp ecx, dword[esp] + jbe .add_new_slot + +.end_reset: + ;Attach IRQ + invoke PciRead8, dword [esi + SDHCI_DEVICE.bus], dword [esi + SDHCI_DEVICE.dev], PCI_IRQ_LINE ;al=irq + movzx eax, al + mov [esi + SDHCI_DEVICE.irq_line], eax ;save irq line + invoke AttachIntHandler, eax, sdhc_irq, esi ;esi = pointre to controller struct + + xor ecx, ecx +.loop: + DEBUGF 1,"SDHCI: ecx=%x slotX=%x\n", ecx, [esi + SDHCI_DEVICE.slot_0 + ecx*4] + cmp dword[esi + SDHCI_DEVICE.slot_0 + ecx*4], 0 + jz .skip_slot + pusha + mov esi, [esi + SDHCI_DEVICE.slot_0 + ecx*4] + mov eax, [esi + SDHCI_SLOT.base_reg_map] + ; call sdhci_slot_init + call sdhci_slot_init + test eax, eax + jz @f + ; IF NOT sdhci_slot_init() THEN free memory for SDHCI_SLOT + ; TODO: free mapio and free slotX in SDHCI_DEVICE +@@: ;DEBUGF 1,"SDHCI_SLOT_INIT: error code =%d \n", eax + popa +.skip_slot: + inc ecx + cmp ecx, [esp] + jbe .loop + + add esp, 4*4 + 4*2 + ret + +.err_first_bar: +.err_count_slots: + add esp, 4*4 +.err_interface: +.err_mem: + ret +endp + +;init controller, set base value, add interrupt function, set stucture for controller +; in: esi - ptr to SDHCI_SLOT +; eax - ptr base reg map +; out: eax - error code 0 - good; other - init error code +proc sdhci_slot_init + ; save registers Capabiliti and Max Current Capabilities mov ebx, [eax + SDHC_CAPABILITY] - mov [esi + SDHCI_CONTROLLER.Capabilities], ebx + mov [esi + SDHCI_SLOT.Capabilities], ebx mov ebx, [eax + SDHC_CAPABILITY + 4] - mov [esi + SDHCI_CONTROLLER.Capabilities + 4], ebx - DEBUGF 1,"SDHCI:Capabilities %x %x\n",[esi + SDHCI_CONTROLLER.Capabilities + 4],[esi + SDHCI_CONTROLLER.Capabilities] + mov [esi + SDHCI_SLOT.Capabilities + 4], ebx + DEBUGF 1,"SDHCI:Capabilities %x %x\n",[esi + SDHCI_SLOT.Capabilities + 4],[esi + SDHCI_SLOT.Capabilities] mov ebx, [eax + SDHC_CURR_CAPABILITY] - mov [esi + SDHCI_CONTROLLER.max_slot_amper], ebx + mov [esi + SDHCI_SLOT.max_slot_amper], ebx mov ebx, [eax + SDHC_CURR_CAPABILITY + 4] - mov [esi + SDHCI_CONTROLLER.max_slot_amper + 4], ebx - DEBUGF 1,"SDHCI:Max current capabilities %x %x\n",[esi + SDHCI_CONTROLLER.max_slot_amper + 4],[esi + SDHCI_CONTROLLER.max_slot_amper] + mov [esi + SDHCI_SLOT.max_slot_amper + 4], ebx + DEBUGF 1,"SDHCI:Amper capabilities %x %x\n",[esi + SDHCI_SLOT.max_slot_amper + 4],[esi + SDHCI_SLOT.max_slot_amper] - ; DMA : 0 - no dma 1 - sdma 2 - adma1 3 - adma2-32bit 4 - adma2-64bit( , 32 ) - mov ebx, [eax + SDHC_CAPABILITY] - mov ecx, 3 - bt ebx, 19 ; support adma2 - jc @f - dec ecx - bt ebx, 20 ; support adma1 - jc @f - dec ecx - bt ebx, 22 ; support sdma - jc @f - dec ecx -@@: - mov [esi + SDHCI_CONTROLLER.dma_mode], ecx - DEBUGF 1,"SDHCI: DMA mode: %x \n", [esi + SDHCI_CONTROLLER.dma_mode] - test ecx, ecx - jz @f - dec ecx -@@: - shl ecx, 3 - ;and ecx, not 0x111 ; shl ecx,3 - or dword[eax + SDHC_CTRL1], ecx - ; 0x28 - - ; + ; get the values of frequency dividers push eax - mov eax, [esi + SDHCI_CONTROLLER.Capabilities] + mov eax, [esi + SDHCI_SLOT.Capabilities] shr eax, 8 and eax, 11111111b ; 1111 1111 mov ebx, 25 @@ -421,10 +553,10 @@ proc sdhci_init @@: xor edi, edi bts edi, ecx - mov dword[esi + SDHCI_CONTROLLER.divider25MHz], edi + mov dword[esi + SDHCI_SLOT.divider25MHz], edi DEBUGF 1,'25MHz : %u\n', edi shr edi, 1 ; +- - mov dword[esi + SDHCI_CONTROLLER.divider50MHz], edi + mov dword[esi + SDHCI_SLOT.divider50MHz], edi DEBUGF 1,'50MHz : %u\n', edi imul eax, 63 ; @@ -437,40 +569,45 @@ proc sdhci_init @@: xor edi, edi bts edi, ecx - mov dword[esi + SDHCI_CONTROLLER.divider400KHz], edi + mov dword[esi + SDHCI_SLOT.divider400KHz], edi DEBUGF 1,'400KHz : %u\n', edi pop eax - ; Host Control Register - ; + ; Set values in Host Control Register - ; 00-04f - ; host control 2 + ;Set values in host control 2 ;set 0x2e - mov dword[eax + SDHC_INT_STATUS], 0x00 - ; set Wekeup_control or byte[eax + Wekeup_control], 111b - ; save and attach IRQ - and dword[eax + SDHC_INT_MASK], 0 - and dword[eax + SDHC_SOG_MASK], 0 + ; set interrupt mask for detect insert/remove crad, + ; using CMD and DAT command, but not using card interrupt + mov eax, [esi + SDHCI_SLOT.base_reg_map] + or dword[eax + SDHC_INT_MASK], INT_STATUS.ALL_ERROR \ + + INT_STATUS.CARD_INS \ + + INT_STATUS.CARD_REM \ + + INT_STATUS.CMD_DONE \ + + INT_STATUS.DAT_DONE \ + + INT_STATUS.DMA_EVT \ + + INT_STATUS.BUF_WR_RDY \ + + INT_STATUS.BUF_RD_RDY - invoke PciRead8, dword [esi + SDHCI_CONTROLLER.bus], dword [esi + SDHCI_CONTROLLER.dev], PCI_IRQ_LINE ;al=irq - movzx eax, al - mov [esi + SDHCI_CONTROLLER.irq_line], eax ;save irq line - invoke AttachIntHandler, eax, sdhc_irq, esi ;esi = pointre to controller struct - - mov eax, [esi + SDHCI_CONTROLLER.base_reg_map] - or dword[eax + SDHC_INT_MASK], INT_STATUS.CARD_INS + INT_STATUS.CARD_REM - or dword[eax + SDHC_SOG_MASK], INT_STATUS.CARD_INS + INT_STATUS.CARD_REM + or dword[eax + SDHC_SOG_MASK], INT_STATUS.ALL_ERROR \ + + INT_STATUS.CARD_INS \ + + INT_STATUS.CARD_REM \ + + INT_STATUS.CMD_DONE \ + + INT_STATUS.DAT_DONE \ + + INT_STATUS.DMA_EVT \ + + INT_STATUS.BUF_WR_RDY \ + + INT_STATUS.BUF_RD_RDY DEBUGF 1,'SDHCI: Enable insert and remove interrupt\n' - ; + ; detected card in slot ;mov eax, [esi + SDHCI_CONTROLLER.base_reg_map] test dword[eax + SDHC_PRSNT_STATE], 0x10000 ; check 16 bit in SDHC_PRSNT_STATE.CARD_INS jz @f + call card_init ; eax - REGISTER MAP esi - SDHCI_CONTROLLER @@: @@ -485,10 +622,7 @@ endp ; eax - map reg ; ebx - divider Clock base proc set_SD_clock - and dword[eax + SDHC_CTRL2], not 100b ; stop clock - - - and dword[eax + SDHC_CTRL2], 0xffff0000 ; clear + and dword[eax + SDHC_CTRL2], 0xffff0000 ; clear and stop clock cmp ebx, 0x80 jbe @f @@ -515,13 +649,12 @@ endp proc card_init DEBUGF 1,'SDHCI: Card inserted\n' - and dword[esi + SDHCI_CONTROLLER.card_reg_rca], 0 ; - ; 001 - or dword[eax + SDHC_INT_MASK], 0xFFFF0001 - or dword[eax + SDHC_SOG_MASK], 0xFFFF0001 + and dword[esi + SDHCI_SLOT.card_reg_rca], 0 + and dword[esi + SDHCI_SLOT.disk_hand], 0 + and dword[esi + SDHCI_SLOT.sdio_service], 0 ; (3.3 - ) ; - mov ebx, [esi + SDHCI_CONTROLLER.Capabilities] + mov ebx, [esi + SDHCI_SLOT.Capabilities] shr ebx, 24 and ebx, 111b ;26bit - 1.8 25bit - 3.0 24bit - 3.3 bsf ecx, ebx ;ecx= 0 for 3.3, 1 for 3.0 , 2 for 1.8 @@ -529,145 +662,210 @@ proc card_init mov edx, 111b sub edx, ecx ; see format data this register in specs shl edx, 1 - or edx, 0x01 ; + or edx, 0x01 ; for start power card shl edx, 8 ; offset 0x29 or dword[eax + SDHC_CTRL1], edx DEBUGF 1,'SDHCI: SDHC_CTRL1= %x \n',[eax + SDHC_CTRL1] DEBUGF 1,'SDHCI: , \n' - ; - ; 400 - mov ebx, [esi + SDHCI_CONTROLLER.divider400KHz] + ; running clock gen on 400kHz + mov ebx, [esi + SDHCI_SLOT.divider400KHz] call set_SD_clock - ; SDHC_CTRL1 + ; clear SDHC_CTRL1 and dword[eax + SDHC_CTRL1], 11000b + 0x0f00 ; dma power control + and dword[eax + SDHC_CTRL1], not 10b - ;; !!! !!! + ;; !!! Begin process init card !!! - ; cmd0 - reset card - GO_IDLE_SATTE ; ok - ; (sd bus, spi) - ; , + GO_IDLE_SATTE - ; cmd5 voltage window = 0 - check sdio + call SEND_IF_COUND ;DEBUGF 1,"SDHCI: CMD5 - check SDIO\n" xor ebx, ebx ; arg cmd, zero to get voltage mask and to check SDIO functions call IO_SEND_OP_COND; 0 - test voltage mask to check SDIO interface, ZF=1-sdio jz .sdio - ;DEBUGF 1,"SDHCI: CMD8 - check SDHC card\n" - call SEND_IF_COUND - ;DEBUGF 1,"SDHCI: ACMD41 - get OCR\n" - mov [esi + SDHCI_CONTROLLER.card_reg_ocr], 1 shl 30 ; set HSP + mov [esi + SDHCI_SLOT.card_reg_ocr], 0 ;OCR_REG.CCS .set_acmd41: - ; TODO: 10, embox + ; TODO: Add timeout on 10 ms, see code embox call get_ocr_mask - ; acmd41 - - ; OCR, + ; first call retuning OCR, other call set voltage call SD_SEND_OP_COND jnz .mmc - test dword[eax + SDHC_RESP1_0], 0x80000000 ; check 31 bit + test dword[eax + SDHC_RESP1_0], OCR_REG.Busy jz .set_acmd41 - ; for no sdio card : cmd2 - get_CID - ALL_SEND_CID ; , - ; irq - ; for all init card : cmd3 - get RCA + + ALL_SEND_CID + call SEND_RCA call SEND_CSD call SELECT_CARD - test [esi + SDHCI_CONTROLLER.card_reg_ocr], 0x40000000 + ; set block length for SDSC + test [esi + SDHCI_SLOT.card_reg_ocr], OCR_REG.CCS jnz @f - - mov ebx, 0x200 ; 512 byte + mov ebx, SD_BLOCK_SIZE call SET_BLOCKLEN @@: - - ; get size device TODO: OCR - test dword[esi + SDHCI_CONTROLLER.card_reg_csd + 12], 0x400000 ;check version SCD ver2 - jz @f - - call GET_SDHC_SIZE - jmp .end_get_size -@@: - test dword[esi + SDHCI_CONTROLLER.card_reg_csd + 12], 0x800000 ;check version SCD ver3 + ; get size device + test dword[esi + SDHCI_SLOT.card_reg_ocr], OCR_REG.CO2T jz @f call GET_SDUC_SIZE jmp .end_get_size @@: - test dword[esi + SDHCI_CONTROLLER.card_reg_csd + 12], 0xC00000 ;check version SCD ver3 - jnz .err ; no get size device + test dword[esi + SDHCI_SLOT.card_reg_ocr], OCR_REG.CCS + jz @f + call GET_SDHC_SIZE + jmp .end_get_size +@@: call GET_SDSC_SIZE .end_get_size: - DEBUGF 1,"SDHCI: Sectors card = %d:%d\n",[esi + SDHCI_CONTROLLER.sector_count + 4],\ - [esi + SDHCI_CONTROLLER.sector_count] - - mov ebx, [esi + SDHCI_CONTROLLER.divider25MHz] - call set_SD_clock + DEBUGF 1,"SDHCI: Sectors card = %d:%d\n",[esi + SDHCI_SLOT.sector_count + 4],\ + [esi + SDHCI_SLOT.sector_count] ; set timeout reg mov byte[eax + 0x2E], 1110b ; set max - ;DEBUGF 1,"SDHCI: TEST1 SDMA - read first sector\n" - ;call TEST_SDMA_R + ; get SCR register + ; : + ; 63-56, 55-48. + call SEND_SCR + jnz .err - ;DEBUGF 1,"SDHCI: TEST2 SDMA - read first sector\n" - ;call TEST_SDMA_R_MUL + ; check supported 4-bit mode + test word[esi + SDHCI_SLOT.card_reg_scr], 0x500 + jz .no_4bit_mode + ; acmd6. set 4bit mode + mov ebx, 10b ;4bit mode + call SET_BUS_WIDTH + jnz .err + ; set flag in register controller + or dword[eax + SDHC_CTRL1], 10b + DEBUGF 1,'SDHCI: set 4bit mode\n' +; TODO: check this code + mov ecx, 0xffff +@@: + dec ecx + jnz @b +; end +.no_4bit_mode: - ; . - ; set 4bit mode else card and controler suppoted it mode. + ; frequency increase up to 25 MHz + mov ebx, [esi + SDHCI_SLOT.divider25MHz] + call set_SD_clock - ; set bus speed mode + ; switch in high speed + ; check support high speed in host + test [esi + SDHCI_SLOT.Capabilities], HISPEED_SUPPORT + jz .no_high_speed + ; check SD_SPEC in SCR register. + ; if spec >= 1.10 then high speed supported + test byte[esi + SDHCI_SLOT.card_reg_scr], 11b + jz .no_high_speed - ; set new clock. 50 + ; cmd6 + invoke KernelAlloc, 512/8 + test eax, eax + jz .err + ;call SWITCH_FUNC + jnz .no_high_speed + ; set flag in register controller + or dword[eax + SDHC_CTRL1], 100b - ; set interrupt TODO: !!! - or dword[eax + SDHC_INT_MASK], 0xFFFFFFFF - or dword[eax + SDHC_SOG_MASK], 0xFFFFFFFF + ; set new clock + mov ebx, [esi + SDHCI_SLOT.divider50MHz] + call set_SD_clock +.no_high_speed: + push esi + add dword[esp], SDHCI_SLOT.disk_name + call add_card_disk - ;TODO: get SCR register - - stdcall add_card_disk, sdcard_disk_name - mov [esi + SDHCI_CONTROLLER.type_card], 2 + mov [esi + SDHCI_SLOT.type_card], 1 DEBUGF 1,'SDHCI: Card init - Memory card\n' ret -; SDIO initalization .sdio: - xor ebx, ebx - call get_ocr_mask - jz .err -@@: ; SDIO initialization (cmd5)set voltage window + call get_ocr_mask call IO_SEND_OP_COND jnz .err - test dword[eax + SDHC_RESP1_0], 0x80000000 ; check 31 bit - jz @b + test dword[eax + SDHC_RESP1_0], OCR_REG.Busy + jz .sdio + mov ecx, [esi + SDHCI_SLOT.card_reg_ocr] + mov [esi + SDHCI_SLOT.SDIO_reg_ocr], ecx + + mov [esi + SDHCI_SLOT.type_card], 2 ; sdio card + ; check MP flag + test [esi + SDHCI_SLOT.SDIO_reg_ocr], OCR_REG.MP + jz .no_combo_card + ; acmd41 for combo card + ; cmd2 + ALL_SEND_CID + mov [esi + SDHCI_SLOT.type_card], 3 ; combo card +.no_combo_card: call SEND_RCA - mov [esi + SDHCI_CONTROLLER.type_card], 1 ; sdio card + ; get CCCR data (SD, SDIO, CCCR version) + ; set 4bit mode + ; set hidn speed + ; set power mode + ; get CIS for CCCR + ; get FBR and CIS for this FBR + + ; find SDIO service + and [esi + SDHCI_SLOT.sdio_service], 0 + and [esi + SDHCI_SLOT.sdio_pdata], 0 + mov ecx, [sdio_drv_list] +.sdio_find_new: + cmp ecx, sdio_drv_list + jz .sdio_end_find + + mov edx, [ecx + SDIO_SERVICE.sdio_func] + push ecx + push esi + call dword[edx + SDIO_SERVICE_FUNC.check_fbr] + pop ecx + test eax, eax + jz .sdio_find_new + mov [esi + SDHCI_SLOT.sdio_service], ecx + mov [esi + SDHCI_SLOT.sdio_pdata], eax + mov eax, [esi + SDHCI_SLOT.base_reg_map] DEBUGF 1,'SDHCI: Card init - SDIO card\n' + ret +.sdio_end_find: DEBUGF 1,'SDHCI: SDIO card not supported. Power and clock stoped\n' and dword[eax + SDHC_CTRL1], not 0x0100 ; stop power and dword[eax + SDHC_CTRL2], not 0x04 ; stop SD clock - ret ; MMC initalization +; see https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/master/minix/drivers/storage/mmc/emmc.c .mmc: - ; - ;cmd1 + GO_IDLE_SATTE + ; cmd1 + ; goto cmd1 + ; cmd 2 + ; cmd 3 + ; cmd 9 + ; cmd 7 + ; cmd 8 !!! SEND_EXT_CSD + ; cmd 6 <- set hign speed + ; Wait for the (optional) busy signal. + ; /* CMD13. Check the result of the SWITCH operation. */ + ; ... + ; cmd16 <- set block length 512 byte ;TODO: MMC !!! - ;call add_card_disk - mov [esi + SDHCI_CONTROLLER.type_card], 4 + ;stdcall add_card_disk + mov [esi + SDHCI_SLOT.type_card], 4 and dword[eax + SDHC_CTRL1], not 0x0100 ; stop power and dword[eax + SDHC_CTRL2], not 0x04 ; stop SD clock @@ -680,17 +878,47 @@ proc card_init ret endp -proc thread_card_detect +; Creat new kernel thread for execute function +;IN: eax - bar +; esi - ptr SDHCI_SLOT +; ecx - ptr to called function +;OUT: - +proc call_func_thread + + sub esp, 5*4 ;data for event struct + push 0xff0000ff + mov [esp + 4], eax ; reg map + mov [esp + 8], esi ; sdhci_controller struct + mov [esp + 12], ecx ; addr function + + pusha + mov ebx, 1 + mov ecx, .new_thread + xor edx, edx ; stack - for kernel mode kernel alloc 8Kb RAM + + invoke CreateThread + test eax, eax + jz .exit + + ; send event for thread + lea esi, [esp + (8*4)] ; esi = ptr to struct event + invoke SendEvent +.exit: + popa + add esp, 6*4 + ret +.new_thread: ;get event with data sub esp, 6*4 ; 6*Dword mov edi, esp invoke GetEvent mov edi, esp - ;DEBUGF 1,'SDHCI: Get event code=%x [edi + 4]=%x, [edi + 8]=%x\n', [edi], [edi + 4], [edi + 8] + ;DEBUGF 1,'SDHCI: Get event code=%x [edi + 4]=%x, [edi + 8]=%x\n',\ + ; [edi], [edi + 4], [edi + 8] mov eax, dword[edi + 4] ; reg map mov esi, dword[edi + 8] ;controller struct - call card_init + call dword[edi + 12] ; destryct thread mov eax, -1 int 0x40 @@ -699,14 +927,27 @@ endp proc card_destruct DEBUGF 1,'SDHCI: Card removed\n' - ; - test ebx, 110b + + cmp dword[esi + SDHCI_SLOT.disk_hand], 0 jz .no_memory_card - call del_card_disk + invoke DiskDel, [esi + SDHCI_SLOT.disk_hand] + mov eax, [esi + SDHCI_SLOT.base_reg_map] .no_memory_card: - ;TODO: + cmp dword[esi + SDHCI_SLOT.sdio_service], 0 + jz .no_sdio + push eax + push [esi + SDHCI_SLOT.sdio_pdata] + mov ecx, [esi + SDHCI_SLOT.sdio_service] + mov ecx, [ecx + SDIO_SERVICE.sdio_func] + call dword[ecx + SDIO_SERVICE_FUNC.close_card] + pop eax + + and dword[esi + SDHCI_SLOT.sdio_service], 0 +.no_sdio: + ;TODO: + mov [esi + SDHCI_SLOT.disk_hand], 0 ;stop power and clock gen and dword[eax + SDHC_CTRL1], not 0x0100 ; stop power and dword[eax + SDHC_CTRL2], not 0x04 ; stop SD clock @@ -715,53 +956,89 @@ endp ; TODO: ; ( ). -; ( ) 2 , . ; + ( ) -proc sdhc_irq +proc sdhc_irq c pdata:dword pusha - mov esi, [esp + 4 + 32] ;stdcall - mov eax,[esi + SDHCI_CONTROLLER.base_reg_map] + mov eax, [pdata] + xor edx, edx +@@: + cmp [eax + SDHCI_DEVICE.slot_0 + edx*4], 0 + jnz .found + inc edx + cmp edx, 5 + ja .fail + jmp @b + +.found: + mov ecx, [eax + SDHCI_DEVICE.slot_0 + edx*4] + mov ecx, [ecx + SDHCI_SLOT.base_reg_map] ; get base addr slot0 + mov cx, word[ecx + SLOT_INTRPT] + and cx, 111b ;clear + bsf dx, cx + jz .fail + movzx edx, dx + mov esi, [eax + SDHCI_DEVICE.slot_0 + edx*4] + test esi, esi + jz .fail + mov eax, [esi + SDHCI_SLOT.base_reg_map] ;DEBUGF 1,"SDHCI: INTRPT: %x \n", [eax + SLOT_INTRPT] - DEBUGF 1,"SLOT_INT_STATUS: %x \n",[eax + SDHC_INT_STATUS] + ;DEBUGF 1,"SLOT_INT_STATUS: %x \n",[eax + SDHC_INT_STATUS] cmp dword[eax + SDHC_INT_STATUS], 0 jz .fail + ; send request on interrupt for stop generated irq signal mov ecx, [eax + SDHC_INT_STATUS] - mov dword[esi + SDHCI_CONTROLLER.int_status], ecx - mov [eax + SDHC_INT_STATUS], ecx ; + mov dword[esi + SDHCI_SLOT.int_status], ecx + mov [eax + SDHC_INT_STATUS], ecx - test dword[esi + SDHCI_CONTROLLER.int_status], INT_STATUS.CARD_INS + test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.CARD_INS jz .no_card_inserted - ; create thread for init card - push esi - push eax - mov ebx, 1 - mov ecx, thread_card_detect - mov edx, 0 ; stack - for kernel mode kernel alloc 8Kb RAM - invoke CreateThread - DEBUGF 1,"SDHCI: create thread tid=%x \n", eax - test eax, eax - pop ebx - pop ecx - jz .no_card_inserted - ; send event for thread - mov [.event_struct + 4], ebx ; reg map - mov [.event_struct + 8], ecx ; sdhci_controller struct - mov esi, .event_struct - ;DEBUGF 1,"SDHCI: send event tid=%x code[1]=%x code[2]=%x \n", eax, [.event_struct + 4], [.event_struct + 8] - push ecx - push ebx - invoke SendEvent - ;DEBUGF 1,"SDHCI: Evend sended, eax=%x uid=%x \n", eax, ebx - pop eax - pop esi + mov ecx, card_init + call call_func_thread .no_card_inserted: - test dword[esi + SDHCI_CONTROLLER.int_status], INT_STATUS.CARD_REM + test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.CARD_REM + jz @f;.exit + + mov ecx, card_destruct + call call_func_thread + +@@: + ; check INT_STATUS.Error + check command or transfer complate + test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.ERROR\ + + INT_STATUS.DAT_DONE\ + + INT_STATUS.CMD_DONE + jnz .sdio_int + ; check dma + test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.DMA_EVT + jz .exit + ; dma int - set new phys addr + mov dword[esi + SDHCI_SLOT.int_status], 0 + and dword[esi + SDHCI_SLOT.virt_addr_buff], -4096 + add dword[esi + SDHCI_SLOT.virt_addr_buff], 4096 + mov ecx, dword[esi + SDHCI_SLOT.virt_addr_buff] + xchg eax, ecx + invoke GetPhysAddr + xchg eax, ecx + mov dword[eax + SDHC_SYS_ADDR], ecx + jmp .exit + +.sdio_int: + test dword[esi + SDHCI_SLOT.int_status], INT_STATUS.SDIO jz .exit - call card_destruct + cmp dword[esi + SDHCI_SLOT.sdio_service], 0 + jz .exit + + push eax + + push [eax + SDHCI_SLOT.sdio_pdata] + mov ecx, [eax + SDHCI_SLOT.sdio_service] + mov ecx, [ecx + SDIO_SERVICE.sdio_func] + call dword[ecx + SDIO_SERVICE_FUNC.int_handler] + + pop eax .exit: popa xor eax, eax @@ -771,159 +1048,143 @@ proc sdhc_irq xor eax, eax inc eax ret -.event_struct: ; 6*dword - dd 0xff0000ff - rd 5 endp ; get voltage mask for ACMD41 and CMD5 -; IN: ebx - base data for OCR esi,eax -standart fo this driver +; IN: esi,eax -standart fo this driver ; OUT: ebx - OCR ; ZF - error mask(ebx[23:0]=0) proc get_ocr_mask - or ebx, [esi + SDHCI_CONTROLLER.card_reg_ocr] ; set mask sd card + ; set mask sd card + or dword[esi + SDHCI_SLOT.card_reg_ocr], OCR_REG.CCS + OCR_REG.CO2T + mov ebx, dword[esi + SDHCI_SLOT.card_reg_ocr] cmp byte[eax + 0x29], 1011b ;1.8 jnz @f - and ebx, (1 shl 30) + 0x80 ; see OCR reg + and ebx, OCR_REG.CCS + OCR_REG.CO2T + 0x80 ; see OCR reg @@: cmp byte[eax + 0x29], 1101b ;3.0 jnz @f - and ebx, (1 shl 30) + (1 shl 17) ; see OCR reg + and ebx, OCR_REG.CCS + OCR_REG.CO2T + (1 shl 17) ; see OCR reg @@: cmp byte[eax + 0x29], 1111b ;1.8 jnz @f - and ebx, (1 shl 30) + (1 shl 20) ; see OCR reg + and ebx, OCR_REG.CCS + OCR_REG.CO2T + (1 shl 20) ; see OCR reg @@: test ebx, 0xffffff ret endp -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 - - ; This function for working drivers and programs worked ; with SDIO interface. proc service_proc stdcall, ioctl:dword - ; 0 - get version - ; 1 - get card count - ; 2 - get card (hand + info(CID, CSD, RCA, OCR)) - ; 3 - set card width bus - ; 4 - set card clock - ; 5 - set card irq hand (for SDIO) - ; 6 - look access card - ; 7 - unlook access card - ; 8 - call card func (for SDIO) - ; 9 - capturing control controller + pusha + mov eax, [ioctl] + mov ecx, [eax + IOCTL.io_code] + cmp ecx, .table_size + jae .err_exit + + jmp dword[.table + ecx*4] +.table: + dd .get_version + dd .get_device + dd .get_slot + dd .get_sdio_export_func +.table_size = ($ - .table)/4 + +; Get version driver +; IN: IOCTL.out_size = 4, +; IOCTL.io_code = 0 +; OUT: [IOCTL.output] = DRIVER VERSION +.get_version: + cmp dword[eax + IOCTL.out_size], 4 + jnz .err_exit + + mov ecx, [eax + IOCTL.output] + mov dword[ecx], DRIVER_VERSION + jmp .exit + +; Get SDHCI_DEVICE struct +; IN: IOCTL.out_size = sizeof.SDHCI_DEVICE, +; [IOCTL.input] = handle or ZERO for get root handle +; OUT: [IOCTL.output] = struct SDHCI_DEVICE or +; handle root list +.get_device: + cmp dword[eax + IOCTL.inp_size], 4 + jnz .err_exit + + mov ecx, [eax + IOCTL.input] + mov ecx, [ecx] + + mov edi, [eax + IOCTL.output] + + test ecx, ecx + jz .get_device.root + + mov esi, ecx ;save handle struct + + cmp ecx, list_controllers + jz @f + + cmp dword[eax + IOCTL.out_size], sizeof.SDHCI_DEVICE + jnz .err_exit + + mov ecx, sizeof.SDHCI_DEVICE + rep movsb + + jmp .exit + @@: + cmp dword[eax + IOCTL.out_size], 8 ; for 2 ptr on root list + jnz .err_exit + + movsd + movsd + jmp .exit + + .get_device.root: + cmp dword[eax + IOCTL.out_size], 4 ; for handle on root list + jb .err_exit + + mov dword[edi], list_controllers + jmp .exit + +; Get SDHCI_SLOT struct +; IN: IOCTL.out_size = sizeof.SDHCI_SLOT, +; [IOCTL.input] = handle +; OUT: [IOCTL.output] = struct SDHCI_SLOT +.get_slot: + cmp dword[eax + IOCTL.inp_size], 4 + jnz .err_exit + + mov esi, [eax + IOCTL.input] + mov esi, [esi] + + mov edi, [eax + IOCTL.output] + + cmp dword[eax + IOCTL.out_size], sizeof.SDHCI_SLOT + jnz .err_exit + + mov ecx, sizeof.SDHCI_SLOT + rep movsb + + jmp .exit + +; 3 - get_sdio_export_func +; IN: IOCTL.out_size = 4 +; OUT: [IOCTL.output] = prt to table export SDIO function this driver. +.get_sdio_export_func: + cmp dword[eax + IOCTL.out_size], 4 + jnz .err_exit + + mov ecx, [eax + IOCTL.output] + mov dword[ecx], export_sdio_api + +.exit: + popa + xor eax, eax + ret +.err_exit: + popa + mov eax, 1 ret endp diff --git a/sdhci.sys b/sdhci.sys index 11f355871459bf82c72ba27ccf1b92f8aab41636..3f05065a4a5ac484093c773c95f43495d76a0a54 100644 GIT binary patch literal 7264 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 literal 7008 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 diff --git a/sdio-test.asm b/sdio-test.asm new file mode 100644 index 0000000..96ed4a4 --- /dev/null +++ b/sdio-test.asm @@ -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 \ No newline at end of file diff --git a/sdio-test.sys b/sdio-test.sys new file mode 100644 index 0000000000000000000000000000000000000000..53de2e1f94f9f8dd8094096514f91a661cff9e45 GIT binary patch literal 1600 zcmbtUU1$_n6h4!z>1NeTKx1D7Z)CwILoze|R1ntPY&0R(kWH&qS~J-hvl}-%GCK)s z4P8hVYV)!nDwYHirS+|8N|BmCGU>M9A_0GbrciN1&@7FDX~n!~w&%|5j7b`N@xncG z&-Z=zJLk@D=it#eFaY3yQpn{1JT$@KG2**J9O;rR!zJ)b@kIHrO#MW8Qz#rGr&Og? z728Qrj7AlWw8%v5h>~!WR38eEc14ma*1O!6bAunCo?*bPc1aeNff8md!_@XWECgV% z0H8nL8|{uDMW+Q7f(tWbicDSI70P)4k7Z6d>}kUPBY{J5TV#HU#|i|Pqmy)|Ez9o2`JY^Bx1j4fbn!8i(7OYp)LWZuvhf@KP5 z8N>cxn@kyGZ!