2019-04-23 17:38:22 -03:00
|
|
|
/*
|
|
|
|
* This file is part of GodMode9
|
|
|
|
* Copyright (C) 2019 Wolfvak
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2019-04-15 21:27:35 -03:00
|
|
|
#include <types.h>
|
2019-04-17 11:58:54 -03:00
|
|
|
#include <vram.h>
|
2019-04-15 21:27:35 -03:00
|
|
|
#include <arm.h>
|
|
|
|
#include <pxi.h>
|
|
|
|
|
|
|
|
#include "arm/gic.h"
|
|
|
|
#include "arm/mmu.h"
|
2019-04-17 15:54:47 -03:00
|
|
|
#include "arm/scu.h"
|
2020-07-26 10:27:48 -03:00
|
|
|
#include "arm/xrq.h"
|
2019-04-15 21:27:35 -03:00
|
|
|
|
2019-04-18 16:39:45 -03:00
|
|
|
#include "hw/codec.h"
|
2019-04-17 11:58:54 -03:00
|
|
|
#include "hw/gpulcd.h"
|
2019-04-15 21:27:35 -03:00
|
|
|
#include "hw/i2c.h"
|
2019-04-17 11:58:54 -03:00
|
|
|
#include "hw/mcu.h"
|
2019-07-27 17:03:54 +02:00
|
|
|
#include <spi.h>
|
2019-04-15 21:27:35 -03:00
|
|
|
|
2019-04-16 15:42:20 -03:00
|
|
|
#include "system/sections.h"
|
|
|
|
|
2019-04-15 21:27:35 -03:00
|
|
|
#define CFG11_MPCORE_CLKCNT ((vu16*)(0x10141300))
|
|
|
|
#define CFG11_SOCINFO ((vu16*)(0x10140FFC))
|
|
|
|
|
2019-04-16 15:42:20 -03:00
|
|
|
#define LEGACY_BOOT_ENTRYPOINT ((vu32*)0x1FFFFFFC)
|
|
|
|
#define LEGACY_BOOT_ROUTINE_SMP (0x0001004C)
|
2019-04-15 21:27:35 -03:00
|
|
|
|
|
|
|
static bool SYS_IsNewConsole(void)
|
|
|
|
{
|
|
|
|
return (*CFG11_SOCINFO & 2) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool SYS_ClkMultEnabled(void)
|
|
|
|
{
|
|
|
|
return (*CFG11_MPCORE_CLKCNT & 1) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SYS_EnableClkMult(void)
|
|
|
|
{
|
|
|
|
// magic bit twiddling to enable extra FCRAM
|
|
|
|
// only done on N3DS and when it hasn't been done yet
|
|
|
|
// state might get a bit messed up so it has to be done
|
|
|
|
// as early as possible in the initialization chain
|
|
|
|
if (SYS_IsNewConsole() && !SYS_ClkMultEnabled()) {
|
2020-08-02 11:40:18 -03:00
|
|
|
gicSetInterruptConfig(88, BIT(0), GIC_PRIO_HIGHEST, NULL);
|
2020-07-19 11:59:52 -03:00
|
|
|
gicEnableInterrupt(88);
|
2019-04-15 21:27:35 -03:00
|
|
|
*CFG11_MPCORE_CLKCNT = 0x8001;
|
|
|
|
do {
|
|
|
|
ARM_WFI();
|
|
|
|
} while(!(*CFG11_MPCORE_CLKCNT & 0x8000));
|
2020-07-19 11:59:52 -03:00
|
|
|
gicDisableInterrupt(88);
|
|
|
|
gicClearInterruptConfig(88);
|
2019-04-15 21:27:35 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-16 15:42:20 -03:00
|
|
|
void SYS_CoreZeroInit(void)
|
2019-04-15 21:27:35 -03:00
|
|
|
{
|
2020-07-19 11:59:52 -03:00
|
|
|
gicGlobalReset();
|
2019-04-15 21:27:35 -03:00
|
|
|
|
2019-04-16 15:42:20 -03:00
|
|
|
*LEGACY_BOOT_ENTRYPOINT = 0;
|
2019-04-15 21:27:35 -03:00
|
|
|
|
|
|
|
SYS_EnableClkMult();
|
|
|
|
|
|
|
|
SCU_Init();
|
|
|
|
|
|
|
|
// Map all sections here
|
2020-07-19 11:59:52 -03:00
|
|
|
mmuMapArea(SECTION_TRI(text), MMU_FLAGS(MMU_CACHE_WT, MMU_READ_ONLY, 0, 1));
|
|
|
|
mmuMapArea(SECTION_TRI(data), MMU_FLAGS(MMU_CACHE_WBA, MMU_READ_WRITE, 1, 1));
|
|
|
|
mmuMapArea(SECTION_TRI(rodata), MMU_FLAGS(MMU_CACHE_WT, MMU_READ_ONLY, 1, 1));
|
|
|
|
mmuMapArea(SECTION_TRI(bss), MMU_FLAGS(MMU_CACHE_WBA, MMU_READ_WRITE, 1, 1));
|
|
|
|
mmuMapArea(SECTION_TRI(shared), MMU_FLAGS(MMU_STRONG_ORDER, MMU_READ_WRITE, 1, 1));
|
2019-04-15 21:27:35 -03:00
|
|
|
|
2020-07-26 10:27:48 -03:00
|
|
|
// High exception vectors
|
|
|
|
mmuMapArea(0xFFFF0000, xrqInstallVectorTable(), 4UL << 10, MMU_FLAGS(MMU_CACHE_WT, MMU_READ_ONLY, 0, 0));
|
|
|
|
|
2020-07-24 13:37:29 -03:00
|
|
|
// BootROM
|
|
|
|
mmuMapArea(0x00010000, 0x00010000, 32UL << 10, MMU_FLAGS(MMU_CACHE_WT, MMU_READ_ONLY, 0, 1));
|
|
|
|
|
2019-04-15 21:27:35 -03:00
|
|
|
// IO Registers
|
2020-07-19 11:59:52 -03:00
|
|
|
mmuMapArea(0x10100000, 0x10100000, 4UL << 20, MMU_FLAGS(MMU_DEV_SHARED, MMU_READ_WRITE, 1, 1));
|
2019-04-15 21:27:35 -03:00
|
|
|
|
|
|
|
// MPCore Private Memory Region
|
2020-07-19 11:59:52 -03:00
|
|
|
mmuMapArea(0x17E00000, 0x17E00000, 8UL << 10, MMU_FLAGS(MMU_DEV_SHARED, MMU_READ_WRITE, 1, 1));
|
2019-04-15 21:27:35 -03:00
|
|
|
|
|
|
|
// VRAM
|
2020-07-19 11:59:52 -03:00
|
|
|
mmuMapArea(0x18000000, 0x18000000, 6UL << 20, MMU_FLAGS(MMU_CACHE_WT, MMU_READ_WRITE, 1, 1));
|
2019-04-15 21:27:35 -03:00
|
|
|
|
|
|
|
// FCRAM
|
2019-04-16 15:42:20 -03:00
|
|
|
if (SYS_IsNewConsole()) {
|
2020-07-19 11:59:52 -03:00
|
|
|
mmuMapArea(0x20000000, 0x20000000, 256UL << 20, MMU_FLAGS(MMU_CACHE_WB, MMU_READ_WRITE, 1, 1));
|
2019-04-16 15:42:20 -03:00
|
|
|
} else {
|
2020-07-19 11:59:52 -03:00
|
|
|
mmuMapArea(0x20000000, 0x20000000, 128UL << 20, MMU_FLAGS(MMU_CACHE_WB, MMU_READ_WRITE, 1, 1));
|
2019-04-16 15:42:20 -03:00
|
|
|
}
|
2019-04-15 21:27:35 -03:00
|
|
|
|
2019-04-16 15:42:20 -03:00
|
|
|
// Initialize peripherals
|
2019-04-15 21:27:35 -03:00
|
|
|
PXI_Reset();
|
2019-04-22 16:24:45 -03:00
|
|
|
|
2019-04-15 21:27:35 -03:00
|
|
|
I2C_init();
|
2019-04-17 11:58:54 -03:00
|
|
|
MCU_Init();
|
2019-04-22 16:24:45 -03:00
|
|
|
|
2019-04-18 16:39:45 -03:00
|
|
|
SPI_Init();
|
|
|
|
CODEC_Init();
|
2019-04-17 11:58:54 -03:00
|
|
|
|
2020-07-18 20:25:34 -03:00
|
|
|
GFX_init(GFX_RGB565);
|
2019-04-15 21:27:35 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void SYS_CoreInit(void)
|
|
|
|
{
|
2019-04-16 15:42:20 -03:00
|
|
|
// Reset local GIC registers
|
2020-07-19 11:59:52 -03:00
|
|
|
gicLocalReset();
|
2019-04-15 21:27:35 -03:00
|
|
|
|
2019-04-16 15:42:20 -03:00
|
|
|
// Set up MMU registers
|
2020-07-19 11:59:52 -03:00
|
|
|
mmuInitRegisters();
|
2019-04-15 21:27:35 -03:00
|
|
|
|
2019-04-16 15:42:20 -03:00
|
|
|
// Enable fancy ARM11 features
|
2019-04-15 21:27:35 -03:00
|
|
|
ARM_SetACR(ARM_GetACR() |
|
|
|
|
ACR_RETSTK | ACR_DBPRED | ACR_SBPRED | ACR_FOLDING | ACR_SMP);
|
|
|
|
|
|
|
|
ARM_SetCR(ARM_GetCR() |
|
|
|
|
CR_MMU | CR_CACHES | CR_FLOWPRED | CR_HIGHVEC | CR_DSUBPAGE);
|
|
|
|
|
|
|
|
ARM_DSB();
|
|
|
|
|
2019-04-16 15:42:20 -03:00
|
|
|
ARM_EnableInterrupts();
|
|
|
|
}
|
2019-04-15 21:27:35 -03:00
|
|
|
|
2019-04-16 15:42:20 -03:00
|
|
|
void SYS_CoreZeroShutdown(void)
|
|
|
|
{
|
|
|
|
ARM_DisableInterrupts();
|
2020-07-19 11:59:52 -03:00
|
|
|
gicGlobalReset();
|
2019-04-15 21:27:35 -03:00
|
|
|
}
|
|
|
|
|
2019-04-17 11:58:54 -03:00
|
|
|
void __attribute__((noreturn)) SYS_CoreShutdown(void)
|
2019-04-15 21:27:35 -03:00
|
|
|
{
|
|
|
|
u32 core = ARM_CoreID();
|
|
|
|
|
2019-04-16 15:42:20 -03:00
|
|
|
ARM_DisableInterrupts();
|
2019-04-15 21:27:35 -03:00
|
|
|
|
2020-07-19 11:59:52 -03:00
|
|
|
gicLocalReset();
|
2019-04-15 21:27:35 -03:00
|
|
|
|
|
|
|
ARM_WbInvDC();
|
|
|
|
ARM_InvIC();
|
|
|
|
ARM_DSB();
|
|
|
|
|
|
|
|
ARM_SetCR(ARM_GetCR() & ~(CR_MMU | CR_CACHES | CR_FLOWPRED));
|
|
|
|
ARM_SetACR(ARM_GetACR() &
|
|
|
|
~(ACR_RETSTK | ACR_DBPRED | ACR_SBPRED | ACR_FOLDING | ACR_SMP));
|
|
|
|
|
2019-07-19 15:35:20 -03:00
|
|
|
SPI_Deinit();
|
|
|
|
|
2019-04-15 21:27:35 -03:00
|
|
|
if (!core) {
|
2019-04-16 15:42:20 -03:00
|
|
|
while(*LEGACY_BOOT_ENTRYPOINT == 0);
|
|
|
|
((void (*)(void))(*LEGACY_BOOT_ENTRYPOINT))();
|
2019-04-15 21:27:35 -03:00
|
|
|
} else {
|
|
|
|
// Branch to bootrom function that does SMP reinit magic
|
|
|
|
// (waits for IPI + branches to word @ 0x1FFFFFDC)
|
2019-04-16 15:42:20 -03:00
|
|
|
((void (*)(void))LEGACY_BOOT_ROUTINE_SMP)();
|
2019-04-15 21:27:35 -03:00
|
|
|
}
|
2019-04-17 11:58:54 -03:00
|
|
|
__builtin_unreachable();
|
2019-04-15 21:27:35 -03:00
|
|
|
}
|