removed the cross allocator, use the shared memory region instead for I2C and NVRAM transfers

This commit is contained in:
Wolfvak 2020-07-19 11:44:03 -03:00
parent 30f0b004c2
commit 5905fb84fb
12 changed files with 77 additions and 161 deletions

View File

@ -20,11 +20,11 @@ VRAM_OUT := $(OUTDIR)/vram0.tar
VRAM_DATA := data
VRAM_FLAGS := --make-new --path-limit 99 --size-limit 3145728
ifeq ($(OS),Windows_NT)
PY3 := py -3
else
#ifeq ($(OS),Windows_NT)
# PY3 := py -3
#else
PY3 := python3
endif
#endif
# Definitions for ARM binaries
export INCLUDE := -I"$(shell pwd)/common"

View File

@ -46,6 +46,15 @@ SECTIONS
__rodata_len = . - __rodata_va;
} >AXIWRAM
.shared (NOLOAD) : ALIGN(4K)
{
__shared_pa = LOADADDR(.shared);
__shared_va = ABSOLUTE(.);
*(.shared*)
. = ALIGN(4K);
__shared_len = . - __shared_va;
} >AXIWRAM
.bss (NOLOAD) : ALIGN(4K)
{
__bss_pa = LOADADDR(.bss);

View File

@ -31,9 +31,6 @@
#include "hw/nvram.h"
#include "system/sys.h"
#include "system/xalloc.h"
static GlobalSharedMemory SharedMemory_State;
#ifndef FIXED_BRIGHTNESS
static const u8 brightness_lvls[] = {
@ -46,6 +43,8 @@ static int prev_bright_lvl = -1;
static bool auto_brightness = true;
#endif
static SystemSHMEM __attribute__((section(".shared"))) SharedMemoryState;
void VBlank_Handler(u32 __attribute__((unused)) irqn)
{
#ifndef FIXED_BRIGHTNESS
@ -57,12 +56,7 @@ void VBlank_Handler(u32 __attribute__((unused)) irqn)
}
#endif
// the state should probably be stored on its own
// section without caching enabled, since it must
// be readable by the ARM9 at all times anyway
SharedMemory_State.hid_state = HID_GetState();
ARM_WbDC_Range(&SharedMemory_State, sizeof(SharedMemory_State));
ARM_DMB();
SharedMemoryState.hidState.full = HID_GetState();
}
static bool legacy_boot = false;
@ -93,32 +87,38 @@ void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
case PXI_GET_SHMEM:
{
ret = (u32)&SharedMemory_State;
ret = (u32)&SharedMemoryState;
break;
}
case PXI_SET_VMODE:
{
int mode = args[0] ? GFX_BGR8 : GFX_RGB565;
GFX_init(mode);
GFX_init(args[0] ? GFX_BGR8 : GFX_RGB565);
ret = 0;
break;
}
case PXI_I2C_READ:
{
ARM_InvDC_Range((void*)args[2], args[3]);
ret = I2C_readRegBuf(args[0], args[1], (u8*)args[2], args[3]);
ARM_WbDC_Range((void*)args[2], args[3]);
ARM_DMB();
u32 devId, regAddr, size;
devId = (args[0] & 0xff);
regAddr = (args[0] >> 8) & 0xff;
size = (args[0] >> 16) % I2C_SHARED_BUFSZ;
ret = I2C_readRegBuf(devId, regAddr, SharedMemoryState.i2cBuffer, size);
break;
}
case PXI_I2C_WRITE:
{
ARM_InvDC_Range((void*)args[2], args[3]);
ARM_DMB();
ret = I2C_writeRegBuf(args[0], args[1], (u8*)args[2], args[3]);
u32 devId, regAddr, size;
devId = (args[0] & 0xff);
regAddr = (args[0] >> 8) & 0xff;
size = (args[0] >> 16) % I2C_SHARED_BUFSZ;
ret = I2C_writeRegBuf(devId, regAddr, SharedMemoryState.i2cBuffer, size);
break;
}
@ -130,10 +130,7 @@ void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
case PXI_NVRAM_READ:
{
ARM_InvDC_Range((void*)args[1], args[2]);
NVRAM_Read(args[0], (u32*)args[1], args[2]);
ARM_WbDC_Range((void*)args[1], args[2]);
ARM_DMB();
NVRAM_Read(args[0], (u32*)SharedMemoryState.spiBuffer, args[1]);
ret = 0;
break;
}
@ -161,12 +158,6 @@ void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
break;
}
case PXI_XALLOC:
{
ret = (u32)XAlloc(args[0]);
break;
}
/* New CMD template:
case CMD_ID:
{
@ -185,14 +176,15 @@ void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
PXI_Send(ret);
}
extern u32 pdcerr;
void __attribute__((noreturn)) MainLoop(void)
{
#ifdef FIXED_BRIGHTNESS
LCD_SetBrightness(FIXED_BRIGHTNESS);
#endif
// clear up the shared memory section
memset(&SharedMemoryState, 0, sizeof(SharedMemoryState));
// enable PXI RX interrupt
GIC_Enable(PXI_RX_INTERRUPT, BIT(0), GIC_HIGHEST_PRIO + 2, PXI_RX_Handler);

View File

@ -26,6 +26,7 @@ DEF_SECT_(text)
DEF_SECT_(data)
DEF_SECT_(rodata)
DEF_SECT_(bss)
DEF_SECT_(shared)
#undef DEF_SECT_
#define SECTION_VA(n) ((u32)&__##n##_va)

View File

@ -82,6 +82,7 @@ void SYS_CoreZeroInit(void)
MMU_Map(SECTION_TRI(data), MMU_FLAGS(CACHED_WB_ALLOC, READ_WRITE, 1, 1));
MMU_Map(SECTION_TRI(rodata), MMU_FLAGS(CACHED_WT, READ_ONLY, 1, 1));
MMU_Map(SECTION_TRI(bss), MMU_FLAGS(CACHED_WB_ALLOC, READ_WRITE, 1, 1));
MMU_Map(SECTION_TRI(shared), MMU_FLAGS(STRONGLY_ORDERED, READ_WRITE, 1, 1));
// IO Registers
MMU_Map(0x10100000, 0x10100000, 4UL << 20, MMU_FLAGS(DEVICE_SHARED, READ_WRITE, 1, 1));

View File

@ -1,37 +0,0 @@
/*
* This file is part of GodMode9
* Copyright (C) 2019 Wolfvak
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// super simple watermark allocator for ARM9 <-> ARM11 xfers
// designed to be request once, free never
#include "system/xalloc.h"
static char ALIGN(4096) xalloc_buf[XALLOC_BUF_SIZE];
static size_t mark = 0;
void *XAlloc(size_t size)
{ // not thread-safe at all
void *ret;
size_t end = size + mark;
if (end >= XALLOC_BUF_SIZE)
return NULL;
ret = &xalloc_buf[mark];
mark = end;
return ret;
}

View File

@ -1,25 +0,0 @@
/*
* This file is part of GodMode9
* Copyright (C) 2019 Wolfvak
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "types.h"
#define XALLOC_BUF_SIZE (16384)
void *XAlloc(size_t size);

View File

@ -27,12 +27,12 @@ static void SetNotificationLED(u32 period_ms, u32 rgb565_color)
// separate things - hopefully LTO won't get in the way
u32 HID_ReadState(void)
{
return ARM_GetSHMEM()->hid_state;
return ARM_GetSHMEM()->hidState.keys;
}
u32 HID_ReadRawTouchState(void)
{
return ARM_GetSHMEM()->hid_state >> 32;
return ARM_GetSHMEM()->hidState.touch;
}
// ts_mult indicates a scalar for each axis

View File

@ -3,65 +3,44 @@
#include "i2c.h"
#include "pxi.h"
// buffer is allocated only once and remains through runtime
static char *i2c_xfer_buf = NULL;
static bool I2C_AllocBuffer(void)
{
if (!i2c_xfer_buf) {
u32 xbuf = PXI_DoCMD(PXI_XALLOC, (u32[]){256}, 1);
if (xbuf == 0 || xbuf == 0xFFFFFFFF)
return false;
i2c_xfer_buf = (char*)xbuf;
}
return true;
}
#include "shmem.h"
bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size)
{
int ret;
u32 *args;
const u32 arg = devId | (regAddr << 8) | (size << 16);
if (!I2C_AllocBuffer())
if (size >= I2C_SHARED_BUFSZ)
return false;
args = (u32[]){devId, regAddr, (u32)i2c_xfer_buf, size};
ret = PXI_DoCMD(PXI_I2C_READ, &arg, 1);
ARM_WbDC_Range(i2c_xfer_buf, size);
ARM_DSB();
ret = PXI_DoCMD(PXI_I2C_READ, args, 4);
ARM_InvDC_Range(i2c_xfer_buf, size);
memcpy(out, i2c_xfer_buf, size);
ARM_InvDC_Range(ARM_GetSHMEM()->i2cBuffer, size);
memcpy(out, ARM_GetSHMEM()->i2cBuffer, size);
return ret;
}
bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size)
{
int ret;
u32 *args;
const u32 arg = devId | (regAddr << 8) | (size << 16);
if (!I2C_AllocBuffer())
if (size >= I2C_SHARED_BUFSZ)
return false;
args = (u32[]){devId, regAddr, (u32)i2c_xfer_buf, size};
memcpy(i2c_xfer_buf, in, size);
ARM_WbDC_Range(i2c_xfer_buf, size);
ARM_InvDC_Range(ARM_GetSHMEM()->i2cBuffer, size);
memcpy(ARM_GetSHMEM()->i2cBuffer, in, size);
ARM_WbDC_Range(ARM_GetSHMEM()->i2cBuffer, size);
ARM_DSB();
ret = PXI_DoCMD(PXI_I2C_WRITE, args, 4);
ret = PXI_DoCMD(PXI_I2C_WRITE, &arg, 1);
return ret;
}
u8 I2C_readReg(I2cDevice devId, u8 regAddr)
{
u8 data;
if (!I2C_readRegBuf(devId, regAddr, &data, 1))
data = 0xFF;
u8 data = 0xFF;
I2C_readRegBuf(devId, regAddr, &data, 1);
return data;
}

View File

@ -1,10 +1,7 @@
#include "common.h"
#include "arm.h"
#include "pxi.h"
#define SPIFLASH_CHUNK_SIZE (0x1000)
static char *spiflash_xfer_buf = NULL;
#include "shmem.h"
bool spiflash_get_status(void)
{
@ -13,27 +10,19 @@ bool spiflash_get_status(void)
bool spiflash_read(u32 offset, u32 size, u8 *buf)
{
u32 args[3];
if (!spiflash_xfer_buf) {
u32 xbuf = PXI_DoCMD(PXI_XALLOC, (u32[]){SPIFLASH_CHUNK_SIZE}, 1);
if (xbuf == 0 || xbuf == 0xFFFFFFFF)
return false;
spiflash_xfer_buf = (char*)xbuf;
}
args[1] = (u32)spiflash_xfer_buf;
u32 args[2];
while(size > 0) {
u32 blksz = min(size, SPIFLASH_CHUNK_SIZE);
u32 blksz = min(size, SPI_SHARED_BUFSZ);
args[0] = offset;
args[2] = blksz;
args[1] = blksz;
ARM_WbDC_Range(ARM_GetSHMEM()->spiBuffer, blksz);
PXI_DoCMD(PXI_NVRAM_READ, args, 2);
ARM_InvDC_Range(ARM_GetSHMEM()->spiBuffer, blksz);
ARM_DSB();
PXI_DoCMD(PXI_NVRAM_READ, args, 3);
ARM_InvDC_Range(spiflash_xfer_buf, blksz);
memcpy(buf, spiflash_xfer_buf, blksz);
memcpy(buf, ARM_GetSHMEM()->spiBuffer, blksz);
buf += blksz;
size -= blksz;

View File

@ -39,9 +39,7 @@ enum {
PXI_NVRAM_READ,
PXI_NOTIFY_LED,
PXI_BRIGHTNESS,
PXI_XALLOC,
PXI_BRIGHTNESS
};
/*

View File

@ -20,19 +20,28 @@
#include <arm.h>
#define I2C_SHARED_BUFSZ 1024
#define SPI_SHARED_BUFSZ 1024
typedef struct {
u64 hid_state;
} GlobalSharedMemory;
union {
struct { u32 keys, touch; };
u64 full;
} hidState;
u8 i2cBuffer[I2C_SHARED_BUFSZ];
u32 spiBuffer[SPI_SHARED_BUFSZ/4];
} __attribute__((packed, aligned(8))) SystemSHMEM;
#ifdef ARM9
#include <pxi.h>
static inline const GlobalSharedMemory *ARM_GetSHMEM(void)
static inline SystemSHMEM *ARM_GetSHMEM(void)
{
return (const GlobalSharedMemory*)ARM_GetTID();
return (SystemSHMEM*)ARM_GetTID();
}
static void ARM_InitSHMEM(void)
static inline void ARM_InitSHMEM(void)
{
ARM_SetTID(PXI_DoCMD(PXI_GET_SHMEM, NULL, 0));
}