Some cleanup and updates based on recent 3dbrew edits.
This commit is contained in:
parent
8e5562a9f7
commit
c3a1458541
|
@ -22,6 +22,9 @@
|
|||
|
||||
|
||||
#define CFG11_REGS_BASE (IO_MEM_ARM9_ARM11 + 0x40000)
|
||||
#define REGs_CFG11_SHAREDWRAM_32K_CODE (( vu8*)(CFG11_REGS_BASE + 0x000)) // 8 regs.
|
||||
#define REGs_CFG11_SHAREDWRAM_32K_DATA (( vu8*)(CFG11_REGS_BASE + 0x008)) // 8 regs.
|
||||
#define REG_CFG11_UNK100 *(( vu32*)(CFG11_REGS_BASE + 0x100))
|
||||
#define REG_CFG11_FIQ_MASK *(( vu8*)(CFG11_REGS_BASE + 0x104))
|
||||
#define REG_CFG11_UNK105 *(( vu8*)(CFG11_REGS_BASE + 0x105)) // Debug related? Mask?
|
||||
#define REG_CFG11_UNK108 *(( vu8*)(CFG11_REGS_BASE + 0x108)) // LGY gamecard related?
|
||||
|
@ -75,6 +78,6 @@
|
|||
#define BOOTROM_OVERLAY_CNT_E (1u)
|
||||
|
||||
// REG_CFG11_SOCINFO
|
||||
#define SOCINFO_O3DS (1u) // Also set on New3DS.
|
||||
#define SOCINFO_N3DS_PROTO (1u<<1) // Never saw the daylight?
|
||||
#define SOCINFO_N3DS (1u<<2) // Set on New3DS.
|
||||
#define SOCINFO_CTR (1u) // Also set on New 3DS.
|
||||
#define SOCINFO_LGR1 (1u<<1) // Never saw the daylight? Set on retail N3DS (LGR2).
|
||||
#define SOCINFO_LGR2 (1u<<2) // Set on New 3DS.
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define REG_PDN_CNT *((vu16*)(PDN_REGS_BASE + 0x000))
|
||||
#define REG_PDN_WAKE_ENABLE *((vu32*)(PDN_REGS_BASE + 0x008))
|
||||
#define REG_PDN_WAKE_REASON *((vu32*)(PDN_REGS_BASE + 0x00C)) // Write 1 to acknowledge and 0 to clear?
|
||||
// Some LGY regs are located inbetween. See lgy.h/c.
|
||||
#define REG_PDN_GPU_CNT *((vu32*)(PDN_REGS_BASE + 0x200))
|
||||
#define REG_PDN_VRAM_CNT *((vu8* )(PDN_REGS_BASE + 0x204)) // This reg doesn't seem to exist on retail hardware.
|
||||
#define REG_PDN_LCD_CNT *((vu8* )(PDN_REGS_BASE + 0x208)) // This reg doesn't seem to exist on retail hardware.
|
||||
|
@ -33,10 +34,10 @@
|
|||
#define REG_PDN_I2S_CNT *((vu8* )(PDN_REGS_BASE + 0x220))
|
||||
#define REG_PDN_CAM_CNT *((vu8* )(PDN_REGS_BASE + 0x224))
|
||||
#define REG_PDN_DSP_CNT *((vu8* )(PDN_REGS_BASE + 0x230))
|
||||
#define REG_PDN_G1_CNT *((vu8* )(PDN_REGS_BASE + 0x240)) // Hantro G1 decoder.
|
||||
#define REG_PDN_MPCORE_SOCMODE *((vu16*)(PDN_REGS_BASE + 0x300))
|
||||
#define REG_PDN_MPCORE_CNT *((vu16*)(PDN_REGS_BASE + 0x304)) // Is this reg actually only vu8?
|
||||
#define REGs_PDN_MPCORE_BOOTCNT ((vu8* )(PDN_REGS_BASE + 0x310))
|
||||
#define REG_PDN_G1_CNT *((vu8* )(PDN_REGS_BASE + 0x240)) // Hantro G1 decoder aka MVD.
|
||||
#define REG_PDN_LGR_SOCMODE *((vu16*)(PDN_REGS_BASE + 0x300))
|
||||
#define REG_PDN_LGR_CNT *((vu16*)(PDN_REGS_BASE + 0x304)) // Is this reg actually only vu8?
|
||||
#define REGs_PDN_LGR_CPU_CNT ((vu8* )(PDN_REGS_BASE + 0x310)) // 4 regs.
|
||||
|
||||
|
||||
// REG_PDN_CNT
|
||||
|
@ -63,15 +64,15 @@ enum
|
|||
// Note: The resets are active low.
|
||||
enum
|
||||
{
|
||||
PDN_GPU_CNT_RST_REGS = 1u, // And more?
|
||||
PDN_GPU_CNT_RST_PSC = 1u<<1, // ?
|
||||
PDN_GPU_CNT_RST_GEOSHADER = 1u<<2, // ?
|
||||
PDN_GPU_CNT_RST_RASTERIZER = 1u<<3, // ?
|
||||
PDN_GPU_CNT_RST_PPF = 1u<<4,
|
||||
PDN_GPU_CNT_RST_PDC = 1u<<5, // ?
|
||||
PDN_GPU_CNT_RST_PDC2 = 1u<<6, // Maybe pixel pipeline or so?
|
||||
PDN_GPU_CNT_NORST_REGS = 1u, // And more?
|
||||
PDN_GPU_CNT_NORST_PSC = 1u<<1, // ?
|
||||
PDN_GPU_CNT_NORST_GEOSHADER = 1u<<2, // ?
|
||||
PDN_GPU_CNT_NORST_RASTERIZER = 1u<<3, // ?
|
||||
PDN_GPU_CNT_NORST_PPF = 1u<<4,
|
||||
PDN_GPU_CNT_NORST_PDC = 1u<<5, // ?
|
||||
PDN_GPU_CNT_NORST_PDC2 = 1u<<6, // Maybe pixel pipeline or so?
|
||||
|
||||
PDN_GPU_CNT_RST_ALL = (PDN_GPU_CNT_RST_PDC2<<1) - 1
|
||||
PDN_GPU_CNT_NORST_ALL = (PDN_GPU_CNT_NORST_PDC2<<1) - 1
|
||||
};
|
||||
|
||||
#define PDN_GPU_CNT_CLK_E (1u<<16)
|
||||
|
@ -84,7 +85,7 @@ enum
|
|||
|
||||
// REG_PDN_FCRAM_CNT
|
||||
// Note: Reset is active low.
|
||||
#define PDN_FCRAM_CNT_RST (1u)
|
||||
#define PDN_FCRAM_CNT_NORST (1u)
|
||||
#define PDN_FCRAM_CNT_CLK_E (1u<<1)
|
||||
#define PDN_FCRAM_CNT_CLK_E_ACK (1u<<2) // Gets set or unset depending on CLK_E.
|
||||
|
||||
|
@ -97,37 +98,37 @@ enum
|
|||
|
||||
// REG_PDN_DSP_CNT
|
||||
// Note: Reset is active low.
|
||||
#define PDN_DSP_CNT_RST (1u)
|
||||
#define PDN_DSP_CNT_NORST (1u)
|
||||
#define PDN_DSP_CNT_CLK_E (1u<<1)
|
||||
|
||||
// REG_PDN_G1_CNT
|
||||
// TODO: Active low or high?
|
||||
#define PDN_G1_CNT_RST (1u)
|
||||
#define PDN_G1_CNT_NORST (1u)
|
||||
|
||||
// REG_PDN_MPCORE_SOCMODE
|
||||
// REG_PDN_LGR_SOCMODE
|
||||
typedef enum
|
||||
{
|
||||
SOCMODE_O3DS_268MHz = 0u,
|
||||
SOCMODE_N3DS_268MHz = 1u, // Also enables FCRAM extension.
|
||||
SOCMODE_N3DS_PROTO_268MHz = 2u, // Also enables FCRAM extension?
|
||||
SOCMODE_N3DS_PROTO_536MHz = 3u, // Also enables FCRAM extension?
|
||||
SOCMODE_N3DS_804MHz = 5u, // Also enables FCRAM extension.
|
||||
SOCMODE_CTR_268MHz = 0u,
|
||||
SOCMODE_LGR2_268MHz = 1u, // Also enables FCRAM extension.
|
||||
SOCMODE_LGR1_268MHz = 2u, // Also enables FCRAM extension?
|
||||
SOCMODE_LGR1_536MHz = 3u, // Also enables FCRAM extension?
|
||||
SOCMODE_LGR2_804MHz = 5u, // Also enables FCRAM extension.
|
||||
|
||||
SOCMODE_MASK = 7u
|
||||
SOCMODE_MASK = 7u
|
||||
} PdnSocmode;
|
||||
|
||||
#define PDN_MPCORE_SOCMODE_ACK (1u<<15)
|
||||
#define PDN_LGR_SOCMODE_ACK (1u<<15)
|
||||
|
||||
// REG_PDN_MPCORE_CNT
|
||||
#define PDN_MPCORE_CNT_MEM_EXT_E (1u) // Does it actually affect all mem extensions or just QTM?
|
||||
#define PDN_MPCORE_CNT_L2C_E (1u<<8)
|
||||
// REG_PDN_LGR_CNT
|
||||
#define PDN_LGR_CNT_WRAM_EXT_E (1u) // QTM WRAM enable.
|
||||
#define PDN_LGR_CNT_L2C_E (1u<<8) // L2C L2 cache enable.
|
||||
|
||||
// REGs_PDN_MPCORE_BOOTCNT
|
||||
// REGs_PDN_LGR_CPU_CNT
|
||||
// Note: Reset is active low.
|
||||
#define MPCORE_BOOTCNT_RST (1u) // Core 2/3 only. Reset and instruction overlay enable.
|
||||
#define MPCORE_BOOTCNT_D_OVERL_E (1u<<1) // Core 2/3 only. Data overlay enable. Also used to signal a core booted.
|
||||
#define MPCORE_BOOTCNT_RST_STAT (1u<<4)
|
||||
#define MPCORE_BOOTCNT_UNK (1u<<5)
|
||||
#define LGR_CPU_CNT_NORST (1u) // Core 2/3 only. Reset and instruction overlay enable.
|
||||
#define LGR_CPU_CNT_D_OVERL_E (1u<<1) // Core 2/3 only. Data overlay enable. Also used to signal a core booted.
|
||||
#define LGR_CPU_CNT_RST_STAT (1u<<4) // Reset status.
|
||||
#define LGR_CPU_CNT_UNK (1u<<5) // Something ready?
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ void GFX_init(GfxFbFmt fmtTop, GfxFbFmt fmtBot)
|
|||
// Reset
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E;
|
||||
wait_cycles(12);
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E | PDN_GPU_CNT_RST_ALL;
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E | PDN_GPU_CNT_NORST_ALL;
|
||||
REG_GX_GPU_CLK = 0x100;
|
||||
REG_GX_PSC_VRAM = 0;
|
||||
REG_GX_PSC_FILL0_CNT = 0;
|
||||
|
@ -177,7 +177,7 @@ void GFX_deinit(void)
|
|||
REG_LCD_RST = 0;
|
||||
REG_GX_PSC_VRAM = 0xF00;
|
||||
REG_GX_GPU_CLK = 0;
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E | PDN_GPU_CNT_RST_REGS;
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E | PDN_GPU_CNT_NORST_REGS;
|
||||
|
||||
deallocFramebufs();
|
||||
|
||||
|
@ -472,12 +472,12 @@ void GX_processCommandList(u32 size, const u32 *const cmdList)
|
|||
REG_LCD_PDC1_SWAP = 0x70100;
|
||||
|
||||
REG_GX_PSC_VRAM = 0xF00;
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_RST_ALL;
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_NORST_ALL;
|
||||
}
|
||||
|
||||
void GFX_returnFromLowPowerState(void)
|
||||
{
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E | PDN_GPU_CNT_RST_ALL;
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E | PDN_GPU_CNT_NORST_ALL;
|
||||
REG_GX_PSC_VRAM = 0;
|
||||
//REG_GX_GPU_CLK = 0x70100;
|
||||
REG_GX_PSC_FILL0_CNT = 0;
|
||||
|
|
|
@ -72,7 +72,7 @@ static void powerDownFcramForLegacy(u8 mode)
|
|||
*((vu32*)0x10201000) &= ~1u; // Bug fix for the GBA cart emu?
|
||||
REG_PDN_FCRAM_CNT = PDN_FCRAM_CNT_CLK_E; // Set reset low (active) but keep clock on.
|
||||
}
|
||||
REG_PDN_FCRAM_CNT = PDN_FCRAM_CNT_RST; // Take it out of reset but disable clock.
|
||||
REG_PDN_FCRAM_CNT = PDN_FCRAM_CNT_NORST; // Take it out of reset but disable clock.
|
||||
while(REG_PDN_FCRAM_CNT & PDN_FCRAM_CNT_CLK_E_ACK); // Wait until clock is disabled.
|
||||
}
|
||||
|
||||
|
|
|
@ -99,22 +99,25 @@ static void lgyFbDmaIrqHandler(UNUSED u32 intSource)
|
|||
signalEvent(g_frameReadyEvent, false);
|
||||
}
|
||||
|
||||
static void setScaleMatrix(vu32 *const regs, u8 colorAdjust, u32 len, u32 patt, const s16 *const matrix)
|
||||
static void setScaleMatrix(vu32 *const regs, u32 len, u32 patt, const s16 *const matrix, u8 inBits, u8 outBits)
|
||||
{
|
||||
regs[0] = len - 1; // Reg *_LEN
|
||||
regs[1] = patt; // Reg *_PATT
|
||||
|
||||
const u8 inMax = (inBits == 0 ? 0 : (s8)-128>>(inBits - 1));
|
||||
const u8 outMax = (1u<<outBits) - 1;
|
||||
for(u32 y = 0; y < 6; y++)
|
||||
{
|
||||
for(u32 x = 0; x < len; x++)
|
||||
{
|
||||
const s16 tmp = matrix[len * y + x];
|
||||
const s32 mEntry = matrix[len * y + x];
|
||||
|
||||
// Correct the color range using the scale matrix hardware.
|
||||
// For example when converting RGB555 to RGB8 LgyFb lazily shifts the 5 bits up
|
||||
// so 0b00011111 becomes 0b11111000. This creates wrong spacing between colors.
|
||||
// TODO: What is the "+ 8" good for?
|
||||
regs[16 + (8 * y + x)] = (colorAdjust != 0 ? tmp * 0xFF / colorAdjust + 8 : tmp + 8); // Reg *_MATRIX/*_ARRAY0
|
||||
if(inMax != 0) regs[16 + (8 * y + x)] = mEntry * outMax / inMax + 8; // Reg *_MATRIX/*_ARRAY0
|
||||
else regs[16 + (8 * y + x)] = mEntry + 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +164,7 @@ void LGYFB_init(KEvent *frameReadyEvent)
|
|||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0
|
||||
};
|
||||
setScaleMatrix(®_LGYFB_TOP_H_LEN, 0xF8, 6, 0b00111111, scaleMatrix);
|
||||
setScaleMatrix(®_LGYFB_TOP_H_LEN, 6, 0b00111111, scaleMatrix, 5, 8);
|
||||
#else
|
||||
// Other
|
||||
static const s16 scaleMatrix[6 * 6] =
|
||||
|
@ -191,8 +194,8 @@ void LGYFB_init(KEvent *frameReadyEvent)
|
|||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0
|
||||
};
|
||||
setScaleMatrix(®_LGYFB_TOP_V_LEN, 0xF8, 6, 0b00011011, scaleMatrix);
|
||||
setScaleMatrix(®_LGYFB_TOP_H_LEN, 0x00, 6, 0b00011011, scaleMatrix);
|
||||
setScaleMatrix(®_LGYFB_TOP_V_LEN, 6, 0b00011011, scaleMatrix, 5, 8);
|
||||
setScaleMatrix(®_LGYFB_TOP_H_LEN, 6, 0b00011011, scaleMatrix, 0, 8);
|
||||
#endif
|
||||
|
||||
// With RGB8 output solid red and blue are converted to 0xF8 and green to 0xFA.
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#include "arm11/hardware/scu.h"
|
||||
|
||||
|
||||
//#define CORE123_INIT 1
|
||||
|
||||
|
||||
|
||||
#ifdef CORE123_INIT
|
||||
static void NAKED core23Entry(void)
|
||||
|
@ -33,12 +36,12 @@ static void NAKED core23Entry(void)
|
|||
__cpsid(aif);
|
||||
REG_GIC_CPU_CTRL = 1;
|
||||
|
||||
// Tell core 0 we are here.
|
||||
const u32 cpuId = __getCpuId();
|
||||
// Tell core 0 we are here
|
||||
if(cpuId == 3) REGs_PDN_MPCORE_BOOTCNT[3] = MPCORE_BOOTCNT_RST;
|
||||
else REGs_PDN_MPCORE_BOOTCNT[2] = MPCORE_BOOTCNT_RST;
|
||||
if(cpuId == 3) REGs_PDN_LGR_CPU_CNT[3] = LGR_CPU_CNT_NORST;
|
||||
else REGs_PDN_LGR_CPU_CNT[2] = LGR_CPU_CNT_NORST;
|
||||
|
||||
// Wait for IPI 2 (core 2) or IPI 3 (core 3)
|
||||
// Wait for IPI 2 (core 2) or IPI 3 (core 3).
|
||||
u32 tmp;
|
||||
do
|
||||
{
|
||||
|
@ -47,124 +50,136 @@ static void NAKED core23Entry(void)
|
|||
REG_GIC_CPU_EOI = tmp;
|
||||
} while(tmp != cpuId);
|
||||
|
||||
// Jump to real entrypoint
|
||||
// Jump to real entrypoint.
|
||||
_start();
|
||||
}
|
||||
#endif
|
||||
|
||||
// This must be called before the MMU is enabled on any core or it will hang!
|
||||
void PDN_core123Init(void)
|
||||
{
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_N3DS_PROTO)
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_LGR1)
|
||||
{
|
||||
REG_GIC_CPU_CTRL = 1;
|
||||
for(u32 i = 0; i < 4; i++) REGs_GIC_DIST_ENABLE_CLEAR[i] = 0xFFFFFFFFu;
|
||||
REGs_GIC_DIST_PENDING_CLEAR[2] = 0x1000000; // Interrupt ID 88
|
||||
REGs_GIC_DIST_PRI[22] = 0;
|
||||
REGs_GIC_DIST_TARGET[22] = 1;
|
||||
REGs_GIC_DIST_ENABLE_SET[2] = 0x1000000;
|
||||
for(u32 i = 0; i < 4; i++) REGs_GIC_DIST_ENABLE_CLEAR[i] = 0xFFFFFFFFu; // Disable all interrupts.
|
||||
REGs_GIC_DIST_PENDING_CLEAR[2] = 1u<<24; // Clear interrupt ID 88.
|
||||
REGs_GIC_DIST_PRI[22] = 0; // Id 88 highest priority.
|
||||
REGs_GIC_DIST_TARGET[22] = 1; // Id 88 target core 0.
|
||||
REGs_GIC_DIST_ENABLE_SET[2] = 1u<<24; // Enable interrupt ID 88.
|
||||
|
||||
// Certain bootloaders leave the ack bit set. Clear it.
|
||||
REG_PDN_LGR_SOCMODE = PDN_LGR_SOCMODE_ACK;
|
||||
|
||||
#ifdef CORE123_INIT
|
||||
// Use 804 MHz for LGR2 and 536 for LGR1.
|
||||
u16 socmode;
|
||||
// If non-prototype SoC use 804 MHz.
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_N3DS) socmode = SOCMODE_N3DS_804MHz;
|
||||
else socmode = SOCMODE_N3DS_PROTO_536MHz;
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_LGR2) socmode = SOCMODE_LGR2_804MHz;
|
||||
else socmode = SOCMODE_LGR1_536MHz;
|
||||
|
||||
if((REG_PDN_MPCORE_SOCMODE & SOCMODE_MASK) != socmode)
|
||||
if((REG_PDN_LGR_SOCMODE & SOCMODE_MASK) != socmode)
|
||||
{
|
||||
// No idea what this does
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_N3DS) REG_PDN_MPCORE_CNT = PDN_MPCORE_CNT_L2C_E | PDN_MPCORE_CNT_MEM_EXT_E;
|
||||
else REG_PDN_MPCORE_CNT = PDN_MPCORE_CNT_MEM_EXT_E;
|
||||
// Enable L2 cache and/or extra WRAM.
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_LGR2) REG_PDN_LGR_CNT = PDN_LGR_CNT_L2C_E | PDN_LGR_CNT_WRAM_EXT_E;
|
||||
else REG_PDN_LGR_CNT = PDN_LGR_CNT_WRAM_EXT_E;
|
||||
|
||||
// Necessary delay.
|
||||
wait(403);
|
||||
wait_cycles(403);
|
||||
|
||||
PDN_setSocmode(socmode);
|
||||
REGs_GIC_DIST_PENDING_CLEAR[2] = 0x1000000;
|
||||
REGs_GIC_DIST_PENDING_CLEAR[2] = 1u<<24; // Clear interrupt ID 88.
|
||||
|
||||
// Fixes for the GPU to work in non-CTR mode.
|
||||
REG_CFG11_GPU_N3DS_CNT = GPU_N3DS_CNT_TEX_FIX | GPU_N3DS_CNT_N3DS_MODE;
|
||||
}
|
||||
|
||||
REG_CFG11_CDMA_PERIPHERALS = CDMA_PERIPHERALS_ALL; // Redirect all to CDMA2.
|
||||
|
||||
if((REG_SCU_CONFIG & 3) == 3)
|
||||
{
|
||||
// Set core 2/3 to normal mode (running)
|
||||
// Set core 2/3 to normal mode (running) in the SCU.
|
||||
REG_SCU_CPU_STAT &= ~0b11110000;
|
||||
|
||||
const u16 socmode = REG_PDN_MPCORE_SOCMODE & SOCMODE_MASK;
|
||||
// Temporarily switch to 268 MHz for core 2/3 bringup.
|
||||
u16 tmpSocmode;
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_N3DS) tmpSocmode = SOCMODE_N3DS_268MHz;
|
||||
else tmpSocmode = SOCMODE_N3DS_PROTO_268MHz;
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_LGR2) tmpSocmode = SOCMODE_LGR2_268MHz;
|
||||
else tmpSocmode = SOCMODE_LGR1_268MHz;
|
||||
|
||||
if(socmode != tmpSocmode)
|
||||
{
|
||||
PDN_setSocmode(tmpSocmode);
|
||||
REGs_GIC_DIST_PENDING_CLEAR[2] = 0x1000000;
|
||||
REGs_GIC_DIST_PENDING_CLEAR[2] = 1u<<24; // Clear interrupt ID 88.
|
||||
}
|
||||
|
||||
REG_CFG11_BOOTROM_OVERLAY_CNT = BOOTROM_OVERLAY_CNT_E;
|
||||
REG_CFG11_BOOTROM_OVERLAY_VAL = (u32)core23Entry;
|
||||
// If not already done enable instruction and data overlays
|
||||
if(!(REGs_PDN_MPCORE_BOOTCNT[2] & MPCORE_BOOTCNT_RST_STAT))
|
||||
// If not already done enable instruction and data overlays.
|
||||
if(!(REGs_PDN_LGR_CPU_CNT[2] & LGR_CPU_CNT_RST_STAT))
|
||||
{
|
||||
REGs_PDN_MPCORE_BOOTCNT[2] = MPCORE_BOOTCNT_D_OVERL_E | MPCORE_BOOTCNT_RST;
|
||||
REGs_PDN_LGR_CPU_CNT[2] = LGR_CPU_CNT_D_OVERL_E | LGR_CPU_CNT_NORST;
|
||||
}
|
||||
if(!(REGs_PDN_MPCORE_BOOTCNT[3] & MPCORE_BOOTCNT_RST_STAT))
|
||||
if(!(REGs_PDN_LGR_CPU_CNT[3] & LGR_CPU_CNT_RST_STAT))
|
||||
{
|
||||
REGs_PDN_MPCORE_BOOTCNT[3] = MPCORE_BOOTCNT_D_OVERL_E | MPCORE_BOOTCNT_RST;
|
||||
REGs_PDN_LGR_CPU_CNT[3] = LGR_CPU_CNT_D_OVERL_E | LGR_CPU_CNT_NORST;
|
||||
}
|
||||
// Wait for core 2/3 to jump out of boot11
|
||||
while((REGs_PDN_MPCORE_BOOTCNT[2] & (MPCORE_BOOTCNT_RST_STAT | MPCORE_BOOTCNT_D_OVERL_E))
|
||||
!= MPCORE_BOOTCNT_RST_STAT);
|
||||
while((REGs_PDN_MPCORE_BOOTCNT[3] & (MPCORE_BOOTCNT_RST_STAT | MPCORE_BOOTCNT_D_OVERL_E))
|
||||
!= MPCORE_BOOTCNT_RST_STAT);
|
||||
REG_CFG11_BOOTROM_OVERLAY_CNT = 0; // Disable all overlays
|
||||
// Wait for core 2/3 to jump out of boot11.
|
||||
while((REGs_PDN_LGR_CPU_CNT[2] & (LGR_CPU_CNT_RST_STAT | LGR_CPU_CNT_D_OVERL_E))
|
||||
!= LGR_CPU_CNT_RST_STAT);
|
||||
while((REGs_PDN_LGR_CPU_CNT[3] & (LGR_CPU_CNT_RST_STAT | LGR_CPU_CNT_D_OVERL_E))
|
||||
!= LGR_CPU_CNT_RST_STAT);
|
||||
REG_CFG11_BOOTROM_OVERLAY_CNT = 0; // Disable all overlays.
|
||||
|
||||
// Set clock back to original one
|
||||
// Switch back to highest clock.
|
||||
if(socmode != tmpSocmode) PDN_setSocmode(socmode);
|
||||
}
|
||||
|
||||
REGs_GIC_DIST_ENABLE_CLEAR[2] = 0x1000000;
|
||||
REGs_GIC_DIST_ENABLE_CLEAR[2] = 1u<<24; // Clear interrupt ID 88.
|
||||
|
||||
// Wakeup core 2/3 and let them jump to their entrypoint.
|
||||
IRQ_softwareInterrupt(2, 0b0100);
|
||||
IRQ_softwareInterrupt(3, 0b1000);
|
||||
#else
|
||||
// Just enables the New3DS FCRAM extension (if not already done).
|
||||
if((REG_PDN_MPCORE_SOCMODE & SOCMODE_MASK) != SOCMODE_N3DS_268MHz)
|
||||
PDN_setSocmode(SOCMODE_N3DS_268MHz);
|
||||
|
||||
REGs_GIC_DIST_ENABLE_CLEAR[2] = 0x1000000;
|
||||
// Make sure we are in CTR mode (if not already).
|
||||
if((REG_PDN_LGR_SOCMODE & SOCMODE_MASK) != SOCMODE_CTR_268MHz)
|
||||
{
|
||||
PDN_setSocmode(SOCMODE_CTR_268MHz);
|
||||
REGs_GIC_DIST_ENABLE_CLEAR[2] = 1u<<24; // Clear interrupt ID 88.
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Wakeup core 1
|
||||
*((vu32*)0x1FFFFFDC) = (u32)_start; // Core 1 entrypoint
|
||||
*((vu32*)0x1FFFFFDC) = (u32)_start; // Core 1 entrypoint.
|
||||
IRQ_softwareInterrupt(1, 0b0010);
|
||||
}
|
||||
|
||||
void PDN_setSocmode(PdnSocmode socmode)
|
||||
{
|
||||
REG_PDN_MPCORE_SOCMODE = PDN_MPCORE_SOCMODE_ACK | socmode;
|
||||
REG_PDN_LGR_SOCMODE = socmode;
|
||||
|
||||
do
|
||||
{
|
||||
__wfi();
|
||||
} while(!(REG_PDN_MPCORE_SOCMODE & PDN_MPCORE_SOCMODE_ACK));
|
||||
} while(!(REG_PDN_LGR_SOCMODE & PDN_LGR_SOCMODE_ACK));
|
||||
|
||||
REG_PDN_LGR_SOCMODE = REG_PDN_LGR_SOCMODE; // Acknowledge (PDN_LGR_SOCMODE_ACK bit set).
|
||||
}
|
||||
|
||||
void PDN_poweroffCore23(void)
|
||||
{
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_N3DS_PROTO)
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_LGR1)
|
||||
{
|
||||
REGs_PDN_MPCORE_BOOTCNT[2] = 0;
|
||||
REGs_PDN_MPCORE_BOOTCNT[3] = 0;
|
||||
REGs_PDN_LGR_CPU_CNT[2] = 0;
|
||||
REGs_PDN_LGR_CPU_CNT[3] = 0;
|
||||
|
||||
REG_CFG11_CDMA_PERIPHERALS = 0;
|
||||
REG_CFG11_GPU_N3DS_CNT = 0;
|
||||
|
||||
REG_PDN_MPCORE_CNT = 0;
|
||||
PDN_setSocmode(SOCMODE_N3DS_268MHz);
|
||||
REG_PDN_LGR_CNT = 0;
|
||||
if(REG_CFG11_SOCINFO & SOCINFO_LGR2) PDN_setSocmode(SOCMODE_LGR2_268MHz);
|
||||
else PDN_setSocmode(SOCMODE_LGR1_268MHz);
|
||||
|
||||
REG_SCU_CPU_STAT |= 0b1111<<4;
|
||||
|
||||
PDN_setSocmode(SOCMODE_O3DS_268MHz);
|
||||
PDN_setSocmode(SOCMODE_CTR_268MHz);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,8 @@ _a7_stub_thumb:
|
|||
.global _a7_stub9_swi
|
||||
_a7_stub9_swi = . - _a7_stub_start + 0x80BFE00 @ Final ARM9 mem location.
|
||||
swi 0x01 @ RegisterRamReset
|
||||
@ After BIOS intro REG_TM0CNT_L is set to 0xFF8C instead of 0.
|
||||
@ No other differences between direct boot and BIOS.
|
||||
|
||||
mov r0, #0xBC @ SoftReset (0xB4) but skipping r2 & r4 loading.
|
||||
mov r2, #0
|
||||
|
|
Loading…
Reference in New Issue