Flash Headers (#1367)

* Move flash stuff

* format

* Cleanup

* format

* bss names

* Small cleanup

* osFlashGetAddr

* uintptr_t
This commit is contained in:
Derek Hensley
2023-09-15 05:41:51 -07:00
committed by GitHub
parent 57501ed415
commit 626f09266d
7 changed files with 160 additions and 151 deletions
+9 -7
View File
@@ -5,6 +5,8 @@
#include "stackcheck.h"
#include "system_malloc.h"
#include "z64thread.h"
#include "sys_flashrom.h"
#include "PR/os_internal_flash.h"
OSMesgQueue sFlashromMesgQueue;
OSMesg sFlashromMesg[1];
@@ -81,7 +83,7 @@ s32 SysFlashrom_ReadData(void* addr, u32 pageNum, u32 pageCount) {
if (!SysFlashrom_IsInit()) {
return -1;
}
osInvalDCache(addr, pageCount * FLASH_PAGE_SIZE);
osInvalDCache(addr, pageCount * FLASH_BLOCK_SIZE);
osFlashReadArray(&msg, OS_MESG_PRI_NORMAL, pageNum, addr, pageCount, &sFlashromMesgQueue);
osRecvMesg(&sFlashromMesgQueue, NULL, OS_MESG_BLOCK);
return 0;
@@ -103,12 +105,12 @@ s32 SysFlashrom_ExecWrite(void* addr, u32 pageNum, u32 pageCount) {
return -1;
}
// Ensure the page is always aligned to a sector boundary.
if ((pageNum % FLASH_PAGE_SIZE) != 0) {
if ((pageNum % FLASH_BLOCK_SIZE) != 0) {
Fault_AddHungupAndCrash("../sys_flashrom.c", 275);
}
osWritebackDCache(addr, pageCount * FLASH_PAGE_SIZE);
osWritebackDCache(addr, pageCount * FLASH_BLOCK_SIZE);
for (i = 0; i < pageCount; i++) {
osFlashWriteBuffer(&msg, OS_MESG_PRI_NORMAL, (u8*)addr + i * FLASH_PAGE_SIZE, &sFlashromMesgQueue);
osFlashWriteBuffer(&msg, OS_MESG_PRI_NORMAL, (u8*)addr + i * FLASH_BLOCK_SIZE, &sFlashromMesgQueue);
osRecvMesg(&sFlashromMesgQueue, NULL, OS_MESG_BLOCK);
result = osFlashWriteArray(i + pageNum);
if (result != 0) {
@@ -125,7 +127,7 @@ s32 SysFlashrom_AttemptWrite(void* addr, u32 pageNum, u32 pageCount) {
if (!SysFlashrom_IsInit()) {
return -1;
}
osWritebackDCache(addr, pageCount * FLASH_PAGE_SIZE);
osWritebackDCache(addr, pageCount * FLASH_BLOCK_SIZE);
i = 0;
failRetry:
result = SysFlashrom_EraseSector(pageNum);
@@ -153,7 +155,7 @@ s32 SysFlashrom_NeedsToErase(void* data, void* addr, u32 pageCount) {
u32 size;
u32 i;
for (i = 0; i < pageCount * FLASH_PAGE_SIZE; i += 4) {
for (i = 0; i < pageCount * FLASH_BLOCK_SIZE; i += 4) {
if ((*(s32*)data & *(s32*)addr) != *(s32*)addr) {
return false;
}
@@ -169,7 +171,7 @@ s32 SysFlashrom_WriteData(void* addr, u32 pageNum, u32 pageCount) {
if (!SysFlashrom_IsInit()) {
return -1;
}
size = pageCount * FLASH_PAGE_SIZE;
size = pageCount * FLASH_BLOCK_SIZE;
data = SystemArena_Malloc(size);
if (data == NULL) {
ret = SysFlashrom_AttemptWrite(addr, pageNum, pageCount);
+69 -83
View File
@@ -1,41 +1,38 @@
#include "prevent_bss_reordering.h"
#include "ultra64.h"
#include "global.h"
#include "PR/os_internal_flash.h"
s32 framDeviceInfo[4];
OSIoMesg framDeviceInfoQuery;
u32 __osFlashID[4];
OSIoMesg __osFlashMsg;
OSMesgQueue __osFlashMessageQ;
OSPiHandle __osFlashHandler;
OSMesg __osFlashMsgBuf;
OSMesg __osFlashMsgBuf[1];
s32 __osFlashVersion;
UNK_TYPE1 D_801FD0FC[0x14];
static s32 sBssPad[5];
typedef enum {
/* 0 */ FLASH_OLD,
/* 1 */ FLASH_NEW
} FlashVersion;
u32 osFlashGetAddr(u32 pageNum) {
s32 addr = (__osFlashVersion == FLASH_OLD) ? pageNum << 6 : pageNum << 7;
uintptr_t osFlashGetAddr(u32 pageNum) {
// Account for hadware bug in old flash where the address bits are shifted 1-off where they should be
uintptr_t addr = (__osFlashVersion == OLD_FLASH) ? pageNum * (FLASH_BLOCK_SIZE >> 1) : pageNum * FLASH_BLOCK_SIZE;
return addr;
}
OSPiHandle* osFlashReInit(u8 latency, u8 pulse, u8 pageSize, u8 relDuration, u32 start) {
__osFlashHandler.baseAddress = RDRAM_UNCACHED | start;
__osFlashHandler.baseAddress = PHYS_TO_K1(start);
__osFlashHandler.type++;
__osFlashHandler.latency = latency;
__osFlashHandler.pulse = pulse;
__osFlashHandler.pageSize = pageSize;
__osFlashHandler.relDuration = relDuration;
__osFlashHandler.domain = 1;
__osFlashHandler.domain = PI_DOMAIN2;
return &__osFlashHandler;
}
void osFlashChange(u32 flashNum) {
__osFlashHandler.baseAddress = RDRAM_UNCACHED | (FRAM_STATUS_REGISTER + (flashNum << 17));
__osFlashHandler.type = 8 + flashNum;
__osFlashHandler.baseAddress = PHYS_TO_K1(FLASH_START_ADDR + (flashNum * FLASH_SIZE));
__osFlashHandler.type = DEVICE_TYPE_FLASH + flashNum;
return;
}
@@ -44,29 +41,31 @@ OSPiHandle* osFlashInit(void) {
u32 flashType;
u32 flashVendor;
osCreateMesgQueue(&__osFlashMessageQ, &__osFlashMsgBuf, 1);
osCreateMesgQueue(&__osFlashMessageQ, __osFlashMsgBuf, ARRAY_COUNT(__osFlashMsgBuf));
if (__osFlashHandler.baseAddress == (RDRAM_UNCACHED | FRAM_BASE_ADDRESS)) {
if (__osFlashHandler.baseAddress == PHYS_TO_K1(FLASH_START_ADDR)) {
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.type = DEVICE_TYPE_FLASH;
__osFlashHandler.baseAddress = PHYS_TO_K1(FLASH_START_ADDR);
__osFlashHandler.latency = FLASH_LATENCY;
__osFlashHandler.pulse = FLASH_PULSE;
__osFlashHandler.pageSize = FLASH_PAGE_SIZE;
__osFlashHandler.relDuration = FLASH_REL_DURATION;
__osFlashHandler.domain = PI_DOMAIN2;
__osFlashHandler.speed = 0;
bzero(&__osFlashHandler.transferInfo, sizeof(__OSTranxInfo));
osEPiLinkHandle(&__osFlashHandler);
osFlashReadId(&flashType, &flashVendor);
if (flashVendor == 0x00C2001E || flashVendor == 0x00C20001 || flashVendor == 0x00C20000) {
__osFlashVersion = FLASH_OLD;
if ((flashVendor == FLASH_VERSION_MX_C) || (flashVendor == FLASH_VERSION_MX_A) ||
(flashVendor == FLASH_VERSION_MX_PROTO_A)) {
__osFlashVersion = OLD_FLASH;
} else {
__osFlashVersion = FLASH_NEW;
__osFlashVersion = NEW_FLASH;
}
return &__osFlashHandler;
@@ -75,12 +74,12 @@ OSPiHandle* osFlashInit(void) {
void osFlashReadStatus(u8* flashStatus) {
u32 outFlashStatus;
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_EXECUTE);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_STATUS);
// read status using IO
osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &outFlashStatus);
// why twice ?
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_EXECUTE);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_STATUS);
osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &outFlashStatus);
*flashStatus = outFlashStatus & 0xFF;
@@ -95,29 +94,28 @@ void osFlashReadId(u32* flashType, u32* flashVendor) {
osFlashReadStatus(&flashStatus);
// select silicon id read mode
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
FRAM_COMMAND_SET_MODE_STATUS_AND_STATUS);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_ID);
// read silicon id using DMA
framDeviceInfoQuery.hdr.pri = 0;
framDeviceInfoQuery.hdr.retQueue = &__osFlashMessageQ;
framDeviceInfoQuery.dramAddr = framDeviceInfo;
framDeviceInfoQuery.devAddr = 0;
framDeviceInfoQuery.size = 8;
__osFlashMsg.hdr.pri = OS_MESG_PRI_NORMAL;
__osFlashMsg.hdr.retQueue = &__osFlashMessageQ;
__osFlashMsg.dramAddr = __osFlashID;
__osFlashMsg.devAddr = 0;
__osFlashMsg.size = 2 * sizeof(u32);
osInvalDCache(framDeviceInfo, sizeof(framDeviceInfo));
osEPiStartDma(&__osFlashHandler, &framDeviceInfoQuery, OS_READ);
osInvalDCache(__osFlashID, sizeof(__osFlashID));
osEPiStartDma(&__osFlashHandler, &__osFlashMsg, OS_READ);
osRecvMesg(&__osFlashMessageQ, NULL, OS_MESG_BLOCK);
*flashType = framDeviceInfo[0];
*flashVendor = framDeviceInfo[1];
*flashType = __osFlashID[0];
*flashVendor = __osFlashID[1];
return;
}
void osFlashClearStatus(void) {
// select status mode
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_EXECUTE);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_STATUS);
// clear status
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress, 0);
@@ -131,10 +129,8 @@ s32 osFlashAllErase(void) {
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);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_CHIP_ERASE);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_EXECUTE_ERASE);
// wait for completion by polling erase-busy flag
osCreateMesgQueue(&mq, &msg, 1);
@@ -142,25 +138,23 @@ s32 osFlashAllErase(void) {
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);
} while ((status & FLASH_STATUS_ERASE_BUSY) == FLASH_STATUS_ERASE_BUSY);
// check erase operation status, clear status
osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status);
osFlashClearStatus();
if (((status & 0xFF) == 0x08) || ((status & 0xFF) == 0x48) || ((status & 0x08) == 0x08)) {
return 0;
return FLASH_STATUS_ERASE_OK;
} else {
return -1;
return FLASH_STATUS_ERASE_ERROR;
}
}
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);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_CHIP_ERASE);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_EXECUTE_ERASE);
}
s32 osFlashCheckEraseEnd(void) {
@@ -168,8 +162,8 @@ s32 osFlashCheckEraseEnd(void) {
// check if erase operation is completed
osFlashReadStatus(&status);
if ((status & 0x02) == 0x02) {
return 2; // busy
if ((status & FLASH_STATUS_ERASE_BUSY) == FLASH_STATUS_ERASE_BUSY) {
return FLASH_STATUS_ERASE_BUSY;
} else {
// check erase operation status, clear status
osFlashReadStatus(&status);
@@ -177,9 +171,9 @@ s32 osFlashCheckEraseEnd(void) {
osFlashClearStatus();
if (((status & 0xFF) == 0x08) || ((status & 0xFF) == 0x48) || ((status & 0x08) == 0x08)) {
return 0;
return FLASH_STATUS_ERASE_OK;
} else {
return -1;
return FLASH_STATUS_ERASE_ERROR;
}
}
@@ -190,10 +184,8 @@ s32 osFlashSectorErase(u32 pageNum) {
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);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_SECTOR_ERASE | pageNum);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_EXECUTE_ERASE);
// wait for completion by polling erase-busy flag
osCreateMesgQueue(&mq, &msg, 1);
@@ -201,39 +193,37 @@ s32 osFlashSectorErase(u32 pageNum) {
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);
} while ((status & FLASH_STATUS_ERASE_BUSY) == FLASH_STATUS_ERASE_BUSY);
// check erase operation status, clear status
osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status);
osFlashClearStatus();
if (((status & 0xFF) == 0x08) || ((status & 0xFF) == 0x48) || ((status & 0x08) == 0x08)) {
return 0;
return FLASH_STATUS_ERASE_OK;
} else {
return -1;
return FLASH_STATUS_ERASE_ERROR;
}
}
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);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_SECTOR_ERASE | pageNum);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_EXECUTE_ERASE);
}
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);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_PAGE_PROGRAM);
// DMA 128-byte page
mb->hdr.pri = priority;
mb->hdr.retQueue = mq;
mb->dramAddr = dramAddr;
mb->devAddr = 0;
mb->size = 0x80;
mb->size = FLASH_BLOCK_SIZE;
ret = osEPiStartDma(&__osFlashHandler, mb, OS_WRITE);
@@ -247,14 +237,12 @@ s32 osFlashWriteArray(u32 pageNum) {
OSMesg msg;
// only needed for new flash ?
if (__osFlashVersion == FLASH_NEW) {
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
FRAM_COMMAND_SET_MODE_WRITE);
if (__osFlashVersion == NEW_FLASH) {
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_PAGE_PROGRAM);
}
// start program page operation
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
FRAM_COMMAND_SET_ERASE_SECTOR_OFFSET_AND_STATUS | pageNum);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_PROGRAM_PAGE | pageNum);
// wait for completion by polling write-busy flag
osCreateMesgQueue(&mq, &msg, 1);
@@ -262,16 +250,16 @@ s32 osFlashWriteArray(u32 pageNum) {
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);
} while ((status & FLASH_STATUS_WRITE_BUSY) == FLASH_STATUS_WRITE_BUSY);
// check program operation status, clear status
osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status);
osFlashClearStatus();
if (((status & 0xFF) == 0x04) || ((status & 0xFF) == 0x44) || ((status & 0x04) == 0x04)) {
return 0;
return FLASH_STATUS_WRITE_OK;
} else {
return -1;
return FLASH_STATUS_WRITE_ERROR;
}
}
@@ -282,8 +270,7 @@ s32 osFlashReadArray(OSIoMesg* mb, s32 priority, u32 pageNum, void* dramAddr, u3
u32 pages;
// select read array mode
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER,
FRAM_COMMAND_SET_MODE_READ_AND_STATUS);
osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FLASH_CMD_REG, FLASH_CMD_READ_ARRAY);
// dummy read to initiate "fast-page" reads ?
osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &dummy);
@@ -296,10 +283,9 @@ s32 osFlashReadArray(OSIoMesg* mb, s32 priority, u32 pageNum, void* dramAddr, u3
last_page = pageNum + pageCount - 1;
if ((last_page & 0xF00) != (pageNum & 0xF00)) {
pages = 256 - (pageNum & 0xFF);
pageCount -= pages;
mb->size = pages << 7;
mb->size = pages * FLASH_BLOCK_SIZE;
mb->devAddr = osFlashGetAddr(pageNum);
osEPiStartDma(&__osFlashHandler, mb, OS_READ);
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
@@ -310,7 +296,7 @@ s32 osFlashReadArray(OSIoMesg* mb, s32 priority, u32 pageNum, void* dramAddr, u3
while (pageCount > 256) {
pages = 256;
pageCount -= 256;
mb->size = pages << 7;
mb->size = pages * FLASH_BLOCK_SIZE;
mb->devAddr = osFlashGetAddr(pageNum);
osEPiStartDma(&__osFlashHandler, mb, OS_READ);
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
@@ -318,7 +304,7 @@ s32 osFlashReadArray(OSIoMesg* mb, s32 priority, u32 pageNum, void* dramAddr, u3
mb->dramAddr = (void*)((uintptr_t)mb->dramAddr + mb->size);
}
mb->size = pageCount << 7;
mb->size = pageCount * FLASH_BLOCK_SIZE;
mb->devAddr = osFlashGetAddr(pageNum);
ret = osEPiStartDma(&__osFlashHandler, mb, OS_READ);