Skip to content
This repository has been archived by the owner on Oct 17, 2020. It is now read-only.

Commit

Permalink
init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Reisyukaku committed Jul 22, 2018
0 parents commit 9625fd1
Show file tree
Hide file tree
Showing 95 changed files with 26,550 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build/
out/
*zip
339 changes: 339 additions & 0 deletions LICENSE.txt

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))

ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif

CC = $(DEVKITARM)/bin/arm-none-eabi-gcc
LD = $(DEVKITARM)/bin/arm-none-eabi-ld
OBJCOPY = $(DEVKITARM)/bin/arm-none-eabi-objcopy

name := ReiNX

dir_source := src
dir_data := data
dir_build := build
dir_out := out

ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
CFLAGS = $(ARCH) -Os -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11# -Wall
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections

objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c)))

define bin2o
bin2s $< | $(AS) -o $(@)
endef

.PHONY: all
all: $(dir_out)/$(name).bin

.PHONY: clean
clean:
@rm -rf $(dir_build)
@rm -rf $(dir_out)

$(dir_out)/$(name).bin: $(dir_build)/$(name).elf
@mkdir -p "$(@D)"
@mkdir -p "$(dir_out)/ReiNX/sysmodules"
@cp -R $(dir_data)/*.kip $(dir_out)/ReiNX/sysmodules/
@cp -R $(dir_data)/*.bin $(dir_out)/ReiNX/
$(OBJCOPY) -S -O binary $< $@

$(dir_build)/$(name).elf: $(objects)
$(CC) $(LDFLAGS) -T link.ld $^ -o $@

$(dir_build)/%.o: $(dir_source)/%.c
@mkdir -p "$(@D)"
$(CC) $(CFLAGS) -c $< -o $@

$(dir_build)/%.o: $(dir_source)/%.s
@mkdir -p "$(@D)"
$(CC) $(CFLAGS) -c $< -o $@
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# ReiNX
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-blue.svg)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)

*The modular switch custom firmware*

**Usage:**

Put `ReiNX` folder on the root of your switch's SD card and run `ReiNX.bin` with your favorite fusee launcher.

**Compiling:**

You'll need devkitpro with devkitA64 and run `make`


**Features:**

* Loads all KIPs from `/ReiNX/sysmodules/` directory

* Optional custom kernel/secmon/warmboot

* Default kips with exefs redir from `/ReiNX/title/{tid}`


**Credits:**

Naehrwert for hardware init code and generally being helpful!

CTCaer and st4rk for their contribution to the hardware code aswell!

SciresM for kernel processes!

The community for your support!
Binary file added data/loader.kip
Binary file not shown.
Binary file added data/sm.kip
Binary file not shown.
Binary file added data/splash.bin
Binary file not shown.
29 changes: 29 additions & 0 deletions link.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
ENTRY(_start)

SECTIONS
{
PROVIDE(__ipl_start = 0x40003000);
. = __ipl_start;
.text.start :
{
*(.text.start)
}
.text :
{
*(.text*);
}
.data :
{
*(.data*);
*(.rodata*);
}
. = ALIGN(0x10);
__ipl_end = .;
.bss :
{
__bss_start = .;
*(COMMON)
*(.bss*)
__bss_end = .;
}
}
196 changes: 196 additions & 0 deletions src/bootloader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*
* Copyright (c) 2018 Reisyukaku
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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 "hwinit.h"
#include "fuse.h"
#include "error.h"
#include "bootloader.h"

void check_sku() {
if (FUSE(FUSE_SKU) != 0x83)
panic();
}

void check_config_fuses() {
u32 config = get_unknown_config();
u32 unitType = get_unit_type();
u32 bromVer = FUSE(FUSE_SOC_SPEEDO_1);

if (config == 3 || unitType == 2 || bromVer < 0x1F)
panic();
}

void mbist_workaround() {
CLOCK(0x410) = (CLOCK(0x410) | 0x8000) & 0xFFFFBFFF;
CLOCK(0xD0) |= 0x40800000u;
CLOCK(0x2AC) = 0x40;
CLOCK(0x294) = 0x40000;
CLOCK(0x304) = 0x18000000;
sleep(2);

I2S(0x0A0) |= 0x400;
I2S(0x088) &= 0xFFFFFFFE;
I2S(0x1A0) |= 0x400;
I2S(0x188) &= 0xFFFFFFFE;
I2S(0x2A0) |= 0x400;
I2S(0x288) &= 0xFFFFFFFE;
I2S(0x3A0) |= 0x400;
I2S(0x388) &= 0xFFFFFFFE;
I2S(0x4A0) |= 0x400;
I2S(0x488) &= 0xFFFFFFFE;
DISPLAY_A(0xCF8) |= 4;
VIC(0x8C) = 0xFFFFFFFF;
sleep(2);

CLOCK(0x2A8) = 0x40;
CLOCK(0x300) = 0x18000000;
CLOCK(0x290) = 0x40000;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = 0xC0;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80000130;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = 0x1F00200;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = 0x80400808;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = 0x402000FC;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = 0x23000780;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = 0x300;
CLOCK(0xF8) = 0;
CLOCK(0xFC) = 0;
CLOCK(0x3A0) = 0;
CLOCK(0x3A4) = 0;
CLOCK(0x554) = 0;
CLOCK(0xD0) &= 0x1F7FFFFF;
CLOCK(0x410) &= 0xFFFF3FFF;
CLOCK(0x148) = CLOCK(0x148) & 0x1FFFFFFF | 0x80000000;
CLOCK(0x180) = CLOCK(0x180) & 0x1FFFFFFF | 0x80000000;
CLOCK(0x6A0) = CLOCK(0x6A0) & 0x1FFFFFFF | 0x80000000;
}

void config_pmc_scratch() {
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF;
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE;
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= 0x10;
}

void config_oscillators() {
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3 | 4;
SYSCTR0(SYSCTR0_CNTFID0) = 19200000;
TMR(0x14) = 0x45F;
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81 | 0xE;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF | 0x400000;
PMC(APBDEV_PMC_CNTRL2) = PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF | 0x1000;
PMC(APBDEV_PMC_SCRATCH188) = PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF | 0x2000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10;
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF;
PMC(APBDEV_PMC_TSC_MULT) = PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000 | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444;
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2;
}

void config_gpios() {
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;

PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = 0x40;
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = 0x40;

gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);

pinmux_config_i2c(I2C_1);
pinmux_config_i2c(I2C_5);
pinmux_config_uart(UART_A);

// Configure volume up/down as inputs.
gpio_config(GPIO_PORT_X, GPIO_PIN_6, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_X, GPIO_PIN_7, GPIO_MODE_GPIO);
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
}

void setup() {
config_oscillators();
APB_MISC(0x40) = 0;
config_gpios();

if (get_unit_type() == 0) {
// TODO: devunit sub_40018D90
}

clock_enable_cl_dvfs();
clock_enable_i2c(I2C_1);
clock_enable_i2c(I2C_5);

static const clock_t clock_unk1 = { 0x358, 0x360, 0x42C, 0x1F, 0, 0 };
static const clock_t clock_unk2 = { 0x358, 0x360, 0, 0x1E, 0, 0 };
clock_enable(&clock_unk1);
clock_enable(&clock_unk2);

i2c_init(I2C_1);
i2c_init(I2C_5);

i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_CNFGBBC, 0x40);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_ONOFFCNFG1, 0x78);

i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_CFG0, 0x38);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_CFG1, 0x3A);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_CFG2, 0x38);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_LDO4, 0xF);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_LDO8, 0xC7);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_SD0, 0x4F);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_SD1, 0x29);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_SD3, 0x1B);

i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_SD0, 42); //42 = (1125000 - 600000) / 12500 -> 1.125V

config_pmc_scratch();

CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888 | 0x3333;

mc_config_carveout();

sdram_init();

sdram_lp0_save_params(sdram_get_params());
}

void bootloader() {
mbist_workaround();
clock_enable_se();

// This makes fuse registers visible
clock_enable_fuse(0x01);

check_sku();

// Check configuration fuses
check_config_fuses();

// Disables fuse programming until next reboot
FUSE(FUSE_PRIVATEKEYDISABLE) = 0x10;

// Setup memory controllers
mc_enable();

// Pre-Firmware setup
setup();
}
19 changes: 19 additions & 0 deletions src/bootloader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2018 Reisyukaku
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/

#pragma once

void bootloader();
40 changes: 40 additions & 0 deletions src/bootrom.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2018 Reisyukaku
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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 "hwinit.h"
#include "bootrom.h"

void bootrom(void) {
// Bootrom part we skipped.
u32 sbk[4] = { FUSE(0x1A4), FUSE(0x1A8), FUSE(0x1AC), FUSE(0x1B0) };
se_aes_key_set(14, sbk, 0x10);

// Lock SBK from being read.
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 14 * 4) = 0x7E;

// This memset needs to happen here, else TZRAM will behave weirdly later on.
memset((void *)0x7C010000, 0, 0x10000);
PMC(APBDEV_PMC_CRYPTO_OP) = 0;
SE(SE_INT_STATUS_REG_OFFSET) = 0x1F;

// Lock SSK (although it's not set and unused anyways).
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 15 * 4) = 0x7E;

// Clear the boot reason to avoid problems later
PMC(APBDEV_PMC_SCRATCH200) = 0x0;
PMC(APBDEV_PMC_RST_STATUS_0) = 0x0;
PMC(APBDEV_PMC_SCRATCH49_0) = 0x0;
}
Loading

0 comments on commit 9625fd1

Please sign in to comment.