mirror of
https://github.com/LumaTeam/Luma3DS.git
synced 2026-02-22 09:54:38 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8b29125bc |
32
Makefile
32
Makefile
@ -12,7 +12,7 @@ ifneq ($(PYTHON_VER_MAJOR), 3)
|
||||
PYTHON3 := py -3
|
||||
endif
|
||||
|
||||
name := ReiNand
|
||||
name := AuReiNand
|
||||
|
||||
dir_source := source
|
||||
dir_data := data
|
||||
@ -26,7 +26,7 @@ dir_loader := loader
|
||||
|
||||
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
|
||||
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, \
|
||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||
@ -43,29 +43,29 @@ launcher: $(dir_out)/$(name).dat
|
||||
a9lh: $(dir_out)/arm9loaderhax.bin
|
||||
|
||||
.PHONY: emunand
|
||||
emunand: $(dir_out)/rei/emunand/emunand.bin
|
||||
emunand: $(dir_out)/aurei/emunand/emunand.bin
|
||||
|
||||
.PHONY: reboot
|
||||
reboot: $(dir_out)/rei/reboot/reboot.bin
|
||||
reboot: $(dir_out)/aurei/reboot/reboot.bin
|
||||
|
||||
.PHONY: ninjhax
|
||||
ninjhax: $(dir_out)/3ds/$(name)
|
||||
|
||||
.PHONY: loader
|
||||
loader: $(dir_out)/rei/loader.bin
|
||||
loader: $(dir_out)/aurei/loader.bin
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@$(MAKE) $(FLAGS) -C $(dir_mset) clean
|
||||
@$(MAKE) $(FLAGS) -C $(dir_ninjhax) clean
|
||||
@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
|
||||
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 $@
|
||||
|
||||
$(dir_out)/3ds/$(name):
|
||||
@ -74,21 +74,21 @@ $(dir_out)/3ds/$(name):
|
||||
@mv $(dir_out)/$(name).3dsx $@
|
||||
@mv $(dir_out)/$(name).smdh $@
|
||||
|
||||
$(dir_out)/rei:
|
||||
@mkdir -p "$(dir_out)/rei"
|
||||
$(dir_out)/aurei:
|
||||
@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 $<
|
||||
@mkdir -p "$(dir_out)/rei/emunand"
|
||||
@mkdir -p "$(dir_out)/aurei/emunand"
|
||||
@mv emunand.bin $@
|
||||
|
||||
$(dir_out)/rei/reboot/reboot.bin: $(dir_reboot)/rebootCode.s
|
||||
$(dir_out)/aurei/reboot/reboot.bin: $(dir_reboot)/rebootCode.s
|
||||
@armips $<
|
||||
@mkdir -p "$(dir_out)/rei/reboot"
|
||||
@mkdir -p "$(dir_out)/aurei/reboot"
|
||||
@mv reboot.bin $@
|
||||
|
||||
$(dir_out)/rei/loader.bin: $(dir_out)/rei $(dir_loader)/Makefile
|
||||
@cd $(dir_loader) && make
|
||||
$(dir_out)/aurei/loader.bin: $(dir_out)/aurei $(dir_loader)/Makefile
|
||||
@$(MAKE) -C $(dir_loader)
|
||||
@mv $(dir_loader)/loader.bin $@
|
||||
|
||||
$(dir_build)/main.bin: $(dir_build)/main.elf
|
||||
|
||||
BIN
icon.png
BIN
icon.png
Binary file not shown.
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 3.1 KiB |
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../../types.h"
|
||||
@ -10,11 +10,11 @@ static const struct { u8 bus_id, reg_addr; } dev_data[] = {
|
||||
{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;
|
||||
}
|
||||
|
||||
inline u8 i2cGetDeviceRegAddr(u8 device_id) {
|
||||
static inline u8 i2cGetDeviceRegAddr(u8 device_id) {
|
||||
return dev_data[device_id].reg_addr;
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ static vu8* reg_data_addrs[] = {
|
||||
(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];
|
||||
}
|
||||
|
||||
@ -38,22 +38,22 @@ static vu8* reg_cnt_addrs[] = {
|
||||
(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];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void i2cWaitBusy(u8 bus_id) {
|
||||
static inline void i2cWaitBusy(u8 bus_id) {
|
||||
while (*i2cGetCntReg(bus_id) & 0x80);
|
||||
}
|
||||
|
||||
inline bool i2cGetResult(u8 bus_id) {
|
||||
static inline u32 i2cGetResult(u8 bus_id) {
|
||||
i2cWaitBusy(bus_id);
|
||||
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;
|
||||
i2cWaitBusy(bus_id);
|
||||
*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);
|
||||
*i2cGetDataReg(bus_id) = dev_reg;
|
||||
*i2cGetCntReg(bus_id) = 0xC2;
|
||||
return i2cGetResult(bus_id);
|
||||
}
|
||||
|
||||
bool i2cSelectRegister(u8 bus_id, u8 reg) {
|
||||
static u32 i2cSelectRegister(u8 bus_id, u8 reg) {
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetDataReg(bus_id) = reg;
|
||||
*i2cGetCntReg(bus_id) = 0xC0;
|
||||
@ -77,58 +77,7 @@ bool i2cSelectRegister(u8 bus_id, u8 reg) {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
u8 i2cReadRegister(u8 dev_id, u8 reg) {
|
||||
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) {
|
||||
u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data) {
|
||||
u8 bus_id = i2cGetDeviceBusId(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;
|
||||
i2cStop(bus_id, 0);
|
||||
if (i2cGetResult(bus_id))
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
*i2cGetCntReg(bus_id) = 0xC5;
|
||||
i2cWaitBusy(bus_id);
|
||||
}
|
||||
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -15,21 +15,4 @@
|
||||
#define I2C_DEV_GYRO 10
|
||||
#define I2C_DEV_IR 13
|
||||
|
||||
u8 i2cGetDeviceBusId(u8 device_id);
|
||||
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);
|
||||
u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
|
||||
@ -26,16 +26,16 @@ void main(void){
|
||||
//Get pressed buttons
|
||||
u16 pressed = HID_PAD;
|
||||
|
||||
if(((pressed & BUTTON_B) && loadPayload("/rei/payloads/b.bin")) ||
|
||||
((pressed & BUTTON_X) && loadPayload("/rei/payloads/x.bin")) ||
|
||||
((pressed & BUTTON_Y) && loadPayload("/rei/payloads/y.bin")) ||
|
||||
((pressed & BUTTON_SELECT) && loadPayload("/rei/payloads/select.bin")) ||
|
||||
((pressed & BUTTON_START) && loadPayload("/rei/payloads/start.bin")) ||
|
||||
((pressed & BUTTON_RIGHT) && loadPayload("/rei/payloads/right.bin")) ||
|
||||
((pressed & BUTTON_LEFT) && loadPayload("/rei/payloads/left.bin")) ||
|
||||
((pressed & BUTTON_UP) && loadPayload("/rei/payloads/up.bin")) ||
|
||||
((pressed & BUTTON_DOWN) && loadPayload("/rei/payloads/down.bin")) ||
|
||||
loadPayload("/rei/payloads/default.bin")){
|
||||
if(((pressed & BUTTON_B) && loadPayload("/aurei/payloads/b.bin")) ||
|
||||
((pressed & BUTTON_X) && loadPayload("/aurei/payloads/x.bin")) ||
|
||||
((pressed & BUTTON_Y) && loadPayload("/aurei/payloads/y.bin")) ||
|
||||
((pressed & BUTTON_SELECT) && loadPayload("/aurei/payloads/select.bin")) ||
|
||||
((pressed & BUTTON_START) && loadPayload("/aurei/payloads/start.bin")) ||
|
||||
((pressed & BUTTON_RIGHT) && loadPayload("/aurei/payloads/right.bin")) ||
|
||||
((pressed & BUTTON_LEFT) && loadPayload("/aurei/payloads/left.bin")) ||
|
||||
((pressed & BUTTON_UP) && loadPayload("/aurei/payloads/up.bin")) ||
|
||||
((pressed & BUTTON_DOWN) && loadPayload("/aurei/payloads/down.bin")) ||
|
||||
loadPayload("/aurei/payloads/default.bin")){
|
||||
//Determine if screen was already inited
|
||||
if(*(vu8 *)0x10141200 == 0x1) initLCD();
|
||||
((void (*)())PAYLOAD_ADDRESS)();
|
||||
|
||||
@ -2,9 +2,10 @@
|
||||
#include "i2c.h"
|
||||
|
||||
void initLCD(void){
|
||||
vu32 *const arm11 = (u32 *)0x1FFFFFF8;
|
||||
vu32 *const arm11 = (vu32 *)0x1FFFFFF8;
|
||||
|
||||
void __attribute__((naked)) ARM11(void){
|
||||
__asm(".word 0xF10C01C0");
|
||||
*(vu32 *)0x10141200 = 0x1007F;
|
||||
*(vu32 *)0x10202014 = 0x00000001;
|
||||
*(vu32 *)0x1020200C &= 0xFFFEFFFE;
|
||||
@ -91,6 +92,11 @@ void initLCD(void){
|
||||
*(vu32 *)0x10400568 = 0x18346500;
|
||||
*(vu32 *)0x1040056c = 0x18346500;
|
||||
|
||||
//Set CakeBrah framebuffers
|
||||
*((vu32 *)0x23FFFE00) = 0x18300000;
|
||||
*((vu32 *)0x23FFFE04) = 0x18300000;
|
||||
*((vu32 *)0x23FFFE08) = 0x18346500;
|
||||
|
||||
//Clear ARM11 entry offset
|
||||
*arm11 = 0;
|
||||
|
||||
@ -100,14 +106,6 @@ void initLCD(void){
|
||||
((void (*)())*arm11)();
|
||||
}
|
||||
|
||||
//Set CakeBrah framebuffers
|
||||
*(vu32 *)0x23FFFE00 = 0x18300000;
|
||||
*(vu32 *)0x23FFFE04 = 0x18300000;
|
||||
*(vu32 *)0x23FFFE08 = 0x18346500;
|
||||
|
||||
*arm11 = (u32)ARM11;
|
||||
|
||||
//This delay is needed for some reason
|
||||
for(vu32 i = 0; i < 0x2000; ++i);
|
||||
while(*arm11);
|
||||
}
|
||||
@ -6,7 +6,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ Memcpy:
|
||||
BX LR
|
||||
|
||||
FileName:
|
||||
.dcw "sdmc:/rei/patched_firmware_sys.bin"
|
||||
.dcw "sdmc:/aurei/patched_firmware_sys.bin"
|
||||
.word 0x0
|
||||
|
||||
.pool
|
||||
|
||||
@ -33,16 +33,16 @@ void __attribute__((naked)) shutdownLCD(void){
|
||||
}
|
||||
|
||||
static void clearScreen(void){
|
||||
memset(fb->top_left, 0, 0x46500);
|
||||
memset(fb->top_right, 0, 0x46500);
|
||||
memset(fb->bottom, 0, 0x38400);
|
||||
memset32(fb->top_left, 0, 0x46500);
|
||||
memset32(fb->top_right, 0, 0x46500);
|
||||
memset32(fb->bottom, 0, 0x38400);
|
||||
}
|
||||
|
||||
void loadSplash(void){
|
||||
clearScreen();
|
||||
//Don't delay boot if no splash image is on the SD
|
||||
if(fileRead(fb->top_left, "/rei/splash.bin", 0x46500) +
|
||||
fileRead(fb->bottom, "/rei/splashbottom.bin", 0x38400)){
|
||||
u64 i = 0xFFFFFF; while(--i) __asm("mov r0, r0"); //Less Ghetto sleep func
|
||||
if(fileRead(fb->top_left, "/aurei/splash.bin", 0x46500) +
|
||||
fileRead(fb->bottom, "/aurei/splashbottom.bin", 0x38400)){
|
||||
u64 i = 0x1300000; while(--i) __asm("mov r0, r0"); //Less Ghetto sleep func
|
||||
}
|
||||
}
|
||||
@ -22,6 +22,11 @@ void getEmunandSect(u32 *off, u32 *head, u32 emuNAND){
|
||||
}
|
||||
//Fallback to the first emuNAND if there's no second one
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
/ 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.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
|
||||
@ -32,7 +32,7 @@ void setupCFW(void){
|
||||
//Retrieve the last booted FIRM
|
||||
u8 previousFirm = CFG_BOOTENV;
|
||||
u32 overrideConfig = 0;
|
||||
const char lastConfigPath[] = "rei/lastbootcfg";
|
||||
const char lastConfigPath[] = "aurei/lastbootcfg";
|
||||
|
||||
//Detect the console being used
|
||||
if(PDN_MPCORE_CFG == 1) console = 0;
|
||||
@ -41,10 +41,10 @@ void setupCFW(void){
|
||||
pressed = HID_PAD;
|
||||
|
||||
//Determine if A9LH is installed
|
||||
if(a9lhBoot || fileExists("/rei/installeda9lh")){
|
||||
if(a9lhBoot || fileExists("/aurei/installeda9lh")){
|
||||
a9lhSetup = 1;
|
||||
//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
|
||||
@ -92,14 +92,14 @@ void setupCFW(void){
|
||||
}
|
||||
}
|
||||
|
||||
if(mode) firmPathPatched = emuNAND ? (emuNAND == 1 ? "/rei/patched_firmware_emu.bin" :
|
||||
"/rei/patched_firmware_em2.bin") :
|
||||
"/rei/patched_firmware_sys.bin";
|
||||
if(mode) firmPathPatched = emuNAND ? (emuNAND == 1 ? "/aurei/patched_firmware_emu.bin" :
|
||||
"/aurei/patched_firmware_em2.bin") :
|
||||
"/aurei/patched_firmware_sys.bin";
|
||||
|
||||
//Skip decrypting and patching FIRM
|
||||
if(fileExists("/rei/usepatchedfw")){
|
||||
if(fileExists("/aurei/usepatchedfw")){
|
||||
//Only needed with this flag
|
||||
if(!mode) firmPathPatched = "/rei/patched_firmware90.bin";
|
||||
if(!mode) firmPathPatched = "/aurei/patched_firmware90.bin";
|
||||
if(fileExists(firmPathPatched)) usePatchedFirm = 1;
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ u32 loadFirm(void){
|
||||
//Load FIRM from SD
|
||||
else{
|
||||
const char *path = usePatchedFirm ? firmPathPatched :
|
||||
(mode ? "/rei/firmware.bin" : "/rei/firmware90.bin");
|
||||
(mode ? "/aurei/firmware.bin" : "/aurei/firmware90.bin");
|
||||
firmSize = fileSize(path);
|
||||
if(!firmSize) return 0;
|
||||
fileRead((u8 *)firmLocation, path, firmSize);
|
||||
@ -147,7 +147,7 @@ static u32 loadEmu(void){
|
||||
emuCodeOffset;
|
||||
|
||||
//Read emunand code from SD
|
||||
const char path[] = "/rei/emunand/emunand.bin";
|
||||
const char path[] = "/aurei/emunand/emunand.bin";
|
||||
u32 size = fileSize(path);
|
||||
if(!size) return 0;
|
||||
if(!console || !mode) nandRedir[5] = 0xA4;
|
||||
@ -168,6 +168,9 @@ static u32 loadEmu(void){
|
||||
*pos_offset = emuOffset;
|
||||
*pos_header = emuHeader;
|
||||
|
||||
//No emuNAND detected
|
||||
if(!*pos_header) return 0;
|
||||
|
||||
//Patch emuNAND code in memory for O3DS and 9.0 N3DS
|
||||
if(!console || !mode){
|
||||
void *pos_instr = memsearch((void *)emuCodeOffset, "\xA6\x01\x08\x30", size, 4);
|
||||
@ -219,7 +222,7 @@ u32 patchFirm(void){
|
||||
fOpenOffset;
|
||||
|
||||
//Read reboot code from SD
|
||||
const char path[] = "/rei/reboot/reboot.bin";
|
||||
const char path[] = "/aurei/reboot/reboot.bin";
|
||||
u32 size = fileSize(path);
|
||||
if(!size) return 0;
|
||||
getReboot(firmLocation, firmSize, &rebootOffset);
|
||||
|
||||
98
source/i2c.c
Normal file
98
source/i2c.c
Normal 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
18
source/i2c.h
Normal 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);
|
||||
@ -8,7 +8,7 @@
|
||||
#define PAYLOAD_ADDRESS 0x24F00000
|
||||
|
||||
void loadPayload(void){
|
||||
if(fileExists("rei/payloads/default.bin") &&
|
||||
fileRead((u8 *)PAYLOAD_ADDRESS, "rei/loader.bin", 0))
|
||||
if(fileExists("aurei/payloads/default.bin") &&
|
||||
fileRead((u8 *)PAYLOAD_ADDRESS, "aurei/loader.bin", 0))
|
||||
((void (*)())PAYLOAD_ADDRESS)();
|
||||
}
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#include "fs.h"
|
||||
#include "firm.h"
|
||||
#include "i2c.h"
|
||||
|
||||
void main(void){
|
||||
mountSD();
|
||||
@ -18,4 +19,8 @@ void startCFW(void){
|
||||
if(!loadFirm()) return;
|
||||
if(!patchFirm()) return;
|
||||
launchFirm();
|
||||
}
|
||||
|
||||
void shutdown(void){
|
||||
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1);
|
||||
}
|
||||
@ -19,6 +19,13 @@ void memset(void *dest, int filler, u32 size){
|
||||
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){
|
||||
const u8 *buf1c = (const u8 *)buf1;
|
||||
const u8 *buf2c = (const u8 *)buf2;
|
||||
|
||||
@ -10,5 +10,6 @@
|
||||
|
||||
void memcpy(void *dest, const void *src, 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);
|
||||
void *memsearch(void *start_pos, const void *search, u32 size, u32 size_search);
|
||||
@ -10,7 +10,7 @@ _start:
|
||||
mcr p15, 0, r0, c5, c0, 2 @ write data 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 r1, =0x01FF801D @ 01ff8000 32k
|
||||
ldr r2, =0x08000027 @ 08000000 1M
|
||||
@ -27,6 +27,11 @@ _start:
|
||||
mcr p15, 0, r5, c6, c5, 0
|
||||
mcr p15, 0, r6, c6, c6, 0
|
||||
mcr p15, 0, r7, c6, c7, 0
|
||||
mov r4, #0x25
|
||||
mov r0, #0x5
|
||||
mcr p15, 0, r4, c2, c0, 0 @ data cacheable
|
||||
mcr p15, 0, r4, c2, c0, 1 @ instruction cacheable
|
||||
mcr p15, 0, r0, c3, c0, 0 @ data bufferable
|
||||
|
||||
@ Enable caches
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control register
|
||||
@ -48,13 +53,11 @@ _start:
|
||||
|
||||
bl main
|
||||
|
||||
@ Set cache settings
|
||||
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
|
||||
mcr p15, 0, r4, c3, c0, 0 @ data bufferable
|
||||
|
||||
bl startCFW
|
||||
|
||||
bl shutdown
|
||||
|
||||
.die:
|
||||
b .die
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user