#include "PRinternal/macros.h" #include "PR/os_internal.h" #include "PR/rcp.h" #include "PRinternal/controller.h" #include "PRinternal/siint.h" static void __osPackEepWriteData(u8 address, u8* buffer); s32 osEepromWrite(OSMesgQueue* mq, u8 address, u8* buffer) { s32 ret = 0; #if BUILD_VERSION < VERSION_J int i; #endif u16 type; u8* ptr = (u8*)&__osEepPifRam.ramarray; __OSContEepromFormat eepromformat; OSContStatus sdata; #if BUILD_VERSION >= VERSION_L u8 temp[8]; #endif __osSiGetAccess(); ret = __osEepStatus(mq, &sdata); #if BUILD_VERSION < VERSION_J ret = __osEepStatus(mq, &sdata); // Duplicate that was removed in 2.0J #endif type = sdata.type & (CONT_EEPROM | CONT_EEP16K); #if BUILD_VERSION >= VERSION_J if (ret == 0) { switch (type) { case CONT_EEPROM: if (address >= EEPROM_MAXBLOCKS) { ret = CONT_RANGE_ERROR; } break; case CONT_EEPROM | CONT_EEP16K: if (address >= EEP16K_MAXBLOCKS) { // not technically possible ret = CONT_RANGE_ERROR; } #if BUILD_VERSION >= VERSION_L else if (__osEepromRead16K) { __osEepromRead16K = 0; __osSiRelAccess(); osEepromRead(mq, (address ^ 1), temp); __osSiGetAccess(); } #endif break; default: ret = CONT_NO_RESPONSE_ERROR; } } if (ret != 0) { __osSiRelAccess(); return ret; } #else if (ret != 0) { __osSiRelAccess(); return CONT_NO_RESPONSE_ERROR; } else { switch (type) { case CONT_EEPROM: if (address > EEPROM_MAXBLOCKS) { __osSiRelAccess(); return -1; } break; case CONT_EEPROM | CONT_EEP16K: if (address > EEP16K_MAXBLOCKS) { // not technically possible __osSiRelAccess(); return -1; } break; default: __osSiRelAccess(); return CONT_NO_RESPONSE_ERROR; } } #endif while (sdata.status & CONT_EEPROM_BUSY) { __osEepStatus(mq, &sdata); } __osPackEepWriteData(address, buffer); ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam); // send command to pif osRecvMesg(mq, NULL, OS_MESG_BLOCK); ret = __osSiRawStartDma(OS_READ, &__osEepPifRam); // recv response __osContLastCmd = CONT_CMD_WRITE_EEPROM; osRecvMesg(mq, NULL, OS_MESG_BLOCK); // skip the first 4 bytes #if BUILD_VERSION >= VERSION_J ptr += 4; #else for (i = 0; i < 4; i++) { ptr++; } #endif eepromformat = *(__OSContEepromFormat*)ptr; ret = CHNL_ERR(eepromformat); __osSiRelAccess(); return ret; } static void __osPackEepWriteData(u8 address, u8* buffer) { u8* ptr = (u8*)&__osEepPifRam.ramarray; __OSContEepromFormat eepromformat; int i; #if BUILD_VERSION < VERSION_J for (i = 0; i < ARRLEN(__osEepPifRam.ramarray); i++) { __osEepPifRam.ramarray[i] = CONT_CMD_NOP; } #endif __osEepPifRam.pifstatus = CONT_CMD_EXE; eepromformat.txsize = CONT_CMD_WRITE_EEPROM_TX; eepromformat.rxsize = CONT_CMD_WRITE_EEPROM_RX; eepromformat.cmd = CONT_CMD_WRITE_EEPROM; eepromformat.address = address; for (i = 0; i < ARRLEN(eepromformat.data); i++) { eepromformat.data[i] = *buffer++; } for (i = 0; i < MAXCONTROLLERS; i++) { *ptr++ = 0; } *(__OSContEepromFormat*)(ptr) = eepromformat; ptr += sizeof(__OSContEepromFormat); ptr[0] = CONT_CMD_END; } s32 __osEepStatus(OSMesgQueue* mq, OSContStatus* data) { s32 ret = 0; int i; u8* ptr = (u8*)__osEepPifRam.ramarray; __OSContRequesFormat requestformat; for (i = 0; i < ARRLEN(__osEepPifRam.ramarray) + 1; i++) { __osEepPifRam.ramarray[i] = 0; } __osEepPifRam.pifstatus = CONT_CMD_EXE; ptr = (u8*)__osEepPifRam.ramarray; for (i = 0; i < MAXCONTROLLERS; i++) { *ptr++ = CONT_CMD_REQUEST_STATUS; } requestformat.dummy = CONT_CMD_NOP; requestformat.txsize = CONT_CMD_REQUEST_STATUS_TX; requestformat.rxsize = CONT_CMD_REQUEST_STATUS_RX; requestformat.cmd = CONT_CMD_REQUEST_STATUS; requestformat.typeh = CONT_CMD_NOP; requestformat.typel = CONT_CMD_NOP; requestformat.status = CONT_CMD_NOP; requestformat.dummy1 = CONT_CMD_NOP; *(__OSContRequesFormat*)ptr = requestformat; ptr += sizeof(__OSContRequesFormat); *ptr = CONT_CMD_END; ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam); osRecvMesg(mq, NULL, OS_MESG_BLOCK); #if BUILD_VERSION >= VERSION_J __osContLastCmd = CONT_CMD_END; #else __osContLastCmd = CONT_CMD_REQUEST_STATUS; #endif ret = __osSiRawStartDma(OS_READ, &__osEepPifRam); osRecvMesg(mq, NULL, OS_MESG_BLOCK); if (ret != 0) { return ret; } ptr = (u8*)&__osEepPifRam; for (i = 0; i < MAXCONTROLLERS; i++) { *ptr++ = 0; } requestformat = *(__OSContRequesFormat*)ptr; data->errno = CHNL_ERR(requestformat); data->type = (requestformat.typel << 8) | requestformat.typeh; data->status = requestformat.status; if (data->errno != 0) { return data->errno; } return 0; }