Potentially fix screen init on some systems

Sanitized I2C
Reorganized the memory layout
 - Moved GM9 to ARM9 RAM
 - Increased RAMdisk size to 88MiB
This commit is contained in:
Wolfvak 2017-09-26 19:56:19 -03:00
parent 5e652b1313
commit 8a4597635d
10 changed files with 165 additions and 157 deletions

View File

@ -74,7 +74,7 @@ endif
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
LDFLAGS = -T../link.ld -nostartfiles -g $(ARCH) -Wl,-Map,$(TARGET).map LDFLAGS = -T../link.ld -nostartfiles -g $(ARCH) -Wl,-Map,$(TARGET).map,-z,max-page-size=512
LIBS := LIBS :=
@ -152,12 +152,12 @@ binary: common
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
firm: binary screeninit firm: binary screeninit
firmtool build $(OUTPUT).firm -n 0x08006000 -A 0x08006000 -D $(OUTPUT).bin $(OUTPUT_D)/screeninit.elf -C NDMA XDMA -S nand-retail -g firmtool build $(OUTPUT).firm -D $(OUTPUT).elf $(OUTPUT_D)/screeninit.elf -C NDMA XDMA -S nand-retail -g
firmtool build $(OUTPUT)_dev.firm -n 0x08006000 -A 0x08006000 -D $(OUTPUT).bin $(OUTPUT_D)/screeninit.elf -C NDMA XDMA -S nand-dev -g firmtool build $(OUTPUT)_dev.firm -D $(OUTPUT).elf $(OUTPUT_D)/screeninit.elf -C NDMA XDMA -S nand-dev -g
ntrboot: binary screeninit ntrboot: binary screeninit
firmtool build $(OUTPUT)_ntr.firm -n 0x08006000 -A 0x08006000 -D $(OUTPUT).bin $(OUTPUT_D)/screeninit.elf -C NDMA XDMA -S spi-retail -g firmtool build $(OUTPUT)_ntr.firm -D $(OUTPUT).elf $(OUTPUT_D)/screeninit.elf -C NDMA XDMA -S spi-retail -g
firmtool build $(OUTPUT)_ntr_dev.firm -n 0x08006000 -A 0x08006000 -D $(OUTPUT).bin $(OUTPUT_D)/screeninit.elf -C NDMA XDMA -S spi-dev -g firmtool build $(OUTPUT)_ntr_dev.firm -D $(OUTPUT).elf $(OUTPUT_D)/screeninit.elf -C NDMA XDMA -S spi-dev -g
release: release:
@-rm -fr $(BUILD) $(OUTPUT_D) $(RELEASE) @-rm -fr $(BUILD) $(OUTPUT_D) $(RELEASE)

View File

@ -18,6 +18,7 @@ enum {
PXI_NONE = 0, PXI_NONE = 0,
PXI_READY, PXI_READY,
PXI_BUSY, PXI_BUSY,
PXI_SCREENINIT,
PXI_BRIGHTNESS PXI_BRIGHTNESS
}; };

View File

@ -4,7 +4,7 @@ ENTRY(_start)
SECTIONS SECTIONS
{ {
. = 0x23F00000; . = 0x08006000;
__start__ = ABSOLUTE(.); __start__ = ABSOLUTE(.);
.text.start : ALIGN(4) { *(.text.start) } .text.start : ALIGN(4) { *(.text.start) }
@ -17,7 +17,7 @@ SECTIONS
__end__ = ABSOLUTE(.); __end__ = ABSOLUTE(.);
__stack_abt = __start__; __stack_abt = 0x22800000;
__stack_top = __start__ - 0x80000; __stack_top = __stack_abt - 0x80000;
__code_size__ = __end__ - __start__; __code_size__ = __end__ - __start__;
} }

View File

@ -19,7 +19,7 @@ ASFLAGS := $(ARCH) -x assembler-with-cpp $(INCLUDE)
CFLAGS := $(ARCH) -Wall -Wextra -MMD -MP -fno-builtin \ CFLAGS := $(ARCH) -Wall -Wextra -MMD -MP -fno-builtin \
-Wno-unused-function -Wno-unused-variable \ -Wno-unused-function -Wno-unused-variable \
-std=c11 -O2 -flto -ffast-math -Wno-main $(INCLUDE) -std=c11 -O2 -flto -ffast-math -Wno-main $(INCLUDE)
LDFLAGS := -nostdlib -nostartfiles LDFLAGS := -nostdlib -nostartfiles -Wl,-z,max-page-size=512
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \

View File

@ -1,7 +1,6 @@
#include <cpu.h> #include <cpu.h>
#include <pxi.h> #include <pxi.h>
#include <gic.h> #include <gic.h>
#include <i2c.h>
#include <gpulcd.h> #include <gpulcd.h>
#include <vram.h> #include <vram.h>
#include <types.h> #include <types.h>
@ -19,6 +18,21 @@ void PXI_IRQHandler(void)
default: default:
break; break;
case PXI_SCREENINIT:
{
GPU_Init();
GPU_PSCFill(VRAM_START, VRAM_END, 0);
GPU_SetFramebuffers((u32[]){VRAM_TOP_LA, VRAM_TOP_LB,
VRAM_TOP_RA, VRAM_TOP_RB,
VRAM_BOT_A, VRAM_BOT_B});
GPU_SetFramebufferMode(0, PDC_RGB24);
GPU_SetFramebufferMode(1, PDC_RGB24);
PXI_SetRemote(PXI_BUSY);
break;
}
case PXI_BRIGHTNESS: case PXI_BRIGHTNESS:
{ {
PXI_RecvArray(pxi_args, 1); PXI_RecvArray(pxi_args, 1);
@ -50,17 +64,6 @@ void main(void)
u32 entry; u32 entry;
PXI_Reset(); PXI_Reset();
GPU_Init();
GPU_PSCFill(VRAM_START, VRAM_END, 0);
GPU_SetFramebuffers((u32[]){VRAM_TOP_LA, VRAM_TOP_LB,
VRAM_TOP_RA, VRAM_TOP_RB,
VRAM_BOT_A, VRAM_BOT_B});
GPU_SetFramebufferMode(0, PDC_RGB24);
GPU_SetFramebufferMode(1, PDC_RGB24);
I2C_writeReg(I2C_DEV_MCU, 0x22, 0x2A);
GIC_Reset(); GIC_Reset();
GIC_SetIRQ(IRQ_PXI_SYNC, PXI_IRQHandler); GIC_SetIRQ(IRQ_PXI_SYNC, PXI_IRQHandler);
PXI_EnableIRQ(); PXI_EnableIRQ();

View File

@ -91,6 +91,6 @@
#define TEMP_BUFFER_SIZE (0x1800000) // 24MB(!) #define TEMP_BUFFER_SIZE (0x1800000) // 24MB(!)
// buffer area defines (in use by image.c, for RAMdrive) // buffer area defines (in use by image.c, for RAMdrive)
#define RAMDRV_BUFFER ((u8*)0x24000000) // top half of FCRAM #define RAMDRV_BUFFER ((u8*)0x22800000) // top of STACK
#define RAMDRV_SIZE_O3DS (0x04000000) // 64MB #define RAMDRV_SIZE_O3DS (0x5800000) // 88MB
#define RAMDRV_SIZE_N3DS (0x0C000000) // 192MB #define RAMDRV_SIZE_N3DS (0xD800000) // 216MB

View File

@ -1,6 +1,7 @@
#include "godmode.h" #include "godmode.h"
#include "power.h" #include "power.h"
#include "pxi.h" #include "pxi.h"
#include "i2c.h"
void main(int argc, char** argv) void main(int argc, char** argv)
{ {
@ -8,14 +9,18 @@ void main(int argc, char** argv)
// Wait for ARM11 // Wait for ARM11
PXI_WaitRemote(PXI_READY); PXI_WaitRemote(PXI_READY);
PXI_DoCMD(PXI_SCREENINIT, NULL, 0);
I2C_writeReg(I2C_DEV_MCU, 0x22, 0x2A);
#ifdef AUTORUN_SCRIPT #ifdef AUTORUN_SCRIPT
// Run the script runner // Run the script runner
if (ScriptRunner(argc) == GODMODE_EXIT_REBOOT) Reboot(); if (ScriptRunner(argc) == GODMODE_EXIT_REBOOT)
else PowerOff();
#else #else
// Run the main program // Run the main program
if (GodMode(argc) == GODMODE_EXIT_REBOOT) Reboot(); if (GodMode(argc) == GODMODE_EXIT_REBOOT)
else PowerOff();
#endif #endif
Reboot();
PowerOff();
} }

View File

@ -5,91 +5,50 @@
#include <arm.h> #include <arm.h>
#include <brf.h> #include <brf.h>
@ Make sure to preserve r0-r2
.global _start .global _start
_start: _start:
@ Switch to supervisor mode and disable interrupts @ Disable interrupts
msr cpsr_c, #(SR_SYS_MODE | SR_IRQ | SR_FIQ) mrs r4, cpsr
orr r4, r4, #(SR_IRQ | SR_FIQ)
msr cpsr_c, r4
@ Short delay (not always necessary, just in case) @ Preserve boot registers
mov r3, #0x40000 mov r9, r0
.Lwaitloop: mov r10, r1
subs r3, #1 mov r11, r2
bgt .Lwaitloop
@ Check the load address
adr r3, _start
ldr r4, =__start__
cmp r3, r4
beq _start_gm
@ Relocate the binary to the correct location and branch to it
ldr r5, =__code_size__
.Lbincopyloop:
subs r5, #4
ldrge r6, [r3, r5]
strge r6, [r4, r5]
bge .Lbincopyloop
mov r5, r0
mov r6, r1
mov r7, r2
ldr r3, =BRF_WB_INV_DCACHE
blx r3
mov r0, r5
mov r1, r6
mov r2, r7
mov lr, #0
mcr p15, 0, lr, c7, c5, 0 @ Invalidate ICache
bx r4
_start_gm:
ldr sp, =__stack_top
mov r9, r0 @ argc
mov r10, r1 @ argv
ldr r4, =0xBEEF
lsl r2, #16
lsr r2, #16
cmp r2, r4 @ magic word
movne r9, #0
@ Disable caches / mpu
ldr r1, =(CR_ENABLE_MPU | CR_ENABLE_DCACHE | CR_ENABLE_ICACHE | \
CR_ENABLE_DTCM)
ldr r2, =(CR_ENABLE_ITCM | CR_CACHE_RROBIN)
mrc p15, 0, r0, c1, c0, 0
bic r0, r1
orr r0, r2
mcr p15, 0, r0, c1, c0, 0
@ Clear bss @ Clear bss
ldr r0, =__bss_start ldr r0, =__bss_start
ldr r1, =__bss_end ldr r1, =__bss_end
mov r2, #0 mov r2, #0
.Lbss_clr: .LBSS_Clear:
cmp r0, r1 cmp r0, r1
strlt r2, [r0], #4 strlo r2, [r0], #4
blt .Lbss_clr blo .LBSS_Clear
@ Invalidate caches ldr r0, =BRF_WB_INV_DCACHE
mov r5, #0 blx r0 @ Writeback & Invalidate Data Cache
mcr p15, 0, r5, c7, c5, 0 @ invalidate I-cache ldr r0, =BRF_INVALIDATE_ICACHE
mcr p15, 0, r5, c7, c6, 0 @ invalidate D-cache blx r0 @ Invalidate Instruction Cache
mcr p15, 0, r5, c7, c10, 4 @ drain write buffer
@ Give read/write access to all the memory regions @ Disable caches / DTCM / MPU
ldr r5, =0x33333333 ldr r1, =(CR_ENABLE_MPU | CR_ENABLE_DCACHE | CR_ENABLE_ICACHE | \
mcr p15, 0, r5, c5, c0, 2 @ write data access CR_ENABLE_DTCM)
mcr p15, 0, r5, c5, c0, 3 @ write instruction access ldr r2, =(CR_ENABLE_ITCM)
mrc p15, 0, r0, c1, c0, 0
bic r0, r1
orr r0, r2
mcr p15, 0, r0, c1, c0, 0
@ Sets MPU regions and cache settings @ Give full access to defined memory regions
ldr r0, =0x33333333
mcr p15, 0, r0, c5, c0, 2 @ write data access
mcr p15, 0, r0, c5, c0, 3 @ write instruction access
@ Set MPU regions and cache settings
adr r0, __mpu_regions adr r0, __mpu_regions
ldmia r0, {r1-r8} ldmia r0, {r1-r8}
mov r0, #0b00101101 @ bootrom/itcm/arm9 mem and fcram are cacheable/bufferable mov r0, #0b00101000
mcr p15, 0, r1, c6, c0, 0 mcr p15, 0, r1, c6, c0, 0
mcr p15, 0, r2, c6, c1, 0 mcr p15, 0, r2, c6, c1, 0
mcr p15, 0, r3, c6, c2, 0 mcr p15, 0, r3, c6, c2, 0
@ -98,13 +57,22 @@ _start_gm:
mcr p15, 0, r6, c6, c5, 0 mcr p15, 0, r6, c6, c5, 0
mcr p15, 0, r7, c6, c6, 0 mcr p15, 0, r7, c6, c6, 0
mcr p15, 0, r8, c6, c7, 0 mcr p15, 0, r8, c6, c7, 0
mcr p15, 0, r0, c3, c0, 0 @ Write bufferable 0, 2, 5 mcr p15, 0, r0, c3, c0, 0 @ Write bufferable
mcr p15, 0, r0, c2, c0, 0 @ Data cacheable 0, 2, 5 mcr p15, 0, r0, c2, c0, 0 @ Data cacheable
mcr p15, 0, r0, c2, c0, 1 @ Inst cacheable 0, 2, 5 mcr p15, 0, r0, c2, c0, 1 @ Inst cacheable
@ Enable dctm @ Enable dctm
ldr r0, =0x3000800A @ set dtcm ldr r0, =0x3000800A
mcr p15, 0, r0, c9, c1, 0 @ set the dtcm Region Register mcr p15, 0, r0, c9, c1, 0 @ set the DTCM Region Register
@ Enable caches / select low exception vectors
ldr r1, =(CR_ALT_VECTORS | CR_DISABLE_TBIT)
ldr r2, =(CR_ENABLE_MPU | CR_ENABLE_DCACHE | CR_ENABLE_ICACHE | \
CR_ENABLE_DTCM | CR_CACHE_RROBIN)
mrc p15, 0, r0, c1, c0, 0
bic r0, r1
orr r0, r2
mcr p15, 0, r0, c1, c0, 0
@ Install exception handlers @ Install exception handlers
ldr r0, =XRQ_Start ldr r0, =XRQ_Start
@ -112,28 +80,30 @@ _start_gm:
ldr r2, =0x00000000 ldr r2, =0x00000000
.LXRQ_Install: .LXRQ_Install:
cmp r0, r1 cmp r0, r1
ldrlt r3, [r0], #4 ldrlo r3, [r0], #4
strlt r3, [r2], #4 strlo r3, [r2], #4
blt .LXRQ_Install blo .LXRQ_Install
@ Enable caches / select low exception vectors @ Fix SDMC mounting
ldr r1, =(CR_ALT_VECTORS | CR_DISABLE_TBIT) mov r0, #0x10000000
ldr r2, =(CR_ENABLE_MPU | CR_ENABLE_DCACHE | CR_ENABLE_ICACHE | \
CR_ENABLE_DTCM)
mrc p15, 0, r0, c1, c0, 0
bic r0, r1
orr r0, r2
mcr p15, 0, r0, c1, c0, 0
@ Fixes mounting of SDMC
ldr r0, =0x10000000
mov r1, #0x340 mov r1, #0x340
str r1, [r0, #0x20] str r1, [r0, #0x20]
mov r0, r9 @ Check arguments
mov r1, r10 lsl r2, r11, #16
lsr r2, r2, #16
bl main ldr r3, =0xBEEF
cmp r2, r3
moveq r0, r9
moveq r1, r10
movne r0, #0
@ Switch to system mode, disable interrupts, setup application stack
msr cpsr_c, #(SR_SYS_MODE | SR_IRQ | SR_FIQ)
ldr sp, =__stack_top
b main
__mpu_regions: __mpu_regions:
.word 0xFFFF001F @ FFFF0000 64k | bootrom (unprotected / protected) .word 0xFFFF001F @ FFFF0000 64k | bootrom (unprotected / protected)

View File

@ -16,39 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once
#include <types.h>
#include <stdbool.h> #include <stdbool.h>
#include "i2c.h"
#define I2C_STOP (1u)
#define I2C_START (1u<<1)
#define I2C_ERROR (1u<<2)
#define I2C_ACK (1u<<4)
#define I2C_DIRE_WRITE (0u)
#define I2C_DIRE_READ (1u<<5)
#define I2C_IRQ_ENABLE (1u<<6)
#define I2C_ENABLE (1u<<7)
#define I2C_GET_ACK(reg) ((bool)((reg)>>4 & 1u))
typedef enum
{
I2C_DEV_POWER = 0, // Unconfirmed
I2C_DEV_CAMERA = 1, // Unconfirmed
I2C_DEV_CAMERA2 = 2, // Unconfirmed
I2C_DEV_MCU = 3,
I2C_DEV_GYRO = 10,
I2C_DEV_DEBUG_PAD = 12,
I2C_DEV_IR = 13,
I2C_DEV_EEPROM = 14, // Unconfirmed
I2C_DEV_NFC = 15,
I2C_DEV_QTM = 16,
I2C_DEV_N3DS_HID = 17
} I2cDevice;
#define I2C1_REGS_BASE (0x10161000) #define I2C1_REGS_BASE (0x10161000)
#define REG_I2C1_DATA *((vu8* )(I2C1_REGS_BASE + 0x00)) #define REG_I2C1_DATA *((vu8* )(I2C1_REGS_BASE + 0x00))
#define REG_I2C1_CNT *((vu8* )(I2C1_REGS_BASE + 0x01)) #define REG_I2C1_CNT *((vu8* )(I2C1_REGS_BASE + 0x01))
@ -94,12 +65,14 @@ static const struct
{2, 0x54} {2, 0x54}
}; };
static inline void i2cWaitBusy(vu8 *cntReg)
static void i2cWaitBusy(vu8 *cntReg)
{ {
while(*cntReg & I2C_ENABLE); while(*cntReg & I2C_ENABLE);
} }
static inline vu8* i2cGetBusRegsBase(u8 busId) static vu8* i2cGetBusRegsBase(u8 busId)
{ {
vu8 *base; vu8 *base;
if(!busId) base = (vu8*)I2C1_REGS_BASE; if(!busId) base = (vu8*)I2C1_REGS_BASE;
@ -161,7 +134,7 @@ static bool i2cStartTransfer(I2cDevice devId, u8 regAddr, bool read, vu8 *regsBa
else return false; else return false;
} }
static void I2C_init(void) void I2C_init(void)
{ {
i2cWaitBusy(i2cGetBusRegsBase(0)); i2cWaitBusy(i2cGetBusRegsBase(0));
REG_I2C1_CNTEX = 2; // ? REG_I2C1_CNTEX = 2; // ?
@ -176,7 +149,7 @@ static void I2C_init(void)
REG_I2C3_SCL = 1280; // ? REG_I2C3_SCL = 1280; // ?
} }
static bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size) bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size)
{ {
const u8 busId = i2cDevTable[devId].busId; const u8 busId = i2cDevTable[devId].busId;
vu8 *const i2cData = i2cGetBusRegsBase(busId); vu8 *const i2cData = i2cGetBusRegsBase(busId);
@ -199,7 +172,7 @@ static bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size)
return true; return true;
} }
static bool I2C_writeReg(I2cDevice devId, u8 regAddr, u8 data) bool I2C_writeReg(I2cDevice devId, u8 regAddr, u8 data)
{ {
const u8 busId = i2cDevTable[devId].busId; const u8 busId = i2cDevTable[devId].busId;
vu8 *const i2cData = i2cGetBusRegsBase(busId); vu8 *const i2cData = i2cGetBusRegsBase(busId);

56
source/system/i2c.h Normal file
View File

@ -0,0 +1,56 @@
#pragma once
/*
* This file is part of fastboot 3DS
* Copyright (C) 2017 derrek, profi200
*
* 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 3 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/>.
*/
#include <stdbool.h>
#include "common.h"
#define I2C_STOP (1u)
#define I2C_START (1u<<1)
#define I2C_ERROR (1u<<2)
#define I2C_ACK (1u<<4)
#define I2C_DIRE_WRITE (0u)
#define I2C_DIRE_READ (1u<<5)
#define I2C_IRQ_ENABLE (1u<<6)
#define I2C_ENABLE (1u<<7)
#define I2C_GET_ACK(reg) ((bool)((reg)>>4 & 1u))
typedef enum
{
I2C_DEV_POWER = 0, // Unconfirmed
I2C_DEV_CAMERA = 1, // Unconfirmed
I2C_DEV_CAMERA2 = 2, // Unconfirmed
I2C_DEV_MCU = 3,
I2C_DEV_GYRO = 10,
I2C_DEV_DEBUG_PAD = 12,
I2C_DEV_IR = 13,
I2C_DEV_EEPROM = 14, // Unconfirmed
I2C_DEV_NFC = 15,
I2C_DEV_QTM = 16,
I2C_DEV_N3DS_HID = 17
} I2cDevice;
void I2C_init(void);
bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size);
bool I2C_writeReg(I2cDevice devId, u8 regAddr, u8 data);