Compare commits

...

5 Commits
v3.9 ... v3.11

30 changed files with 262 additions and 205 deletions

View File

@@ -12,7 +12,7 @@ ifneq ($(PYTHON_VER_MAJOR), 3)
PYTHON3 := py -3 PYTHON3 := py -3
endif endif
name := ReiNand name := AuReiNand
dir_source := source dir_source := source
dir_data := data dir_data := data
@@ -26,7 +26,7 @@ dir_loader := loader
ASFLAGS := -mlittle-endian -mcpu=arm946e-s -march=armv5te ASFLAGS := -mlittle-endian -mcpu=arm946e-s -march=armv5te
CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -fshort-wchar -std=c11 -Wno-main -O2 -ffast-math CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -fshort-wchar -std=c11 -Wno-main -O2 -ffast-math
FLAGS := name=$(name).dat dir_out=$(abspath $(dir_out)) ICON=$(abspath icon.png) --no-print-directory FLAGS := name=$(name).dat dir_out=$(abspath $(dir_out)) ICON=$(abspath icon.png) APP_DESCRIPTION="Noob-friendly 3DS CFW." APP_AUTHOR="Reisyukaku/Aurora Wright" --no-print-directory
objects_cfw = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ objects_cfw = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
@@ -43,29 +43,29 @@ launcher: $(dir_out)/$(name).dat
a9lh: $(dir_out)/arm9loaderhax.bin a9lh: $(dir_out)/arm9loaderhax.bin
.PHONY: emunand .PHONY: emunand
emunand: $(dir_out)/rei/emunand/emunand.bin emunand: $(dir_out)/aurei/emunand/emunand.bin
.PHONY: reboot .PHONY: reboot
reboot: $(dir_out)/rei/reboot/reboot.bin reboot: $(dir_out)/aurei/reboot/reboot.bin
.PHONY: ninjhax .PHONY: ninjhax
ninjhax: $(dir_out)/3ds/$(name) ninjhax: $(dir_out)/3ds/$(name)
.PHONY: loader .PHONY: loader
loader: $(dir_out)/rei/loader.bin loader: $(dir_out)/aurei/loader.bin
.PHONY: clean .PHONY: clean
clean: clean:
@$(MAKE) $(FLAGS) -C $(dir_mset) clean @$(MAKE) $(FLAGS) -C $(dir_mset) clean
@$(MAKE) $(FLAGS) -C $(dir_ninjhax) clean @$(MAKE) $(FLAGS) -C $(dir_ninjhax) clean
@rm -rf $(dir_out) $(dir_build) @rm -rf $(dir_out) $(dir_build)
@cd $(dir_loader) && make clean @$(MAKE) -C $(dir_loader) clean
$(dir_out)/$(name).dat: $(dir_build)/main.bin $(dir_out)/rei $(dir_out)/$(name).dat: $(dir_build)/main.bin $(dir_out)/aurei
@$(MAKE) $(FLAGS) -C $(dir_mset) launcher @$(MAKE) $(FLAGS) -C $(dir_mset) launcher
dd if=$(dir_build)/main.bin of=$@ bs=512 seek=144 dd if=$(dir_build)/main.bin of=$@ bs=512 seek=144
$(dir_out)/arm9loaderhax.bin: $(dir_build)/main.bin $(dir_out)/rei $(dir_out)/arm9loaderhax.bin: $(dir_build)/main.bin $(dir_out)/aurei
@cp -av $(dir_build)/main.bin $@ @cp -av $(dir_build)/main.bin $@
$(dir_out)/3ds/$(name): $(dir_out)/3ds/$(name):
@@ -74,21 +74,21 @@ $(dir_out)/3ds/$(name):
@mv $(dir_out)/$(name).3dsx $@ @mv $(dir_out)/$(name).3dsx $@
@mv $(dir_out)/$(name).smdh $@ @mv $(dir_out)/$(name).smdh $@
$(dir_out)/rei: $(dir_out)/aurei:
@mkdir -p "$(dir_out)/rei" @mkdir -p "$(dir_out)/aurei"
$(dir_out)/rei/emunand/emunand.bin: $(dir_emu)/emuCode.s $(dir_out)/aurei/emunand/emunand.bin: $(dir_emu)/emuCode.s
@armips $< @armips $<
@mkdir -p "$(dir_out)/rei/emunand" @mkdir -p "$(dir_out)/aurei/emunand"
@mv emunand.bin $@ @mv emunand.bin $@
$(dir_out)/rei/reboot/reboot.bin: $(dir_reboot)/rebootCode.s $(dir_out)/aurei/reboot/reboot.bin: $(dir_reboot)/rebootCode.s
@armips $< @armips $<
@mkdir -p "$(dir_out)/rei/reboot" @mkdir -p "$(dir_out)/aurei/reboot"
@mv reboot.bin $@ @mv reboot.bin $@
$(dir_out)/rei/loader.bin: $(dir_out)/rei $(dir_loader)/Makefile $(dir_out)/aurei/loader.bin: $(dir_out)/aurei $(dir_loader)/Makefile
@cd $(dir_loader) && make @$(MAKE) -C $(dir_loader)
@mv $(dir_loader)/loader.bin $@ @mv $(dir_loader)/loader.bin $@
$(dir_build)/main.bin: $(dir_build)/main.elf $(dir_build)/main.bin: $(dir_build)/main.elf

View File

@@ -1,9 +1,6 @@
.nds .arm.little
sdmmc equ 0x434D4453 ;dummy .create "emunand.bin", 0
.create "emunand.bin", 0x0801A5C0
.org 0x0801A5C0
.arm .arm
nand_sd: nand_sd:
; Original code that still needs to be executed. ; Original code that still needs to be executed.
@@ -15,7 +12,7 @@ nand_sd:
; If we're already trying to access the SD, return. ; If we're already trying to access the SD, return.
ldr r2, [r0, #4] ldr r2, [r0, #4]
ldr r1, =sdmmc ldr r1, [sdmmc]
cmp r2, r1 cmp r2, r1
beq nand_sd_ret beq nand_sd_ret
@@ -23,12 +20,10 @@ nand_sd:
ldr r2, [r0, #8] ; Get sector to read ldr r2, [r0, #8] ; Get sector to read
cmp r2, #0 ; For GW compatibility, see if we're trying to read the ncsd header (sector 0) cmp r2, #0 ; For GW compatibility, see if we're trying to read the ncsd header (sector 0)
ldr r3, =nand_offset ldr r3, [nand_offset]
ldr r3, [r3]
add r2, r3 ; Add the offset to the NAND in the SD. add r2, r3 ; Add the offset to the NAND in the SD.
ldreq r3, =ncsd_header_offset ldreq r3, [ncsd_header_offset]
ldreq r3, [r3]
addeq r2, r3 ; If we're reading the ncsd header, add the offset of that sector. addeq r2, r3 ; If we're reading the ncsd header, add the offset of that sector.
str r2, [r0, #8] ; Store sector to read str r2, [r0, #8] ; Store sector to read
@@ -45,6 +40,7 @@ nand_sd:
add r0, #4 add r0, #4
bx r0 bx r0
.pool .pool
sdmmc: .ascii "SDMC"
nand_offset: .ascii "NAND" ; for rednand this should be 1 nand_offset: .ascii "NAND" ; for rednand this should be 1
ncsd_header_offset: .ascii "NCSD" ; depends on nand manufacturer + emunand type (GW/RED) ncsd_header_offset: .ascii "NCSD" ; depends on nand manufacturer + emunand type (GW/RED)
.close .close

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -32,7 +32,7 @@ INCLUDES := include source/fatfs source/fatfs/sdmmc
ARCH := -mthumb -mthumb-interwork ARCH := -mthumb -mthumb-interwork
CFLAGS := -g -Wall -O2\ CFLAGS := -g -Wall -O2\
-march=armv5te -mtune=arm946e-s -fomit-frame-pointer\ -march=armv5te -mtune=arm946e-s\
-ffast-math -Wno-main -std=c99\ -ffast-math -Wno-main -std=c99\
$(ARCH) $(ARCH)

View File

@@ -69,7 +69,7 @@ DRESULT disk_read (
DRESULT disk_write ( DRESULT disk_write (
__attribute__((unused)) __attribute__((unused))
BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */ const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */ DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */ UINT count /* Number of sectors to write */
) )

View File

@@ -811,7 +811,7 @@ FRESULT sync_fs ( /* FR_OK: successful, FR_DISK_ERR: failed */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Hidden API for hacks and disk tools */ /* Hidden API for hacks and disk tools */
DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ static DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
FATFS* fs, /* File system object */ FATFS* fs, /* File system object */
DWORD clst /* Cluster# to be converted */ DWORD clst /* Cluster# to be converted */
) )
@@ -829,7 +829,7 @@ DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Hidden API for hacks and disk tools */ /* Hidden API for hacks and disk tools */
DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluster status */ static DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluster status */
FATFS* fs, /* File system object */ FATFS* fs, /* File system object */
DWORD clst /* FAT index number (cluster number) to get the value */ DWORD clst /* FAT index number (cluster number) to get the value */
) )
@@ -884,7 +884,7 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluste
/* Hidden API for hacks and disk tools */ /* Hidden API for hacks and disk tools */
#if !_FS_READONLY #if !_FS_READONLY
FRESULT put_fat ( static FRESULT put_fat (
FATFS* fs, /* File system object */ FATFS* fs, /* File system object */
DWORD clst, /* FAT index number (cluster number) to be changed */ DWORD clst, /* FAT index number (cluster number) to be changed */
DWORD val /* New value to be set to the entry */ DWORD val /* New value to be set to the entry */

View File

@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common.h"
#include "sdmmc.h" #include "sdmmc.h"
#include "delay.h" #include "delay.h"

View File

@@ -10,11 +10,11 @@ static const struct { u8 bus_id, reg_addr; } dev_data[] = {
{2, 0xA4}, {2, 0x9A}, {2, 0xA0}, {2, 0xA4}, {2, 0x9A}, {2, 0xA0},
}; };
inline u8 i2cGetDeviceBusId(u8 device_id) { static inline u8 i2cGetDeviceBusId(u8 device_id) {
return dev_data[device_id].bus_id; return dev_data[device_id].bus_id;
} }
inline u8 i2cGetDeviceRegAddr(u8 device_id) { static inline u8 i2cGetDeviceRegAddr(u8 device_id) {
return dev_data[device_id].reg_addr; return dev_data[device_id].reg_addr;
} }
@@ -26,7 +26,7 @@ static vu8* reg_data_addrs[] = {
(vu8*)(I2C3_REG_OFF + I2C_REG_DATA), (vu8*)(I2C3_REG_OFF + I2C_REG_DATA),
}; };
inline vu8* i2cGetDataReg(u8 bus_id) { static inline vu8* i2cGetDataReg(u8 bus_id) {
return reg_data_addrs[bus_id]; return reg_data_addrs[bus_id];
} }
@@ -38,22 +38,22 @@ static vu8* reg_cnt_addrs[] = {
(vu8*)(I2C3_REG_OFF + I2C_REG_CNT), (vu8*)(I2C3_REG_OFF + I2C_REG_CNT),
}; };
inline vu8* i2cGetCntReg(u8 bus_id) { static inline vu8* i2cGetCntReg(u8 bus_id) {
return reg_cnt_addrs[bus_id]; return reg_cnt_addrs[bus_id];
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
inline void i2cWaitBusy(u8 bus_id) { static inline void i2cWaitBusy(u8 bus_id) {
while (*i2cGetCntReg(bus_id) & 0x80); while (*i2cGetCntReg(bus_id) & 0x80);
} }
inline bool i2cGetResult(u8 bus_id) { static inline u32 i2cGetResult(u8 bus_id) {
i2cWaitBusy(bus_id); i2cWaitBusy(bus_id);
return (*i2cGetCntReg(bus_id) >> 4) & 1; return (*i2cGetCntReg(bus_id) >> 4) & 1;
} }
void i2cStop(u8 bus_id, u8 arg0) { static void i2cStop(u8 bus_id, u8 arg0) {
*i2cGetCntReg(bus_id) = (arg0 << 5) | 0xC0; *i2cGetCntReg(bus_id) = (arg0 << 5) | 0xC0;
i2cWaitBusy(bus_id); i2cWaitBusy(bus_id);
*i2cGetCntReg(bus_id) = 0xC5; *i2cGetCntReg(bus_id) = 0xC5;
@@ -61,14 +61,14 @@ void i2cStop(u8 bus_id, u8 arg0) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool i2cSelectDevice(u8 bus_id, u8 dev_reg) { static u32 i2cSelectDevice(u8 bus_id, u8 dev_reg) {
i2cWaitBusy(bus_id); i2cWaitBusy(bus_id);
*i2cGetDataReg(bus_id) = dev_reg; *i2cGetDataReg(bus_id) = dev_reg;
*i2cGetCntReg(bus_id) = 0xC2; *i2cGetCntReg(bus_id) = 0xC2;
return i2cGetResult(bus_id); return i2cGetResult(bus_id);
} }
bool i2cSelectRegister(u8 bus_id, u8 reg) { static u32 i2cSelectRegister(u8 bus_id, u8 reg) {
i2cWaitBusy(bus_id); i2cWaitBusy(bus_id);
*i2cGetDataReg(bus_id) = reg; *i2cGetDataReg(bus_id) = reg;
*i2cGetCntReg(bus_id) = 0xC0; *i2cGetCntReg(bus_id) = 0xC0;
@@ -77,58 +77,7 @@ bool i2cSelectRegister(u8 bus_id, u8 reg) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
u8 i2cReadRegister(u8 dev_id, u8 reg) { u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data) {
u8 bus_id = i2cGetDeviceBusId(dev_id);
u8 dev_addr = i2cGetDeviceRegAddr(dev_id);
for (size_t i = 0; i < 8; i++) {
if (i2cSelectDevice(bus_id, dev_addr) && i2cSelectRegister(bus_id, reg)) {
if (i2cSelectDevice(bus_id, dev_addr | 1)) {
i2cWaitBusy(bus_id);
i2cStop(bus_id, 1);
i2cWaitBusy(bus_id);
return *i2cGetDataReg(bus_id);
}
}
*i2cGetCntReg(bus_id) = 0xC5;
i2cWaitBusy(bus_id);
}
return 0xff;
}
bool i2cReadRegisterBuffer(unsigned int dev_id, int reg, u8* buffer, size_t buf_size) {
u8 bus_id = i2cGetDeviceBusId(dev_id);
u8 dev_addr = i2cGetDeviceRegAddr(dev_id);
size_t j = 0;
while (!i2cSelectDevice(bus_id, dev_addr)
|| !i2cSelectRegister(bus_id, reg)
|| !i2cSelectDevice(bus_id, dev_addr | 1))
{
i2cWaitBusy(bus_id);
*i2cGetCntReg(bus_id) = 0xC5;
i2cWaitBusy(bus_id);
if (++j >= 8)
return false;
}
if (buf_size != 1) {
for (size_t i = 0; i < buf_size - 1; i++) {
i2cWaitBusy(bus_id);
*i2cGetCntReg(bus_id) = 0xF0;
i2cWaitBusy(bus_id);
buffer[i] = *i2cGetDataReg(bus_id);
}
}
i2cWaitBusy(bus_id);
*i2cGetCntReg(bus_id) = 0xE1;
i2cWaitBusy(bus_id);
*buffer = *i2cGetDataReg(bus_id);
return true;
}
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data) {
u8 bus_id = i2cGetDeviceBusId(dev_id); u8 bus_id = i2cGetDeviceBusId(dev_id);
u8 dev_addr = i2cGetDeviceRegAddr(dev_id); u8 dev_addr = i2cGetDeviceRegAddr(dev_id);
@@ -139,11 +88,11 @@ bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data) {
*i2cGetCntReg(bus_id) = 0xC1; *i2cGetCntReg(bus_id) = 0xC1;
i2cStop(bus_id, 0); i2cStop(bus_id, 0);
if (i2cGetResult(bus_id)) if (i2cGetResult(bus_id))
return true; return 1;
} }
*i2cGetCntReg(bus_id) = 0xC5; *i2cGetCntReg(bus_id) = 0xC5;
i2cWaitBusy(bus_id); i2cWaitBusy(bus_id);
} }
return false; return 0;
} }

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "common.h" #include "types.h"
#define I2C1_REG_OFF 0x10161000 #define I2C1_REG_OFF 0x10161000
#define I2C2_REG_OFF 0x10144000 #define I2C2_REG_OFF 0x10144000
@@ -15,21 +15,4 @@
#define I2C_DEV_GYRO 10 #define I2C_DEV_GYRO 10
#define I2C_DEV_IR 13 #define I2C_DEV_IR 13
u8 i2cGetDeviceBusId(u8 device_id); u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
u8 i2cGetDeviceRegAddr(u8 device_id);
vu8* i2cGetDataReg(u8 bus_id);
vu8* i2cGetCntReg(u8 bus_id);
void i2cWaitBusy(u8 bus_id);
bool i2cGetResult(u8 bus_id);
u8 i2cGetData(u8 bus_id);
void i2cStop(u8 bus_id, u8 arg0);
bool i2cSelectDevice(u8 bus_id, u8 dev_reg);
bool i2cSelectRegister(u8 bus_id, u8 reg);
u8 i2cReadRegister(u8 dev_id, u8 reg);
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
bool i2cReadRegisterBuffer(unsigned int dev_id, int reg, u8* buffer, size_t buf_size);

View File

@@ -5,7 +5,7 @@
#define PAYLOAD_ADDRESS 0x23F00000 #define PAYLOAD_ADDRESS 0x23F00000
u32 loadPayload(const char *path){ static u32 loadPayload(const char *path){
FIL payload; FIL payload;
unsigned int br; unsigned int br;
if(f_open(&payload, path, FA_READ) == FR_OK) if(f_open(&payload, path, FA_READ) == FR_OK)
@@ -19,24 +19,25 @@ u32 loadPayload(const char *path){
return 0; return 0;
} }
void main(){ void main(void){
FATFS fs; FATFS fs;
f_mount(&fs, "0:", 1); f_mount(&fs, "0:", 1);
//Get pressed buttons //Get pressed buttons
u16 pressed = HID_PAD; u16 pressed = HID_PAD;
if(((pressed & BUTTON_B) && loadPayload("/rei/payloads/b.bin")) || if(((pressed & BUTTON_B) && loadPayload("/aurei/payloads/b.bin")) ||
((pressed & BUTTON_X) && loadPayload("/rei/payloads/x.bin")) || ((pressed & BUTTON_X) && loadPayload("/aurei/payloads/x.bin")) ||
((pressed & BUTTON_Y) && loadPayload("/rei/payloads/y.bin")) || ((pressed & BUTTON_Y) && loadPayload("/aurei/payloads/y.bin")) ||
((pressed & BUTTON_SELECT) && loadPayload("/rei/payloads/select.bin")) || ((pressed & BUTTON_SELECT) && loadPayload("/aurei/payloads/select.bin")) ||
((pressed & BUTTON_START) && loadPayload("/rei/payloads/start.bin")) || ((pressed & BUTTON_START) && loadPayload("/aurei/payloads/start.bin")) ||
((pressed & BUTTON_RIGHT) && loadPayload("/rei/payloads/right.bin")) || ((pressed & BUTTON_RIGHT) && loadPayload("/aurei/payloads/right.bin")) ||
((pressed & BUTTON_LEFT) && loadPayload("/rei/payloads/left.bin")) || ((pressed & BUTTON_LEFT) && loadPayload("/aurei/payloads/left.bin")) ||
((pressed & BUTTON_UP) && loadPayload("/rei/payloads/up.bin")) || ((pressed & BUTTON_UP) && loadPayload("/aurei/payloads/up.bin")) ||
((pressed & BUTTON_DOWN) && loadPayload("/rei/payloads/down.bin")) || ((pressed & BUTTON_DOWN) && loadPayload("/aurei/payloads/down.bin")) ||
loadPayload("/rei/payloads/default.bin")){ loadPayload("/aurei/payloads/default.bin")){
initLCD(); //Determine if screen was already inited
if(*(vu8 *)0x10141200 == 0x1) initLCD();
((void (*)())PAYLOAD_ADDRESS)(); ((void (*)())PAYLOAD_ADDRESS)();
} }
} }

View File

@@ -1,12 +1,11 @@
#include "screeninit.h" #include "screeninit.h"
#include "i2c.h" #include "i2c.h"
void initLCD() void initLCD(void){
{ vu32 *const arm11 = (vu32 *)0x1FFFFFF8;
vu32 *const arm11 = (u32 *)0x1FFFFFF8;
void __attribute__((naked)) ARM11() void __attribute__((naked)) ARM11(void){
{ __asm(".word 0xF10C01C0");
*(vu32 *)0x10141200 = 0x1007F; *(vu32 *)0x10141200 = 0x1007F;
*(vu32 *)0x10202014 = 0x00000001; *(vu32 *)0x10202014 = 0x00000001;
*(vu32 *)0x1020200C &= 0xFFFEFFFE; *(vu32 *)0x1020200C &= 0xFFFEFFFE;
@@ -93,6 +92,11 @@ void initLCD()
*(vu32 *)0x10400568 = 0x18346500; *(vu32 *)0x10400568 = 0x18346500;
*(vu32 *)0x1040056c = 0x18346500; *(vu32 *)0x1040056c = 0x18346500;
//Set CakeBrah framebuffers
*((vu32 *)0x23FFFE00) = 0x18300000;
*((vu32 *)0x23FFFE04) = 0x18300000;
*((vu32 *)0x23FFFE08) = 0x18346500;
//Clear ARM11 entry offset //Clear ARM11 entry offset
*arm11 = 0; *arm11 = 0;
@@ -102,17 +106,6 @@ void initLCD()
((void (*)())*arm11)(); ((void (*)())*arm11)();
} }
//Determine if screen was already inited
if(*(vu8 *)0x10141200 != 0x1) return;
//Set CakeBrah framebuffers
*(vu32 *)0x23FFFE00 = 0x18300000;
*(vu32 *)0x23FFFE04 = 0x18300000;
*(vu32 *)0x23FFFE08 = 0x18346500;
*arm11 = (u32)ARM11; *arm11 = (u32)ARM11;
//This delay is needed for some reason
for(vu32 i = 0; i < 0x2000; ++i);
while(*arm11); while(*arm11);
} }

View File

@@ -2,4 +2,4 @@
#include "types.h" #include "types.h"
void initLCD(); void initLCD(void);

View File

@@ -2,6 +2,9 @@
.align 4 .align 4
.global _start .global _start
_start: _start:
@ Fix payloads like Decrypt9
mov r0, #0x5
mcr p15, 0, r0, c3, c0, 0 @ data bufferable
@ Flush caches @ Flush caches
mov r0, #0 mov r0, #0

View File

@@ -1,12 +1,11 @@
.nds .arm.little
.create "reboot.bin", 0
byteswritten equ 0x2000E000 byteswritten equ 0x2000E000
externalFirm equ 0x2000A000
kernelCode equ 0x080F0000 kernelCode equ 0x080F0000
buffer equ 0x24000000 buffer equ 0x24000000
fileOpen equ 0x4E45504F ;dummy fileOpen equ 0x4E45504F ;dummy
.create "reboot.bin", 0
.arm .arm
//Code jumps here right after the sprintf call //Code jumps here right after the sprintf call
process9Reboot: process9Reboot:
@@ -34,18 +33,16 @@ process9Reboot:
ldreq r1, =(FileName - OpenFirm - 12) ldreq r1, =(FileName - OpenFirm - 12)
addeq r1, pc addeq r1, pc
addne r1, sp, #0x3A8-0x70 addne r1, sp, #0x3A8-0x70
ldr r0, =externalFirm
moveq r2, #1 moveq r2, #1
movne r2, #0 movne r2, #0
str r2, [r0] str r2, [externalFirm]
mov r2, #1 mov r2, #1
add r0, r7, #8 add r0, r7, #8
ldr r6, =fileOpen ldr r6, =fileOpen
blx r6 blx r6
SeekFirm: SeekFirm:
ldr r0, =externalFirm ldr r0, [externalFirm]
ldr r0, [r0]
cmp r0, #1 cmp r0, #1
moveq r0, r7 moveq r0, r7
ldreq r1, =byteswritten ldreq r1, =byteswritten
@@ -99,9 +96,12 @@ Memcpy:
BX LR BX LR
FileName: FileName:
.dcw "sdmc:/rei/patched_firmware_sys.bin" .dcw "sdmc:/aurei/patched_firmware_sys.bin"
.word 0x0 .word 0x0
externalFirm:
.word 0x2000A000
.pool .pool
// Kernel Code // Kernel Code

View File

@@ -32,17 +32,17 @@ void __attribute__((naked)) shutdownLCD(void){
((void (*)())*arm11)(); ((void (*)())*arm11)();
} }
static void clearScreen(void){ static void clearScreens(void){
memset(fb->top_left, 0, 0x46500); memset32(fb->top_left, 0, 0x46500);
memset(fb->top_right, 0, 0x46500); memset32(fb->top_right, 0, 0x46500);
memset(fb->bottom, 0, 0x38400); memset32(fb->bottom, 0, 0x38400);
} }
void loadSplash(void){ void loadSplash(void){
clearScreen(); clearScreens();
//Don't delay boot if no splash image is on the SD //Don't delay boot if no splash image is on the SD
if(fileRead(fb->top_left, "/rei/splash.bin", 0x46500) + if(fileRead(fb->top_left, "/aurei/splash.bin", 0x46500) +
fileRead(fb->bottom, "/rei/splashbottom.bin", 0x38400)){ fileRead(fb->bottom, "/aurei/splashbottom.bin", 0x38400)){
u64 i = 0xFFFFFF; while(--i) __asm("mov r0, r0"); //Less Ghetto sleep func u64 i = 0x1300000; while(--i) __asm("mov r0, r0"); //Less Ghetto sleep func
} }
} }

View File

@@ -22,6 +22,11 @@ void getEmunandSect(u32 *off, u32 *head, u32 emuNAND){
} }
//Fallback to the first emuNAND if there's no second one //Fallback to the first emuNAND if there's no second one
else if(emuNAND == 2) getEmunandSect(off, head, 1); else if(emuNAND == 2) getEmunandSect(off, head, 1);
//Check if a RedNAND is present
else if(sdmmc_sdcard_readsectors(1, 1, temp) == 0){
if(*(u32 *)(temp + 0x100) != NCSD_MAGIC)
*head = 0;
}
} }
} }
@@ -58,3 +63,11 @@ void getMPU(void *pos, u32 *off, u32 size){
*off = (u32)memsearch(pos, pattern, size, 4); *off = (u32)memsearch(pos, pattern, size, 4);
} }
void getEmuCode(void *pos, u32 *off, u32 size){
u8 *proc9 = (u8 *)memsearch(pos, "ess9", size, 4);
const unsigned char pattern[] = {0x00, 0xFF, 0xFF, 0xFF};
//Looking for the last spot before Process9
*off = (u32)memsearch(pos, pattern, size - (size - (u32)(proc9 - (u8 *)pos)), 4) + 0xD;
}

View File

@@ -14,3 +14,4 @@ void getEmunandSect(u32 *off, u32 *head, u32 emuNAND);
void getSDMMC(void *pos, u32 *off, u32 size); void getSDMMC(void *pos, u32 *off, u32 size);
void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff); void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff);
void getMPU(void *pos, u32 *off, u32 size); void getMPU(void *pos, u32 *off, u32 size);
void getEmuCode(void *pos, u32 *off, u32 size);

View File

@@ -69,7 +69,7 @@ DRESULT disk_read (
DRESULT disk_write ( DRESULT disk_write (
__attribute__((unused)) __attribute__((unused))
BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */ const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */ DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */ UINT count /* Number of sectors to write */
) )

View File

@@ -811,7 +811,7 @@ FRESULT sync_fs ( /* FR_OK: successful, FR_DISK_ERR: failed */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Hidden API for hacks and disk tools */ /* Hidden API for hacks and disk tools */
DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ static DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
FATFS* fs, /* File system object */ FATFS* fs, /* File system object */
DWORD clst /* Cluster# to be converted */ DWORD clst /* Cluster# to be converted */
) )
@@ -829,7 +829,7 @@ DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Hidden API for hacks and disk tools */ /* Hidden API for hacks and disk tools */
DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluster status */ static DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluster status */
FATFS* fs, /* File system object */ FATFS* fs, /* File system object */
DWORD clst /* FAT index number (cluster number) to get the value */ DWORD clst /* FAT index number (cluster number) to get the value */
) )
@@ -884,7 +884,7 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluste
/* Hidden API for hacks and disk tools */ /* Hidden API for hacks and disk tools */
#if !_FS_READONLY #if !_FS_READONLY
FRESULT put_fat ( static FRESULT put_fat (
FATFS* fs, /* File system object */ FATFS* fs, /* File system object */
DWORD clst, /* FAT index number (cluster number) to be changed */ DWORD clst, /* FAT index number (cluster number) to be changed */
DWORD val /* New value to be set to the entry */ DWORD val /* New value to be set to the entry */

View File

@@ -23,7 +23,7 @@
/ and optional writing functions as well. */ / and optional writing functions as well. */
#define _FS_MINIMIZE 0 #define _FS_MINIMIZE 3
/* This option defines minimization level to remove some basic API functions. /* This option defines minimization level to remove some basic API functions.
/ /
/ 0: All basic functions are enabled. / 0: All basic functions are enabled.

View File

@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common.h"
#include "sdmmc.h" #include "sdmmc.h"
#include "delay.h" #include "delay.h"

View File

@@ -32,7 +32,7 @@ void setupCFW(void){
//Retrieve the last booted FIRM //Retrieve the last booted FIRM
u8 previousFirm = CFG_BOOTENV; u8 previousFirm = CFG_BOOTENV;
u32 overrideConfig = 0; u32 overrideConfig = 0;
const char lastConfigPath[] = "rei/lastbootcfg"; const char lastConfigPath[] = "aurei/lastbootcfg";
//Detect the console being used //Detect the console being used
if(PDN_MPCORE_CFG == 1) console = 0; if(PDN_MPCORE_CFG == 1) console = 0;
@@ -41,10 +41,10 @@ void setupCFW(void){
pressed = HID_PAD; pressed = HID_PAD;
//Determine if A9LH is installed //Determine if A9LH is installed
if(a9lhBoot || fileExists("/rei/installeda9lh")){ if(a9lhBoot || fileExists("/aurei/installeda9lh")){
a9lhSetup = 1; a9lhSetup = 1;
//Check flag for > 9.2 SysNAND //Check flag for > 9.2 SysNAND
if(fileExists("/rei/updatedsysnand")) updatedSys = 1; if(fileExists("/aurei/updatedsysnand")) updatedSys = 1;
} }
//If booting with A9LH and it's a MCU reboot, try to force boot options //If booting with A9LH and it's a MCU reboot, try to force boot options
@@ -92,14 +92,14 @@ void setupCFW(void){
} }
} }
if(mode) firmPathPatched = emuNAND ? (emuNAND == 1 ? "/rei/patched_firmware_emu.bin" : if(mode) firmPathPatched = emuNAND ? (emuNAND == 1 ? "/aurei/patched_firmware_emu.bin" :
"/rei/patched_firmware_em2.bin") : "/aurei/patched_firmware_em2.bin") :
"/rei/patched_firmware_sys.bin"; "/aurei/patched_firmware_sys.bin";
//Skip decrypting and patching FIRM //Skip decrypting and patching FIRM
if(fileExists("/rei/usepatchedfw")){ if(fileExists("/aurei/usepatchedfw")){
//Only needed with this flag //Only needed with this flag
if(!mode) firmPathPatched = "/rei/patched_firmware90.bin"; if(!mode) firmPathPatched = "/aurei/patched_firmware90.bin";
if(fileExists(firmPathPatched)) usePatchedFirm = 1; if(fileExists(firmPathPatched)) usePatchedFirm = 1;
} }
} }
@@ -118,7 +118,7 @@ u32 loadFirm(void){
//Load FIRM from SD //Load FIRM from SD
else{ else{
const char *path = usePatchedFirm ? firmPathPatched : const char *path = usePatchedFirm ? firmPathPatched :
(mode ? "/rei/firmware.bin" : "/rei/firmware90.bin"); (mode ? "/aurei/firmware.bin" : "/aurei/firmware90.bin");
firmSize = fileSize(path); firmSize = fileSize(path);
if(!firmSize) return 0; if(!firmSize) return 0;
fileRead((u8 *)firmLocation, path, firmSize); fileRead((u8 *)firmLocation, path, firmSize);
@@ -147,13 +147,10 @@ static u32 loadEmu(void){
emuCodeOffset; emuCodeOffset;
//Read emunand code from SD //Read emunand code from SD
const char path[] = "/rei/emunand/emunand.bin"; const char path[] = "/aurei/emunand/emunand.bin";
u32 size = fileSize(path); u32 size = fileSize(path);
if(!size) return 0; if(!size) return 0;
if(!console || !mode) nandRedir[5] = 0xA4; getEmuCode(firmLocation, &emuCodeOffset, firmSize);
//Find offset for emuNAND code from the offset in nandRedir
emuCodeOffset = *(u32 *)(nandRedir + 4) - (u32)section[2].address +
section[2].offset + (u32)firmLocation;
fileRead((u8 *)emuCodeOffset, path, size); fileRead((u8 *)emuCodeOffset, path, size);
//Find and patch emunand related offsets //Find and patch emunand related offsets
@@ -168,11 +165,12 @@ static u32 loadEmu(void){
*pos_offset = emuOffset; *pos_offset = emuOffset;
*pos_header = emuHeader; *pos_header = emuHeader;
//Patch emuNAND code in memory for O3DS and 9.0 N3DS //No emuNAND detected
if(!console || !mode){ if(!*pos_header) return 0;
void *pos_instr = memsearch((void *)emuCodeOffset, "\xA6\x01\x08\x30", size, 4);
memcpy(pos_instr, emuInstr, sizeof(emuInstr)); //Calculate offset for the hooks
} *(u32 *)(nandRedir + 4) = emuCodeOffset - (u32)firmLocation -
section[2].offset + (u32)section[2].address;
//Add emunand hooks //Add emunand hooks
memcpy((void *)emuRead, nandRedir, sizeof(nandRedir)); memcpy((void *)emuRead, nandRedir, sizeof(nandRedir));
@@ -219,7 +217,7 @@ u32 patchFirm(void){
fOpenOffset; fOpenOffset;
//Read reboot code from SD //Read reboot code from SD
const char path[] = "/rei/reboot/reboot.bin"; const char path[] = "/aurei/reboot/reboot.bin";
u32 size = fileSize(path); u32 size = fileSize(path);
if(!size) return 0; if(!size) return 0;
getReboot(firmLocation, firmSize, &rebootOffset); getReboot(firmLocation, firmSize, &rebootOffset);

98
source/i2c.c Normal file
View File

@@ -0,0 +1,98 @@
#include "i2c.h"
//-----------------------------------------------------------------------------
static const struct { u8 bus_id, reg_addr; } dev_data[] = {
{0, 0x4A}, {0, 0x7A}, {0, 0x78},
{1, 0x4A}, {1, 0x78}, {1, 0x2C},
{1, 0x2E}, {1, 0x40}, {1, 0x44},
{2, 0xD6}, {2, 0xD0}, {2, 0xD2},
{2, 0xA4}, {2, 0x9A}, {2, 0xA0},
};
static inline u8 i2cGetDeviceBusId(u8 device_id) {
return dev_data[device_id].bus_id;
}
static inline u8 i2cGetDeviceRegAddr(u8 device_id) {
return dev_data[device_id].reg_addr;
}
//-----------------------------------------------------------------------------
static vu8* reg_data_addrs[] = {
(vu8*)(I2C1_REG_OFF + I2C_REG_DATA),
(vu8*)(I2C2_REG_OFF + I2C_REG_DATA),
(vu8*)(I2C3_REG_OFF + I2C_REG_DATA),
};
static inline vu8* i2cGetDataReg(u8 bus_id) {
return reg_data_addrs[bus_id];
}
//-----------------------------------------------------------------------------
static vu8* reg_cnt_addrs[] = {
(vu8*)(I2C1_REG_OFF + I2C_REG_CNT),
(vu8*)(I2C2_REG_OFF + I2C_REG_CNT),
(vu8*)(I2C3_REG_OFF + I2C_REG_CNT),
};
static inline vu8* i2cGetCntReg(u8 bus_id) {
return reg_cnt_addrs[bus_id];
}
//-----------------------------------------------------------------------------
static inline void i2cWaitBusy(u8 bus_id) {
while (*i2cGetCntReg(bus_id) & 0x80);
}
static inline u32 i2cGetResult(u8 bus_id) {
i2cWaitBusy(bus_id);
return (*i2cGetCntReg(bus_id) >> 4) & 1;
}
static void i2cStop(u8 bus_id, u8 arg0) {
*i2cGetCntReg(bus_id) = (arg0 << 5) | 0xC0;
i2cWaitBusy(bus_id);
*i2cGetCntReg(bus_id) = 0xC5;
}
//-----------------------------------------------------------------------------
static u32 i2cSelectDevice(u8 bus_id, u8 dev_reg) {
i2cWaitBusy(bus_id);
*i2cGetDataReg(bus_id) = dev_reg;
*i2cGetCntReg(bus_id) = 0xC2;
return i2cGetResult(bus_id);
}
static u32 i2cSelectRegister(u8 bus_id, u8 reg) {
i2cWaitBusy(bus_id);
*i2cGetDataReg(bus_id) = reg;
*i2cGetCntReg(bus_id) = 0xC0;
return i2cGetResult(bus_id);
}
//-----------------------------------------------------------------------------
u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data) {
u8 bus_id = i2cGetDeviceBusId(dev_id);
u8 dev_addr = i2cGetDeviceRegAddr(dev_id);
for (int i = 0; i < 8; i++) {
if (i2cSelectDevice(bus_id, dev_addr) && i2cSelectRegister(bus_id, reg)) {
i2cWaitBusy(bus_id);
*i2cGetDataReg(bus_id) = data;
*i2cGetCntReg(bus_id) = 0xC1;
i2cStop(bus_id, 0);
if (i2cGetResult(bus_id))
return 1;
}
*i2cGetCntReg(bus_id) = 0xC5;
i2cWaitBusy(bus_id);
}
return 0;
}

18
source/i2c.h Normal file
View File

@@ -0,0 +1,18 @@
#pragma once
#include "types.h"
#define I2C1_REG_OFF 0x10161000
#define I2C2_REG_OFF 0x10144000
#define I2C3_REG_OFF 0x10148000
#define I2C_REG_DATA 0
#define I2C_REG_CNT 1
#define I2C_REG_CNTEX 2
#define I2C_REG_SCL 4
#define I2C_DEV_MCU 3
#define I2C_DEV_GYRO 10
#define I2C_DEV_IR 13
u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data);

View File

@@ -8,7 +8,7 @@
#define PAYLOAD_ADDRESS 0x24F00000 #define PAYLOAD_ADDRESS 0x24F00000
void loadPayload(void){ void loadPayload(void){
if(fileExists("rei/payloads/default.bin") && if(fileExists("aurei/payloads/default.bin") &&
fileRead((u8 *)PAYLOAD_ADDRESS, "rei/loader.bin", 0)) fileRead((u8 *)PAYLOAD_ADDRESS, "aurei/loader.bin", 0))
((void (*)())PAYLOAD_ADDRESS)(); ((void (*)())PAYLOAD_ADDRESS)();
} }

View File

@@ -8,14 +8,16 @@
#include "fs.h" #include "fs.h"
#include "firm.h" #include "firm.h"
#include "i2c.h"
void main(){ void main(void){
mountSD(); mountSD();
setupCFW(); setupCFW();
}
void startCFW(){
if(!loadFirm()) return; if(!loadFirm()) return;
if(!patchFirm()) return; if(!patchFirm()) return;
launchFirm(); launchFirm();
} }
void shutdown(void){
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1);
}

View File

@@ -19,6 +19,12 @@ void memset(void *dest, int filler, u32 size){
destc[i] = (u8)filler; destc[i] = (u8)filler;
} }
void memset32(void *dest, u32 filler, u32 size){
u32 *dest32 = (u32 *)dest;
for (u32 i = 0; i < size / 4; i++)
dest32[i] = filler;
}
int memcmp(const void *buf1, const void *buf2, u32 size){ int memcmp(const void *buf1, const void *buf2, u32 size){
const u8 *buf1c = (const u8 *)buf1; const u8 *buf1c = (const u8 *)buf1;
const u8 *buf2c = (const u8 *)buf2; const u8 *buf2c = (const u8 *)buf2;

View File

@@ -10,5 +10,6 @@
void memcpy(void *dest, const void *src, u32 size); void memcpy(void *dest, const void *src, u32 size);
void memset(void *dest, int filler, u32 size); void memset(void *dest, int filler, u32 size);
void memset32(void *dest, u32 filler, u32 size);
int memcmp(const void *buf1, const void *buf2, u32 size); int memcmp(const void *buf1, const void *buf2, u32 size);
void *memsearch(void *start_pos, const void *search, u32 size, u32 size_search); void *memsearch(void *start_pos, const void *search, u32 size, u32 size_search);

View File

@@ -17,7 +17,8 @@ const u8 mpu[0x2C] = { //MPU shit
0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x08 0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x08
}; };
u8 nandRedir[0x08] = {0x00, 0x4C, 0xA0, 0x47, 0xC0, 0xA5, 0x01, 0x08}; //Branch to emunand function //Branch to emunand function. To be filled in
u8 nandRedir[0x08] = {0x00, 0x4C, 0xA0, 0x47, 0x00, 0x00, 0x00, 0x00};
const u8 sigPat1[2] = {0x00, 0x20}; const u8 sigPat1[2] = {0x00, 0x20};
const u8 sigPat2[4] = {0x00, 0x20, 0x70, 0x47}; const u8 sigPat2[4] = {0x00, 0x20, 0x70, 0x47};

View File

@@ -10,7 +10,7 @@ _start:
mcr p15, 0, r0, c5, c0, 2 @ write data access mcr p15, 0, r0, c5, c0, 2 @ write data access
mcr p15, 0, r0, c5, c0, 3 @ write instruction access mcr p15, 0, r0, c5, c0, 3 @ write instruction access
@ Set MPU permissions @ Set MPU permissions and cache settings
ldr r0, =0xFFFF001D @ ffff0000 32k ldr r0, =0xFFFF001D @ ffff0000 32k
ldr r1, =0x01FF801D @ 01ff8000 32k ldr r1, =0x01FF801D @ 01ff8000 32k
ldr r2, =0x08000027 @ 08000000 1M ldr r2, =0x08000027 @ 08000000 1M
@@ -27,6 +27,10 @@ _start:
mcr p15, 0, r5, c6, c5, 0 mcr p15, 0, r5, c6, c5, 0
mcr p15, 0, r6, c6, c6, 0 mcr p15, 0, r6, c6, c6, 0
mcr p15, 0, r7, c6, c7, 0 mcr p15, 0, r7, c6, c7, 0
mov r0, #0x25
mcr p15, 0, r0, c2, c0, 0 @ data cacheable
mcr p15, 0, r0, c2, c0, 1 @ instruction cacheable
mcr p15, 0, r0, c3, c0, 0 @ data bufferable
@ Enable caches @ Enable caches
mrc p15, 0, r0, c1, c0, 0 @ read control register mrc p15, 0, r0, c1, c0, 0 @ read control register
@@ -48,13 +52,7 @@ _start:
bl main bl main
@ Set cache settings bl shutdown
mov r0, #0x25
mcr p15, 0, r0, c3, c0, 0 @ Write bufferable 0, 2, 5
mcr p15, 0, r0, c2, c0, 0 @ Data cacheable 0, 2, 5
mcr p15, 0, r0, c2, c0, 1 @ Inst cacheable 0, 2, 5
bl startCFW
.die: .die:
b .die b .die