Skip to content

Instantly share code, notes, and snippets.

@xerpi
Last active January 17, 2024 09:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xerpi/b415505890bc155fee91ca064e45263f to your computer and use it in GitHub Desktop.
Save xerpi/b415505890bc155fee91ca064e45263f to your computer and use it in GitHub Desktop.
// https://wiki.henkaku.xyz/vita/SDIF_Registers
typedef struct sd_mmc_registers {
uint32_t sdma_system_addr;
uint16_t block_size;
uint16_t block_count;
uint32_t argument1;
uint16_t transfer_mode;
uint16_t command;
uint16_t resp0;
uint16_t resp1;
uint16_t resp2;
uint16_t resp3;
uint16_t resp4;
uint16_t resp5;
uint16_t resp6;
uint16_t resp7;
uint32_t buffer_data_port;
uint32_t present_state;
uint8_t host_control1;
uint8_t power_control;
uint8_t block_gap_control;
uint8_t wakeup_control;
uint16_t clock_control;
uint8_t timeout_control;
uint8_t software_reset;
uint16_t normal_interrupt_status;
uint16_t error_interrupt_status;
uint16_t normal_interrupt_status_enable;
uint16_t error_interrupt_status_enable;
uint16_t normal_interrupt_signal_enable;
uint16_t error_interrupt_signal_enable;
uint16_t auto_cmd_error_status;
uint16_t host_control2;
uint32_t capabilities_lo;
uint32_t capabilities_hi;
uint64_t maximum_current_capabilities;
uint16_t force_event_for_auto_cmd_error_status;
uint16_t force_event_for_error_interrupt_status;
uint8_t adma_error_status;
uint8_t unused1;
uint16_t unused2;
uint32_t adma_system_address_lo;
uint32_t adma_system_address_hi;
uint16_t preset_value_for_initialization;
uint16_t preset_value_for_default_speed;
uint16_t preset_value_for_high_speed;
uint16_t preset_value_for_sdr12;
uint16_t preset_value_for_sdr25;
uint16_t preset_value_for_sdr50;
uint16_t preset_value_for_sdr104;
uint16_t preset_value_for_ddr50;
uint8_t unused3[0x70];
uint32_t shared_bus_control;
uint8_t unused4[0x18];
uint16_t slot_interrupt_status;
uint16_t host_controller_version;
} __attribute__((packed)) sd_mmc_registers;
#define HW_RESET (1 << 0)
#define SW_RESET (1 << 1)
int sdif_reset(sd_context_global *ctx, int flags)
{
uint32_t soc;
uint32_t delay;
uint16_t enable;
sd_mmc_registers *host_regs;
bool is_idx_2;
const uint32_t array_idx = (ctx->ctx_data).array_idx;
host_regs = (ctx->ctx_data).host_registers;
if (flags & HW_RESET) {
soc = scePervasiveGetSoCRevisionForDriver();
if ((soc & 0x1ff00) == 0) {
if (ksceSblAimgrIsGenuineDolce() == 0) {
if (array_idx < 2) {
ScePervasiveForDriver_9F8E589C_ScePervasiveMisc_0x110_0x1C(array_idx, 0x200);
if (array_idx != 0) {
scePervasiveSdifResetEnableForDriver(array_idx);
} else {
if (data_segment.sdif_context_general.unk_8 == 1) {
ksceDebugPrintf2(0xf, &unk_table, "Skip sdif port[%d] reset\n",0);
} else {
scePervasiveSdifResetEnableForDriver(0);
ksceSblSmSchedProxyExecuteF00DCommand(3, 0, 0, 0);
}
}
} else {
scePervasiveSdifResetEnableForDriver(array_idx);
}
} else {
if (array_idx != 0) {
ScePervasiveForDriver_9F8E589C_ScePervasiveMisc_0x110_0x1C(array_idx, 0);
scePervasiveSdifResetEnableForDriver(array_idx);
} else {
ScePervasiveForDriver_9F8E589C_ScePervasiveMisc_0x110_0x1C(0, 0x200);
if (data_segment.sdif_context_general.unk_8 == 1) {
ksceDebugPrintf2(0xf, &unk_table, "Skip sdif port[%d] reset\n",0);
} else {
scePervasiveSdifResetEnableForDriver(0);
ksceSblSmSchedProxyExecuteF00DCommand(3, 0, 0, 0);
}
}
}
} else {
if ((soc & 0x1ff00) == 0x100) {
if ((ksceSysconGetHardwareInfo() & 0xff0000) < 0x800000) {
if (array_idx != 0) {
if (array_idx < 3) {
ScePervasiveForDriver_043B33F5_ScePervasiveMisc_0x310(array_idx, 2);
}
scePervasiveSdifResetEnableForDriver(array_idx);
} else {
ScePervasiveForDriver_043B33F5_ScePervasiveMisc_0x310(0, 4);
if (data_segment.sdif_context_general.unk_8 == 1) {
ksceDebugPrintf2(0xf, &unk_table, "Skip sdif port[%d] reset\n",0);
} else {
scePervasiveSdifResetEnableForDriver(0);
ksceSblSmSchedProxyExecuteF00DCommand(3, 0, 0, 0);
}
}
} else {
if (array_idx != 0) {
if (array_idx == 1) {
if (sceKernelIsAllowSdCardFromMgmt() == 0) {
ScePervasiveForDriver_043B33F5_ScePervasiveMisc_0x310(1, 3);
} else {
ScePervasiveForDriver_043B33F5_ScePervasiveMisc_0x310(1, 6);
}
} else if (array_idx == 2) {
ScePervasiveForDriver_043B33F5_ScePervasiveMisc_0x310(2, 3);
}
scePervasiveSdifResetEnableForDriver(array_idx);
} else {
ScePervasiveForDriver_043B33F5_ScePervasiveMisc_0x310(0, 5);
if (data_segment.sdif_context_general.unk_8 == 1) {
ksceDebugPrintf2(0xf, &unk_table, "Skip sdif port[%d] reset\n",0);
} else {
scePervasiveSdifResetEnableForDriver(0);
ksceSblSmSchedProxyExecuteF00DCommand(3, 0, 0, 0);
}
}
}
} else {
if (array_idx != 0) {
scePervasiveSdifResetEnableForDriver(array_idx);
} else {
if (data_segment.sdif_context_general.unk_8 == 1) {
ksceDebugPrintf2(0xf, &unk_table, "Skip sdif port[%d] reset\n",0);
} else {
scePervasiveSdifResetEnableForDriver(0);
ksceSblSmSchedProxyExecuteF00DCommand(3, 0, 0, 0);
}
}
}
}
scePervasiveSdifResetDisableForDriver(array_idx);
scePervasiveSdifClkGateEnableForDriver(array_idx);
(ctx->ctx_data).timeout_control = 0xe;
switch(array_idx) {
case 0:
(ctx->ctx_data).unk_18 = 0x80;
pervasive_sdif_misc_0x124(0, 1);
break;
case 1:
case 3:
(ctx->ctx_data).unk_18 = 0x300000;
pervasive_sdif_misc_0x124(array_idx, 0);
break;
case 2:
(ctx->ctx_data).unk_18 = 0x80;
pervasive_sdif_misc_0x124(2, 1);
break;
default:
(ctx->ctx_data).unk_18 = 0;
break;
}
}
if (flags & SW_RESET) {
/* Bit 0 – SWRSTALL Software reset for All */
host_regs->software_reset = 1;
do {
} while (host_regs->software_reset & 1);
host_regs->timeout_control = (ctx->ctx_data).timeout_control;
delay = 102;
do {
/* Bit 17 – CARDSS Card State Stable */
if ((host_regs->present_state & (1 << 17)) {
break;
}
} while ((array_idx != 1) || (delay--, delay != 0));
host_regs->normal_interrupt_status_enable = 0;
host_regs->error_interrupt_status_enable = 0;
host_regs->normal_interrupt_signal_enable = 0;
host_regs->error_interrupt_signal_enable = 0;
host_regs->normal_interrupt_status = host_regs->normal_interrupt_status;
host_regs->error_interrupt_status = host_regs->error_interrupt_status;
do {
} while (host_regs->normal_interrupt_status != 0);
do {
} while (host_regs->error_interrupt_status != 0);
if (array_idx == 2)
enable = 0x1fb;
else
enable = 0xfb;
host_regs->normal_interrupt_status_enable = enable;
host_regs->error_interrupt_status_enable = 0x37f;
host_regs->normal_interrupt_signal_enable = enable;
host_regs->error_interrupt_signal_enable = 0x37f;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment