In memory of Ben “bushing” Byer, who passed away on Monday, February 8th, 2016.

Changes

Jump to navigation Jump to search
5,117 bytes added ,  06:51, 18 June 2021
Moved the slot1 stuff here
Line 1: Line 1:  +
The drivers in this directory control access to the front SD slot, as well as an unused space for a second slot.
 +
 +
== Ioctl listing ==
 +
 +
{| class="wikitable"
 +
|-
 +
! Request number
 +
! Name
 +
! Input
 +
! Output
 +
! Notes
 +
|-
 +
| 1
 +
| sd_hc_write8
 +
| 6-word param array: [reg, 0, 0, 1 (reg size), data, 0]
 +
| none
 +
| reg and data should both be 8-bit values
 +
|-
 +
| 2
 +
| sd_hc_read8
 +
| 6-word param array: [reg, 0, 0, 1 (reg size), 0, 0]
 +
| 32-bit word
 +
|
 +
|-
 +
| 4
 +
| sd_reset_card
 +
| none
 +
| 32-bit word
 +
|
 +
|-
 +
| 6
 +
| sd_set_clock
 +
| 32-bit word: one half of the sdclk divisor: a power of two or zero.  (usually, 1)
 +
| none
 +
|
 +
|-
 +
| 7
 +
| sd_command
 +
| 9-word param array: [cmd, cmd_type, resp_type, arg, block_count, block_size, (u32)addr, 0, 0]
 +
| 4-word reply buffer ??
 +
| input or output from command will go into the address point to by addr, which should be a physical pointer
 +
|-
 +
| 7 (ioctlv)
 +
| sd_data_command
 +
| 9-word param array: [cmd, cmd_type, resp_type, arg, block_count, block_size, (u32)addr, 0, 0], data buffer of arbitrary size (block_count * block_size?)
 +
| 4-word reply buffer?
 +
|
 +
|-
 +
| 11
 +
| sd_get_status
 +
| none
 +
| 32-bit status register
 +
|
 +
|-
 +
| 12
 +
| sd_get_ocr
 +
| none
 +
| 32-bit register
 +
|
 +
|}
 +
 +
=== GetDeviceStatus ===
 +
<source lang="c">
 +
SD_GetDeviceStatus
 +
u32 buffer
 +
ios_ioctl( sd_fd, 0x0B, 0, 0, &buffer, 4);
 +
</source>
 +
buffer contains the status of the SD slot
 +
 +
Upper 16 bits:
 +
:* 0: SD is not initialized (or busy)
 +
:* 1: SD is initialized
 +
Lower 16 bits:
 +
:* 1: SD card is inserted.
 +
:* 2: No SD card is inserted (sdio interrupt)
 +
 +
=== ResetDevice ===
 +
<source lang="c">
 +
SD_ResetDevice
 +
ios_ioctl( sd_fd, 4, 0, 0, buffer, 4);
 +
</source>
 +
buffer contains the rca and stuff bits
 +
 +
Upper 16 bits: rca (relative card address)
 +
 +
Lower 16 bits: stuff bits
 +
=== GetOCRegister ===
 +
<source lang="c">
 +
SD_GetOCRegister
 +
ios_ioctl( sd_fd, 0xC, 0, 0, buffer, 4);
 +
</source>
 +
=== GetHCRegister ===
 +
The host controller is just a standard SD host controller and you can directly read and write to its registers using the following two functions.
 +
<source lang="c">
 +
SD_GetHCRegister (untested iirc)
 +
((u32*)inbuf)[0] = register_offset;
 +
((u32*)inbuf)[3] = 1;
 +
((u32*)inbuf)[4] = 0;
 +
 +
ios_ioctl( sd_fd, 2, inbuf, 0x18, outbuf, 4);
 +
</source>
 +
=== SetHCRegister ===
 +
<source lang="c">
 +
SD_SetHCRegister
 +
((u32*)inbuf)[0] = register_offset;
 +
((u32*)inbuf)[3] = 1;
 +
((u32*)inbuf)[4] = value;
 +
 +
ios_ioctl( sd_fd, 1, inbuf, 0x18, 0, 0);
 +
</source>
 +
=== SendCMD ===
 +
<source lang="c">
 +
SD_SendCMD(cmd, cmd_type, resp_type, arg, buffer, block_count, sector_size)
 +
 +
((u32*)inbuf)[0]=cmd;
 +
((u32*)inbuf)[1]=cmd_type;
 +
((u32*)inbuf)[2]=resp_type;
 +
((u32*)inbuf)[3]=arg;
 +
((u32*)inbuf)[4]=block_count;
 +
((u32*)inbuf)[5]=sector_size;
 +
((u32*)inbuf)[6]=buffer;
 +
((u32*)inbuf)[7]=0; // ?
 +
((u32*)inbuf)[8]=0; // ?
 +
 +
ios_ioctl( sd_fd, 7, inbuf, 0x24, outbuf, 0x10);
 +
</source>
 +
 +
=== SD Commands ===
 +
<source lang="c">
 +
 +
SD_SendCmd(0x10, 3, 1, 0x200, 0, 0, 0) card_set_blocklen(0x200)
 +
SD_SendCmd(0x37, 3, 1, rca&0xFFFF0000, 0, 0, 0) set data bus width
 +
 +
SD_SendCmd(7, 3, 2, rca&0xFFFF0000, 0, 0, 0) // select
 +
SD_SendCmd(7, 3, 2, 0, 0, 0, 0) // deselect
 +
IOS_Ioctl(fd, 11, 0, 0, (u32 *)&status, 4); // get status
 +
IOS_Ioctl(fd, 4, 0, 0, (u32 *)&rca, 4) // reset and get rca
 +
IOS_Ioctl(fd, 6, (u32 *)&clock, 4, 0, 0) // using 1 as clock seems to work
 +
</source>
 +
==== ''Set bus width to 4'' ====
 +
<source lang="c">
 +
SD_SendCmd(0x37, 3, 1, rca&0xFFFF0000, 0, 0, 0)
 +
SD_SendCmd(6, 3, 1, 2, 0, 0, 0)
 +
 +
//To set the Bus Width to 4: Read the HCR register and AND it with 0x2. Then OR it 0x2 and write that result back.
 +
</source>
 +
 +
==== ''Block Read'' ====
 +
<source lang="c">
 +
IOS_ioctlv(fd, 7, 2, 1, vectors)
 +
// Vector Table: {InputBuffer, 0x24, &buffer, 0x200, ReplyBuffer, 0x10}
 +
// First vector (InputBuffer) is {0x12, 3, 1, blockno * 0x200, 1, 0x200, &buffer (yes the same &buffer that's in the Vector Table), 1, 0}
 +
// 0x12 is CMD18 READ_MULTI_BLOCK. Blockno * 0x200 is the physical address of the SD card
 +
// The Second Vector is the buffer where SD contents are read (dumped) to. If doing a Block Write, these are the contents that get written to the SD.
 +
// The Third Vector is a simple 0x10 Reply Buffer.
 +
// blockno * 0x200 is the physical address of the SD card
 +
</source>
 +
==== ''Block Write'' ====
 +
Works the same way as reading does. Just use 0x19 instead of 0x12 in the first vector.
 +
0x19 is CMD25 WRITE_MULTIPLE_BLOCK
 +
==== ''How to Read/Write'' ====
 +
1. IOS_Open /dev/sdio/slotX (0); fd is returned from IOS_Open
 +
 +
2. Reset the SD
 +
 +
3. Select the SD
 +
 +
4. Set Block Length to 0x200
 +
 +
5. Do all the necessary IOCTL calls to set Bus Width to 4 (SD CMD 0x37, SD CMD 6, Get HCR, Set HCR)
 +
 +
6. Clock the SD using value of 1
 +
 +
7. Execute READ_MULTI_BLOCK / Execute WRITE_MULTI_BLOCK
 +
 +
8. IOS_Close /dev/sdio/slotX
 +
==== ''Async device state monitoring'' ====
 +
<source lang="c">
 +
SD_SendCmd(0x40, 0, 0, 1, 0, 0, 0) get card insertion event (waits until event happens or request is cancelled)
 +
SD_SendCmd(0x40, 0, 0, 2, 0, 0, 0) get card removal event (as above)
 +
SD_SendCmd(0x41, 0, 0, ?, 0, 0, 0) cancel event request (arg is 1 or 2)
 +
</source>
 +
 +
[[Category:IOS API documentation]]
 +
 +
== Devices ==
 
{{Special:Prefixindex/{{FULLPAGENAME}}/}}
 
{{Special:Prefixindex/{{FULLPAGENAME}}/}}
    
[[Category:Wii Filesystem]]
 
[[Category:Wii Filesystem]]
5,579

edits

Navigation menu