simplify the sharedmem buffers

also made the wait on boot unconditional
This commit is contained in:
Wolfvak 2020-11-17 20:14:44 -03:00 committed by d0k3
parent 9ecb90a2ba
commit eadc1ab6b9
5 changed files with 56 additions and 44 deletions

View File

@ -85,26 +85,24 @@ static void pxiRxHandler(u32 __attribute__((unused)) irqn)
atomic_store(&pendingPxiRx, 1);
}
static void pxiRxUpdate(u32 *cmd, u32 *args)
static u32 pxiRxUpdate(u32 *args)
{
u32 msg, lo, hi;
*cmd = PXICMD_NONE;
if (!atomic_exchange(&pendingPxiRx, 0))
return;
return PXICMD_NONE;
msg = PXI_Recv();
lo = msg & 0xFFFF;
hi = msg >> 16;
*cmd = lo;
PXI_RecvArray(args, hi);
return lo;
}
void __attribute__((noreturn)) MainLoop(void)
{
bool runCmdProcessor = true;
bool runPxiCmdProcessor = true;
#ifdef FIXED_BRIGHTNESS
u8 fixed_bright_lvl = brightness_lvls[clamp(FIXED_BRIGHTNESS, 0, countof(brightness_lvls)-1)];
@ -139,61 +137,70 @@ void __attribute__((noreturn)) MainLoop(void)
// Process commands until the ARM9 tells
// us it's time to boot something else
// also handles Vblank events as needed
// also handles VBlank events as needed
do {
u32 cmd, resp, args[PXI_MAX_ARGS];
u32 pxiCmd, pxiReply, args[PXI_MAX_ARGS];
vblankUpdate();
pxiRxUpdate(&cmd, args);
pxiCmd = pxiRxUpdate(args);
switch(cmd) {
switch(pxiCmd) {
// ignore args and just wait until the next event
case PXICMD_NONE:
ARM_WFI();
break;
// revert to legacy boot mode
case PXICMD_LEGACY_BOOT:
runCmdProcessor = false;
resp = 0;
runPxiCmdProcessor = false;
pxiReply = 0;
break;
// returns the shared memory address
case PXICMD_GET_SHMEM_ADDRESS:
resp = (u32)&sharedMem;
pxiReply = (u32)&sharedMem;
break;
// takes in a single argument word and performs either an
// I2C read or write depending on the value of the top bit
case PXICMD_I2C_OP:
{
u32 devId, regAddr, size;
devId = (args[0] & 0xff);
regAddr = (args[0] >> 8) & 0xff;
size = (args[0] >> 16) % I2C_SHARED_BUFSZ;
regAddr = (args[0] >> 8) & 0xFF;
size = (args[0] >> 16) % SHMEM_BUFFER_SIZE;
if (args[0] & BIT(31)) {
resp = I2C_writeRegBuf(devId, regAddr, sharedMem.i2cBuffer, size);
pxiReply = I2C_writeRegBuf(devId, regAddr, sharedMem.dataBuffer.b, size);
} else {
resp = I2C_readRegBuf(devId, regAddr, sharedMem.i2cBuffer, size);
pxiReply = I2C_readRegBuf(devId, regAddr, sharedMem.dataBuffer.b, size);
}
break;
}
// checks whether the NVRAM chip is online (not doing any work)
case PXICMD_NVRAM_ONLINE:
resp = (NVRAM_Status() & NVRAM_SR_WIP) == 0;
pxiReply = (NVRAM_Status() & NVRAM_SR_WIP) == 0;
break;
// reads data from the NVRAM chip
case PXICMD_NVRAM_READ:
NVRAM_Read(args[0], (u32*)sharedMem.spiBuffer, args[1]);
resp = 0;
NVRAM_Read(args[0], sharedMem.dataBuffer.w, args[1]);
pxiReply = 0;
break;
// sets the notification LED with the given color and period
case PXICMD_SET_NOTIFY_LED:
mcuSetStatusLED(args[0], args[1]);
resp = 0;
pxiReply = 0;
break;
// sets the LCDs brightness (if FIXED_BRIGHTNESS is disabled)
case PXICMD_SET_BRIGHTNESS:
{
s32 newbrightness = (s32)args[0];
resp = GFX_getBrightness();
pxiReply = GFX_getBrightness();
#ifndef FIXED_BRIGHTNESS
if ((newbrightness > 0) && (newbrightness < 0x100)) {
GFX_setBrightness(newbrightness, newbrightness);
@ -206,14 +213,15 @@ void __attribute__((noreturn)) MainLoop(void)
break;
}
// replies -1 on default
default:
resp = 0xFFFFFFFF;
pxiReply = 0xFFFFFFFF;
break;
}
if (cmd != PXICMD_NONE)
PXI_Send(resp); // was a command sent from the ARM9, send a response
} while(runCmdProcessor);
if (pxiCmd != PXICMD_NONE)
PXI_Send(pxiReply); // was a command sent from the ARM9, send a response
} while(runPxiCmdProcessor);
// perform deinit in reverse order
gicDisableInterrupt(VBLANK_INTERRUPT);

View File

@ -107,9 +107,8 @@ void SYS_CoreZeroInit(void)
mmuMapArea(0x20000000, 0x20000000, 128UL << 20, MMU_FLAGS(MMU_CACHE_WB, MMU_READ_WRITE, 1, 1));
}
if (SYS_IsNewConsole()) {
TIMER_WaitMS(150);
}
// screen init magicks
TIMER_WaitMS(64);
// Initialize peripherals
PXI_Reset();

View File

@ -8,29 +8,30 @@
bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size)
{
int ret;
u8 *const dataBuffer = ARM_GetSHMEM()->dataBuffer.b;
const u32 arg = devId | (regAddr << 8) | (size << 16);
if (size >= I2C_SHARED_BUFSZ)
if (size >= SHMEM_BUFFER_SIZE)
return false;
ret = PXI_DoCMD(PXICMD_I2C_OP, &arg, 1);
ARM_InvDC_Range(dataBuffer, size);
ARM_InvDC_Range(ARM_GetSHMEM()->i2cBuffer, size);
memcpy(out, ARM_GetSHMEM()->i2cBuffer, size);
memcpy(out, dataBuffer, size);
return ret;
}
bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size)
{
int ret;
u8 *const dataBuffer = ARM_GetSHMEM()->dataBuffer.b;
const u32 arg = devId | (regAddr << 8) | (size << 16) | BIT(31);
if (size >= I2C_SHARED_BUFSZ)
if (size >= SHMEM_BUFFER_SIZE)
return false;
ARM_InvDC_Range(ARM_GetSHMEM()->i2cBuffer, size);
memcpy(ARM_GetSHMEM()->i2cBuffer, in, size);
ARM_WbDC_Range(ARM_GetSHMEM()->i2cBuffer, size);
memcpy(dataBuffer, in, size);
ARM_WbDC_Range(dataBuffer, size);
ARM_DSB();
ret = PXI_DoCMD(PXICMD_I2C_OP, &arg, 1);

View File

@ -10,19 +10,20 @@ bool spiflash_get_status(void)
bool spiflash_read(u32 offset, u32 size, u8 *buf)
{
u32 *const dataBuffer = ARM_GetSHMEM()->dataBuffer.w;
u32 args[2];
while(size > 0) {
u32 blksz = min(size, SPI_SHARED_BUFSZ);
u32 blksz = min(size, SHMEM_BUFFER_SIZE);
args[0] = offset;
args[1] = blksz;
ARM_WbDC_Range(ARM_GetSHMEM()->spiBuffer, blksz);
PXI_DoCMD(PXICMD_NVRAM_READ, args, 2);
ARM_InvDC_Range(ARM_GetSHMEM()->spiBuffer, blksz);
ARM_InvDC_Range(dataBuffer, blksz);
ARM_DSB();
memcpy(buf, ARM_GetSHMEM()->spiBuffer, blksz);
memcpy(buf, dataBuffer, blksz);
buf += blksz;
size -= blksz;

View File

@ -20,8 +20,7 @@
#include <arm.h>
#define I2C_SHARED_BUFSZ 1024
#define SPI_SHARED_BUFSZ 1024
#define SHMEM_BUFFER_SIZE 2048
typedef struct {
union {
@ -29,8 +28,12 @@ typedef struct {
u64 full;
} hidState;
u8 i2cBuffer[I2C_SHARED_BUFSZ];
u32 spiBuffer[SPI_SHARED_BUFSZ/4];
union {
uint8_t b[SHMEM_BUFFER_SIZE];
uint16_t s[SHMEM_BUFFER_SIZE / 2];
uint32_t w[SHMEM_BUFFER_SIZE / 4];
uint64_t q[SHMEM_BUFFER_SIZE / 8];
} dataBuffer;
} __attribute__((packed, aligned(8))) SystemSHMEM;
#ifdef ARM9