diff --git a/Makefile b/Makefile index 525a528..2e96241 100644 --- a/Makefile +++ b/Makefile @@ -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" diff --git a/arm11/link.ld b/arm11/link.ld index a0f3845..3b81b9e 100644 --- a/arm11/link.ld +++ b/arm11/link.ld @@ -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); diff --git a/arm11/source/main.c b/arm11/source/main.c index 3de988b..96283ed 100644 --- a/arm11/source/main.c +++ b/arm11/source/main.c @@ -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); diff --git a/arm11/source/system/sections.h b/arm11/source/system/sections.h index 1a93316..46fb862 100755 --- a/arm11/source/system/sections.h +++ b/arm11/source/system/sections.h @@ -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) diff --git a/arm11/source/system/sys.c b/arm11/source/system/sys.c index ce51239..ff566b1 100755 --- a/arm11/source/system/sys.c +++ b/arm11/source/system/sys.c @@ -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)); diff --git a/arm11/source/system/xalloc.c b/arm11/source/system/xalloc.c deleted file mode 100755 index d075352..0000000 --- a/arm11/source/system/xalloc.c +++ /dev/null @@ -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 . - */ - -// 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; -} diff --git a/arm11/source/system/xalloc.h b/arm11/source/system/xalloc.h deleted file mode 100755 index de80418..0000000 --- a/arm11/source/system/xalloc.h +++ /dev/null @@ -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 . - */ - -#pragma once - -#include "types.h" - -#define XALLOC_BUF_SIZE (16384) - -void *XAlloc(size_t size); diff --git a/arm9/source/common/hid.c b/arm9/source/common/hid.c index 3f18bb5..bc5f12e 100644 --- a/arm9/source/common/hid.c +++ b/arm9/source/common/hid.c @@ -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 diff --git a/arm9/source/system/i2c.c b/arm9/source/system/i2c.c index 6ee1fd4..5a90bc7 100755 --- a/arm9/source/system/i2c.c +++ b/arm9/source/system/i2c.c @@ -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; } diff --git a/arm9/source/system/spiflash.c b/arm9/source/system/spiflash.c index 2f7cb08..6964770 100755 --- a/arm9/source/system/spiflash.c +++ b/arm9/source/system/spiflash.c @@ -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; diff --git a/common/pxi.h b/common/pxi.h index f302fb4..37922d8 100644 --- a/common/pxi.h +++ b/common/pxi.h @@ -39,9 +39,7 @@ enum { PXI_NVRAM_READ, PXI_NOTIFY_LED, - PXI_BRIGHTNESS, - - PXI_XALLOC, + PXI_BRIGHTNESS }; /* diff --git a/common/shmem.h b/common/shmem.h index 1e00929..39b5255 100755 --- a/common/shmem.h +++ b/common/shmem.h @@ -20,19 +20,28 @@ #include +#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 -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)); }