|
| 1 | +#include "ps2sif.h" |
| 2 | +#include "ps2syscalls.h" |
| 3 | + |
| 4 | +sceSifInitRpc_t sceSifInitRpc; |
| 5 | +sceSifExitRpc_t sceSifExitRpc; |
| 6 | + |
| 7 | +void sceSifWriteBackDCache(void *buffer, int len) { |
| 8 | + if (len > 0) { |
| 9 | + unsigned long saddr = (unsigned long)buffer & ~63; |
| 10 | + unsigned long eaddr = ((unsigned long)buffer + (len - 1)) & ~63; |
| 11 | + unsigned long chunk64_cnt = ((eaddr - saddr) >> 6) + 1; |
| 12 | + unsigned long chunk8_rem = chunk64_cnt & 7; |
| 13 | + unsigned long chunk8_cnt = chunk64_cnt >> 3; |
| 14 | + while (chunk8_rem--) { |
| 15 | + asm volatile ("sync" ::: "memory"); |
| 16 | + asm volatile ("cache 0x18, 0(%0)" :: "r"(saddr) : "memory"); |
| 17 | + asm volatile ("sync" ::: "memory"); |
| 18 | + saddr += 64; |
| 19 | + } |
| 20 | + while (chunk8_cnt--) { |
| 21 | + asm volatile ("sync" ::: "memory"); |
| 22 | + asm volatile ("cache 0x18, 0(%0)" :: "r"(saddr) : "memory"); |
| 23 | + asm volatile ("sync" ::: "memory"); |
| 24 | + asm volatile ("cache 0x18, 64(%0)" :: "r"(saddr) : "memory"); |
| 25 | + asm volatile ("sync" ::: "memory"); |
| 26 | + asm volatile ("cache 0x18, 128(%0)" :: "r"(saddr) : "memory"); |
| 27 | + asm volatile ("sync" ::: "memory"); |
| 28 | + asm volatile ("cache 0x18, 192(%0)" :: "r"(saddr) : "memory"); |
| 29 | + asm volatile ("sync" ::: "memory"); |
| 30 | + asm volatile ("cache 0x18, 256(%0)" :: "r"(saddr) : "memory"); |
| 31 | + asm volatile ("sync" ::: "memory"); |
| 32 | + asm volatile ("cache 0x18, 320(%0)" :: "r"(saddr) : "memory"); |
| 33 | + asm volatile ("sync" ::: "memory"); |
| 34 | + asm volatile ("cache 0x18, 384(%0)" :: "r"(saddr) : "memory"); |
| 35 | + asm volatile ("sync" ::: "memory"); |
| 36 | + asm volatile ("cache 0x18, 448(%0)" :: "r"(saddr) : "memory"); |
| 37 | + asm volatile ("sync" ::: "memory"); |
| 38 | + saddr += 512; |
| 39 | + } |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +int sceSifSyncIop(void) { |
| 44 | + return (sceSifGetReg(SIF_SMFLG) & 0x40000) != 0; |
| 45 | +} |
| 46 | + |
| 47 | +int sceSifResetIop(const char *arg, int mode) { |
| 48 | + static sceSifCmdResetData rst_data __attribute__((aligned(64))); |
| 49 | + sceSifDmaData dmat; |
| 50 | + int arglen = 0; |
| 51 | + |
| 52 | + sceSifStopDma(); |
| 53 | + if (*arg != '\0') { |
| 54 | + for (;;) { |
| 55 | + rst_data.arg[arglen] = arg[arglen]; |
| 56 | + if (arg[++arglen] == '\0') break; |
| 57 | + } |
| 58 | + } |
| 59 | + rst_data.chdr.psize = sizeof(rst_data); |
| 60 | + rst_data.chdr.fcode = SIF_CMDC_RESET_CMD; |
| 61 | + rst_data.flag = mode; |
| 62 | + rst_data.size = arglen; |
| 63 | + |
| 64 | + dmat.data = (unsigned int)(unsigned long)(&rst_data); |
| 65 | + dmat.addr = sceSifGetReg(SIF_CMDI_SYSTEM); |
| 66 | + dmat.size = sizeof(rst_data); |
| 67 | + dmat.mode = SIF_DMA_ERT | SIF_DMA_INT_O; |
| 68 | + |
| 69 | + sceSifWriteBackDCache(&rst_data, sizeof(rst_data)); |
| 70 | + sceSifSetReg(SIF_SMFLG, 0x40000); |
| 71 | + if (!sceSifSetDma(&dmat, 1)) { |
| 72 | + return 0; |
| 73 | + } |
| 74 | + sceSifSetReg(SIF_SMFLG, 0x10000); |
| 75 | + sceSifSetReg(SIF_SMFLG, 0x20000); |
| 76 | + sceSifSetReg(SIF_CMDC_INIT_CMD, 0); |
| 77 | + sceSifSetReg(SIF_CMDI_SYSTEM, 0); |
| 78 | + return 1; |
| 79 | +} |
0 commit comments