summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpetrie911 <69443847+petrie911@users.noreply.github.com>2021-11-03 17:30:20 -0500
committerGitHub <noreply@github.com>2021-11-03 18:30:20 -0400
commitad4c16d40fa2465b50f207d2fa84f6fac810ac0f (patch)
tree222a3557556642626565b23c0f66fbbf0f19592e /src
parent78153a1bf46e8be1559ea03af6eb1521a1d3bae2 (diff)
osFlash (#158)
* some matches * Decompile code_0x80186A70 Add defines for KSEG0/1 and (Un)Cached RDRAM * format * cleanup * moved osFlash and imported data * implement fixes * format again * Update include/functions.h Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * Update include/variables.h Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * Update src/libultra/flash/osFlash.c Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * Update src/libultra/flash/osFlash.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * returns are needed * format * Update src/libultra/flash/osFlash.c Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * Update src/libultra/flash/osFlash.c Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * Update src/libultra/flash/osFlash.c Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * Update src/libultra/flash/osFlash.c Co-authored-by: Kenix3 <kenixwhisperwind@gmail.com> * Update src/libultra/flash/osFlash.c Co-authored-by: Kenix3 <kenixwhisperwind@gmail.com> * Update src/libultra/flash/osFlash.c Co-authored-by: Kenix3 <kenixwhisperwind@gmail.com> * should be fixed Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain> Co-authored-by: MMDecomp <mmdecomp@gmail.com> Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> Co-authored-by: Kenix3 <kenixwhisperwind@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/code/osFlash.c39
-rw-r--r--src/libultra/flash/osFlash.c325
2 files changed, 325 insertions, 39 deletions
diff --git a/src/code/osFlash.c b/src/code/osFlash.c
deleted file mode 100644
index e661bc9c7..000000000
--- a/src/code/osFlash.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "global.h"
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186A70.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186AB8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B28.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B30.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B38.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B68.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B70.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B78.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186CAC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186D60.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186E64.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186EC8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80187018.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80187080.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80187124.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80187284.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_801872FC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_801873BC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_8018752C.s")
diff --git a/src/libultra/flash/osFlash.c b/src/libultra/flash/osFlash.c
new file mode 100644
index 000000000..bf3044029
--- /dev/null
+++ b/src/libultra/flash/osFlash.c
@@ -0,0 +1,325 @@
+#include "ultra64.h"
+#include "global.h"
+
+static s32 framDeviceInfo[4];
+static OSIoMesg framDeviceInfoQuery;
+static OSMesgQueue __osFlashMessageQ;
+static OSPiHandle __osFlashHandler;
+static OSMesg __osFlashMsgBuf;
+static s32 __osFlashVersion;
+static UNK_TYPE1 D_801FD0FC[0x14];
+
+typedef enum {
+ FLASH_OLD,
+ FLASH_NEW,
+} FlashVersion;
+
+u32 osFlashGetAddr(u32 pageNum) {
+ s32 addr = (__osFlashVersion == FLASH_OLD) ? pageNum << 6 : pageNum << 7;
+
+ return addr;
+}
+
+OSPiHandle* osFlashReInit(u8 latency, u8 pulse, u8 pageSize, u8 relDuration, u32 start) {
+ __osFlashHandler.baseAddress = RDRAM_UNCACHED | start;
+ __osFlashHandler.type++;
+ __osFlashHandler.latency = latency;
+ __osFlashHandler.pulse = pulse;
+ __osFlashHandler.pageSize = pageSize;
+ __osFlashHandler.relDuration = relDuration;
+ __osFlashHandler.domain = 1;
+
+ return &__osFlashHandler;
+}
+
+void osFlashChange(u32 flash_num) {
+ __osFlashHandler.baseAddress = RDRAM_UNCACHED | (FRAM_STATUS_REGISTER + (flash_num << 17));
+ __osFlashHandler.type = 8 + flash_num;
+
+ return;
+}
+
+OSPiHandle* osFlashInit(void) {
+ u32 flashType;
+ u32 flashVendor;
+
+ osCreateMesgQueue(&__osFlashMessageQ, &__osFlashMsgBuf, 1);
+
+ if (__osFlashHandler.baseAddress == (RDRAM_UNCACHED | FRAM_BASE_ADDRESS)) {
+ return &__osFlashHandler;
+ }
+
+ __osFlashHandler.type = 8;
+ __osFlashHandler.baseAddress = (RDRAM_UNCACHED | FRAM_BASE_ADDRESS);
+ __osFlashHandler.latency = 5;
+ __osFlashHandler.pulse = 12;
+ __osFlashHandler.pageSize = 15;
+ __osFlashHandler.relDuration = 2;
+ __osFlashHandler.domain = 1;
+ __osFlashHandler.speed = 0;
+ bzero(&__osFlashHandler.transferInfo, sizeof(__OSTranxInfo));
+
+ osEPiLinkHandle(&__osFlashHandler);
+ osFlashReadId(&flashType, &flashVendor);
+
+ if (flashVendor == 0x00C2001E || flashVendor == 0x00C20001 || flashVendor == 0x00C20000) {
+ __osFlashVersion = FLASH_OLD;
+ } else {
+ __osFlashVersion = FLASH_NEW;
+ }
+
+ return &__osFlashHandler;
+}
+
+void osFlashReadStatus(u8* flashStatus) {
+ u32 outFlashStatus;
+
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_EXECUTE);
+ // read status using IO
+ osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &outFlashStatus);
+
+ // why twice ?
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_EXECUTE);
+ osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &outFlashStatus);
+
+ *flashStatus = outFlashStatus & 0xFF;
+
+ return;
+}
+
+void osFlashReadId(u32* flashType, u32* flashVendor) {
+ u8 flashStatus;
+
+ // why read status?
+ osFlashReadStatus(&flashStatus);
+
+ // select silicon id read mode
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_SET_MODE_STATUS_AND_STATUS);
+
+ // read silicon id using DMA
+ framDeviceInfoQuery.hdr.pri = 0;
+ framDeviceInfoQuery.hdr.retQueue = &__osFlashMessageQ;
+ framDeviceInfoQuery.dramAddr = framDeviceInfo;
+ framDeviceInfoQuery.devAddr = 0;
+ framDeviceInfoQuery.size = 8;
+
+ osInvalDCache(framDeviceInfo, sizeof(framDeviceInfo));
+ osEPiStartDma(&__osFlashHandler, &framDeviceInfoQuery, OS_READ);
+ osRecvMesg(&__osFlashMessageQ, NULL, OS_MESG_BLOCK);
+
+ *flashType = framDeviceInfo[0];
+ *flashVendor = framDeviceInfo[1];
+
+ return;
+}
+
+void osFlashClearStatus(void) {
+ // select status mode
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_EXECUTE);
+ // clear status
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress, 0);
+
+ return;
+}
+
+s32 osFlashAllErase(void) {
+ u32 status;
+ OSTimer timer;
+ OSMesgQueue mq;
+ OSMesg msg;
+
+ // start chip erase operation
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_UNK_ERASE_OPERATION);
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_SET_MODE_ERASE_AND_STATUS);
+
+ // wait for completion by polling erase-busy flag
+ osCreateMesgQueue(&mq, &msg, 1);
+ do {
+ osSetTimer(&timer, OS_USEC_TO_CYCLES(15000), 0, &mq, &msg);
+ osRecvMesg(&mq, &msg, OS_MESG_BLOCK);
+ osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status);
+ } while ((status & 2) == 2);
+
+ // check erase operation status, clear status
+ osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status);
+ osFlashClearStatus();
+
+ if (((status & 0xFF) == 0x08) || ((status & 0xFF) == 0x48) || ((status & 0x08) == 0x08)) {
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+void osFlashAllEraseThrough(void) {
+ // start chip erase operation
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_UNK_ERASE_OPERATION);
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_SET_MODE_ERASE_AND_STATUS);
+}
+
+s32 osFlashCheckEraseEnd(void) {
+ u8 status;
+
+ // check if erase operation is completed
+ osFlashReadStatus(&status);
+ if ((status & 0x02) == 0x02) {
+ return 2; // busy
+ } else {
+ // check erase operation status, clear status
+ osFlashReadStatus(&status);
+ }
+ osFlashClearStatus();
+
+ if (((status & 0xFF) == 0x08) || ((status & 0xFF) == 0x48) || ((status & 0x08) == 0x08)) {
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+s32 osFlashSectorErase(u32 pageNum) {
+ u32 status;
+ OSTimer timer;
+ OSMesgQueue mq;
+ OSMesg msg;
+
+ // start sector erase operation
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_SET_ERASE_SECTOR_OFFSET | pageNum);
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_SET_MODE_ERASE_AND_STATUS);
+
+ // wait for completion by polling erase-busy flag
+ osCreateMesgQueue(&mq, &msg, 1);
+ do {
+ osSetTimer(&timer, OS_USEC_TO_CYCLES(12500), 0, &mq, &msg);
+ osRecvMesg(&mq, &msg, OS_MESG_BLOCK);
+ osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status);
+ } while ((status & 2) == 2);
+
+ // check erase operation status, clear status
+ osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status);
+ osFlashClearStatus();
+
+ if (((status & 0xFF) == 0x08) || ((status & 0xFF) == 0x48) || ((status & 0x08) == 0x08)) {
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+void osFlashSectorEraseThrough(u32 pageNum) {
+ // start sector erase operation
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_SET_ERASE_SECTOR_OFFSET | pageNum);
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_SET_MODE_ERASE_AND_STATUS);
+}
+
+s32 osFlashWriteBuffer(OSIoMesg* mb, s32 priority, void* dramAddr, OSMesgQueue* mq) {
+ s32 ret;
+
+ // select load page mode
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_SET_MODE_WRITE);
+
+ // DMA 128-byte page
+ mb->hdr.pri = priority;
+ mb->hdr.retQueue = mq;
+ mb->dramAddr = dramAddr;
+ mb->devAddr = 0;
+ mb->size = 0x80;
+
+ ret = osEPiStartDma(&__osFlashHandler, mb, OS_WRITE);
+
+ return ret;
+}
+
+s32 osFlashWriteArray(u32 pageNum) {
+ u32 status;
+ OSTimer timer;
+ OSMesgQueue mq;
+ OSMesg msg;
+
+ // only needed for new flash ?
+ if (__osFlashVersion == FLASH_NEW) {
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_SET_MODE_WRITE);
+ }
+
+ // start program page operation
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_SET_ERASE_SECTOR_OFFSET_AND_STATUS | pageNum);
+
+ // wait for completion by polling write-busy flag
+ osCreateMesgQueue(&mq, &msg, 1);
+ do {
+ osSetTimer(&timer, OS_USEC_TO_CYCLES(200), 0, &mq, &msg);
+ osRecvMesg(&mq, &msg, OS_MESG_BLOCK);
+ osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status);
+ } while ((status & 0x01) == 0x01);
+
+ // check program operation status, clear status
+ osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status);
+ osFlashClearStatus();
+
+ if (((status & 0xFF) == 0x04) || ((status & 0xFF) == 0x44) || ((status & 0x04) == 0x04)) {
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+s32 osFlashReadArray(OSIoMesg* mb, s32 priority, u32 pageNum, void* dramAddr, u32 pageCount, OSMesgQueue* mq) {
+ s32 ret;
+ u32 dummy;
+ u32 last_page;
+ u32 pages;
+
+ // select read array mode
+ osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
+ FRAM_COMMAND_SET_MODE_READ_AND_STATUS);
+
+ // dummy read to initiate "fast-page" reads ?
+ osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &dummy);
+
+ // DMA requested pages
+ mb->hdr.pri = priority;
+ mb->hdr.retQueue = mq;
+ mb->dramAddr = dramAddr;
+
+ last_page = pageNum + pageCount - 1;
+
+ if ((last_page & 0xF00) != (pageNum & 0xF00)) {
+
+ pages = 256 - (pageNum & 0xFF);
+ pageCount -= pages;
+ mb->size = pages << 7;
+ mb->devAddr = osFlashGetAddr(pageNum);
+ osEPiStartDma(&__osFlashHandler, mb, OS_READ);
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
+ pageNum = (pageNum + 256) & 0xF00;
+ mb->dramAddr = (void*)((uintptr_t)mb->dramAddr + mb->size);
+ }
+
+ while (pageCount > 256) {
+ pages = 256;
+ pageCount -= 256;
+ mb->size = pages << 7;
+ mb->devAddr = osFlashGetAddr(pageNum);
+ osEPiStartDma(&__osFlashHandler, mb, OS_READ);
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
+ pageNum += 256;
+ mb->dramAddr = (void*)((uintptr_t)mb->dramAddr + mb->size);
+ }
+
+ mb->size = pageCount << 7;
+ mb->devAddr = osFlashGetAddr(pageNum);
+ ret = osEPiStartDma(&__osFlashHandler, mb, OS_READ);
+
+ return ret;
+}