diff options
| author | petrie911 <69443847+petrie911@users.noreply.github.com> | 2021-11-03 17:30:20 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-03 18:30:20 -0400 |
| commit | ad4c16d40fa2465b50f207d2fa84f6fac810ac0f (patch) | |
| tree | 222a3557556642626565b23c0f66fbbf0f19592e /src | |
| parent | 78153a1bf46e8be1559ea03af6eb1521a1d3bae2 (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.c | 39 | ||||
| -rw-r--r-- | src/libultra/flash/osFlash.c | 325 |
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; +} |
