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));
}