mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
fix broken cross-buffer assumption, check nvram reads
This commit is contained in:
parent
1a0fe17b6c
commit
2ef408f4af
@ -4,7 +4,7 @@ ENTRY(__boot)
|
|||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
AXIWRAM (RWX) : ORIGIN = 0x1FF80000, LENGTH = 96K
|
AXIWRAM (RWX) : ORIGIN = 0x1FF80000, LENGTH = 128K
|
||||||
HIGHRAM (RWX) : ORIGIN = 0xFFFF0000, LENGTH = 4K
|
HIGHRAM (RWX) : ORIGIN = 0xFFFF0000, LENGTH = 4K
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "hw/nvram.h"
|
#include "hw/nvram.h"
|
||||||
|
|
||||||
#include "system/sys.h"
|
#include "system/sys.h"
|
||||||
|
#include "system/xalloc.h"
|
||||||
|
|
||||||
static GlobalSharedMemory SharedMemory_State;
|
static GlobalSharedMemory SharedMemory_State;
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ void VBlank_Handler(u32 __attribute__((unused)) irqn)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// the state should probably be stored on its own
|
// the state should probably be stored on its own
|
||||||
// setion without caching enabled, since it must
|
// section without caching enabled, since it must
|
||||||
// be readable by the ARM9 at all times anyway
|
// be readable by the ARM9 at all times anyway
|
||||||
SharedMemory_State.hid_state = HID_GetState();
|
SharedMemory_State.hid_state = HID_GetState();
|
||||||
ARM_WbDC_Range(&SharedMemory_State, sizeof(SharedMemory_State));
|
ARM_WbDC_Range(&SharedMemory_State, sizeof(SharedMemory_State));
|
||||||
@ -158,6 +159,12 @@ void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PXI_XALLOC:
|
||||||
|
{
|
||||||
|
ret = (u32)XAlloc(args[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* New CMD template:
|
/* New CMD template:
|
||||||
case CMD_ID:
|
case CMD_ID:
|
||||||
{
|
{
|
||||||
|
37
arm11/source/system/xalloc.c
Executable file
37
arm11/source/system/xalloc.c
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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 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;
|
||||||
|
}
|
25
arm11/source/system/xalloc.h
Executable file
25
arm11/source/system/xalloc.h
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
@ -106,7 +106,9 @@ bool CalibrateTouchFromFlash(void) {
|
|||||||
|
|
||||||
// check NVRAM console ID
|
// check NVRAM console ID
|
||||||
u32 console_id = 0;
|
u32 console_id = 0;
|
||||||
spiflash_read(0x001C, 4, (u8*)&console_id);
|
if (!spiflash_read(0x001C, 4, (u8*)&console_id))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (((console_id >> 8) & 0xFF) != 0x57)
|
if (((console_id >> 8) & 0xFF) != 0x57)
|
||||||
return false; // not a 3DS
|
return false; // not a 3DS
|
||||||
|
|
||||||
@ -114,7 +116,9 @@ bool CalibrateTouchFromFlash(void) {
|
|||||||
// see: https://problemkaputt.de/gbatek.htm#dsfirmwareusersettings
|
// see: https://problemkaputt.de/gbatek.htm#dsfirmwareusersettings
|
||||||
u32 fw_usercfg_buf[0x100 / 0x4];
|
u32 fw_usercfg_buf[0x100 / 0x4];
|
||||||
u8* fw_usercfg = (u8*) fw_usercfg_buf;
|
u8* fw_usercfg = (u8*) fw_usercfg_buf;
|
||||||
spiflash_read(0x1FE00, 0x100, fw_usercfg);
|
if (!spiflash_read(0x1FE00, 0x100, fw_usercfg))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (getle16(fw_usercfg + 0x72) != crc16_quick(fw_usercfg, 0x70))
|
if (getle16(fw_usercfg + 0x72) != crc16_quick(fw_usercfg, 0x70))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -4,63 +4,57 @@
|
|||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "pxi.h"
|
#include "pxi.h"
|
||||||
|
|
||||||
/*
|
// buffer is allocated only once and remains through runtime
|
||||||
disgusting hack that deserves to die in hell
|
static char *i2c_xfer_buf = NULL;
|
||||||
ideally all buffers would be able to be accessed
|
|
||||||
by the ARM11, but those in ARM9 RAM are inaccessible
|
|
||||||
(.data, .rodata & .bss)
|
|
||||||
|
|
||||||
the current hack assumes all buffers in the heap are
|
static bool I2C_AllocBuffer(void)
|
||||||
located in FCRAM, which is accessible to both processors
|
{
|
||||||
but it's horrendous, and hopefully temporary
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
static char *i2c_fcram_buf = NULL;
|
|
||||||
bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size)
|
bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size)
|
||||||
{
|
{
|
||||||
if (!i2c_fcram_buf)
|
|
||||||
i2c_fcram_buf = malloc(256);
|
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
u32 args[] = {devId, regAddr, (u32)i2c_fcram_buf, size};
|
u32 *args;
|
||||||
|
|
||||||
ARM_WbDC_Range(i2c_fcram_buf, size);
|
if (!I2C_AllocBuffer())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
args = (u32[]){devId, regAddr, (u32)i2c_xfer_buf, size};
|
||||||
|
|
||||||
|
ARM_WbDC_Range(i2c_xfer_buf, size);
|
||||||
ARM_DSB();
|
ARM_DSB();
|
||||||
|
|
||||||
ret = PXI_DoCMD(PXI_I2C_READ, args, 4);
|
ret = PXI_DoCMD(PXI_I2C_READ, args, 4);
|
||||||
|
|
||||||
ARM_InvDC_Range(i2c_fcram_buf, size);
|
ARM_InvDC_Range(i2c_xfer_buf, size);
|
||||||
memcpy(out, i2c_fcram_buf, size);
|
memcpy(out, i2c_xfer_buf, size);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size)
|
bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size)
|
||||||
{
|
{
|
||||||
if (!i2c_fcram_buf)
|
|
||||||
i2c_fcram_buf = malloc(256);
|
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
u32 args[] = {devId, regAddr, (u32)i2c_fcram_buf, size};
|
|
||||||
|
|
||||||
memcpy(i2c_fcram_buf, in, size);
|
if (!I2C_AllocBuffer())
|
||||||
ARM_WbDC_Range(i2c_fcram_buf, size);
|
return false;
|
||||||
|
|
||||||
|
u32 args[] = {devId, regAddr, (u32)i2c_xfer_buf, size};
|
||||||
|
|
||||||
|
memcpy(i2c_xfer_buf, in, size);
|
||||||
|
ARM_WbDC_Range(i2c_xfer_buf, size);
|
||||||
ARM_DSB();
|
ARM_DSB();
|
||||||
|
|
||||||
ret = PXI_DoCMD(PXI_I2C_WRITE, args, 4);
|
ret = PXI_DoCMD(PXI_I2C_WRITE, args, 4);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
u32 args[] = {devId, regAddr, (u32)out, size};
|
|
||||||
cpu_writeback_invalidate_dc_range(out, size);
|
|
||||||
cpu_membarrier();
|
|
||||||
ret = PXI_DoCMD(PXI_I2C_READ, args, 4);
|
|
||||||
cpu_invalidate_dc_range(out, size);
|
|
||||||
return ret;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
u8 I2C_readReg(I2cDevice devId, u8 regAddr)
|
u8 I2C_readReg(I2cDevice devId, u8 regAddr)
|
||||||
{
|
{
|
||||||
u8 data;
|
u8 data;
|
||||||
@ -69,16 +63,6 @@ u8 I2C_readReg(I2cDevice devId, u8 regAddr)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
u32 args[] = {devId, regAddr, (u32)in, size};
|
|
||||||
cpu_writeback_dc_range(in, size);
|
|
||||||
cpu_membarrier();
|
|
||||||
ret = PXI_DoCMD(PXI_I2C_WRITE, args, 4);
|
|
||||||
return ret;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
bool I2C_writeReg(I2cDevice devId, u8 regAddr, u8 data)
|
bool I2C_writeReg(I2cDevice devId, u8 regAddr, u8 data)
|
||||||
{
|
{
|
||||||
return I2C_writeRegBuf(devId, regAddr, &data, 1);
|
return I2C_writeRegBuf(devId, regAddr, &data, 1);
|
||||||
|
44
arm9/source/system/spiflash.c
Executable file
44
arm9/source/system/spiflash.c
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "arm.h"
|
||||||
|
#include "pxi.h"
|
||||||
|
|
||||||
|
#define SPIFLASH_CHUNK_SIZE (0x1000)
|
||||||
|
|
||||||
|
static char *spiflash_xalloc_buf = NULL;
|
||||||
|
|
||||||
|
bool spiflash_get_status(void)
|
||||||
|
{
|
||||||
|
return PXI_DoCMD(PXI_NVRAM_ONLINE, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool spiflash_read(u32 offset, u32 size, u8 *buf)
|
||||||
|
{
|
||||||
|
u32 args[3];
|
||||||
|
|
||||||
|
if (!spiflash_xalloc_buf) {
|
||||||
|
u32 xbuf = PXI_DoCMD(PXI_XALLOC, (u32[]){SPIFLASH_CHUNK_SIZE}, 1);
|
||||||
|
if (xbuf == 0 || xbuf == 0xFFFFFFFF)
|
||||||
|
return false;
|
||||||
|
spiflash_xalloc_buf = (char*)xbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
args[1] = (u32)spiflash_xalloc_buf;
|
||||||
|
|
||||||
|
while(size > 0) {
|
||||||
|
u32 rem = min(size, SPIFLASH_CHUNK_SIZE);
|
||||||
|
|
||||||
|
args[0] = offset;
|
||||||
|
args[2] = rem;
|
||||||
|
|
||||||
|
ARM_DSB();
|
||||||
|
PXI_DoCMD(PXI_NVRAM_READ, args, 3);
|
||||||
|
ARM_InvDC_Range(spiflash_xalloc_buf, rem);
|
||||||
|
memcpy(buf, spiflash_xalloc_buf, rem);
|
||||||
|
|
||||||
|
buf += rem;
|
||||||
|
size -= rem;
|
||||||
|
offset += rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
@ -25,16 +25,6 @@
|
|||||||
#define NVRAM_SIZE 0x20000 // 1 Mbit (128kiB)
|
#define NVRAM_SIZE 0x20000 // 1 Mbit (128kiB)
|
||||||
|
|
||||||
// true if spiflash is installed, false otherwise
|
// true if spiflash is installed, false otherwise
|
||||||
static inline bool spiflash_get_status(void)
|
bool spiflash_get_status(void);
|
||||||
{ // there should probably be a command for this...
|
|
||||||
return PXI_DoCMD(PXI_NVRAM_ONLINE, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void spiflash_read(u32 offset, u32 size, u8 *buf)
|
bool spiflash_read(u32 offset, u32 size, u8 *buf);
|
||||||
{
|
|
||||||
u32 args[] = {offset, (u32)buf, size};
|
|
||||||
ARM_WbDC_Range(buf, size);
|
|
||||||
ARM_DSB();
|
|
||||||
PXI_DoCMD(PXI_NVRAM_READ, args, 3);
|
|
||||||
ARM_InvDC_Range(buf, size);
|
|
||||||
}
|
|
||||||
|
@ -165,8 +165,9 @@ int ReadVMemNVRAM(const VirtualFile* vfile, void* buffer, u64 offset, u64 count)
|
|||||||
wififlash_initialized = spiflash_get_status();
|
wififlash_initialized = spiflash_get_status();
|
||||||
if (!wififlash_initialized) return 1;
|
if (!wififlash_initialized) return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
spiflash_read((u32) offset, (u32) count, buffer);
|
if (!spiflash_read((u32) offset, (u32) count, buffer))
|
||||||
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,8 @@ enum {
|
|||||||
|
|
||||||
PXI_NOTIFY_LED,
|
PXI_NOTIFY_LED,
|
||||||
PXI_BRIGHTNESS,
|
PXI_BRIGHTNESS,
|
||||||
|
|
||||||
|
PXI_XALLOC,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user