fusee: uncompress fusee-primary, which is now getting pretty big.

This commit is contained in:
Michael Scire
2020-11-29 17:29:07 -08:00
committed by SciresM
parent 8104beb2e0
commit f600dff961
67 changed files with 2107 additions and 1464 deletions

View File

@@ -1,95 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_APB_MISC_H
#define FUSEE_APB_MISC_H
#include <stdint.h>
#define APB_MISC_BASE 0x70000000
#define APB_PADCTL_BASE 0x70000810
#define MAKE_APB_MISC_REG(n) MAKE_REG32(APB_MISC_BASE + n)
#define MAKE_APB_PADCTL_REG(n) MAKE_REG32(APB_PADCTL_BASE + n)
#define APB_MISC_PP_PINMUX_GLOBAL_0 MAKE_APB_MISC_REG(0x40)
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL_0 MAKE_APB_MISC_REG(0xB64)
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL_0 MAKE_APB_MISC_REG(0xB68)
#define SDMMC1_PAD_CAL_DRVUP_SHIFT (20)
#define SDMMC1_PAD_CAL_DRVDN_SHIFT (12)
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWR_SHIFT (28)
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWF_SHIFT (30)
#define SDMMC1_PAD_CAL_DRVUP_MASK (0x7Fu << SDMMC1_PAD_CAL_DRVUP_SHIFT)
#define SDMMC1_PAD_CAL_DRVDN_MASK (0x7Fu << SDMMC1_PAD_CAL_DRVDN_SHIFT)
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWR_MASK (0x03u << SDMMC1_CLK_CFG_CAL_DRVDN_SLWR_SHIFT)
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWF_MASK (0x03u << SDMMC1_CLK_CFG_CAL_DRVDN_SLWF_SHIFT)
#define EMMC2_PAD_DRVUP_COMP_SHIFT (8)
#define EMMC2_PAD_DRVDN_COMP_SHIFT (2)
#define EMMC2_PAD_DRVUP_COMP_MASK (0x3Fu << EMMC2_PAD_DRVUP_COMP_SHIFT)
#define EMMC2_PAD_DRVDN_COMP_MASK (0x3Fu << EMMC2_PAD_DRVDN_COMP_SHIFT)
#define SDMMC2_PAD_CAL_DRVUP_SHIFT (20)
#define SDMMC2_PAD_CAL_DRVDN_SHIFT (12)
#define SDMMC2_PAD_CAL_DRVUP_MASK (0x7Fu << SDMMC2_PAD_CAL_DRVUP_SHIFT)
#define SDMMC2_PAD_CAL_DRVDN_MASK (0x7Fu << SDMMC2_PAD_CAL_DRVDN_SHIFT)
#define EMMC4_PAD_DRVUP_COMP_SHIFT (8)
#define EMMC4_PAD_DRVDN_COMP_SHIFT (2)
#define EMMC4_PAD_DRVUP_COMP_MASK (0x3Fu << EMMC4_PAD_DRVUP_COMP_SHIFT)
#define EMMC4_PAD_DRVDN_COMP_MASK (0x3Fu << EMMC4_PAD_DRVDN_COMP_SHIFT)
#define PADCTL_SDMMC1_DEEP_LOOPBACK (1 << 0)
#define PADCTL_SDMMC3_DEEP_LOOPBACK (1 << 0)
#define PADCTL_SDMMC2_ENABLE_DATA_IN (0xFF << 8)
#define PADCTL_SDMMC2_ENABLE_CLK_IN (0x3 << 4)
#define PADCTL_SDMMC2_DEEP_LOOPBACK (1 << 0)
#define PADCTL_SDMMC4_ENABLE_DATA_IN (0xFF << 8)
#define PADCTL_SDMMC4_ENABLE_CLK_IN (0x3 << 4)
#define PADCTL_SDMMC4_DEEP_LOOPBACK (1 << 0)
#define PADCTL_SDMMC1_CD_SOURCE (1 << 0)
#define PADCTL_SDMMC1_WP_SOURCE (1 << 1)
#define PADCTL_SDMMC3_CD_SOURCE (1 << 2)
#define PADCTL_SDMMC3_WP_SOURCE (1 << 3)
typedef struct {
uint32_t asdbgreg; /* 0x810 */
uint32_t _0x814[0x31];
uint32_t sdmmc1_clk_lpbk_control; /* 0x8D4 */
uint32_t sdmmc3_clk_lpbk_control; /* 0x8D8 */
uint32_t emmc2_pad_cfg_control; /* 0x8DC */
uint32_t emmc4_pad_cfg_control; /* 0x8E0 */
uint32_t _0x8E4[0x6E];
uint32_t sdmmc1_pad_cfgpadctrl; /* 0xA98 */
uint32_t emmc2_pad_cfgpadctrl; /* 0xA9C */
uint32_t emmc2_pad_drv_type_cfgpadctrl; /* 0xAA0 */
uint32_t emmc2_pad_pupd_cfgpadctrl; /* 0xAA4 */
uint32_t _0xAA8[0x03];
uint32_t sdmmc3_pad_cfgpadctrl; /* 0xAB0 */
uint32_t emmc4_pad_cfgpadctrl; /* 0xAB4 */
uint32_t emmc4_pad_drv_type_cfgpadctrl; /* 0xAB8 */
uint32_t emmc4_pad_pupd_cfgpadctrl; /* 0xABC */
uint32_t _0xAC0[0x2E];
uint32_t vgpio_gpio_mux_sel; /* 0xB74 */
uint32_t qspi_sck_lpbk_control; /* 0xB78 */
} tegra_padctl_t;
static inline volatile tegra_padctl_t *padctl_get_regs(void)
{
return (volatile tegra_padctl_t *)APB_PADCTL_BASE;
}
#endif

View File

@@ -1,82 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <stdint.h>
#include "btn.h"
#include "i2c.h"
#include "gpio.h"
#include "timers.h"
uint32_t btn_read()
{
uint32_t res = 0;
if (!gpio_read(GPIO_BUTTON_VOL_DOWN))
res |= BTN_VOL_DOWN;
if (!gpio_read(GPIO_BUTTON_VOL_UP))
res |= BTN_VOL_UP;
uint32_t val = 0;
if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, 0x15, &val, 1))
{
if (val & 0x4)
res |= BTN_POWER;
}
return res;
}
uint32_t btn_wait()
{
uint32_t res = 0, btn = btn_read();
int pwr = 0;
if (btn & BTN_POWER)
{
pwr = 1;
btn &= ~BTN_POWER;
}
do
{
res = btn_read();
if (!(res & BTN_POWER) && pwr)
pwr = 0;
else if (pwr)
res &= ~BTN_POWER;
} while (btn == res);
return res;
}
uint32_t btn_wait_timeout(uint32_t time_ms, uint32_t mask)
{
uint32_t timeout = get_time_ms() + time_ms;
uint32_t res = btn_read() & mask;
do
{
if (!(res & mask))
res = btn_read() & mask;
} while (get_time_ms() < timeout);
return res;
}

View File

@@ -1,139 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 "car.h"
#include "timers.h"
#include "utils.h"
static inline uint32_t get_clk_source_reg(CarDevice dev) {
switch (dev) {
case CARDEVICE_UARTA: return 0x178;
case CARDEVICE_UARTB: return 0x17C;
case CARDEVICE_UARTC: return 0x1A0;
case CARDEVICE_I2C1: return 0x124;
case CARDEVICE_I2C5: return 0x128;
case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0x42C;
case CARDEVICE_HOST1X: return 0x180;
case CARDEVICE_TSEC: return 0x1F4;
case CARDEVICE_SOR_SAFE: return 0;
case CARDEVICE_SOR0: return 0;
case CARDEVICE_SOR1: return 0x410;
case CARDEVICE_KFUSE: return 0;
case CARDEVICE_CL_DVFS: return 0;
case CARDEVICE_CORESIGHT: return 0x1D4;
case CARDEVICE_ACTMON: return 0x3E8;
case CARDEVICE_BPMP: return 0;
default: generic_panic();
}
}
static inline uint32_t get_clk_source_val(CarDevice dev) {
switch (dev) {
case CARDEVICE_UARTA: return 0;
case CARDEVICE_UARTB: return 0;
case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 6;
case CARDEVICE_I2C5: return 6;
case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 4;
case CARDEVICE_TSEC: return 0;
case CARDEVICE_SOR_SAFE: return 0;
case CARDEVICE_SOR0: return 0;
case CARDEVICE_SOR1: return 0;
case CARDEVICE_KFUSE: return 0;
case CARDEVICE_CL_DVFS: return 0;
case CARDEVICE_CORESIGHT: return 0;
case CARDEVICE_ACTMON: return 6;
case CARDEVICE_BPMP: return 0;
default: generic_panic();
}
}
static inline uint32_t get_clk_source_div(CarDevice dev) {
switch (dev) {
case CARDEVICE_UARTA: return 0;
case CARDEVICE_UARTB: return 0;
case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 0;
case CARDEVICE_I2C5: return 0;
case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 3;
case CARDEVICE_TSEC: return 2;
case CARDEVICE_SOR_SAFE: return 0;
case CARDEVICE_SOR0: return 0;
case CARDEVICE_SOR1: return 2;
case CARDEVICE_KFUSE: return 0;
case CARDEVICE_CL_DVFS: return 0;
case CARDEVICE_CORESIGHT: return 4;
case CARDEVICE_ACTMON: return 0;
case CARDEVICE_BPMP: return 0;
default: generic_panic();
}
}
static uint32_t g_clk_reg_offsets[NUM_CAR_BANKS] = {0x010, 0x014, 0x018, 0x360, 0x364, 0x280, 0x298};
static uint32_t g_rst_reg_offsets[NUM_CAR_BANKS] = {0x004, 0x008, 0x00C, 0x358, 0x35C, 0x28C, 0x2A4};
void clk_enable(CarDevice dev) {
uint32_t clk_source_reg;
if ((clk_source_reg = get_clk_source_reg(dev))) {
MAKE_CAR_REG(clk_source_reg) = (get_clk_source_val(dev) << 29) | get_clk_source_div(dev);
}
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
}
void clk_disable(CarDevice dev) {
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
}
void rst_enable(CarDevice dev) {
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
}
void rst_disable(CarDevice dev) {
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
}
void clkrst_enable(CarDevice dev) {
clk_enable(dev);
rst_disable(dev);
}
void clkrst_disable(CarDevice dev) {
rst_enable(dev);
clk_disable(dev);
}
void clkrst_reboot(CarDevice dev) {
clkrst_disable(dev);
if (dev == CARDEVICE_KFUSE) {
/* Workaround for KFUSE clock. */
clk_enable(dev);
udelay(100);
rst_disable(dev);
udelay(200);
} else {
clkrst_enable(dev);
}
}
void clkrst_enable_fuse_regs(bool enable) {
volatile tegra_car_t *car = car_get_regs();
car->misc_clk_enb = ((car->misc_clk_enb & 0xEFFFFFFF) | ((enable & 1) << 28));
}

View File

@@ -1,505 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_CAR_H
#define FUSEE_CAR_H
#include <stdint.h>
#include <stdbool.h>
#define CAR_BASE 0x60006000
#define MAKE_CAR_REG(n) MAKE_REG32(CAR_BASE + n)
#define CLK_L_SDMMC1 (1 << 14)
#define CLK_L_SDMMC2 (1 << 9)
#define CLK_U_SDMMC3 (1 << 5)
#define CLK_L_SDMMC4 (1 << 15)
#define CLK_SOURCE_MASK (0b111 << 29)
#define CLK_SOURCE_FIRST (0b000 << 29)
#define CLK_DIVIDER_MASK (0xff << 0)
#define CLK_DIVIDER_UNITY (0x00 << 0)
#define NUM_CAR_BANKS 7
/* Clock and reset devices. */
typedef enum {
CARDEVICE_UARTA = ((0 << 5) | 0x6),
CARDEVICE_UARTB = ((0 << 5) | 0x7),
CARDEVICE_UARTC = ((1 << 5) | 0x17),
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F),
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
CARDEVICE_TSEC = ((2 << 5) | 0x13),
CARDEVICE_SOR_SAFE = ((6 << 5) | 0x1E),
CARDEVICE_SOR0 = ((5 << 5) | 0x16),
CARDEVICE_SOR1 = ((5 << 5) | 0x17),
CARDEVICE_KFUSE = ((1 << 5) | 0x8),
CARDEVICE_CL_DVFS = ((4 << 5) | 0x1B),
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
CARDEVICE_BPMP = ((0 << 5) | 0x1)
} CarDevice;
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
typedef struct {
uint32_t rst_src; /* _RST_SOURCE_0, 0x00 */
/* _RST_DEVICES_L/H/U_0 0x4-0xc */
uint32_t rst_dev_l;
uint32_t rst_dev_h;
uint32_t rst_dev_u;
/* _CLK_OUT_ENB_L/H/U_0 0x10-0x18 */
uint32_t clk_out_enb_l;
uint32_t clk_out_enb_h;
uint32_t clk_out_enb_u;
uint32_t _0x1C;
uint32_t cclk_brst_pol; /* _CCLK_BURST_POLICY_0, 0x20 */
uint32_t super_cclk_div; /* _SUPER_CCLK_DIVIDER_0, 0x24 */
uint32_t sclk_brst_pol; /* _SCLK_BURST_POLICY_0, 0x28 */
uint32_t super_sclk_div; /* _SUPER_SCLK_DIVIDER_0, 0x2c */
uint32_t clk_sys_rate; /* _CLK_SYSTEM_RATE_0, 0x30 */
uint32_t prog_dly_clk; /* _PROG_DLY_CLK_0, 0x34 */
uint32_t aud_sync_clk_rate; /* _AUDIO_SYNC_CLK_RATE_0, 0x38 */
uint32_t _0x3C;
uint32_t cop_clk_skip_plcy; /* _COP_CLK_SKIP_POLICY_0, 0x40 */
uint32_t clk_mask_arm; /* _CLK_MASK_ARM_0, 0x44 */
uint32_t misc_clk_enb; /* _MISC_CLK_ENB_0, 0x48 */
uint32_t clk_cpu_cmplx; /* _CLK_CPU_CMPLX_0, 0x4c */
uint32_t osc_ctrl; /* _OSC_CTRL_0, 0x50 */
uint32_t pll_lfsr; /* _PLL_LFSR_0, 0x54 */
uint32_t osc_freq_det; /* _OSC_FREQ_DET_0, 0x58 */
uint32_t osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS_0, 0x5c */
uint32_t _0x60[2];
uint32_t plle_ss_cntl; /* _PLLE_SS_CNTL_0, 0x68 */
uint32_t plle_misc1; /* _PLLE_MISC1_0, 0x6c */
uint32_t _0x70[4];
/* PLLC 0x80-0x8c */
uint32_t pllc_base;
uint32_t pllc_out;
uint32_t pllc_misc0;
uint32_t pllc_misc1;
/* PLLM 0x90-0x9c */
uint32_t pllm_base;
uint32_t pllm_out;
uint32_t pllm_misc1;
uint32_t pllm_misc2;
/* PLLP 0xa0-0xac */
uint32_t pllp_base;
uint32_t pllp_outa;
uint32_t pllp_outb;
uint32_t pllp_misc;
/* PLLA 0xb0-0xbc */
uint32_t plla_base;
uint32_t plla_out;
uint32_t plla_misc0;
uint32_t plla_misc1;
/* PLLU 0xc0-0xcc */
uint32_t pllu_base;
uint32_t pllu_out;
uint32_t pllu_misc1;
uint32_t pllu_misc2;
/* PLLD 0xd0-0xdc */
uint32_t plld_base;
uint32_t plld_out;
uint32_t plld_misc1;
uint32_t plld_misc2;
/* PLLX 0xe0-0xe4 */
uint32_t pllx_base;
uint32_t pllx_misc;
/* PLLE 0xe8-0xf4 */
uint32_t plle_base;
uint32_t plle_misc;
uint32_t plle_ss_cntl1;
uint32_t plle_ss_cntl2;
uint32_t lvl2_clk_gate_ovra; /* _LVL2_CLK_GATE_OVRA_0, 0xf8 */
uint32_t lvl2_clk_gate_ovrb; /* _LVL2_CLK_GATE_OVRB_0, 0xfc */
uint32_t clk_source_i2s2; /* _CLK_SOURCE_I2S2_0, 0x100 */
uint32_t clk_source_i2s3; /* _CLK_SOURCE_I2S3_0, 0x104 */
uint32_t clk_source_spdif_out; /* _CLK_SOURCE_SPDIF_OUT_0, 0x108 */
uint32_t clk_source_spdif_in; /* _CLK_SOURCE_SPDIF_IN_0, 0x10c */
uint32_t clk_source_pwm; /* _CLK_SOURCE_PWM_0, 0x110 */
uint32_t _0x114;
uint32_t clk_source_spi2; /* _CLK_SOURCE_SPI2_0, 0x118 */
uint32_t clk_source_spi3; /* _CLK_SOURCE_SPI3_0, 0x11c */
uint32_t _0x120;
uint32_t clk_source_i2c1; /* _CLK_SOURCE_I2C1_0, 0x124 */
uint32_t clk_source_i2c5; /* _CLK_SOURCE_I2C5_0, 0x128 */
uint32_t _0x12c[2];
uint32_t clk_source_spi1; /* _CLK_SOURCE_SPI1_0, 0x134 */
uint32_t clk_source_disp1; /* _CLK_SOURCE_DISP1_0, 0x138 */
uint32_t clk_source_disp2; /* _CLK_SOURCE_DISP2_0, 0x13c */
uint32_t _0x140;
uint32_t clk_source_isp; /* _CLK_SOURCE_ISP_0, 0x144 */
uint32_t clk_source_vi; /* _CLK_SOURCE_VI_0, 0x148 */
uint32_t _0x14c;
uint32_t clk_source_sdmmc1; /* _CLK_SOURCE_SDMMC1_0, 0x150 */
uint32_t clk_source_sdmmc2; /* _CLK_SOURCE_SDMMC2_0, 0x154 */
uint32_t _0x158[3];
uint32_t clk_source_sdmmc4; /* _CLK_SOURCE_SDMMC4_0, 0x164 */
uint32_t _0x168[4];
uint32_t clk_source_uarta; /* _CLK_SOURCE_UARTA_0, 0x178 */
uint32_t clk_source_uartb; /* _CLK_SOURCE_UARTB_0, 0x17c */
uint32_t clk_source_host1x; /* _CLK_SOURCE_HOST1X_0, 0x180 */
uint32_t _0x184[5];
uint32_t clk_source_i2c2; /* _CLK_SOURCE_I2C2_0, 0x198 */
uint32_t clk_source_emc; /* _CLK_SOURCE_EMC_0, 0x19c */
uint32_t clk_source_uartc; /* _CLK_SOURCE_UARTC_0, 0x1a0 */
uint32_t _0x1a4;
uint32_t clk_source_vi_sensor; /* _CLK_SOURCE_VI_SENSOR_0, 0x1a8 */
uint32_t _0x1ac[2];
uint32_t clk_source_spi4; /* _CLK_SOURCE_SPI4_0, 0x1b4 */
uint32_t clk_source_i2c3; /* _CLK_SOURCE_I2C3_0, 0x1b8 */
uint32_t clk_source_sdmmc3; /* _CLK_SOURCE_SDMMC3_0, 0x1bc */
uint32_t clk_source_uartd; /* _CLK_SOURCE_UARTD_0, 0x1c0 */
uint32_t _0x1c4[2];
uint32_t clk_source_owr; /* _CLK_SOURCE_OWR_0, 0x1cc */
uint32_t _0x1d0;
uint32_t clk_source_csite; /* _CLK_SOURCE_CSITE_0, 0x1d4 */
uint32_t clk_source_i2s1; /* _CLK_SOURCE_I2S1_0, 0x1d8 */
uint32_t clk_source_dtv; /* _CLK_SOURCE_DTV_0, 0x1dc */
uint32_t _0x1e0[5];
uint32_t clk_source_tsec; /* _CLK_SOURCE_TSEC_0, 0x1f4 */
uint32_t _0x1f8;
uint32_t clk_spare2; /* _CLK_SPARE2_0, 0x1fc */
uint32_t _0x200[32];
uint32_t clk_out_enb_x; /* _CLK_OUT_ENB_X_0, 0x280 */
uint32_t clk_enb_x_set; /* _CLK_ENB_X_SET_0, 0x284 */
uint32_t clk_enb_x_clr; /* _CLK_ENB_X_CLR_0, 0x288 */
uint32_t rst_devices_x; /* _RST_DEVICES_X_0, 0x28c */
uint32_t rst_dev_x_set; /* _RST_DEV_X_SET_0, 0x290 */
uint32_t rst_dev_x_clr; /* _RST_DEV_X_CLR_0, 0x294 */
uint32_t clk_out_enb_y; /* _CLK_OUT_ENB_Y_0, 0x298 */
uint32_t clk_enb_y_set; /* _CLK_ENB_Y_SET_0, 0x29c */
uint32_t clk_enb_y_clr; /* _CLK_ENB_Y_CLR_0, 0x2a0 */
uint32_t rst_devices_y; /* _RST_DEVICES_Y_0, 0x2a4 */
uint32_t rst_dev_y_set; /* _RST_DEV_Y_SET_0, 0x2a8 */
uint32_t rst_dev_y_clr; /* _RST_DEV_Y_CLR_0, 0x2ac */
uint32_t _0x2b0[17];
uint32_t dfll_base; /* _DFLL_BASE_0, 0x2f4 */
uint32_t _0x2f8[2];
/* _RST_DEV_L/H/U_SET_0 0x300-0x314 */
uint32_t rst_dev_l_set;
uint32_t rst_dev_l_clr;
uint32_t rst_dev_h_set;
uint32_t rst_dev_h_clr;
uint32_t rst_dev_u_set;
uint32_t rst_dev_u_clr;
uint32_t _0x318[2];
/* _CLK_ENB_L/H/U_CLR_0 0x320-0x334 */
uint32_t clk_enb_l_set;
uint32_t clk_enb_l_clr;
uint32_t clk_enb_h_set;
uint32_t clk_enb_h_clr;
uint32_t clk_enb_u_set;
uint32_t clk_enb_u_clr;
uint32_t _0x338;
uint32_t ccplex_pg_sm_ovrd; /* _CCPLEX_PG_SM_OVRD_0, 0x33c */
uint32_t rst_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */
uint32_t rst_cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */
/* Additional (T30) registers */
uint32_t clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */
uint32_t clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */
uint32_t _0x350[2];
uint32_t rst_dev_v; /* _RST_DEVICES_V_0, 0x358 */
uint32_t rst_dev_w; /* _RST_DEVICES_W_0, 0x35c */
uint32_t clk_out_enb_v; /* _CLK_OUT_ENB_V_0, 0x360 */
uint32_t clk_out_enb_w; /* _CLK_OUT_ENB_W_0, 0x364 */
uint32_t cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */
uint32_t super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36c */
uint32_t cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */
uint32_t super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */
uint32_t clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */
uint32_t clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37c */
uint32_t cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */
uint32_t cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTRL1_0, 0x384 */
uint32_t cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2_0, 0x388 */
uint32_t _0x38c[5];
uint32_t lvl2_clk_gate_ovrc; /* _LVL2_CLK_GATE_OVRC, 0x3a0 */
uint32_t lvl2_clk_gate_ovrd; /* _LVL2_CLK_GATE_OVRD, 0x3a4 */
uint32_t _0x3a8[2];
uint32_t _0x3b0;
uint32_t clk_source_mselect; /* _CLK_SOURCE_MSELECT_0, 0x3b4 */
uint32_t clk_source_tsensor; /* _CLK_SOURCE_TSENSOR_0, 0x3b8 */
uint32_t clk_source_i2s4; /* _CLK_SOURCE_I2S4_0, 0x3bc */
uint32_t clk_source_i2s5; /* _CLK_SOURCE_I2S5_0, 0x3c0 */
uint32_t clk_source_i2c4; /* _CLK_SOURCE_I2C4_0, 0x3c4 */
uint32_t _0x3c8[2];
uint32_t clk_source_ahub; /* _CLK_SOURCE_AHUB_0, 0x3d0 */
uint32_t _0x3d4[4];
uint32_t clk_source_hda2codec_2x; /* _CLK_SOURCE_HDA2CODEC_2X_0, 0x3e4 */
uint32_t clk_source_actmon; /* _CLK_SOURCE_ACTMON_0, 0x3e8 */
uint32_t clk_source_extperiph1; /* _CLK_SOURCE_EXTPERIPH1_0, 0x3ec */
uint32_t clk_source_extperiph2; /* _CLK_SOURCE_EXTPERIPH2_0, 0x3f0 */
uint32_t clk_source_extperiph3; /* _CLK_SOURCE_EXTPERIPH3_0, 0x3f4 */
uint32_t _0x3f8;
uint32_t clk_source_i2c_slow; /* _CLK_SOURCE_I2C_SLOW_0, 0x3fc */
uint32_t clk_source_sys; /* _CLK_SOURCE_SYS_0, 0x400 */
uint32_t clk_source_ispb; /* _CLK_SOURCE_ISPB_0, 0x404 */
uint32_t _0x408[2];
uint32_t clk_source_sor1; /* _CLK_SOURCE_SOR1_0, 0x410 */
uint32_t clk_source_sor0; /* _CLK_SOURCE_SOR0_0, 0x414 */
uint32_t _0x418[2];
uint32_t clk_source_sata_oob; /* _CLK_SOURCE_SATA_OOB_0, 0x420 */
uint32_t clk_source_sata; /* _CLK_SOURCE_SATA_0, 0x424 */
uint32_t clk_source_hda; /* _CLK_SOURCE_HDA_0, 0x428 */
uint32_t _0x42c;
/* _RST_DEV_V/W_SET_0 0x430-0x43c */
uint32_t rst_dev_v_set;
uint32_t rst_dev_v_clr;
uint32_t rst_dev_w_set;
uint32_t rst_dev_w_clr;
/* _CLK_ENB_V/W_CLR_0 0x440-0x44c */
uint32_t clk_enb_v_set;
uint32_t clk_enb_v_clr;
uint32_t clk_enb_w_set;
uint32_t clk_enb_w_clr;
/* Additional (T114+) registers */
uint32_t rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */
uint32_t rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */
uint32_t rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */
uint32_t rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR_0, 0x45c */
uint32_t clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET_0, 0x460 */
uint32_t clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR_0, 0x464 */
uint32_t clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET_0, 0x468 */
uint32_t clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR_0, 0x46c */
uint32_t cpu_cmplx_status; /* _CPU_CMPLX_STATUS_0, 0x470 */
uint32_t _0x474;
uint32_t intstatus; /* _INTSTATUS_0, 0x478 */
uint32_t intmask; /* _INTMASK_0, 0x47c */
uint32_t utmip_pll_cfg0; /* _UTMIP_PLL_CFG0_0, 0x480 */
uint32_t utmip_pll_cfg1; /* _UTMIP_PLL_CFG1_0, 0x484 */
uint32_t utmip_pll_cfg2; /* _UTMIP_PLL_CFG2_0, 0x488 */
uint32_t plle_aux; /* _PLLE_AUX_0, 0x48c */
uint32_t sata_pll_cfg0; /* _SATA_PLL_CFG0_0, 0x490 */
uint32_t sata_pll_cfg1; /* _SATA_PLL_CFG1_0, 0x494 */
uint32_t pcie_pll_cfg0; /* _PCIE_PLL_CFG0_0, 0x498 */
uint32_t prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK_0, 0x49c */
uint32_t audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0_0, 0x4a0 */
uint32_t audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1_0, 0x4a4 */
uint32_t audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2_0, 0x4a8 */
uint32_t audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3_0, 0x4ac */
uint32_t audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4_0, 0x4b0 */
uint32_t audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF_0, 0x4b4 */
uint32_t plld2_base; /* _PLLD2_BASE_0, 0x4b8 */
uint32_t plld2_misc; /* _PLLD2_MISC_0, 0x4bc */
uint32_t utmip_pll_cfg3; /* _UTMIP_PLL_CFG3_0, 0x4c0 */
uint32_t pllrefe_base; /* _PLLREFE_BASE_0, 0x4c4 */
uint32_t pllrefe_misc; /* _PLLREFE_MISC_0, 0x4c8 */
uint32_t pllrefe_out; /* _PLLREFE_OUT_0, 0x4cc */
uint32_t cpu_finetrim_byp; /* _CPU_FINETRIM_BYP_0, 0x4d0 */
uint32_t cpu_finetrim_select; /* _CPU_FINETRIM_SELECT_0, 0x4d4 */
uint32_t cpu_finetrim_dr; /* _CPU_FINETRIM_DR_0, 0x4d8 */
uint32_t cpu_finetrim_df; /* _CPU_FINETRIM_DF_0, 0x4dc */
uint32_t cpu_finetrim_f; /* _CPU_FINETRIM_F_0, 0x4e0 */
uint32_t cpu_finetrim_r; /* _CPU_FINETRIM_R_0, 0x4e4 */
uint32_t pllc2_base; /* _PLLC2_BASE_0, 0x4e8 */
uint32_t pllc2_misc0; /* _PLLC2_MISC_0_0, 0x4ec */
uint32_t pllc2_misc1; /* _PLLC2_MISC_1_0, 0x4f0 */
uint32_t pllc2_misc2; /* _PLLC2_MISC_2_0, 0x4f4 */
uint32_t pllc2_misc3; /* _PLLC2_MISC_3_0, 0x4f8 */
uint32_t pllc3_base; /* _PLLC3_BASE_0, 0x4fc */
uint32_t pllc3_misc0; /* _PLLC3_MISC_0_0, 0x500 */
uint32_t pllc3_misc1; /* _PLLC3_MISC_1_0, 0x504 */
uint32_t pllc3_misc2; /* _PLLC3_MISC_2_0, 0x508 */
uint32_t pllc3_misc3; /* _PLLC3_MISC_3_0, 0x50c */
uint32_t pllx_misc1; /* _PLLX_MISC_1_0, 0x510 */
uint32_t pllx_misc2; /* _PLLX_MISC_2_0, 0x514 */
uint32_t pllx_misc3; /* _PLLX_MISC_3_0, 0x518 */
uint32_t xusbio_pll_cfg0; /* _XUSBIO_PLL_CFG0_0, 0x51c */
uint32_t xusbio_pll_cfg1; /* _XUSBIO_PLL_CFG0_1, 0x520 */
uint32_t plle_aux1; /* _PLLE_AUX1_0, 0x524 */
uint32_t pllp_reshift; /* _PLLP_RESHIFT_0, 0x528 */
uint32_t utmipll_hw_pwrdn_cfg0; /* _UTMIPLL_HW_PWRDN_CFG0_0, 0x52c */
uint32_t pllu_hw_pwrdn_cfg0; /* _PLLU_HW_PWRDN_CFG0_0, 0x530 */
uint32_t xusb_pll_cfg0; /* _XUSB_PLL_CFG0_0, 0x534 */
uint32_t _0x538;
uint32_t clk_cpu_misc; /* _CLK_CPU_MISC_0, 0x53c */
uint32_t clk_cpug_misc; /* _CLK_CPUG_MISC_0, 0x540 */
uint32_t clk_cpulp_misc; /* _CLK_CPULP_MISC_0, 0x544 */
uint32_t pllx_hw_ctrl_cfg; /* _PLLX_HW_CTRL_CFG_0, 0x548 */
uint32_t pllx_sw_ramp_cfg; /* _PLLX_SW_RAMP_CFG_0, 0x54c */
uint32_t pllx_hw_ctrl_status; /* _PLLX_HW_CTRL_STATUS_0, 0x550 */
uint32_t lvl2_clk_gate_ovre; /* _LVL2_CLK_GATE_OVRE, 0x554 */
uint32_t super_gr3d_clk_div; /* _SUPER_GR3D_CLK_DIVIDER_0, 0x558 */
uint32_t spare_reg0; /* _SPARE_REG0_0, 0x55c */
uint32_t audio_sync_clk_dmic1; /* _AUDIO_SYNC_CLK_DMIC1_0, 0x560 */
uint32_t audio_sync_clk_dmic2; /* _AUDIO_SYNC_CLK_DMIC2_0, 0x564 */
uint32_t _0x568[2];
uint32_t plld2_ss_cfg; /* _PLLD2_SS_CFG, 0x570 */
uint32_t plld2_ss_ctrl1; /* _PLLD2_SS_CTRL1_0, 0x574 */
uint32_t plld2_ss_ctrl2; /* _PLLD2_SS_CTRL2_0, 0x578 */
uint32_t _0x57c[5];
uint32_t plldp_base; /* _PLLDP_BASE, 0x590*/
uint32_t plldp_misc; /* _PLLDP_MISC, 0x594 */
uint32_t plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */
uint32_t plldp_ss_ctrl1; /* _PLLDP_SS_CTRL1_0, 0x59c */
uint32_t plldp_ss_ctrl2; /* _PLLDP_SS_CTRL2_0, 0x5a0 */
uint32_t pllc4_base; /* _PLLC4_BASE_0, 0x5a4 */
uint32_t pllc4_misc; /* _PLLC4_MISC_0, 0x5a8 */
uint32_t _0x5ac[6];
uint32_t clk_spare0; /* _CLK_SPARE0_0, 0x5c4 */
uint32_t clk_spare1; /* _CLK_SPARE1_0, 0x5c8 */
uint32_t gpu_isob_ctrl; /* _GPU_ISOB_CTRL_0, 0x5cc */
uint32_t pllc_misc2; /* _PLLC_MISC_2_0, 0x5d0 */
uint32_t pllc_misc3; /* _PLLC_MISC_3_0, 0x5d4 */
uint32_t plla_misc2; /* _PLLA_MISC2_0, 0x5d8 */
uint32_t _0x5dc[2];
uint32_t pllc4_out; /* _PLLC4_OUT_0, 0x5e4 */
uint32_t pllmb_base; /* _PLLMB_BASE_0, 0x5e8 */
uint32_t pllmb_misc1; /* _PLLMB_MISC1_0, 0x5ec */
uint32_t pllx_misc4; /* _PLLX_MISC_4_0, 0x5f0 */
uint32_t pllx_misc5; /* _PLLX_MISC_5_0, 0x5f4 */
uint32_t _0x5f8[2];
uint32_t clk_source_xusb_core_host; /* _CLK_SOURCE_XUSB_CORE_HOST_0, 0x600 */
uint32_t clk_source_xusb_falcon; /* _CLK_SOURCE_XUSB_FALCON_0, 0x604 */
uint32_t clk_source_xusb_fs; /* _CLK_SOURCE_XUSB_FS_0, 0x608 */
uint32_t clk_source_xusb_core_dev; /* _CLK_SOURCE_XUSB_CORE_DEV_0, 0x60c */
uint32_t clk_source_xusb_ss; /* _CLK_SOURCE_XUSB_SS_0, 0x610 */
uint32_t clk_source_cilab; /* _CLK_SOURCE_CILAB_0, 0x614 */
uint32_t clk_source_cilcd; /* _CLK_SOURCE_CILCD_0, 0x618 */
uint32_t clk_source_cilef; /* _CLK_SOURCE_CILEF_0, 0x61c */
uint32_t clk_source_dsia_lp; /* _CLK_SOURCE_DSIA_LP_0, 0x620 */
uint32_t clk_source_dsib_lp; /* _CLK_SOURCE_DSIB_LP_0, 0x624 */
uint32_t clk_source_entropy; /* _CLK_SOURCE_ENTROPY_0, 0x628 */
uint32_t clk_source_dvfs_ref; /* _CLK_SOURCE_DVFS_REF_0, 0x62c */
uint32_t clk_source_dvfs_soc; /* _CLK_SOURCE_DVFS_SOC_0, 0x630 */
uint32_t _0x634[3];
uint32_t clk_source_emc_latency; /* _CLK_SOURCE_EMC_LATENCY_0, 0x640 */
uint32_t clk_source_soc_therm; /* _CLK_SOURCE_SOC_THERM_0, 0x644 */
uint32_t _0x648;
uint32_t clk_source_dmic1; /* _CLK_SOURCE_DMIC1_0, 0x64c */
uint32_t clk_source_dmic2; /* _CLK_SOURCE_DMIC2_0, 0x650 */
uint32_t _0x654;
uint32_t clk_source_vi_sensor2; /* _CLK_SOURCE_VI_SENSOR2_0, 0x658 */
uint32_t clk_source_i2c6; /* _CLK_SOURCE_I2C6_0, 0x65c */
uint32_t clk_source_mipibif; /* _CLK_SOURCE_MIPIBIF_0, 0x660 */
uint32_t clk_source_emc_dll; /* _CLK_SOURCE_EMC_DLL_0, 0x664 */
uint32_t _0x668;
uint32_t clk_source_uart_fst_mipi_cal; /* _CLK_SOURCE_UART_FST_MIPI_CAL_0, 0x66c */
uint32_t _0x670[2];
uint32_t clk_source_vic; /* _CLK_SOURCE_VIC_0, 0x678 */
uint32_t pllp_outc; /* _PLLP_OUTC_0, 0x67c */
uint32_t pllp_misc1; /* _PLLP_MISC1_0, 0x680 */
uint32_t _0x684[2];
uint32_t emc_div_clk_shaper_ctrl; /* _EMC_DIV_CLK_SHAPER_CTRL_0, 0x68c */
uint32_t emc_pllc_shaper_ctrl; /* _EMC_PLLC_SHAPER_CTRL_0, 0x690 */
uint32_t clk_source_sdmmc_legacy_tm; /* _CLK_SOURCE_SDMMC_LEGACY_TM_0, 0x694 */
uint32_t clk_source_nvdec; /* _CLK_SOURCE_NVDEC_0, 0x698 */
uint32_t clk_source_nvjpg; /* _CLK_SOURCE_NVJPG_0, 0x69c */
uint32_t clk_source_nvenc; /* _CLK_SOURCE_NVENC_0, 0x6a0 */
uint32_t plla1_base; /* _PLLA1_BASE_0, 0x6a4 */
uint32_t plla1_misc0; /* _PLLA1_MISC_0_0, 0x6a8 */
uint32_t plla1_misc1; /* _PLLA1_MISC_1_0, 0x6ac */
uint32_t plla1_misc2; /* _PLLA1_MISC_2_0, 0x6b0 */
uint32_t plla1_misc3; /* _PLLA1_MISC_3_0, 0x6b4 */
uint32_t audio_sync_clk_dmic3; /* _AUDIO_SYNC_CLK_DMIC3_0, 0x6b8 */
uint32_t clk_source_dmic3; /* _CLK_SOURCE_DMIC3_0, 0x6bc */
uint32_t clk_source_ape; /* _CLK_SOURCE_APE_0, 0x6c0 */
uint32_t clk_source_qspi; /* _CLK_SOURCE_QSPI_0, 0x6c4 */
uint32_t clk_source_vi_i2c; /* _CLK_SOURCE_VI_I2C_0, 0x6c8 */
uint32_t clk_source_usb2_hsic_trk; /* _CLK_SOURCE_USB2_HSIC_TRK_0, 0x6cc */
uint32_t clk_source_pex_sata_usb_rx_byp; /* _CLK_SOURCE_PEX_SATA_USB_RX_BYP_0, 0x6d0 */
uint32_t clk_source_maud; /* _CLK_SOURCE_MAUD_0, 0x6d4 */
uint32_t clk_source_tsecb; /* _CLK_SOURCE_TSECB_0, 0x6d8 */
uint32_t clk_cpug_misc1; /* _CLK_CPUG_MISC1_0, 0x6dc */
uint32_t aclk_burst_policy; /* _ACLK_BURST_POLICY_0, 0x6e0 */
uint32_t super_aclk_divider; /* _SUPER_ACLK_DIVIDER_0, 0x6e4 */
uint32_t nvenc_super_clk_divider; /* _NVENC_SUPER_CLK_DIVIDER_0, 0x6e8 */
uint32_t vi_super_clk_divider; /* _VI_SUPER_CLK_DIVIDER_0, 0x6ec */
uint32_t vic_super_clk_divider; /* _VIC_SUPER_CLK_DIVIDER_0, 0x6f0 */
uint32_t nvdec_super_clk_divider; /* _NVDEC_SUPER_CLK_DIVIDER_0, 0x6f4 */
uint32_t isp_super_clk_divider; /* _ISP_SUPER_CLK_DIVIDER_0, 0x6f8 */
uint32_t ispb_super_clk_divider; /* _ISPB_SUPER_CLK_DIVIDER_0, 0x6fc */
uint32_t nvjpg_super_clk_divider; /* _NVJPG_SUPER_CLK_DIVIDER_0, 0x700 */
uint32_t se_super_clk_divider; /* _SE_SUPER_CLK_DIVIDER_0, 0x704 */
uint32_t tsec_super_clk_divider; /* _TSEC_SUPER_CLK_DIVIDER_0, 0x708 */
uint32_t tsecb_super_clk_divider; /* _TSECB_SUPER_CLK_DIVIDER_0, 0x70c */
uint32_t clk_source_uartape; /* _CLK_SOURCE_UARTAPE_0, 0x710 */
uint32_t clk_cpug_misc2; /* _CLK_CPUG_MISC2_0, 0x714 */
uint32_t clk_source_dbgapb; /* _CLK_SOURCE_DBGAPB_0, 0x718 */
uint32_t clk_ccplex_cc4_ret_clk_enb; /* _CLK_CCPLEX_CC4_RET_CLK_ENB_0, 0x71c */
uint32_t actmon_cpu_clk; /* _ACTMON_CPU_CLK_0, 0x720 */
uint32_t clk_source_emc_safe; /* _CLK_SOURCE_EMC_SAFE_0, 0x724 */
uint32_t sdmmc2_pllc4_out0_shaper_ctrl; /* _SDMMC2_PLLC4_OUT0_SHAPER_CTRL_0, 0x728 */
uint32_t sdmmc2_pllc4_out1_shaper_ctrl; /* _SDMMC2_PLLC4_OUT1_SHAPER_CTRL_0, 0x72c */
uint32_t sdmmc2_pllc4_out2_shaper_ctrl; /* _SDMMC2_PLLC4_OUT2_SHAPER_CTRL_0, 0x730 */
uint32_t sdmmc2_div_clk_shaper_ctrl; /* _SDMMC2_DIV_CLK_SHAPER_CTRL_0, 0x734 */
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
} tegra_car_t;
static inline volatile tegra_car_t *car_get_regs(void) {
return (volatile tegra_car_t *)CAR_BASE;
}
void clk_enable(CarDevice dev);
void clk_disable(CarDevice dev);
void rst_enable(CarDevice dev);
void rst_disable(CarDevice dev);
void clkrst_enable(CarDevice dev);
void clkrst_disable(CarDevice dev);
void clkrst_reboot(CarDevice dev);
void clkrst_enable_fuse_regs(bool enable);
#endif

View File

@@ -1,51 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 "chainloader.h"
int g_chainloader_argc = 0;
char g_chainloader_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE] = {0};
chainloader_entry_t g_chainloader_entries[CHAINLOADER_MAX_ENTRIES] = {0}; /* keep them sorted */
size_t g_chainloader_num_entries = 0;
uintptr_t g_chainloader_entrypoint = 0;
#pragma GCC optimize (3)
static void *xmemmove(void *dst, const void *src, size_t len)
{
const uint8_t *src8 = (const uint8_t *)src;
uint8_t *dst8 = (uint8_t *)dst;
if (dst8 < src8) {
for (size_t i = 0; i < len; i++) {
dst8[i] = src8[i];
}
} else if (dst8 > src8) {
for (size_t i = len; len > 0; len--)
dst8[i - 1] = src8[i - 1];
}
return dst;
}
void relocate_and_chainload_main(void) {
for(size_t i = 0; i < g_chainloader_num_entries; i++) {
chainloader_entry_t *entry = &g_chainloader_entries[i];
xmemmove((void *)entry->load_address, (const void *)entry->src_address, entry->size);
}
((void (*)(int, void *))g_chainloader_entrypoint)(g_chainloader_argc, g_chainloader_arg_data);
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_CHAINLOADER_H
#define FUSEE_CHAINLOADER_H
#include <stddef.h>
#include <stdint.h>
#define CHAINLOADER_ARG_DATA_MAX_SIZE 0x6200
#define CHAINLOADER_MAX_ENTRIES 128
typedef struct chainloader_entry_t {
uintptr_t load_address;
uintptr_t src_address;
size_t size;
size_t num;
} chainloader_entry_t;
extern int g_chainloader_argc;
extern chainloader_entry_t g_chainloader_entries[CHAINLOADER_MAX_ENTRIES]; /* keep them sorted */
extern size_t g_chainloader_num_entries;
extern uintptr_t g_chainloader_entrypoint;
extern char g_chainloader_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE];
void relocate_and_chainload(void);
#endif

View File

@@ -1,267 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <string.h>
#include "di.h"
#include "timers.h"
#include "i2c.h"
#include "pmc.h"
#include "max77620.h"
#include "gpio.h"
#include "pinmux.h"
#include "car.h"
#include "di.inl"
static uint32_t _display_ver = 0;
static void exec_cfg(uint32_t *base, const cfg_op_t *ops, uint32_t num_ops)
{
for (uint32_t i = 0; i < num_ops; i++)
base[ops[i].off] = ops[i].val;
}
static void _display_dsi_wait(uint32_t timeout, uint32_t off, uint32_t mask)
{
uint32_t end = get_time_us() + timeout;
while ((get_time_us() < end) && (MAKE_DSI_REG(off) & mask)) {
/* Wait. */
}
udelay(5);
}
void display_init()
{
volatile tegra_car_t *car = car_get_regs();
volatile tegra_pmc_t *pmc = pmc_get_regs();
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
/* Power on. */
uint8_t val = 0xD0;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1);
val = 0x09;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_GPIO7, &val, 1);
/* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */
car->rst_dev_h_clr = 0x1010000;
car->clk_enb_h_set = 0x1010000;
car->rst_dev_l_clr = 0x18000000;
car->clk_enb_l_set = 0x18000000;
car->clk_enb_x_set = 0x20000;
car->clk_source_uart_fst_mipi_cal = 0xA;
car->clk_enb_w_set = 0x80000;
car->clk_source_dsia_lp = 0xA;
/* DPD idle. */
pmc->io_dpd_req = 0x40000000;
pmc->io_dpd2_req = 0x40000000;
/* Configure pins. */
pinmux->nfc_en &= ~PINMUX_TRISTATE;
pinmux->nfc_int &= ~PINMUX_TRISTATE;
pinmux->lcd_bl_pwm &= ~PINMUX_TRISTATE;
pinmux->lcd_bl_en &= ~PINMUX_TRISTATE;
pinmux->lcd_rst &= ~PINMUX_TRISTATE;
/* Configure Backlight +-5V GPIOs. */
gpio_configure_mode(GPIO_LCD_BL_P5V, GPIO_MODE_GPIO);
gpio_configure_mode(GPIO_LCD_BL_N5V, GPIO_MODE_GPIO);
gpio_configure_direction(GPIO_LCD_BL_P5V, GPIO_DIRECTION_OUTPUT);
gpio_configure_direction(GPIO_LCD_BL_N5V, GPIO_DIRECTION_OUTPUT);
/* Enable Backlight +5V. */
gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_HIGH);
udelay(10000);
/* Enable Backlight -5V. */
gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_HIGH);
udelay(10000);
/* Configure Backlight PWM, EN and RST GPIOs. */
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_GPIO);
gpio_configure_mode(GPIO_LCD_BL_EN, GPIO_MODE_GPIO);
gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO);
gpio_configure_direction(GPIO_LCD_BL_PWM, GPIO_DIRECTION_OUTPUT);
gpio_configure_direction(GPIO_LCD_BL_EN, GPIO_DIRECTION_OUTPUT);
gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT);
/* Enable Backlight EN. */
gpio_write(GPIO_LCD_BL_EN, GPIO_LEVEL_HIGH);
/* Configure display interface and display. */
MAKE_MIPI_CAL_REG(0x60) = 0;
exec_cfg((uint32_t *)CAR_BASE, _display_config_1, 4);
exec_cfg((uint32_t *)DI_BASE, _display_config_2, 94);
exec_cfg((uint32_t *)DSI_BASE, _display_config_3, 60);
udelay(10000);
/* Enable Backlight RST. */
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH);
udelay(60000);
MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204;
MAKE_DSI_REG(DSI_WR_DATA) = 0x337;
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
_display_dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO));
MAKE_DSI_REG(DSI_WR_DATA) = 0x406;
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
_display_dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO));
MAKE_DSI_REG(DSI_HOST_CONTROL) = (DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC);
_display_dsi_wait(150000, DSI_HOST_CONTROL, DSI_HOST_CONTROL_IMM_BTA);
udelay(5000);
_display_ver = MAKE_DSI_REG(DSI_RD_DATA);
if (_display_ver == 0x10)
exec_cfg((uint32_t *)DSI_BASE, _display_config_4, 43);
MAKE_DSI_REG(DSI_WR_DATA) = 0x1105;
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
udelay(180000);
MAKE_DSI_REG(DSI_WR_DATA) = 0x2905;
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
udelay(20000);
exec_cfg((uint32_t *)DSI_BASE, _display_config_5, 21);
exec_cfg((uint32_t *)CAR_BASE, _display_config_6, 3);
MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4;
exec_cfg((uint32_t *)DSI_BASE, _display_config_7, 10);
udelay(10000);
exec_cfg((uint32_t *)MIPI_CAL_BASE, _display_config_8, 6);
exec_cfg((uint32_t *)DSI_BASE, _display_config_9, 4);
exec_cfg((uint32_t *)MIPI_CAL_BASE, _display_config_10, 16);
udelay(10000);
exec_cfg((uint32_t *)DI_BASE, _display_config_11, 113);
}
void display_backlight(bool enable)
{
/* Enable Backlight PWM. */
gpio_write(GPIO_LCD_BL_PWM, enable ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
}
void display_end()
{
volatile tegra_car_t *car = car_get_regs();
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
/* Disable Backlight. */
display_backlight(false);
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 1;
MAKE_DSI_REG(DSI_WR_DATA) = 0x2805;
MAKE_DI_REG(DC_CMD_STATE_ACCESS) = (READ_MUX | WRITE_MUX);
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 0;
exec_cfg((uint32_t *)DI_BASE, _display_config_12, 17);
exec_cfg((uint32_t *)DSI_BASE, _display_config_13, 16);
udelay(10000);
if (_display_ver == 0x10)
exec_cfg((uint32_t *)DSI_BASE, _display_config_14, 22);
MAKE_DSI_REG(DSI_WR_DATA) = 0x1005;
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
udelay(50000);
/* Disable Backlight RST. */
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW);
udelay(10000);
/* Disable Backlight -5V. */
gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_LOW);
udelay(10000);
/* Disable Backlight +5V. */
gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_LOW);
udelay(10000);
/* Disable clocks. */
car->rst_dev_h_set = 0x1010000;
car->clk_enb_h_clr = 0x1010000;
car->rst_dev_l_set = 0x18000000;
car->clk_enb_l_clr = 0x18000000;
MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF));
MAKE_DSI_REG(DSI_POWER_CONTROL) = 0;
/* Backlight PWM. */
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO);
pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE);
pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1);
}
void display_color_screen(uint32_t color)
{
exec_cfg((uint32_t *)DI_BASE, cfg_display_one_color, 8);
/* Configure display to show single color. */
MAKE_DI_REG(DC_WIN_AD_WIN_OPTIONS) = 0;
MAKE_DI_REG(DC_WIN_BD_WIN_OPTIONS) = 0;
MAKE_DI_REG(DC_WIN_CD_WIN_OPTIONS) = 0;
MAKE_DI_REG(DC_DISP_BLEND_BACKGROUND_COLOR) = color;
MAKE_DI_REG(DC_CMD_STATE_CONTROL) = ((MAKE_DI_REG(DC_CMD_STATE_CONTROL) & 0xFFFFFFFE) | GENERAL_ACT_REQ);
udelay(35000);
display_backlight(true);
}
uint32_t *display_init_framebuffer(void *address)
{
static cfg_op_t conf[sizeof(cfg_display_framebuffer)/sizeof(cfg_op_t)] = {0};
if (conf[0].val == 0) {
for (uint32_t i = 0; i < sizeof(cfg_display_framebuffer)/sizeof(cfg_op_t); i++) {
conf[i] = cfg_display_framebuffer[i];
}
}
uint32_t *lfb_addr = (uint32_t *)address;
conf[19].val = (uint32_t)address;
/* This configures the framebuffer @ address with a resolution of 1280x720 (line stride 768). */
exec_cfg((uint32_t *)DI_BASE, conf, 32);
udelay(35000);
return lfb_addr;
}

View File

@@ -1,368 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_DI_H_
#define FUSEE_DI_H_
#include <stdint.h>
#include <stdbool.h>
#define HOST1X_BASE 0x50000000
#define DI_BASE 0x54200000
#define DSI_BASE 0x54300000
#define VIC_BASE 0x54340000
#define MIPI_CAL_BASE 0x700E3000
#define MAKE_HOST1X_REG(n) MAKE_REG32(HOST1X_BASE + n)
#define MAKE_DI_REG(n) MAKE_REG32(DI_BASE + n * 4)
#define MAKE_DSI_REG(n) MAKE_REG32(DSI_BASE + n * 4)
#define MAKE_MIPI_CAL_REG(n) MAKE_REG32(MIPI_CAL_BASE + n)
#define MAKE_VIC_REG(n) MAKE_REG32(VIC_BASE + n)
/* Display registers. */
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
#define SYNCPT_CNTRL_NO_STALL (1 << 8)
#define SYNCPT_CNTRL_SOFT_RESET (1 << 0)
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
#define SYNCPT_VSYNC_ENABLE (1 << 8)
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
#define DC_CMD_DISPLAY_COMMAND 0x32
#define DISP_CTRL_MODE_STOP (0 << 5)
#define DISP_CTRL_MODE_C_DISPLAY (1 << 5)
#define DISP_CTRL_MODE_NC_DISPLAY (2 << 5)
#define DISP_CTRL_MODE_MASK (3 << 5)
#define DC_CMD_DISPLAY_POWER_CONTROL 0x36
#define PW0_ENABLE (1 << 0)
#define PW1_ENABLE (1 << 2)
#define PW2_ENABLE (1 << 4)
#define PW3_ENABLE (1 << 6)
#define PW4_ENABLE (1 << 8)
#define PM0_ENABLE (1 << 16)
#define PM1_ENABLE (1 << 18)
#define DC_CMD_INT_MASK 0x38
#define DC_CMD_INT_ENABLE 0x39
#define DC_CMD_STATE_ACCESS 0x40
#define READ_MUX (1 << 0)
#define WRITE_MUX (1 << 2)
#define DC_CMD_STATE_CONTROL 0x41
#define GENERAL_ACT_REQ (1 << 0)
#define WIN_A_ACT_REQ (1 << 1)
#define WIN_B_ACT_REQ (1 << 2)
#define WIN_C_ACT_REQ (1 << 3)
#define CURSOR_ACT_REQ (1 << 7)
#define GENERAL_UPDATE (1 << 8)
#define WIN_A_UPDATE (1 << 9)
#define WIN_B_UPDATE (1 << 10)
#define WIN_C_UPDATE (1 << 11)
#define CURSOR_UPDATE (1 << 15)
#define NC_HOST_TRIG (1 << 24)
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
#define WINDOW_A_SELECT (1 << 4)
#define WINDOW_B_SELECT (1 << 5)
#define WINDOW_C_SELECT (1 << 6)
#define DC_CMD_REG_ACT_CONTROL 0x043
#define DC_COM_CRC_CONTROL 0x300
#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
#define DC_COM_DSC_TOP_CTL 0x33E
#define DC_DISP_DISP_WIN_OPTIONS 0x402
#define HDMI_ENABLE (1 << 30)
#define DSI_ENABLE (1 << 29)
#define SOR1_TIMING_CYA (1 << 27)
#define SOR1_ENABLE (1 << 26)
#define SOR_ENABLE (1 << 25)
#define CURSOR_ENABLE (1 << 16)
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
#define DC_DISP_REF_TO_SYNC 0x406
#define DC_DISP_SYNC_WIDTH 0x407
#define DC_DISP_BACK_PORCH 0x408
#define DC_DISP_ACTIVE 0x409
#define DC_DISP_FRONT_PORCH 0x40A
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
#define PIXEL_CLK_DIVIDER_PCD3 (3 << 8)
#define PIXEL_CLK_DIVIDER_PCD4 (4 << 8)
#define PIXEL_CLK_DIVIDER_PCD6 (5 << 8)
#define PIXEL_CLK_DIVIDER_PCD8 (6 << 8)
#define PIXEL_CLK_DIVIDER_PCD9 (7 << 8)
#define PIXEL_CLK_DIVIDER_PCD12 (8 << 8)
#define PIXEL_CLK_DIVIDER_PCD16 (9 << 8)
#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8)
#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8)
#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8)
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F
#define DISP_DATA_FORMAT_DF1P1C (0 << 0)
#define DISP_DATA_FORMAT_DF1P2C24B (1 << 0)
#define DISP_DATA_FORMAT_DF1P2C18B (2 << 0)
#define DISP_DATA_FORMAT_DF1P2C16B (3 << 0)
#define DISP_DATA_FORMAT_DF2S (4 << 0)
#define DISP_DATA_FORMAT_DF3S (5 << 0)
#define DISP_DATA_FORMAT_DFSPI (6 << 0)
#define DISP_DATA_FORMAT_DF1P3C24B (7 << 0)
#define DISP_DATA_FORMAT_DF1P3C18B (8 << 0)
#define DISP_ALIGNMENT_MSB (0 << 8)
#define DISP_ALIGNMENT_LSB (1 << 8)
#define DISP_ORDER_RED_BLUE (0 << 9)
#define DISP_ORDER_BLUE_RED (1 << 9)
#define DC_DISP_DISP_COLOR_CONTROL 0x430
#define DITHER_CONTROL_MASK (3 << 8)
#define DITHER_CONTROL_DISABLE (0 << 8)
#define DITHER_CONTROL_ORDERED (2 << 8)
#define DITHER_CONTROL_ERRDIFF (3 << 8)
#define BASE_COLOR_SIZE_MASK (0xf << 0)
#define BASE_COLOR_SIZE_666 (0 << 0)
#define BASE_COLOR_SIZE_111 (1 << 0)
#define BASE_COLOR_SIZE_222 (2 << 0)
#define BASE_COLOR_SIZE_333 (3 << 0)
#define BASE_COLOR_SIZE_444 (4 << 0)
#define BASE_COLOR_SIZE_555 (5 << 0)
#define BASE_COLOR_SIZE_565 (6 << 0)
#define BASE_COLOR_SIZE_332 (7 << 0)
#define BASE_COLOR_SIZE_888 (8 << 0)
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
#define SC1_H_QUALIFIER_NONE (1 << 16)
#define SC0_H_QUALIFIER_NONE (1 << 0)
#define DC_DISP_DATA_ENABLE_OPTIONS 0x432
#define DE_SELECT_ACTIVE_BLANK (0 << 0)
#define DE_SELECT_ACTIVE (1 << 0)
#define DE_SELECT_ACTIVE_IS (2 << 0)
#define DE_CONTROL_ONECLK (0 << 2)
#define DE_CONTROL_NORMAL (1 << 2)
#define DE_CONTROL_EARLY_EXT (2 << 2)
#define DE_CONTROL_EARLY (3 << 2)
#define DE_CONTROL_ACTIVE_BLANK (4 << 2)
#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
#define DC_WIN_CSC_YOF 0x611
#define DC_WIN_CSC_KYRGB 0x612
#define DC_WIN_CSC_KUR 0x613
#define DC_WIN_CSC_KVR 0x614
#define DC_WIN_CSC_KUG 0x615
#define DC_WIN_CSC_KVG 0x616
#define DC_WIN_CSC_KUB 0x617
#define DC_WIN_CSC_KVB 0x618
#define DC_WIN_AD_WIN_OPTIONS 0xB80
#define DC_WIN_BD_WIN_OPTIONS 0xD80
#define DC_WIN_CD_WIN_OPTIONS 0xF80
/* The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER). */
#define DC_WIN_WIN_OPTIONS 0x700
#define H_DIRECTION (1 << 0)
#define V_DIRECTION (1 << 2)
#define COLOR_EXPAND (1 << 6)
#define CSC_ENABLE (1 << 18)
#define WIN_ENABLE (1 << 30)
#define DC_WIN_COLOR_DEPTH 0x703
#define WIN_COLOR_DEPTH_P1 0x0
#define WIN_COLOR_DEPTH_P2 0x1
#define WIN_COLOR_DEPTH_P4 0x2
#define WIN_COLOR_DEPTH_P8 0x3
#define WIN_COLOR_DEPTH_B4G4R4A4 0x4
#define WIN_COLOR_DEPTH_B5G5R5A 0x5
#define WIN_COLOR_DEPTH_B5G6R5 0x6
#define WIN_COLOR_DEPTH_AB5G5R5 0x7
#define WIN_COLOR_DEPTH_B8G8R8A8 0xC
#define WIN_COLOR_DEPTH_R8G8B8A8 0xD
#define WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 0xE
#define WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 0xF
#define WIN_COLOR_DEPTH_YCbCr422 0x10
#define WIN_COLOR_DEPTH_YUV422 0x11
#define WIN_COLOR_DEPTH_YCbCr420P 0x12
#define WIN_COLOR_DEPTH_YUV420P 0x13
#define WIN_COLOR_DEPTH_YCbCr422P 0x14
#define WIN_COLOR_DEPTH_YUV422P 0x15
#define WIN_COLOR_DEPTH_YCbCr422R 0x16
#define WIN_COLOR_DEPTH_YUV422R 0x17
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
#define WIN_COLOR_DEPTH_YUV422RA 0x19
#define DC_WIN_BUFFER_CONTROL 0x702
#define DC_WIN_POSITION 0x704
#define DC_WIN_SIZE 0x705
#define H_SIZE(x) (((x) & 0x1fff) << 0)
#define V_SIZE(x) (((x) & 0x1fff) << 16)
#define DC_WIN_PRESCALED_SIZE 0x706
#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
#define DC_WIN_H_INITIAL_DDA 0x707
#define DC_WIN_V_INITIAL_DDA 0x708
#define DC_WIN_DDA_INC 0x709
#define H_DDA_INC(x) (((x) & 0xffff) << 0)
#define V_DDA_INC(x) (((x) & 0xffff) << 16)
#define DC_WIN_LINE_STRIDE 0x70A
#define DC_WIN_DV_CONTROL 0x70E
/* The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */
#define DC_WINBUF_START_ADDR 0x800
#define DC_WINBUF_ADDR_H_OFFSET 0x806
#define DC_WINBUF_ADDR_V_OFFSET 0x808
#define DC_WINBUF_SURFACE_KIND 0x80B
/* Display serial interface registers. */
#define DSI_RD_DATA 0x9
#define DSI_WR_DATA 0xA
#define DSI_POWER_CONTROL 0xB
#define DSI_POWER_CONTROL_ENABLE 1
#define DSI_INT_ENABLE 0xC
#define DSI_INT_STATUS 0xD
#define DSI_INT_MASK 0xE
#define DSI_HOST_CONTROL 0xF
#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21)
#define DSI_HOST_CONTROL_CRC_RESET (1 << 20)
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
#define DSI_HOST_CONTROL_RAW (1 << 6)
#define DSI_HOST_CONTROL_HS (1 << 5)
#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
#define DSI_HOST_CONTROL_CS (1 << 1)
#define DSI_HOST_CONTROL_ECC (1 << 0)
#define DSI_CONTROL 0x10
#define DSI_CONTROL_HS_CLK_CTRL (1 << 20)
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
#define DSI_CONTROL_DCS_ENABLE (1 << 3)
#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
#define DSI_CONTROL_VIDEO_ENABLE (1 << 1)
#define DSI_CONTROL_HOST_ENABLE (1 << 0)
#define DSI_SOL_DELAY 0x11
#define DSI_MAX_THRESHOLD 0x12
#define DSI_TRIGGER 0x13
#define DSI_TRIGGER_HOST (1 << 1)
#define DSI_TRIGGER_VIDEO (1 << 0)
#define DSI_TX_CRC 0x14
#define DSI_STATUS 0x15
#define DSI_INIT_SEQ_CONTROL 0x1A
#define DSI_INIT_SEQ_DATA_0 0x1B
#define DSI_INIT_SEQ_DATA_1 0x1C
#define DSI_INIT_SEQ_DATA_2 0x1D
#define DSI_INIT_SEQ_DATA_3 0x1E
#define DSI_PKT_SEQ_0_LO 0x23
#define DSI_PKT_SEQ_0_HI 0x24
#define DSI_PKT_SEQ_1_LO 0x25
#define DSI_PKT_SEQ_1_HI 0x26
#define DSI_PKT_SEQ_2_LO 0x27
#define DSI_PKT_SEQ_2_HI 0x28
#define DSI_PKT_SEQ_3_LO 0x29
#define DSI_PKT_SEQ_3_HI 0x2A
#define DSI_PKT_SEQ_4_LO 0x2B
#define DSI_PKT_SEQ_4_HI 0x2C
#define DSI_PKT_SEQ_5_LO 0x2D
#define DSI_PKT_SEQ_5_HI 0x2E
#define DSI_DCS_CMDS 0x33
#define DSI_PKT_LEN_0_1 0x34
#define DSI_PKT_LEN_2_3 0x35
#define DSI_PKT_LEN_4_5 0x36
#define DSI_PKT_LEN_6_7 0x37
#define DSI_PHY_TIMING_0 0x3C
#define DSI_PHY_TIMING_1 0x3D
#define DSI_PHY_TIMING_2 0x3E
#define DSI_BTA_TIMING 0x3F
#define DSI_TIMEOUT_0 0x44
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
#define DSI_TIMEOUT_1 0x45
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
#define DSI_TO_TALLY 0x46
#define DSI_PAD_CONTROL_0 0x4B
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
#define DSI_PAD_CONTROL_CD 0x4c
#define DSI_VIDEO_MODE_CONTROL 0x4E
#define DSI_PAD_CONTROL_1 0x4F
#define DSI_PAD_CONTROL_2 0x50
#define DSI_PAD_CONTROL_3 0x51
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
#define DSI_PAD_CONTROL_4 0x52
typedef struct _cfg_op_t
{
uint32_t off;
uint32_t val;
} cfg_op_t;
void display_init();
void display_end();
/* Show one single color on the display. */
void display_color_screen(uint32_t color);
/* Switches screen backlight ON/OFF. */
void display_backlight(bool enable);
/* Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
uint32_t *display_init_framebuffer(void *address);
#endif

View File

@@ -1,563 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (C) 2018 CTCaer
*
* 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/>.
*/
//Clock config.
static const cfg_op_t _display_config_1[4] = {
{0x4E, 0x40000000}, //CLK_RST_CONTROLLER_CLK_SOURCE_DISP1
{0x34, 0x4830A001}, //CLK_RST_CONTROLLER_PLLD_BASE
{0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
{0x37, 0x2D0AAA} //CLK_RST_CONTROLLER_PLLD_MISC
};
//Display A config.
static const cfg_op_t _display_config_2[94] = {
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_REG_ACT_CONTROL, 0x54},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_DISP_DC_MCCIF_FIFOCTRL, 0},
{DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},
{DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},
{DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},
{DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},
{DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9}, // 9: SYNCPT
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
{0x4E4, 0},
{DC_COM_CRC_CONTROL, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_COMMAND, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}
};
//DSI Init config.
static const cfg_op_t _display_config_3[60] = {
{DSI_WR_DATA, 0},
{DSI_INT_ENABLE, 0},
{DSI_INT_STATUS, 0},
{DSI_INT_MASK, 0},
{DSI_INIT_SEQ_DATA_0, 0},
{DSI_INIT_SEQ_DATA_1, 0},
{DSI_INIT_SEQ_DATA_2, 0},
{DSI_INIT_SEQ_DATA_3, 0},
{DSI_DCS_CMDS, 0},
{DSI_PKT_SEQ_0_LO, 0},
{DSI_PKT_SEQ_1_LO, 0},
{DSI_PKT_SEQ_2_LO, 0},
{DSI_PKT_SEQ_3_LO, 0},
{DSI_PKT_SEQ_4_LO, 0},
{DSI_PKT_SEQ_5_LO, 0},
{DSI_PKT_SEQ_0_HI, 0},
{DSI_PKT_SEQ_1_HI, 0},
{DSI_PKT_SEQ_2_HI, 0},
{DSI_PKT_SEQ_3_HI, 0},
{DSI_PKT_SEQ_4_HI, 0},
{DSI_PKT_SEQ_5_HI, 0},
{DSI_CONTROL, 0},
{DSI_PAD_CONTROL_CD, 0},
{DSI_SOL_DELAY, 0x18},
{DSI_MAX_THRESHOLD, 0x1E0},
{DSI_TRIGGER, 0},
{DSI_INIT_SEQ_CONTROL, 0},
{DSI_PKT_LEN_0_1, 0},
{DSI_PKT_LEN_2_3, 0},
{DSI_PKT_LEN_4_5, 0},
{DSI_PKT_LEN_6_7, 0},
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070601},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30109},
{DSI_BTA_TIMING, 0x190A14},
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
{DSI_TO_TALLY, 0},
{DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_POWER_CONTROL, 0},
{DSI_POWER_CONTROL, 0},
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070601},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30118},
{DSI_BTA_TIMING, 0x190A14},
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
{DSI_TO_TALLY, 0},
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_MAX_THRESHOLD, 0x40},
{DSI_TRIGGER, 0},
{DSI_TX_CRC, 0},
{DSI_INIT_SEQ_CONTROL, 0}
};
//DSI config (if ver == 0x10).
static const cfg_op_t _display_config_4[43] = {
{DSI_WR_DATA, 0x439},
{DSI_WR_DATA, 0x9483FFB9},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xBD15},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x1939},
{DSI_WR_DATA, 0xAAAAAAD8},
{DSI_WR_DATA, 0xAAAAAAEB},
{DSI_WR_DATA, 0xAAEBAAAA},
{DSI_WR_DATA, 0xAAAAAAAA},
{DSI_WR_DATA, 0xAAAAAAEB},
{DSI_WR_DATA, 0xAAEBAAAA},
{DSI_WR_DATA, 0xAA},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x1BD15},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x2739},
{DSI_WR_DATA, 0xFFFFFFD8},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFF},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x2BD15},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xF39},
{DSI_WR_DATA, 0xFFFFFFD8},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFF},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xBD15},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x6D915},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x439},
{DSI_WR_DATA, 0xB9},
{DSI_TRIGGER, DSI_TRIGGER_HOST}
};
//DSI config.
static const cfg_op_t _display_config_5[21] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070601},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30172},
{DSI_BTA_TIMING, 0x190A14},
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
{DSI_TO_TALLY, 0},
{DSI_PKT_SEQ_0_LO, 0x40000208},
{DSI_PKT_SEQ_2_LO, 0x40000308},
{DSI_PKT_SEQ_4_LO, 0x40000308},
{DSI_PKT_SEQ_1_LO, 0x40000308},
{DSI_PKT_SEQ_3_LO, 0x3F3B2B08},
{DSI_PKT_SEQ_3_HI, 0x2CC},
{DSI_PKT_SEQ_5_LO, 0x3F3B2B08},
{DSI_PKT_SEQ_5_HI, 0x2CC},
{DSI_PKT_LEN_0_1, 0xCE0000},
{DSI_PKT_LEN_2_3, 0x87001A2},
{DSI_PKT_LEN_4_5, 0x190},
{DSI_PKT_LEN_6_7, 0x190},
{DSI_HOST_CONTROL, 0},
};
//Clock config.
static const cfg_op_t _display_config_6[3] = {
{0x34, 0x4810C001}, //CLK_RST_CONTROLLER_PLLD_BASE
{0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
{0x37, 0x2DFC00} //CLK_RST_CONTROLLER_PLLD_MISC
};
//DSI config.
static const cfg_op_t _display_config_7[10] = {
{DSI_TRIGGER, 0},
{DSI_CONTROL, 0},
{DSI_SOL_DELAY, 6},
{DSI_MAX_THRESHOLD, 0x1E0},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
};
//MIPI CAL config.
static const cfg_op_t _display_config_8[6] = {
{0x18, 0},
{2, 0xF3F10000},
{0x16, 1},
{0x18, 0},
{0x18, 0x10010},
{0x17, 0x300}
};
//DSI config.
static const cfg_op_t _display_config_9[4] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PAD_CONTROL_2, 0},
{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
{DSI_PAD_CONTROL_4, 0}
};
//MIPI CAL config.
static const cfg_op_t _display_config_10[16] = {
{0xE, 0x200200},
{0xF, 0x200200},
{0x19, 0x200002},
{0x1A, 0x200002},
{5, 0},
{6, 0},
{7, 0},
{8, 0},
{9, 0},
{0xA, 0},
{0x10, 0},
{0x11, 0},
{0x1A, 0},
{0x1C, 0},
{0x1D, 0},
{0, 0x2A000001}
};
//Display A config.
static const cfg_op_t _display_config_11[113] = {
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
{0x4E4, 0},
{DC_COM_CRC_CONTROL, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_COMMAND, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_STATE_ACCESS, 0},
/* Set Display timings */
{DC_DISP_DISP_TIMING_OPTIONS, 0},
{DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.
{DC_DISP_SYNC_WIDTH, 0x10048},
{DC_DISP_BACK_PORCH, 0x90048},
{DC_DISP_ACTIVE, 0x50002D0},
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
/* End of Display timings */
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_DISP_DISP_CLOCK_CONTROL, 0},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},
{DC_DISP_FRONT_PORCH, 0xA0088},
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_STATE_ACCESS, 0},
{DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0}
};
////Display A config.
static const cfg_op_t _display_config_12[17] = {
{DC_DISP_FRONT_PORCH, 0xA0088},
{DC_CMD_INT_MASK, 0},
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_INT_ENABLE, 0},
{DC_CMD_CONT_SYNCPT_VSYNC, 0},
{DC_CMD_DISPLAY_COMMAND, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_DISPLAY_POWER_CONTROL, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
};
//DSI config.
static const cfg_op_t _display_config_13[16] = {
{DSI_POWER_CONTROL, 0},
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070601},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30109},
{DSI_BTA_TIMING, 0x190A14},
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
{DSI_TO_TALLY, 0},
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_MAX_THRESHOLD, 0x40},
{DSI_TRIGGER, 0},
{DSI_TX_CRC, 0},
{DSI_INIT_SEQ_CONTROL, 0}
};
//DSI config (if ver == 0x10).
static const cfg_op_t _display_config_14[22] = {
{DSI_WR_DATA, 0x439},
{DSI_WR_DATA, 0x9483FFB9},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x2139},
{DSI_WR_DATA, 0x191919D5},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xB39},
{DSI_WR_DATA, 0x4F0F41B1},
{DSI_WR_DATA, 0xF179A433},
{DSI_WR_DATA, 0x2D81},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x439},
{DSI_WR_DATA, 0xB9},
{DSI_TRIGGER, DSI_TRIGGER_HOST}
};
//Display A config.
static const cfg_op_t cfg_display_one_color[8] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} //DISPLAY_CTRL_MODE: continuous display.
};
//Display A config.
static const cfg_op_t cfg_display_framebuffer[32] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, //T_A8R8G8B8 //NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8
{DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_POSITION, 0}, //(0,0)
{DC_WIN_H_INITIAL_DDA, 0},
{DC_WIN_V_INITIAL_DDA, 0},
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)}, //Pre-scaled size: 1280x2880 bytes.
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, //Window size: 1280 vertical lines x 720 horizontal pixels.
{DC_WIN_LINE_STRIDE, 0x6000C00}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
{DC_WIN_BUFFER_CONTROL, 0},
{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
{DC_WINBUF_START_ADDR, 0xC0000000}, //Framebuffer address.
{DC_WINBUF_ADDR_H_OFFSET, 0},
{DC_WINBUF_ADDR_V_OFFSET, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, //Enable window AD.
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,118 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <inttypes.h>
#include "exception_handlers.h"
#include "utils.h"
#include "../../../fusee/common/log.h"
#include "../../../fusee/common/vsprintf.h"
#define CODE_DUMP_SIZE 0x30
#define STACK_DUMP_SIZE 0x30
extern const uint32_t exception_handler_table[];
static const char *exception_names[] = {
"Reset", "Undefined instruction", "SWI", "Prefetch abort", "Data abort", "Reserved", "IRQ", "FIQ",
};
static const char *register_names[] = {
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12",
"SP", "LR", "PC", "CPSR",
};
/* Adapted from https://gist.github.com/ccbrown/9722406 */
static void hexdump(const void* data, size_t size, uintptr_t addrbase, char* strbuf) {
const uint8_t *d = (const uint8_t *)data;
char ascii[17] = {0};
ascii[16] = '\0';
for (size_t i = 0; i < size; i++) {
if (i % 16 == 0) {
strbuf += sprintf(strbuf, "%0*" PRIXPTR ": | ", 2 * sizeof(addrbase), addrbase + i);
}
strbuf += sprintf(strbuf, "%02X ", d[i]);
if (d[i] >= ' ' && d[i] <= '~') {
ascii[i % 16] = d[i];
} else {
ascii[i % 16] = '.';
}
if ((i+1) % 8 == 0 || i+1 == size) {
strbuf += sprintf(strbuf, " ");
if ((i+1) % 16 == 0) {
strbuf += sprintf(strbuf, "| %s \n", ascii);
} else if (i+1 == size) {
ascii[(i+1) % 16] = '\0';
if ((i+1) % 16 <= 8) {
strbuf += sprintf(strbuf, " ");
}
for (size_t j = (i+1) % 16; j < 16; j++) {
strbuf += sprintf(strbuf, " ");
}
strbuf += sprintf(strbuf, "| %s \n", ascii);
}
}
}
}
void setup_exception_handlers(void) {
volatile uint32_t *bpmp_exception_handler_table = (volatile uint32_t *)0x6000F200;
for (int i = 0; i < 8; i++) {
if (exception_handler_table[i] != 0) {
bpmp_exception_handler_table[i] = exception_handler_table[i];
}
}
}
void exception_handler_main(uint32_t *registers, unsigned int exception_type) {
char exception_log[0x400] = {0};
uint8_t code_dump[CODE_DUMP_SIZE] = {0};
uint8_t stack_dump[STACK_DUMP_SIZE] = {0};
size_t code_dump_size = 0;
size_t stack_dump_size = 0;
uint32_t pc = registers[15];
uint32_t cpsr = registers[16];
uint32_t instr_addr = pc + ((cpsr & 0x20) ? 2 : 4) - CODE_DUMP_SIZE;
sprintf(exception_log, "An exception occurred!\n");
code_dump_size = safecpy(code_dump, (const void *)instr_addr, CODE_DUMP_SIZE);
stack_dump_size = safecpy(stack_dump, (const void *)registers[13], STACK_DUMP_SIZE);
sprintf(exception_log + strlen(exception_log), "\nException type: %s\n", exception_names[exception_type]);
sprintf(exception_log + strlen(exception_log), "\nRegisters:\n");
/* Print r0 to pc. */
for (int i = 0; i < 16; i += 2) {
sprintf(exception_log + strlen(exception_log), "%-7s%08"PRIX32" %-7s%08"PRIX32"\n",
register_names[i], registers[i], register_names[i+1], registers[i+1]);
}
/* Print cpsr. */
sprintf(exception_log + strlen(exception_log), "%-7s%08"PRIX32"\n", register_names[16], registers[16]);
/* Print code and stack regions. */
sprintf(exception_log + strlen(exception_log), "\nCode dump:\n");
hexdump(code_dump, code_dump_size, instr_addr, exception_log + strlen(exception_log));
sprintf(exception_log + strlen(exception_log), "\nStack dump:\n");
hexdump(stack_dump, stack_dump_size, registers[13], exception_log + strlen(exception_log));
sprintf(exception_log + strlen(exception_log), "\n");
/* Throw fatal error with the full exception log. */
fatal_error(exception_log);
}

View File

@@ -1,28 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_EXCEPTION_HANDLERS_H
#define FUSEE_EXCEPTION_HANDLERS_H
#include <stdint.h>
#include <stddef.h>
/* Copies up to len bytes, stops and returns the read length on data fault. */
size_t safecpy(void *dst, const void *src, size_t len);
void setup_exception_handlers(void);
#endif

View File

@@ -1,125 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
.macro GEN_USUAL_HANDLER name, index, lr_arm_displ, lr_thumb_displ
_exception_handler_\name:
ldr sp, =_regs
stmia sp!, {r0-r7}
/* Adjust lr to make it point to the location where the exception occured. */
mrs r1, spsr
tst r1, #0x20
subeq lr, lr, #\lr_arm_displ
subne lr, lr, #\lr_thumb_displ
mov r0, sp
mov r1, #\index
b _exception_handler_common
.endm
.section .text.exception_handlers_asm, "ax", %progbits
.arm
.align 5
_exception_handler_common:
mrs r2, spsr
mrs r3, cpsr
/* Mask interrupts. */
orr r3, #0xC0
msr cpsr_cx, r3
/* Switch to the mode that triggered the interrupt, get the remaining regs, switch back. */
ands r4, r2, #0xF
moveq r4, #0xF /* usr => sys */
bic r5, r3, #0xF
orr r5, r4
msr cpsr_c, r5
stmia r0!, {r8-lr}
msr cpsr_c, r3
str lr, [r0], #4
str r2, [r0]
/* Finally, switch to system mode, setting interrupts and clearing the flags; set sp as well. */
msr cpsr_cxsf, #0xDF
ldr sp, =(_exception_handler_stack + 0x1000)
ldr r0, =_regs
bl exception_handler_main
b .
GEN_USUAL_HANDLER undefined_instruction, 1, 4, 2
GEN_USUAL_HANDLER swi, 2, 4, 2
GEN_USUAL_HANDLER prefetch_abort, 3, 4, 4
GEN_USUAL_HANDLER data_abort_normal, 4, 8, 8
GEN_USUAL_HANDLER fiq, 7, 4, 4
_exception_handler_data_abort:
/* Mask interrupts (abort mode). */
msr cpsr_cx, #0xD7
adr sp, safecpy+8
cmp lr, sp
blo _exception_handler_data_abort_normal
adr sp, _safecpy_end+8
cmp lr, sp
bhs _exception_handler_data_abort_normal
/* Set the flags, set r12 to 0 for safecpy, return from exception. */
msr spsr_f, #(1 << 30)
mov r12, #0
subs pc, lr, #4
.global safecpy
.type safecpy, %function
safecpy:
push {r4, lr}
mov r3, #0
movs r12, #1
_safecpy_loop:
ldrb r4, [r1, r3]
cmp r12, #0
beq _safecpy_loop_end
strb r4, [r0, r3]
add r3, #1
cmp r3, r2
blo _safecpy_loop
_safecpy_loop_end:
mov r0, r3
pop {r4, lr}
bx lr /* Need to do that separately on ARMv4. */
_safecpy_end:
.section .rodata.exception_handlers_asm, "a", %progbits
.align 2
.global exception_handler_table
exception_handler_table:
.word 0 /* Reset */
.word _exception_handler_undefined_instruction
.word _exception_handler_swi
.word _exception_handler_prefetch_abort
.word _exception_handler_data_abort
.word 0 /* Reserved */
.word 0 /* IRQ */
.word _exception_handler_fiq
.section .bss.exception_handlers_asm, "w", %nobits
.align 4
_exception_handler_stack: .skip 0x1000
_regs: .skip (4 * 17)

View File

@@ -1,31 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_FLOW_CTLR_H
#define FUSEE_FLOW_CTLR_H
#include <stdint.h>
#define FLOW_CTLR_BASE 0x60007000
#define MAKE_FLOW_REG(n) MAKE_REG32(FLOW_CTLR_BASE + n)
#define FLOW_CTLR_HALT_COP_EVENTS_0 MAKE_FLOW_REG(0x004)
#define FLOW_CTLR_RAM_REPAIR_0 MAKE_FLOW_REG(0x040)
#define FLOW_CTLR_FLOW_DBG_QUAL_0 MAKE_FLOW_REG(0x050)
#define FLOW_CTLR_L2FLUSH_CONTROL_0 MAKE_FLOW_REG(0x094)
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 MAKE_FLOW_REG(0x098)
#endif

View File

@@ -1,139 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 "fs_utils.h"
#include "mc.h"
#include "../../../fusee/common/fatfs/ff.h"
#include "../../../fusee/common/log.h"
FATFS sd_fs;
static bool g_sd_mounted = false;
static bool g_sd_initialized = false;
static bool g_ahb_redirect_enabled = false;
sdmmc_t g_sd_sdmmc;
sdmmc_device_t g_sd_device;
bool mount_sd(void)
{
/* Already mounted. */
if (g_sd_mounted)
return true;
/* Enable AHB redirection if necessary. */
if (!g_ahb_redirect_enabled) {
mc_enable_ahb_redirect();
g_ahb_redirect_enabled = true;
}
if (!g_sd_initialized) {
/* Initialize SD. */
if (sdmmc_device_sd_init(&g_sd_device, &g_sd_sdmmc, SDMMC_BUS_WIDTH_4BIT, SDMMC_SPEED_SD_SDR104))
{
g_sd_initialized = true;
/* Mount SD. */
if (f_mount(&sd_fs, "", 1) == FR_OK) {
print(SCREEN_LOG_LEVEL_INFO, "Mounted SD card!\n");
g_sd_mounted = true;
}
}
else
fatal_error("Failed to initialize the SD card!.\n");
}
return g_sd_mounted;
}
void unmount_sd(void)
{
if (g_sd_mounted)
{
f_mount(NULL, "", 1);
sdmmc_device_finish(&g_sd_device);
g_sd_mounted = false;
}
/* Disable AHB redirection if necessary. */
if (g_ahb_redirect_enabled) {
mc_disable_ahb_redirect();
g_ahb_redirect_enabled = false;
}
}
uint32_t get_file_size(const char *filename)
{
/* SD card hasn't been mounted yet. */
if (!g_sd_mounted)
return 0;
/* Open the file for reading. */
FIL f;
if (f_open(&f, filename, FA_READ) != FR_OK)
return 0;
/* Get the file size. */
uint32_t file_size = f_size(&f);
/* Close the file. */
f_close(&f);
return file_size;
}
int read_from_file(void *dst, uint32_t dst_size, const char *filename)
{
/* SD card hasn't been mounted yet. */
if (!g_sd_mounted)
return 0;
/* Open the file for reading. */
FIL f;
if (f_open(&f, filename, FA_READ) != FR_OK)
return 0;
/* Sync. */
f_sync(&f);
/* Read from file. */
UINT br = 0;
int res = f_read(&f, dst, dst_size, &br);
f_close(&f);
return (res == FR_OK) ? (int)br : 0;
}
int write_to_file(void *src, uint32_t src_size, const char *filename)
{
/* SD card hasn't been mounted yet. */
if (!g_sd_mounted)
return 0;
/* Open the file for writing. */
FIL f;
if (f_open(&f, filename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
return 0;
/* Sync. */
f_sync(&f);
/* Write to file. */
UINT bw = 0;
int res = f_write(&f, src, src_size, &bw);
f_close(&f);
return (res == FR_OK) ? (int)bw : 0;
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_FS_UTILS_H
#define FUSEE_FS_UTILS_H
#include <stdbool.h>
#include <stdint.h>
#include "../../../fusee/common/sdmmc/sdmmc.h"
#include "utils.h"
extern sdmmc_t g_sd_sdmmc;
extern sdmmc_device_t g_sd_device;
bool mount_sd(void);
void unmount_sd(void);
uint32_t get_file_size(const char *filename);
int read_from_file(void *dst, uint32_t dst_size, const char *filename);
int write_to_file(void *src, uint32_t src_size, const char *filename);
#endif

View File

@@ -1,344 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <vapours/ams_version.h>
#include "car.h"
#include "fuse.h"
#include "pmc.h"
#include "timers.h"
/* Initialize the fuse driver */
void fuse_init(void) {
/* Make all fuse registers visible, disable the private key and disable programming. */
clkrst_enable_fuse_regs(true);
fuse_disable_private_key();
fuse_disable_programming();
}
/* Disable access to the private key and set the TZ sticky bit. */
void fuse_disable_private_key(void) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
fuse->FUSE_PRIVATEKEYDISABLE = 0x10;
}
/* Disable all fuse programming. */
void fuse_disable_programming(void) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
fuse->FUSE_DISABLEREGPROGRAM = 1;
}
/* Enable power to the fuse hardware array. */
void fuse_enable_power(void) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
pmc->fuse_control &= ~(0x200); /* Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
mdelay(1);
pmc->fuse_control |= 0x100; /* Set PMC_FUSE_CTRL_PS18_LATCH_SET. */
mdelay(1);
}
/* Disable power to the fuse hardware array. */
void fuse_disable_power(void) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
pmc->fuse_control &= ~(0x100); /* Clear PMC_FUSE_CTRL_PS18_LATCH_SET. */
mdelay(1);
pmc->fuse_control |= 0x200; /* Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
mdelay(1);
}
/* Wait for the fuse driver to go idle. */
static void fuse_wait_idle(void) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
uint32_t ctrl_val = 0;
/* Wait for STATE_IDLE */
while ((ctrl_val & (0xF0000)) != 0x40000) {
ctrl_val = fuse->FUSE_FUSECTRL;
}
}
/* Read a fuse from the hardware array. */
uint32_t fuse_hw_read(uint32_t addr) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
/* Wait for idle state. */
fuse_wait_idle();
/* Program the target address. */
fuse->FUSE_FUSEADDR = addr;
/* Enable read operation in control register. */
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x1; /* Set READ command. */
fuse->FUSE_FUSECTRL = ctrl_val;
/* Wait for idle state. */
fuse_wait_idle();
return fuse->FUSE_FUSERDATA;
}
/* Write a fuse in the hardware array. */
void fuse_hw_write(uint32_t value, uint32_t addr) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
/* Wait for idle state. */
fuse_wait_idle();
/* Program the target address and value. */
fuse->FUSE_FUSEADDR = addr;
fuse->FUSE_FUSEWDATA = value;
/* Enable write operation in control register. */
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x2; /* Set WRITE command. */
fuse->FUSE_FUSECTRL = ctrl_val;
/* Wait for idle state. */
fuse_wait_idle();
}
/* Sense the fuse hardware array into the fuse cache. */
void fuse_hw_sense(void) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
/* Wait for idle state. */
fuse_wait_idle();
/* Enable sense operation in control register */
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
fuse->FUSE_FUSECTRL = ctrl_val;
/* Wait for idle state. */
fuse_wait_idle();
}
/* Read the SKU info register. */
uint32_t fuse_get_sku_info(void) {
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
return fuse_chip->FUSE_SKU_INFO;
}
/* Read the bootrom patch version. */
uint32_t fuse_get_bootrom_patch_version(void) {
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB;
}
/* Read a spare bit register. */
uint32_t fuse_get_spare_bit(uint32_t index) {
uint32_t soc_type = fuse_get_soc_type();
if (soc_type == 0) {
if (index < 32) {
volatile tegra_fuse_chip_erista_t *fuse_chip = fuse_chip_erista_get_regs();
return fuse_chip->FUSE_SPARE_BIT[index];
}
} else if (soc_type == 1) {
if (index < 30) {
volatile tegra_fuse_chip_mariko_t *fuse_chip = fuse_chip_mariko_get_regs();
return fuse_chip->FUSE_SPARE_BIT[index];
}
}
return 0;
}
/* Read a reserved ODM register. */
uint32_t fuse_get_reserved_odm(uint32_t index) {
uint32_t soc_type = fuse_get_soc_type();
if (index < 8) {
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
return fuse_chip->FUSE_RESERVED_ODM0[index];
} else if (soc_type == 1) {
volatile tegra_fuse_chip_mariko_t *fuse_chip = fuse_chip_mariko_get_regs();
if (index < 22) {
return fuse_chip->FUSE_RESERVED_ODM8[index - 8];
} else if (index < 25) {
return fuse_chip->FUSE_RESERVED_ODM22[index - 22];
} else if (index < 26) {
return fuse_chip->FUSE_RESERVED_ODM25;
} else if (index < 29) {
return fuse_chip->FUSE_RESERVED_ODM26[index - 26];
} else if (index < 30) {
return fuse_chip->FUSE_RESERVED_ODM29;
}
}
return 0;
}
/* Get the DramId. */
uint32_t fuse_get_dram_id(void) {
return ((fuse_get_reserved_odm(4) >> 3) & 0x1F);
}
/* Derive the DeviceId. */
uint64_t fuse_get_device_id(void) {
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
uint64_t device_id = 0;
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
uint64_t derived_lot_code = 0;
for (unsigned int i = 0; i < 5; i++) {
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
}
derived_lot_code &= 0x03FFFFFF;
device_id |= y_coord << 0;
device_id |= x_coord << 9;
device_id |= wafer_id << 18;
device_id |= derived_lot_code << 24;
device_id |= fab_code << 50;
return device_id;
}
/* Derive the HardwareType with firmware specific checks. */
uint32_t fuse_get_hardware_type_with_firmware_check(uint32_t target_firmware) {
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
uint32_t fuse_spare_bit9 = (fuse_chip->FUSE_SPARE_BIT[9] & 1);
switch (hardware_type) {
case 0x00: return (fuse_spare_bit9 == 0) ? 0 : 3;
case 0x01: return 0; /* HardwareType_Icosa */
case 0x02: return 1; /* HardwareType_Copper */
default: return 3; /* HardwareType_Undefined */
}
} else {
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
switch (hardware_type) {
case 0x01: return 0; /* HardwareType_Icosa */
case 0x02: return 1; /* HardwareType_Copper */
case 0x04: return 3; /* HardwareType_Iowa */
default: return 4; /* HardwareType_Undefined */
}
} else {
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
switch (hardware_type) {
case 0x01: return 0; /* HardwareType_Icosa */
case 0x02: return 4; /* HardwareType_Calcio */
case 0x04: return 3; /* HardwareType_Iowa */
case 0x08: return 2; /* HardwareType_Hoag */
default: return 0xF; /* HardwareType_Undefined */
}
} else {
switch (hardware_type) {
case 0x01: return 0; /* HardwareType_Icosa */
case 0x02: return 4; /* HardwareType_Calcio */
case 0x04: return 3; /* HardwareType_Iowa */
case 0x08: return 2; /* HardwareType_Hoag */
case 0x10: return 5; /* HardwareType_Five */
default: return 0xF; /* HardwareType_Undefined */
}
}
}
}
}
/* Derive the HardwareType. */
uint32_t fuse_get_hardware_type(void) {
return fuse_get_hardware_type_with_firmware_check(ATMOSPHERE_TARGET_FIRMWARE_CURRENT);
}
/* Derive the HardwareState. */
uint32_t fuse_get_hardware_state(void) {
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
uint32_t hardware_state = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3));
switch (hardware_state) {
case 0x03: return 0; /* HardwareState_Development */
case 0x04: return 1; /* HardwareState_Production */
default: return 2; /* HardwareState_Undefined */
}
}
/* Derive the 16-byte HardwareInfo and copy to output buffer. */
void fuse_get_hardware_info(void *dst) {
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
uint32_t hw_info[0x4];
uint32_t ops_reserved = fuse_chip->FUSE_OPT_OPS_RESERVED & 0x3F;
uint32_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
uint32_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
uint32_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
uint32_t lot_code_0 = fuse_chip->FUSE_OPT_LOT_CODE_0;
uint32_t lot_code_1 = fuse_chip->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF;
uint32_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
uint32_t vendor_code = fuse_chip->FUSE_OPT_VENDOR_CODE & 0xF;
/* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved));
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
hw_info[3] = (uint32_t)(vendor_code);
memcpy(dst, hw_info, 0x10);
}
/* Check if have a new ODM fuse format. */
bool fuse_is_new_format(void) {
return ((fuse_get_reserved_odm(4) & 0x800) && (fuse_get_reserved_odm(0) == 0x8E61ECAE) && (fuse_get_reserved_odm(1) == 0xF2BA3BB2));
}
/* Get the DeviceUniqueKeyGeneration. */
uint32_t fuse_get_device_unique_key_generation(void) {
if (fuse_is_new_format()) {
return (fuse_get_reserved_odm(2) & 0x1F);
} else {
return 0;
}
}
/* Get the SocType from the HardwareType. */
uint32_t fuse_get_soc_type(void) {
switch (fuse_get_hardware_type()) {
case 0:
case 1:
return 0; /* SocType_Erista */
case 3:
case 2:
case 4:
case 5:
return 1; /* SocType_Mariko */
default:
return 0xF; /* SocType_Undefined */
}
}
/* Get the Regulator type. */
uint32_t fuse_get_regulator(void) {
if (fuse_get_soc_type() == 1) {
return ((fuse_get_reserved_odm(28) & 1) + 1); /* Regulator_Mariko_Max77812_A or Regulator_Mariko_Max77812_B */
} else {
return 0; /* Regulator_Erista_Max77621 */
}
}

View File

@@ -1,484 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_FUSE_H
#define FUSEE_FUSE_H
#define FUSE_BASE 0x7000F800
#define FUSE_CHIP_BASE (FUSE_BASE + 0x98)
#define MAKE_FUSE_REG(n) MAKE_REG32(FUSE_BASE + n)
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
typedef struct {
uint32_t FUSE_FUSECTRL;
uint32_t FUSE_FUSEADDR;
uint32_t FUSE_FUSERDATA;
uint32_t FUSE_FUSEWDATA;
uint32_t FUSE_FUSETIME_RD1;
uint32_t FUSE_FUSETIME_RD2;
uint32_t FUSE_FUSETIME_PGM1;
uint32_t FUSE_FUSETIME_PGM2;
uint32_t FUSE_PRIV2INTFC_START;
uint32_t FUSE_FUSEBYPASS;
uint32_t FUSE_PRIVATEKEYDISABLE;
uint32_t FUSE_DISABLEREGPROGRAM;
uint32_t FUSE_WRITE_ACCESS_SW;
uint32_t FUSE_PWR_GOOD_SW;
uint32_t _0x38;
uint32_t FUSE_PRIV2RESHIFT;
uint32_t _0x40[0x3];
uint32_t FUSE_FUSETIME_RD3;
uint32_t _0x50[0xC];
uint32_t FUSE_PRIVATE_KEY0_NONZERO;
uint32_t FUSE_PRIVATE_KEY1_NONZERO;
uint32_t FUSE_PRIVATE_KEY2_NONZERO;
uint32_t FUSE_PRIVATE_KEY3_NONZERO;
uint32_t FUSE_PRIVATE_KEY4_NONZERO;
uint32_t _0x94;
} tegra_fuse_t;
typedef struct {
uint32_t _0x98[0x1A];
uint32_t FUSE_PRODUCTION_MODE;
uint32_t FUSE_JTAG_SECUREID_VALID;
uint32_t FUSE_ODM_LOCK;
uint32_t FUSE_OPT_OPENGL_EN;
uint32_t FUSE_SKU_INFO;
uint32_t FUSE_CPU_SPEEDO_0_CALIB;
uint32_t FUSE_CPU_IDDQ_CALIB;
uint32_t _0x11C[0x3];
uint32_t FUSE_OPT_FT_REV;
uint32_t FUSE_CPU_SPEEDO_1_CALIB;
uint32_t FUSE_CPU_SPEEDO_2_CALIB;
uint32_t FUSE_SOC_SPEEDO_0_CALIB;
uint32_t FUSE_SOC_SPEEDO_1_CALIB;
uint32_t FUSE_SOC_SPEEDO_2_CALIB;
uint32_t FUSE_SOC_IDDQ_CALIB;
uint32_t _0x144;
uint32_t FUSE_FA;
uint32_t FUSE_RESERVED_PRODUCTION;
uint32_t FUSE_HDMI_LANE0_CALIB;
uint32_t FUSE_HDMI_LANE1_CALIB;
uint32_t FUSE_HDMI_LANE2_CALIB;
uint32_t FUSE_HDMI_LANE3_CALIB;
uint32_t FUSE_ENCRYPTION_RATE;
uint32_t FUSE_PUBLIC_KEY[0x8];
uint32_t FUSE_TSENSOR1_CALIB;
uint32_t FUSE_TSENSOR2_CALIB;
uint32_t _0x18C;
uint32_t FUSE_OPT_CP_REV;
uint32_t FUSE_OPT_PFG;
uint32_t FUSE_TSENSOR0_CALIB;
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE;
uint32_t FUSE_SECURITY_MODE;
uint32_t FUSE_PRIVATE_KEY[0x5];
uint32_t FUSE_ARM_JTAG_DIS;
uint32_t FUSE_BOOT_DEVICE_INFO;
uint32_t FUSE_RESERVED_SW;
uint32_t FUSE_OPT_VP9_DISABLE;
uint32_t FUSE_RESERVED_ODM0[0x8];
uint32_t FUSE_OBS_DIS;
uint32_t _0x1EC;
uint32_t FUSE_USB_CALIB;
uint32_t FUSE_SKU_DIRECT_CONFIG;
uint32_t FUSE_KFUSE_PRIVKEY_CTRL;
uint32_t FUSE_PACKAGE_INFO;
uint32_t FUSE_OPT_VENDOR_CODE;
uint32_t FUSE_OPT_FAB_CODE;
uint32_t FUSE_OPT_LOT_CODE_0;
uint32_t FUSE_OPT_LOT_CODE_1;
uint32_t FUSE_OPT_WAFER_ID;
uint32_t FUSE_OPT_X_COORDINATE;
uint32_t FUSE_OPT_Y_COORDINATE;
uint32_t FUSE_OPT_SEC_DEBUG_EN;
uint32_t FUSE_OPT_OPS_RESERVED;
uint32_t _0x224;
uint32_t FUSE_GPU_IDDQ_CALIB;
uint32_t FUSE_TSENSOR3_CALIB;
uint32_t FUSE_CLOCK_BOUNDOUT0;
uint32_t FUSE_CLOCK_BOUNDOUT1;
uint32_t _0x238[0x3];
uint32_t FUSE_OPT_SAMPLE_TYPE;
uint32_t FUSE_OPT_SUBREVISION;
uint32_t FUSE_OPT_SW_RESERVED_0;
uint32_t FUSE_OPT_SW_RESERVED_1;
uint32_t FUSE_TSENSOR4_CALIB;
uint32_t FUSE_TSENSOR5_CALIB;
uint32_t FUSE_TSENSOR6_CALIB;
uint32_t FUSE_TSENSOR7_CALIB;
uint32_t FUSE_OPT_PRIV_SEC_EN;
uint32_t _0x268[0x5];
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
uint32_t FUSE_TSENSOR_COMMON;
uint32_t FUSE_OPT_CP_BIN;
uint32_t FUSE_OPT_GPU_DISABLE;
uint32_t FUSE_OPT_FT_BIN;
uint32_t FUSE_OPT_DONE_MAP;
uint32_t _0x294;
uint32_t FUSE_APB2JTAG_DISABLE;
uint32_t FUSE_ODM_INFO;
uint32_t _0x2A0[0x2];
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
uint32_t _0x2AC[0x5];
uint32_t FUSE_WOA_SKU_FLAG;
uint32_t FUSE_ECO_RESERVE_1;
uint32_t FUSE_GCPLEX_CONFIG_FUSE;
uint32_t FUSE_PRODUCTION_MONTH;
uint32_t FUSE_RAM_REPAIR_INDICATOR;
uint32_t FUSE_TSENSOR9_CALIB;
uint32_t _0x2D8;
uint32_t FUSE_VMIN_CALIBRATION;
uint32_t FUSE_AGING_SENSOR_CALIBRATION;
uint32_t FUSE_DEBUG_AUTHENTICATION;
uint32_t FUSE_SECURE_PROVISION_INDEX;
uint32_t FUSE_SECURE_PROVISION_INFO;
uint32_t FUSE_OPT_GPU_DISABLE_CP1;
uint32_t FUSE_SPARE_ENDIS;
uint32_t FUSE_ECO_RESERVE_0;
uint32_t _0x2FC[0x2];
uint32_t FUSE_RESERVED_CALIB0;
uint32_t FUSE_RESERVED_CALIB1;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1;
uint32_t FUSE_OPT_CPU_DISABLE;
uint32_t FUSE_OPT_CPU_DISABLE_CP1;
uint32_t FUSE_TSENSOR10_CALIB;
uint32_t FUSE_TSENSOR10_CALIB_AUX;
uint32_t _0x324[0x5];
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2;
uint32_t FUSE_OPT_CPU_DISABLE_CP2;
uint32_t FUSE_OPT_GPU_DISABLE_CP2;
uint32_t FUSE_USB_CALIB_EXT;
uint32_t FUSE_RESERVED_FIELD;
uint32_t _0x358[0x9];
uint32_t FUSE_SPARE_REALIGNMENT_REG;
uint32_t FUSE_SPARE_BIT[0x20];
} tegra_fuse_chip_common_t;
typedef struct {
uint32_t _0x98[0x1A];
uint32_t FUSE_PRODUCTION_MODE;
uint32_t FUSE_JTAG_SECUREID_VALID;
uint32_t FUSE_ODM_LOCK;
uint32_t FUSE_OPT_OPENGL_EN;
uint32_t FUSE_SKU_INFO;
uint32_t FUSE_CPU_SPEEDO_0_CALIB;
uint32_t FUSE_CPU_IDDQ_CALIB;
uint32_t _0x11C[0x3];
uint32_t FUSE_OPT_FT_REV;
uint32_t FUSE_CPU_SPEEDO_1_CALIB;
uint32_t FUSE_CPU_SPEEDO_2_CALIB;
uint32_t FUSE_SOC_SPEEDO_0_CALIB;
uint32_t FUSE_SOC_SPEEDO_1_CALIB;
uint32_t FUSE_SOC_SPEEDO_2_CALIB;
uint32_t FUSE_SOC_IDDQ_CALIB;
uint32_t _0x144;
uint32_t FUSE_FA;
uint32_t FUSE_RESERVED_PRODUCTION;
uint32_t FUSE_HDMI_LANE0_CALIB;
uint32_t FUSE_HDMI_LANE1_CALIB;
uint32_t FUSE_HDMI_LANE2_CALIB;
uint32_t FUSE_HDMI_LANE3_CALIB;
uint32_t FUSE_ENCRYPTION_RATE;
uint32_t FUSE_PUBLIC_KEY[0x8];
uint32_t FUSE_TSENSOR1_CALIB;
uint32_t FUSE_TSENSOR2_CALIB;
uint32_t _0x18C;
uint32_t FUSE_OPT_CP_REV;
uint32_t FUSE_OPT_PFG;
uint32_t FUSE_TSENSOR0_CALIB;
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE;
uint32_t FUSE_SECURITY_MODE;
uint32_t FUSE_PRIVATE_KEY[0x5];
uint32_t FUSE_ARM_JTAG_DIS;
uint32_t FUSE_BOOT_DEVICE_INFO;
uint32_t FUSE_RESERVED_SW;
uint32_t FUSE_OPT_VP9_DISABLE;
uint32_t FUSE_RESERVED_ODM0[0x8];
uint32_t FUSE_OBS_DIS;
uint32_t _0x1EC;
uint32_t FUSE_USB_CALIB;
uint32_t FUSE_SKU_DIRECT_CONFIG;
uint32_t FUSE_KFUSE_PRIVKEY_CTRL;
uint32_t FUSE_PACKAGE_INFO;
uint32_t FUSE_OPT_VENDOR_CODE;
uint32_t FUSE_OPT_FAB_CODE;
uint32_t FUSE_OPT_LOT_CODE_0;
uint32_t FUSE_OPT_LOT_CODE_1;
uint32_t FUSE_OPT_WAFER_ID;
uint32_t FUSE_OPT_X_COORDINATE;
uint32_t FUSE_OPT_Y_COORDINATE;
uint32_t FUSE_OPT_SEC_DEBUG_EN;
uint32_t FUSE_OPT_OPS_RESERVED;
uint32_t FUSE_SATA_CALIB; /* Erista only. */
uint32_t FUSE_GPU_IDDQ_CALIB;
uint32_t FUSE_TSENSOR3_CALIB;
uint32_t FUSE_CLOCK_BOUNDOUT0;
uint32_t FUSE_CLOCK_BOUNDOUT1;
uint32_t _0x238[0x3];
uint32_t FUSE_OPT_SAMPLE_TYPE;
uint32_t FUSE_OPT_SUBREVISION;
uint32_t FUSE_OPT_SW_RESERVED_0;
uint32_t FUSE_OPT_SW_RESERVED_1;
uint32_t FUSE_TSENSOR4_CALIB;
uint32_t FUSE_TSENSOR5_CALIB;
uint32_t FUSE_TSENSOR6_CALIB;
uint32_t FUSE_TSENSOR7_CALIB;
uint32_t FUSE_OPT_PRIV_SEC_EN;
uint32_t FUSE_PKC_DISABLE; /* Erista only. */
uint32_t _0x26C[0x4];
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
uint32_t FUSE_TSENSOR_COMMON;
uint32_t FUSE_OPT_CP_BIN;
uint32_t FUSE_OPT_GPU_DISABLE;
uint32_t FUSE_OPT_FT_BIN;
uint32_t FUSE_OPT_DONE_MAP;
uint32_t _0x294;
uint32_t FUSE_APB2JTAG_DISABLE;
uint32_t FUSE_ODM_INFO;
uint32_t _0x2A0[0x2];
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
uint32_t _0x2AC[0x5];
uint32_t FUSE_WOA_SKU_FLAG;
uint32_t FUSE_ECO_RESERVE_1;
uint32_t FUSE_GCPLEX_CONFIG_FUSE;
uint32_t FUSE_PRODUCTION_MONTH;
uint32_t FUSE_RAM_REPAIR_INDICATOR;
uint32_t FUSE_TSENSOR9_CALIB;
uint32_t _0x2D8;
uint32_t FUSE_VMIN_CALIBRATION;
uint32_t FUSE_AGING_SENSOR_CALIBRATION;
uint32_t FUSE_DEBUG_AUTHENTICATION;
uint32_t FUSE_SECURE_PROVISION_INDEX;
uint32_t FUSE_SECURE_PROVISION_INFO;
uint32_t FUSE_OPT_GPU_DISABLE_CP1;
uint32_t FUSE_SPARE_ENDIS;
uint32_t FUSE_ECO_RESERVE_0;
uint32_t _0x2FC[0x2];
uint32_t FUSE_RESERVED_CALIB0;
uint32_t FUSE_RESERVED_CALIB1;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1;
uint32_t FUSE_OPT_CPU_DISABLE;
uint32_t FUSE_OPT_CPU_DISABLE_CP1;
uint32_t FUSE_TSENSOR10_CALIB;
uint32_t FUSE_TSENSOR10_CALIB_AUX;
uint32_t FUSE_OPT_RAM_SVOP_DP; /* Erista only. */
uint32_t FUSE_OPT_RAM_SVOP_PDP; /* Erista only. */
uint32_t FUSE_OPT_RAM_SVOP_REG; /* Erista only. */
uint32_t FUSE_OPT_RAM_SVOP_SP; /* Erista only. */
uint32_t FUSE_OPT_RAM_SVOP_SMPDP; /* Erista only. */
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2;
uint32_t FUSE_OPT_CPU_DISABLE_CP2;
uint32_t FUSE_OPT_GPU_DISABLE_CP2;
uint32_t FUSE_USB_CALIB_EXT;
uint32_t FUSE_RESERVED_FIELD;
uint32_t _0x358[0x9];
uint32_t FUSE_SPARE_REALIGNMENT_REG;
uint32_t FUSE_SPARE_BIT[0x20];
} tegra_fuse_chip_erista_t;
typedef struct {
uint32_t FUSE_RESERVED_ODM8[0xE]; /* Mariko only. */
uint32_t FUSE_KEK[0x4]; /* Mariko only. */
uint32_t FUSE_BEK[0x4]; /* Mariko only. */
uint32_t _0xF0; /* Mariko only. */
uint32_t _0xF4; /* Mariko only. */
uint32_t _0xF8; /* Mariko only. */
uint32_t _0xFC; /* Mariko only. */
uint32_t FUSE_PRODUCTION_MODE;
uint32_t FUSE_JTAG_SECUREID_VALID;
uint32_t FUSE_ODM_LOCK;
uint32_t FUSE_OPT_OPENGL_EN;
uint32_t FUSE_SKU_INFO;
uint32_t FUSE_CPU_SPEEDO_0_CALIB;
uint32_t FUSE_CPU_IDDQ_CALIB;
uint32_t FUSE_RESERVED_ODM22[0x3]; /* Mariko only. */
uint32_t FUSE_OPT_FT_REV;
uint32_t FUSE_CPU_SPEEDO_1_CALIB;
uint32_t FUSE_CPU_SPEEDO_2_CALIB;
uint32_t FUSE_SOC_SPEEDO_0_CALIB;
uint32_t FUSE_SOC_SPEEDO_1_CALIB;
uint32_t FUSE_SOC_SPEEDO_2_CALIB;
uint32_t FUSE_SOC_IDDQ_CALIB;
uint32_t FUSE_RESERVED_ODM25; /* Mariko only. */
uint32_t FUSE_FA;
uint32_t FUSE_RESERVED_PRODUCTION;
uint32_t FUSE_HDMI_LANE0_CALIB;
uint32_t FUSE_HDMI_LANE1_CALIB;
uint32_t FUSE_HDMI_LANE2_CALIB;
uint32_t FUSE_HDMI_LANE3_CALIB;
uint32_t FUSE_ENCRYPTION_RATE;
uint32_t FUSE_PUBLIC_KEY[0x8];
uint32_t FUSE_TSENSOR1_CALIB;
uint32_t FUSE_TSENSOR2_CALIB;
uint32_t FUSE_OPT_SECURE_SCC_DIS; /* Mariko only. */
uint32_t FUSE_OPT_CP_REV;
uint32_t FUSE_OPT_PFG;
uint32_t FUSE_TSENSOR0_CALIB;
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE;
uint32_t FUSE_SECURITY_MODE;
uint32_t FUSE_PRIVATE_KEY[0x5];
uint32_t FUSE_ARM_JTAG_DIS;
uint32_t FUSE_BOOT_DEVICE_INFO;
uint32_t FUSE_RESERVED_SW;
uint32_t FUSE_OPT_VP9_DISABLE;
uint32_t FUSE_RESERVED_ODM0[0x8];
uint32_t FUSE_OBS_DIS;
uint32_t _0x1EC; /* Mariko only. */
uint32_t FUSE_USB_CALIB;
uint32_t FUSE_SKU_DIRECT_CONFIG;
uint32_t FUSE_KFUSE_PRIVKEY_CTRL;
uint32_t FUSE_PACKAGE_INFO;
uint32_t FUSE_OPT_VENDOR_CODE;
uint32_t FUSE_OPT_FAB_CODE;
uint32_t FUSE_OPT_LOT_CODE_0;
uint32_t FUSE_OPT_LOT_CODE_1;
uint32_t FUSE_OPT_WAFER_ID;
uint32_t FUSE_OPT_X_COORDINATE;
uint32_t FUSE_OPT_Y_COORDINATE;
uint32_t FUSE_OPT_SEC_DEBUG_EN;
uint32_t FUSE_OPT_OPS_RESERVED;
uint32_t _0x224; /* Mariko only. */
uint32_t FUSE_GPU_IDDQ_CALIB;
uint32_t FUSE_TSENSOR3_CALIB;
uint32_t FUSE_CLOCK_BOUNDOUT0;
uint32_t FUSE_CLOCK_BOUNDOUT1;
uint32_t FUSE_RESERVED_ODM26[0x3]; /* Mariko only. */
uint32_t FUSE_OPT_SAMPLE_TYPE;
uint32_t FUSE_OPT_SUBREVISION;
uint32_t FUSE_OPT_SW_RESERVED_0;
uint32_t FUSE_OPT_SW_RESERVED_1;
uint32_t FUSE_TSENSOR4_CALIB;
uint32_t FUSE_TSENSOR5_CALIB;
uint32_t FUSE_TSENSOR6_CALIB;
uint32_t FUSE_TSENSOR7_CALIB;
uint32_t FUSE_OPT_PRIV_SEC_EN;
uint32_t FUSE_BOOT_SECURITY_INFO; /* Mariko only. */
uint32_t _0x26C; /* Mariko only. */
uint32_t _0x270; /* Mariko only. */
uint32_t _0x274; /* Mariko only. */
uint32_t _0x278; /* Mariko only. */
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
uint32_t FUSE_TSENSOR_COMMON;
uint32_t FUSE_OPT_CP_BIN;
uint32_t FUSE_OPT_GPU_DISABLE;
uint32_t FUSE_OPT_FT_BIN;
uint32_t FUSE_OPT_DONE_MAP;
uint32_t FUSE_RESERVED_ODM29; /* Mariko only. */
uint32_t FUSE_APB2JTAG_DISABLE;
uint32_t FUSE_ODM_INFO;
uint32_t _0x2A0[0x2];
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
uint32_t _0x2AC;
uint32_t _0x2B0; /* Mariko only. */
uint32_t _0x2B4; /* Mariko only. */
uint32_t _0x2B8; /* Mariko only. */
uint32_t _0x2BC; /* Mariko only. */
uint32_t FUSE_WOA_SKU_FLAG;
uint32_t FUSE_ECO_RESERVE_1;
uint32_t FUSE_GCPLEX_CONFIG_FUSE;
uint32_t FUSE_PRODUCTION_MONTH;
uint32_t FUSE_RAM_REPAIR_INDICATOR;
uint32_t FUSE_TSENSOR9_CALIB;
uint32_t _0x2D8;
uint32_t FUSE_VMIN_CALIBRATION;
uint32_t FUSE_AGING_SENSOR_CALIBRATION;
uint32_t FUSE_DEBUG_AUTHENTICATION;
uint32_t FUSE_SECURE_PROVISION_INDEX;
uint32_t FUSE_SECURE_PROVISION_INFO;
uint32_t FUSE_OPT_GPU_DISABLE_CP1;
uint32_t FUSE_SPARE_ENDIS;
uint32_t FUSE_ECO_RESERVE_0;
uint32_t _0x2FC[0x2];
uint32_t FUSE_RESERVED_CALIB0;
uint32_t FUSE_RESERVED_CALIB1;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1;
uint32_t FUSE_OPT_CPU_DISABLE;
uint32_t FUSE_OPT_CPU_DISABLE_CP1;
uint32_t FUSE_TSENSOR10_CALIB;
uint32_t FUSE_TSENSOR10_CALIB_AUX;
uint32_t _0x324; /* Mariko only. */
uint32_t _0x328; /* Mariko only. */
uint32_t _0x32C; /* Mariko only. */
uint32_t _0x330; /* Mariko only. */
uint32_t _0x334; /* Mariko only. */
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2;
uint32_t FUSE_OPT_CPU_DISABLE_CP2;
uint32_t FUSE_OPT_GPU_DISABLE_CP2;
uint32_t FUSE_USB_CALIB_EXT;
uint32_t FUSE_RESERVED_FIELD;
uint32_t _0x358[0x9];
uint32_t FUSE_SPARE_REALIGNMENT_REG;
uint32_t FUSE_SPARE_BIT[0x1E];
} tegra_fuse_chip_mariko_t;
static inline volatile tegra_fuse_t *fuse_get_regs(void)
{
return (volatile tegra_fuse_t *)FUSE_BASE;
}
static inline volatile tegra_fuse_chip_common_t *fuse_chip_common_get_regs(void)
{
return (volatile tegra_fuse_chip_common_t *)FUSE_CHIP_BASE;
}
static inline volatile tegra_fuse_chip_erista_t *fuse_chip_erista_get_regs(void)
{
return (volatile tegra_fuse_chip_erista_t *)FUSE_CHIP_BASE;
}
static inline volatile tegra_fuse_chip_mariko_t *fuse_chip_mariko_get_regs(void)
{
return (volatile tegra_fuse_chip_mariko_t *)FUSE_CHIP_BASE;
}
void fuse_init(void);
void fuse_disable_programming(void);
void fuse_disable_private_key(void);
void fuse_enable_power(void);
void fuse_disable_power(void);
uint32_t fuse_get_sku_info(void);
uint32_t fuse_get_spare_bit(uint32_t index);
uint32_t fuse_get_reserved_odm(uint32_t index);
uint32_t fuse_get_bootrom_patch_version(void);
uint64_t fuse_get_device_id(void);
uint32_t fuse_get_dram_id(void);
uint32_t fuse_get_hardware_type_with_firmware_check(uint32_t target_firmware);
uint32_t fuse_get_hardware_type(void);
uint32_t fuse_get_retail_type(void);
void fuse_get_hardware_info(void *dst);
bool fuse_is_new_format(void);
uint32_t fuse_get_device_unique_key_generation(void);
uint32_t fuse_get_soc_type(void);
uint32_t fuse_get_regulator(void);
uint32_t fuse_hw_read(uint32_t addr);
void fuse_hw_write(uint32_t value, uint32_t addr);
void fuse_hw_sense(void);
#endif

View File

@@ -1,78 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <string.h>
#include <stdint.h>
#include <errno.h>
#include "gpio.h"
#include "utils.h"
/* Set GPIO's value. */
static void gpio_register_set(uint32_t pin, bool do_set, uint32_t offset) {
volatile tegra_gpio_t *gpio = gpio_get_regs();
/* Retrieve the register set that corresponds to the given pin and offset. */
volatile uint32_t *cluster = (uint32_t *)((uintptr_t)&gpio->bank[(pin >> GPIO_BANK_SHIFT)] + offset);
/* Figure out the offset into the cluster, and the mask to be used. */
uint32_t port = ((pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK);
uint32_t mask = (1 << (pin & GPIO_PIN_MASK));
/* Set or clear the bit, as appropriate. */
if (do_set)
cluster[port] |= mask;
else
cluster[port] &= ~mask;
/* Dummy read. */
cluster[port];
}
/* Get GPIO's value. */
static bool gpio_register_get(uint32_t pin, uint32_t offset) {
volatile tegra_gpio_t *gpio = gpio_get_regs();
/* Retrieve the register set that corresponds to the given pin and offset. */
volatile uint32_t *cluster = (uint32_t *)((uintptr_t)&gpio->bank[(pin >> GPIO_BANK_SHIFT)] + offset);
/* Figure out the offset into the cluster, and the mask to be used. */
uint32_t port = ((pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK);
uint32_t mask = (1 << (pin & GPIO_PIN_MASK));
/* Convert the given value to a boolean. */
return !!(cluster[port] & mask);
}
/* Configure GPIO's mode. */
void gpio_configure_mode(uint32_t pin, uint32_t mode) {
gpio_register_set(pin, mode == GPIO_MODE_GPIO, offsetof(tegra_gpio_bank_t, config));
}
/* Configure GPIO's direction. */
void gpio_configure_direction(uint32_t pin, uint32_t dir) {
gpio_register_set(pin, dir == GPIO_DIRECTION_OUTPUT, offsetof(tegra_gpio_bank_t, direction));
}
/* Write to GPIO. */
void gpio_write(uint32_t pin, uint32_t value) {
gpio_register_set(pin, value == GPIO_LEVEL_HIGH, offsetof(tegra_gpio_bank_t, out));
}
/* Read from GPIO. */
uint32_t gpio_read(uint32_t pin) {
return gpio_register_get(pin, offsetof(tegra_gpio_bank_t, in));
}

View File

@@ -1,127 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_GPIO_H
#define FUSEE_GPIO_H
#include <stdint.h>
#define GPIO_BASE 0x6000D000
#define MAKE_GPIO_REG(n) MAKE_REG32(GPIO_BASE + n)
#define TEGRA_GPIO_PORTS 4
#define TEGRA_GPIO_BANKS 8
#define GPIO_BANK_SHIFT 5
#define GPIO_PORT_SHIFT 3
#define GPIO_PORT_MASK 0x03
#define GPIO_PIN_MASK 0x07
typedef enum {
TEGRA_GPIO_PORT_A = 0,
TEGRA_GPIO_PORT_B = 1,
TEGRA_GPIO_PORT_C = 2,
TEGRA_GPIO_PORT_D = 3,
TEGRA_GPIO_PORT_E = 4,
TEGRA_GPIO_PORT_F = 5,
TEGRA_GPIO_PORT_G = 6,
TEGRA_GPIO_PORT_H = 7,
TEGRA_GPIO_PORT_I = 8,
TEGRA_GPIO_PORT_J = 9,
TEGRA_GPIO_PORT_K = 10,
TEGRA_GPIO_PORT_L = 11,
TEGRA_GPIO_PORT_M = 12,
TEGRA_GPIO_PORT_N = 13,
TEGRA_GPIO_PORT_O = 14,
TEGRA_GPIO_PORT_P = 15,
TEGRA_GPIO_PORT_Q = 16,
TEGRA_GPIO_PORT_R = 17,
TEGRA_GPIO_PORT_S = 18,
TEGRA_GPIO_PORT_T = 19,
TEGRA_GPIO_PORT_U = 20,
TEGRA_GPIO_PORT_V = 21,
TEGRA_GPIO_PORT_W = 22,
TEGRA_GPIO_PORT_X = 23,
TEGRA_GPIO_PORT_Y = 24,
TEGRA_GPIO_PORT_Z = 25,
TEGRA_GPIO_PORT_AA = 26,
TEGRA_GPIO_PORT_BB = 27,
TEGRA_GPIO_PORT_CC = 28,
TEGRA_GPIO_PORT_DD = 29,
TEGRA_GPIO_PORT_EE = 30,
TEGRA_GPIO_PORT_FF = 31,
} tegra_gpio_port;
typedef struct {
uint32_t config[TEGRA_GPIO_PORTS];
uint32_t direction[TEGRA_GPIO_PORTS];
uint32_t out[TEGRA_GPIO_PORTS];
uint32_t in[TEGRA_GPIO_PORTS];
uint32_t int_status[TEGRA_GPIO_PORTS];
uint32_t int_enable[TEGRA_GPIO_PORTS];
uint32_t int_level[TEGRA_GPIO_PORTS];
uint32_t int_clear[TEGRA_GPIO_PORTS];
uint32_t masked_config[TEGRA_GPIO_PORTS];
uint32_t masked_dir_out[TEGRA_GPIO_PORTS];
uint32_t masked_out[TEGRA_GPIO_PORTS];
uint32_t masked_in[TEGRA_GPIO_PORTS];
uint32_t masked_int_status[TEGRA_GPIO_PORTS];
uint32_t masked_int_enable[TEGRA_GPIO_PORTS];
uint32_t masked_int_level[TEGRA_GPIO_PORTS];
uint32_t masked_int_clear[TEGRA_GPIO_PORTS];
} tegra_gpio_bank_t;
typedef struct {
tegra_gpio_bank_t bank[TEGRA_GPIO_BANKS];
} tegra_gpio_t;
static inline volatile tegra_gpio_t *gpio_get_regs(void)
{
return (volatile tegra_gpio_t *)GPIO_BASE;
}
#define TEGRA_GPIO(port, offset) \
((TEGRA_GPIO_PORT_##port * 8) + offset)
/* Mode select */
#define GPIO_MODE_SFIO 0
#define GPIO_MODE_GPIO 1
/* Direction */
#define GPIO_DIRECTION_INPUT 0
#define GPIO_DIRECTION_OUTPUT 1
/* Level */
#define GPIO_LEVEL_LOW 0
#define GPIO_LEVEL_HIGH 1
/* Named GPIOs */
#define GPIO_BUTTON_VOL_DOWN TEGRA_GPIO(X, 7)
#define GPIO_BUTTON_VOL_UP TEGRA_GPIO(X, 6)
#define GPIO_MICROSD_CARD_DETECT TEGRA_GPIO(Z, 1)
#define GPIO_MICROSD_WRITE_PROTECT TEGRA_GPIO(Z, 4)
#define GPIO_MICROSD_SUPPLY_ENABLE TEGRA_GPIO(E, 4)
#define GPIO_LCD_BL_P5V TEGRA_GPIO(I, 0)
#define GPIO_LCD_BL_N5V TEGRA_GPIO(I, 1)
#define GPIO_LCD_BL_PWM TEGRA_GPIO(V, 0)
#define GPIO_LCD_BL_EN TEGRA_GPIO(V, 1)
#define GPIO_LCD_BL_RST TEGRA_GPIO(V, 2)
void gpio_configure_mode(uint32_t pin, uint32_t mode);
void gpio_configure_direction(uint32_t pin, uint32_t dir);
void gpio_write(uint32_t pin, uint32_t value);
uint32_t gpio_read(uint32_t pin);
#endif

View File

@@ -1,404 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 "apb_misc.h"
#include "car.h"
#include "di.h"
#include "fuse.h"
#include "gpio.h"
#include "i2c.h"
#include "max77620.h"
#include "mc.h"
#include "pinmux.h"
#include "pmc.h"
#include "se.h"
#include "sdram.h"
#include "sysctr0.h"
#include "sysreg.h"
#include "timers.h"
#include "uart.h"
static void config_oscillators(void) {
volatile tegra_car_t *car = car_get_regs();
volatile tegra_pmc_t *pmc = pmc_get_regs();
car->spare_reg0 = ((car->spare_reg0 & 0xFFFFFFF3) | 4);
SYSCTR0_CNTFID0_0 = 19200000;
TIMERUS_USEC_CFG_0 = 0x45F;
car->osc_ctrl = 0x50000071;
pmc->osc_edpd_over = ((pmc->osc_edpd_over & 0xFFFFFF81) | 0xE);
pmc->osc_edpd_over = ((pmc->osc_edpd_over & 0xFFBFFFFF) | 0x400000);
pmc->cntrl2 = ((pmc->cntrl2 & 0xFFFFEFFF) | 0x1000);
pmc->scratch188 = ((pmc->scratch188 & 0xFCFFFFFF) | 0x2000000);
car->clk_sys_rate = 0x10;
car->pllmb_base &= 0xBFFFFFFF;
pmc->tsc_mult = ((pmc->tsc_mult & 0xFFFF0000) | 0x249F); /* 0x249F = 19200000 * (16 / 32.768 kHz) */
car->sclk_brst_pol = 0x20004444;
car->super_sclk_div = 0x80000000;
car->clk_sys_rate = 2;
}
static void config_gpios_erista(void) {
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
pinmux->uart2_tx = 0;
pinmux->uart3_tx = 0;
pinmux->pe6 = PINMUX_INPUT;
pinmux->ph6 = PINMUX_INPUT;
gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(E, 6), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(H, 6), GPIO_MODE_GPIO);
gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT);
i2c_config(I2C_1);
i2c_config(I2C_5);
uart_config(UART_A);
/* Configure volume up/down buttons as inputs. */
gpio_configure_mode(GPIO_BUTTON_VOL_UP, GPIO_MODE_GPIO);
gpio_configure_mode(GPIO_BUTTON_VOL_DOWN, GPIO_MODE_GPIO);
gpio_configure_direction(GPIO_BUTTON_VOL_UP, GPIO_DIRECTION_INPUT);
gpio_configure_direction(GPIO_BUTTON_VOL_DOWN, GPIO_DIRECTION_INPUT);
}
static void config_gpios_mariko(void) {
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
uint32_t hardware_type = fuse_get_hardware_type();
/* Only for HardwareType_Iowa and HardwareType_Five. */
if ((hardware_type == 3) || (hardware_type == 5)) {
pinmux->uart2_tx = 0;
pinmux->uart3_tx = 0;
gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO);
gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT);
}
pinmux->pe6 = PINMUX_INPUT;
pinmux->ph6 = PINMUX_INPUT;
gpio_configure_mode(TEGRA_GPIO(E, 6), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(H, 6), GPIO_MODE_GPIO);
gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT);
i2c_config(I2C_1);
i2c_config(I2C_5);
uart_config(UART_A);
/* Configure volume up/down buttons as inputs. */
gpio_configure_mode(GPIO_BUTTON_VOL_UP, GPIO_MODE_GPIO);
gpio_configure_mode(GPIO_BUTTON_VOL_DOWN, GPIO_MODE_GPIO);
gpio_configure_direction(GPIO_BUTTON_VOL_UP, GPIO_DIRECTION_INPUT);
gpio_configure_direction(GPIO_BUTTON_VOL_DOWN, GPIO_DIRECTION_INPUT);
/* Configure home button as input. */
gpio_configure_mode(TEGRA_GPIO(Y, 1), GPIO_MODE_GPIO);
gpio_configure_direction(TEGRA_GPIO(Y, 1), GPIO_DIRECTION_INPUT);
}
static void config_pmc_scratch(void) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
pmc->scratch20 &= 0xFFF3FFFF;
pmc->scratch190 &= 0xFFFFFFFE;
pmc->secure_scratch21 |= 0x10;
}
static void mbist_workaround(void) {
volatile tegra_car_t *car = car_get_regs();
car->clk_source_sor1 = ((car->clk_source_sor1 | 0x8000) & 0xFFFFBFFF);
car->plld_base |= 0x40800000u;
car->rst_dev_y_clr = 0x40;
car->rst_dev_x_clr = 0x40000;
car->rst_dev_l_clr = 0x18000000;
udelay(2);
/* Setup I2S. */
MAKE_I2S_REG(0x0A0) |= 0x400;
MAKE_I2S_REG(0x088) &= 0xFFFFFFFE;
MAKE_I2S_REG(0x1A0) |= 0x400;
MAKE_I2S_REG(0x188) &= 0xFFFFFFFE;
MAKE_I2S_REG(0x2A0) |= 0x400;
MAKE_I2S_REG(0x288) &= 0xFFFFFFFE;
MAKE_I2S_REG(0x3A0) |= 0x400;
MAKE_I2S_REG(0x388) &= 0xFFFFFFFE;
MAKE_I2S_REG(0x4A0) |= 0x400;
MAKE_I2S_REG(0x488) &= 0xFFFFFFFE;
MAKE_DI_REG(DC_COM_DSC_TOP_CTL) |= 4;
MAKE_VIC_REG(0x8C) = 0xFFFFFFFF;
udelay(2);
/* Set devices in reset. */
car->rst_dev_y_set = 0x40;
car->rst_dev_l_set = 0x18000000;
car->rst_dev_x_set = 0x40000;
/* Clock out enables. */
car->clk_out_enb_h = 0xC0;
car->clk_out_enb_l = 0x80000130;
car->clk_out_enb_u = 0x1F00200;
car->clk_out_enb_v = 0x80400808;
car->clk_out_enb_w = 0x402000FC;
car->clk_out_enb_x = 0x23000780;
car->clk_out_enb_y = 0x300;
/* LVL2 clock gate overrides. */
car->lvl2_clk_gate_ovra = 0;
car->lvl2_clk_gate_ovrb = 0;
car->lvl2_clk_gate_ovrc = 0;
car->lvl2_clk_gate_ovrd = 0;
car->lvl2_clk_gate_ovre = 0;
/* Configure clock sources. */
car->plld_base &= 0x1F7FFFFF;
car->clk_source_sor1 &= 0xFFFF3FFF;
car->clk_source_vi = ((car->clk_source_vi & 0x1FFFFFFF) | 0x80000000);
car->clk_source_host1x = ((car->clk_source_host1x & 0x1FFFFFFF) | 0x80000000);
car->clk_source_nvenc = ((car->clk_source_nvenc & 0x1FFFFFFF) | 0x80000000);
}
static void config_se_brom(void) {
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
volatile tegra_se_t *se = se_get_regs();
volatile tegra_pmc_t *pmc = pmc_get_regs();
/* Bootrom part we skipped. */
uint32_t sbk[4] = {fuse_chip->FUSE_PRIVATE_KEY[0], fuse_chip->FUSE_PRIVATE_KEY[1], fuse_chip->FUSE_PRIVATE_KEY[2], fuse_chip->FUSE_PRIVATE_KEY[3]};
set_aes_keyslot(0xE, sbk, 0x10);
/* Lock SBK from being read. */
se->SE_CRYPTO_KEYTABLE_ACCESS[0xE] = 0x7E;
/* This memset needs to happen here, else TZRAM will behave weirdly later on. */
memset((void *)0x7C010000, 0, 0x10000);
pmc->crypto_op = 0;
se->SE_INT_STATUS = 0x1F;
/* Lock SSK (although it's not set and unused anyways). */
se->SE_CRYPTO_KEYTABLE_ACCESS[0xF] = 0x7E;
/* Clear the boot reason to avoid problems later */
pmc->scratch200 = 0;
pmc->rst_status = 0;
}
void nx_hwinit_erista(bool enable_log) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
volatile tegra_car_t *car = car_get_regs();
/* Bootrom stuff we skipped by going through RCM. */
config_se_brom();
AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F;
pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD);
/* Apply the memory built-in self test workaround. */
mbist_workaround();
/* Reboot SE. */
clkrst_reboot(CARDEVICE_SE);
/* Initialize the fuse driver. */
fuse_init();
/* Initialize the memory controller. */
mc_enable();
/* Configure oscillators. */
config_oscillators();
/* Disable pinmux tristate input clamping. */
APB_MISC_PP_PINMUX_GLOBAL_0 = 0;
/* Configure GPIOs. */
/* NOTE: [3.0.0+] Part of the GPIO configuration is skipped if the unit is SDEV. */
/* NOTE: [6.0.0+] The GPIO configuration's order was changed a bit. */
config_gpios_erista();
/* UART debugging. */
if (enable_log) {
clkrst_reboot(CARDEVICE_UARTA);
uart_init(UART_A, 115200);
}
/* Reboot CL-DVFS. */
clkrst_reboot(CARDEVICE_CL_DVFS);
/* Reboot I2C1. */
clkrst_reboot(CARDEVICE_I2C1);
/* Reboot I2C5. */
clkrst_reboot(CARDEVICE_I2C5);
/* Reboot SE. */
/* NOTE: [4.0.0+] This was removed. */
/* clkrst_reboot(CARDEVICE_SE); */
/* Reboot TZRAM. */
clkrst_reboot(CARDEVICE_TZRAM);
/* Initialize I2C1. */
/* NOTE: [6.0.0+] This was moved to after the PMIC is configured. */
i2c_init(I2C_1);
/* Initialize I2C5. */
i2c_init(I2C_5);
/* Configure the PMIC. */
uint8_t val = 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
val = 0x60;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
val = 0x38;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);
val = 0x3A;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG1, &val, 1);
val = 0x38;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG2, &val, 1);
val = 0xF;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO4, &val, 1);
val = 0xC7;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO8, &val, 1);
val = 0x4F;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD0, &val, 1);
val = 0x29;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD1, &val, 1);
val = 0x1B;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD3, &val, 1);
/* NOTE: [3.0.0+] This was added. */
val = 0x22;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_GPIO3, &val, 1);
/* TODO: In 3.x+, if the unit is SDEV, the MBLPD bit is set. */
/*
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
val |= 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
*/
/* Configure SD0 voltage. */
val = 42; /* 42 = (1125000 - 600000) / 12500 -> 1.125V */
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD0, &val, 1);
/* Configure and lock PMC scratch registers. */
/* NOTE: [4.0.0+] This was removed. */
config_pmc_scratch();
/* Set super clock burst policy. */
car->sclk_brst_pol = ((car->sclk_brst_pol & 0xFFFF8888) | 0x3333);
/* Configure memory controller carveouts. */
/* NOTE: [4.0.0+] This is now done in the Secure Monitor. */
/* mc_config_carveout(); */
/* Save SDRAM parameters to scratch. */
sdram_save_params_erista(sdram_get_params_erista(fuse_get_dram_id()));
/* Initialize SDRAM. */
sdram_init_erista();
}
void nx_hwinit_mariko(bool enable_log) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
volatile tegra_car_t *car = car_get_regs();
/* Enable SE clock. */
clkrst_reboot(CARDEVICE_SE);
/* Initialize the fuse driver. */
fuse_init();
/* Initialize the memory controller. */
mc_enable();
/* Configure oscillators. */
config_oscillators();
/* Disable pinmux tristate input clamping. */
APB_MISC_PP_PINMUX_GLOBAL_0 = 0;
/* Configure GPIOs. */
config_gpios_mariko();
/* UART debugging. */
if (enable_log) {
clkrst_reboot(CARDEVICE_UARTA);
uart_init(UART_A, 115200);
}
/* Enable CL-DVFS clock. */
clkrst_reboot(CARDEVICE_CL_DVFS);
/* Enable I2C1 clock. */
clkrst_reboot(CARDEVICE_I2C1);
/* Enable I2C5 clock. */
clkrst_reboot(CARDEVICE_I2C5);
/* Enable TZRAM clock. */
clkrst_reboot(CARDEVICE_TZRAM);
/* Initialize I2C5. */
i2c_init(I2C_5);
/* Configure the PMIC. */
uint8_t val = 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
val = 0x78;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
/* Configure SD0 voltage. */
val = 0x24;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD0, &val, 1);
/* Enable LDO8 in HardwareType_Hoag only. */
if (fuse_get_hardware_type() == 2) {
val = 0xE8;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO8_CFG, &val, 1);
}
/* Initialize I2C1. */
i2c_init(I2C_1);
/* Set super clock burst policy. */
car->sclk_brst_pol = ((car->sclk_brst_pol & 0xFFFF8888) | 0x3333);
/* Mariko only PMC configuration for TZRAM. */
pmc->tzram_pwr_cntrl &= 0xFFFFFFFE;
pmc->tzram_non_sec_disable = 0x3;
pmc->tzram_sec_disable = 0x3;
/* Save SDRAM parameters to scratch. */
sdram_save_params_mariko(sdram_get_params_mariko(fuse_get_dram_id()));
/* Initialize SDRAM. */
sdram_init_mariko();
}

View File

@@ -1,30 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_HWINIT_H_
#define FUSEE_HWINIT_H_
#include <stdbool.h>
#define I2S_BASE 0x702D1000
#define MAKE_I2S_REG(n) MAKE_REG32(I2S_BASE + n)
void nx_hwinit_erista(bool enable_log);
void nx_hwinit_mariko(bool enable_log);
#endif

View File

@@ -1,252 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 "i2c.h"
#include "utils.h"
#include "timers.h"
#include "pinmux.h"
/* Prototypes for internal commands. */
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id);
void i2c_load_config(volatile tegra_i2c_t *regs);
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size);
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size);
/* Configure I2C pinmux. */
void i2c_config(I2CDevice id) {
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
switch (id) {
case I2C_1:
pinmux->gen1_i2c_scl = PINMUX_INPUT;
pinmux->gen1_i2c_sda = PINMUX_INPUT;
break;
case I2C_2:
pinmux->gen2_i2c_scl = PINMUX_INPUT;
pinmux->gen2_i2c_sda = PINMUX_INPUT;
break;
case I2C_3:
pinmux->gen3_i2c_scl = PINMUX_INPUT;
pinmux->gen3_i2c_sda = PINMUX_INPUT;
break;
case I2C_4:
pinmux->cam_i2c_scl = PINMUX_INPUT;
pinmux->cam_i2c_sda = PINMUX_INPUT;
break;
case I2C_5:
pinmux->pwr_i2c_scl = PINMUX_INPUT;
pinmux->pwr_i2c_sda = PINMUX_INPUT;
break;
case I2C_6:
/* Unused. */
break;
default: break;
}
}
/* Initialize I2C based on registers. */
void i2c_init(I2CDevice id) {
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
/* Setup divisor, and clear the bus. */
regs->I2C_I2C_CLK_DIVISOR_REGISTER_0 = 0x50001;
regs->I2C_I2C_BUS_CLEAR_CONFIG_0 = 0x90003;
/* Load hardware configuration. */
i2c_load_config(regs);
/* Wait a while until BUS_CLEAR_DONE is set. */
for (unsigned int i = 0; i < 10; i++) {
udelay(20000);
if (regs->I2C_INTERRUPT_STATUS_REGISTER_0 & 0x800) {
break;
}
}
/* Read the BUS_CLEAR_STATUS. Result doesn't matter. */
regs->I2C_I2C_BUS_CLEAR_STATUS_0;
/* Read and set the Interrupt Status. */
uint32_t int_status = regs->I2C_INTERRUPT_STATUS_REGISTER_0;
regs->I2C_INTERRUPT_STATUS_REGISTER_0 = int_status;
}
/* Sets a bit in a PMIC register over I2C during CPU shutdown. */
void i2c_send_pmic_cpu_shutdown_cmd(void) {
uint32_t val = 0;
/* PMIC == Device 4:3C. */
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
val |= 4;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
}
/* Queries the value of TI charger bit over I2C. */
bool i2c_query_ti_charger_bit_7(void) {
uint32_t val = 0;
/* TI Charger = Device 0:6B. */
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
return (val & 0x80) != 0;
}
/* Clears TI charger bit over I2C. */
void i2c_clear_ti_charger_bit_7(void) {
uint32_t val = 0;
/* TI Charger = Device 0:6B. */
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
val &= 0x7F;
i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
}
/* Sets TI charger bit over I2C. */
void i2c_set_ti_charger_bit_7(void) {
uint32_t val = 0;
/* TI Charger = Device 0:6B. */
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
val |= 0x80;
i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
}
/* Get registers pointer based on I2C ID. */
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id) {
switch (id) {
case I2C_1:
return I2C1_REGS;
case I2C_2:
return I2C2_REGS;
case I2C_3:
return I2C3_REGS;
case I2C_4:
return I2C4_REGS;
case I2C_5:
return I2C5_REGS;
case I2C_6:
return I2C6_REGS;
default:
generic_panic();
}
return NULL;
}
/* Load hardware config for I2C4. */
void i2c_load_config(volatile tegra_i2c_t *regs) {
/* Set MSTR_CONFIG_LOAD, TIMEOUT_CONFIG_LOAD, undocumented bit. */
regs->I2C_I2C_CONFIG_LOAD_0 = 0x25;
/* Wait a bit for master config to be loaded. */
for (unsigned int i = 0; i < 20; i++) {
udelay(1);
if (!(regs->I2C_I2C_CONFIG_LOAD_0 & 1)) {
break;
}
}
}
/* Reads a register from a device over I2C, writes result to output. */
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
uint32_t val = r;
/* Write single byte register ID to device. */
if (!i2c_write(regs, device, &val, 1)) {
return false;
}
/* Limit output size to 32-bits. */
if (dst_size > 4) {
return false;
}
return i2c_read(regs, device, dst, dst_size);
}
/* Writes a value to a register over I2C. */
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size) {
uint32_t val = r;
if (src_size == 0) {
return true;
} else if (src_size <= 3) {
memcpy(((uint8_t *)&val) + 1, src, src_size);
return i2c_write(i2c_get_registers_from_id(id), device, &val, src_size + 1);
} else {
return false;
}
}
/* Writes bytes to device over I2C. */
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size) {
if (src_size > 4) {
return false;
} else if (src_size == 0) {
return true;
}
/* Set device for 7-bit write mode. */
regs->I2C_I2C_CMD_ADDR0_0 = device << 1;
/* Load in data to write. */
regs->I2C_I2C_CMD_DATA1_0 = read32le(src, 0);
/* Set config with LENGTH = src_size, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
regs->I2C_I2C_CNFG_0 = ((src_size << 1) - 2) | 0x2800;
i2c_load_config(regs);
/* Config |= SEND; */
regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
while (regs->I2C_I2C_STATUS_0 & 0x100) {
/* Wait until not busy. */
}
/* Return CMD1_STAT == SL1_XFER_SUCCESSFUL. */
return (regs->I2C_I2C_STATUS_0 & 0xF) == 0;
}
/* Reads bytes from device over I2C. */
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size) {
if (dst_size > 4) {
return false;
} else if (dst_size == 0) {
return true;
}
/* Set device for 7-bit read mode. */
regs->I2C_I2C_CMD_ADDR0_0 = (device << 1) | 1;
/* Set config with LENGTH = dst_size, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
regs->I2C_I2C_CNFG_0 = ((dst_size << 1) - 2) | 0x2840;
i2c_load_config(regs);
/* Config |= SEND; */
regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
while (regs->I2C_I2C_STATUS_0 & 0x100) {
/* Wait until not busy. */
}
/* Ensure success. */
if ((regs->I2C_I2C_STATUS_0 & 0xF) != 0) {
return false;
}
uint32_t val = regs->I2C_I2C_CMD_DATA1_0;
memcpy(dst, &val, dst_size);
return true;
}

View File

@@ -1,105 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_I2C_H
#define FUSEE_I2C_H
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#define I2C1234_BASE 0x7000C000
#define I2C56_BASE 0x7000D000
#define MAX77621_CPU_I2C_ADDR 0x1B
#define MAX77621_GPU_I2C_ADDR 0x1C
#define MAX17050_I2C_ADDR 0x36
#define MAX77620_PWR_I2C_ADDR 0x3C
#define MAX77620_RTC_I2C_ADDR 0x68
#define BQ24193_I2C_ADDR 0x6B
typedef enum {
I2C_1 = 0,
I2C_2 = 1,
I2C_3 = 2,
I2C_4 = 3,
I2C_5 = 4,
I2C_6 = 5,
} I2CDevice;
typedef struct {
uint32_t I2C_I2C_CNFG_0;
uint32_t I2C_I2C_CMD_ADDR0_0;
uint32_t I2C_I2C_CMD_ADDR1_0;
uint32_t I2C_I2C_CMD_DATA1_0;
uint32_t I2C_I2C_CMD_DATA2_0;
uint32_t _0x14;
uint32_t _0x18;
uint32_t I2C_I2C_STATUS_0;
uint32_t I2C_I2C_SL_CNFG_0;
uint32_t I2C_I2C_SL_RCVD_0;
uint32_t I2C_I2C_SL_STATUS_0;
uint32_t I2C_I2C_SL_ADDR1_0;
uint32_t I2C_I2C_SL_ADDR2_0;
uint32_t I2C_I2C_TLOW_SEXT_0;
uint32_t _0x38;
uint32_t I2C_I2C_SL_DELAY_COUNT_0;
uint32_t I2C_I2C_SL_INT_MASK_0;
uint32_t I2C_I2C_SL_INT_SOURCE_0;
uint32_t I2C_I2C_SL_INT_SET_0;
uint32_t _0x4C;
uint32_t I2C_I2C_TX_PACKET_FIFO_0;
uint32_t I2C_I2C_RX_FIFO_0;
uint32_t I2C_PACKET_TRANSFER_STATUS_0;
uint32_t I2C_FIFO_CONTROL_0;
uint32_t I2C_FIFO_STATUS_0;
uint32_t I2C_INTERRUPT_MASK_REGISTER_0;
uint32_t I2C_INTERRUPT_STATUS_REGISTER_0;
uint32_t I2C_I2C_CLK_DIVISOR_REGISTER_0;
uint32_t I2C_I2C_INTERRUPT_SOURCE_REGISTER_0;
uint32_t I2C_I2C_INTERRUPT_SET_REGISTER_0;
uint32_t I2C_I2C_SLV_TX_PACKET_FIFO_0;
uint32_t I2C_I2C_SLV_RX_FIFO_0;
uint32_t I2C_I2C_SLV_PACKET_STATUS_0;
uint32_t I2C_I2C_BUS_CLEAR_CONFIG_0;
uint32_t I2C_I2C_BUS_CLEAR_STATUS_0;
uint32_t I2C_I2C_CONFIG_LOAD_0;
uint32_t _0x90;
uint32_t I2C_I2C_INTERFACE_TIMING_0_0;
uint32_t I2C_I2C_INTERFACE_TIMING_1_0;
uint32_t I2C_I2C_HS_INTERFACE_TIMING_0_0;
uint32_t I2C_I2C_HS_INTERFACE_TIMING_1_0;
} tegra_i2c_t;
#define I2C1_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x000))
#define I2C2_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x400))
#define I2C3_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x500))
#define I2C4_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x700))
#define I2C5_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x000))
#define I2C6_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x100))
void i2c_config(I2CDevice id);
void i2c_init(I2CDevice id);
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
void i2c_send_pmic_cpu_shutdown_cmd(void);
bool i2c_query_ti_charger_bit_7(void);
void i2c_clear_ti_charger_bit_7(void);
void i2c_set_ti_charger_bit_7(void);
#endif

View File

@@ -1,146 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <stdint.h>
#include <stddef.h>
#include <string.h>
#include <malloc.h>
#include <sys/iosupport.h>
#include "utils.h"
void __libc_init_array(void);
void __libc_fini_array(void);
extern uint8_t __bss_start__[], __bss_end__[];
extern uint8_t __heap_start__[], __heap_end__[];
extern char *fake_heap_start;
extern char *fake_heap_end;
int __program_argc;
void **__program_argv;
void __attribute__((noreturn)) __program_exit(int rc);
void __attribute__((noreturn)) (*__program_exit_callback)(int rc) = NULL;
static void __program_parse_argc_argv(int argc, char *argdata);
static void __program_cleanup_argv(void);
static void __program_init_heap(void) {
fake_heap_start = (char*)__heap_start__;
fake_heap_end = (char*)__heap_end__;
}
static void __program_init_newlib_hooks(void) {
__syscalls.exit = __program_exit; /* For exit, etc. */
}
static void __program_move_additional_sections(void) {
#if defined(FUSEE_STAGE1_SRC) || defined(FUSEE_STAGE2_SRC)
extern uint8_t __chainloader_lma__[], __chainloader_start__[], __chainloader_bss_start__[], __chainloader_end__[];
memcpy(__chainloader_start__, __chainloader_lma__, __chainloader_bss_start__ - __chainloader_start__);
memset(__chainloader_bss_start__, 0, __chainloader_end__ - __chainloader_bss_start__);
#endif
}
void __program_init(int argc, char *argdata) {
/* Zero-fill the .bss section */
memset(__bss_start__, 0, __bss_end__ - __bss_start__);
__program_init_heap();
__program_init_newlib_hooks();
__program_parse_argc_argv(argc, argdata);
/* Once argv is parsed, we can discard the low IRAM region */
__program_move_additional_sections();
__libc_init_array();
}
void __program_exit(int rc) {
__libc_fini_array();
__program_cleanup_argv();
if (__program_exit_callback == NULL) {
/* Default callback */
generic_panic();
} else {
__program_exit_callback(rc);
}
for (;;);
}
#ifdef FUSEE_STAGE1_SRC
static void __program_parse_argc_argv(int argc, char *argdata) {
__program_argc = 0;
__program_argv = NULL;
}
#elif defined(FUSEE_STAGE2_SRC)
#include "stage2.h"
static void __program_parse_argc_argv(int argc, char *argdata) {
size_t pos = 0, len;
__program_argc = argc;
__program_argv = malloc(argc * sizeof(void **));
if (__program_argv == NULL) {
generic_panic();
}
len = strlen(argdata);
__program_argv[0] = malloc(len + 1);
if (__program_argv[0] == NULL) {
generic_panic();
}
strcpy((char *)__program_argv[0], argdata);
pos += len + 1;
__program_argv[1] = malloc(sizeof(stage2_args_t));
if (__program_argv[1] == NULL) {
generic_panic();
}
memcpy(__program_argv[1], argdata + pos, sizeof(stage2_args_t));
}
#else
static void __program_parse_argc_argv(int argc, char *argdata) {
size_t pos = 0, len;
__program_argc = argc;
__program_argv = malloc(argc * sizeof(void **));
if (__program_argv == NULL) {
generic_panic();
}
for (int i = 0; i < argc; i++) {
len = strlen(argdata + pos);
__program_argv[i] = malloc(len + 1);
if (__program_argv[i] == NULL) {
generic_panic();
}
strcpy((char *)__program_argv[i], argdata + pos);
pos += len + 1;
}
}
#endif
static void __program_cleanup_argv(void) {
#ifndef FUSEE_STAGE1_SRC
for (int i = 0; i < __program_argc; i++) {
free(__program_argv[i]);
__program_argv[i] = NULL;
}
free(__program_argv);
#endif
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "lz4.h"
#include "utils.h"
#define PRIMARY_START (0x40008000)
#define PRIMARY_SIZE_MAX (0x28000)
#define PRIMARY_END (PRIMARY_START + PRIMARY_SIZE_MAX)
void load_fusee_primary_main(void *compressed_main, size_t main_size) {
/* Relocate the compressed binary to a place where we can safely decompress it. */
void *relocated_main = (void *)(PRIMARY_END - main_size);
loader_memmove(relocated_main, compressed_main, main_size);
/* Uncompress the compressed binary. */
lz4_uncompress((void *)PRIMARY_START, PRIMARY_SIZE_MAX, relocated_main, main_size);
/* Jump to the newly uncompressed binary. */
((void (*)(void))(PRIMARY_START))();
/* We will never reach this point. */
__builtin_unreachable();
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "lz4.h"
#include "utils.h"
typedef struct {
const uint8_t *src;
size_t src_size;
size_t src_offset;
uint8_t *dst;
size_t dst_size;
size_t dst_offset;
} lz4_ctx;
static uint8_t lz4_ctx_read_byte(lz4_ctx *ctx) {
return ctx->src[ctx->src_offset++];
}
static bool lz4_ctx_can_read(const lz4_ctx *ctx) {
return ctx->src_offset < ctx->src_size;
}
static size_t lz4_ctx_get_copy_size(lz4_ctx *ctx, uint8_t ctrl) {
size_t size = ctrl;
if (ctrl >= 0xF) {
do {
while (!lz4_ctx_can_read(ctx));
ctrl = lz4_ctx_read_byte(ctx);
size += ctrl;
} while (ctrl == 0xFF);
}
return size;
}
static void lz4_ctx_copy(lz4_ctx *ctx, size_t size) {
/* Perform the copy. */
loader_memcpy(ctx->dst + ctx->dst_offset, ctx->src + ctx->src_offset, size);
ctx->dst_offset += size;
ctx->src_offset += size;
}
static void lz4_ctx_uncompress(lz4_ctx *ctx) {
while (true) {
/* Read a control byte. */
const uint8_t control = lz4_ctx_read_byte(ctx);
/* Copy what it specifies we should copy. */
lz4_ctx_copy(ctx, lz4_ctx_get_copy_size(ctx, control >> 4));
/* If we've exceeded size, we're done. */
if (ctx->src_offset >= ctx->src_size) {
break;
}
/* Read the wide copy offset. */
uint16_t wide_offset = lz4_ctx_read_byte(ctx);
while (!lz4_ctx_can_read(ctx));
wide_offset |= (lz4_ctx_read_byte(ctx) << 8);
/* Determine the copy size. */
const size_t wide_copy_size = lz4_ctx_get_copy_size(ctx, control & 0xF);
/* Copy bytes. */
const size_t end_offset = ctx->dst_offset + wide_copy_size + 4;
for (size_t cur_offset = ctx->dst_offset; cur_offset < end_offset; ctx->dst_offset = (++cur_offset)) {
while (!(wide_offset <= cur_offset));
ctx->dst[cur_offset] = ctx->dst[cur_offset - wide_offset];
}
}
}
void lz4_uncompress(void *dst, size_t dst_size, const void *src, size_t src_size) {
/* Create and execute a decompressor. */
lz4_ctx ctx = { src, src_size, 0, dst, dst_size, 0 };
lz4_ctx_uncompress(&ctx);
}

View File

@@ -1,6 +1,4 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,16 +13,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FUSEE_BTN_H_
#define FUSEE_BTN_H_
#pragma once
#define BTN_POWER 0x1
#define BTN_VOL_DOWN 0x2
#define BTN_VOL_UP 0x4
uint32_t btn_read();
uint32_t btn_wait();
uint32_t btn_wait_timeout(uint32_t time_ms, uint32_t mask);
#endif
void lz4_uncompress(void *dst, size_t dst_size, const void *src, size_t src_size);

View File

@@ -1,204 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 "utils.h"
#include "exception_handlers.h"
#include "panic.h"
#include "fuse.h"
#include "hwinit.h"
#include "di.h"
#include "timers.h"
#include "fs_utils.h"
#include "stage2.h"
#include "chainloader.h"
#include "../../../fusee/common/sdmmc/sdmmc.h"
#include "../../../fusee/common/fatfs/ff.h"
#include "../../../fusee/common/log.h"
#include "../../../fusee/common/vsprintf.h"
#include "../../../fusee/common/ini.h"
#include "../../../fusee/common/display/video_fb.h"
extern void (*__program_exit_callback)(int rc);
static void *g_framebuffer;
static char g_bct0_buffer[BCTO_MAX_SIZE];
#define CONFIG_LOG_LEVEL_KEY "log_level"
static const char *get_default_bct0(void) {
return "BCT0\n"
"[stage1]\n"
"stage2_path = atmosphere/fusee-secondary.bin\n"
"stage2_mtc_path = atmosphere/fusee-mtc.bin\n"
"stage2_addr = 0xF0000000\n"
"stage2_entrypoint = 0xF0000000\n"
"\n"
"[stratosphere]\n"
"\n";
}
static const char *load_config(void) {
if (!read_from_file(g_bct0_buffer, BCTO_MAX_SIZE, "atmosphere/config/BCT.ini")) {
print(SCREEN_LOG_LEVEL_DEBUG, "Failed to read BCT0 from SD!\n");
print(SCREEN_LOG_LEVEL_DEBUG, "Using default BCT0!\n");
const char * const default_bct0 = get_default_bct0();
memcpy(g_bct0_buffer, default_bct0, strlen(default_bct0));
}
if (memcmp(g_bct0_buffer, "BCT0", 4) != 0) {
fatal_error("Unexpected magic in BCT.ini!\n");
}
/* Return pointer to first line of the ini. */
const char *bct0 = g_bct0_buffer;
while (*bct0 && *bct0 != '\n') {
bct0++;
}
if (!bct0) {
fatal_error("BCT.ini has no newline!\n");
}
return bct0;
}
static int config_ini_handler(void *user, const char *section, const char *name, const char *value) {
if (strcmp(section, "config") == 0) {
if (strcmp(name, CONFIG_LOG_LEVEL_KEY) == 0) {
ScreenLogLevel *config_log_level = (ScreenLogLevel *)user;
int log_level = 0;
sscanf(value, "%d", &log_level);
*config_log_level = (ScreenLogLevel)log_level;
} else {
return 0;
}
} else {
return 0;
}
return 1;
}
static void setup_display(void) {
g_framebuffer = (void *)0xC0000000;
/* Zero-fill the framebuffer and register it as printk provider. */
video_init(g_framebuffer);
/* Initialize the display. */
display_init();
/* Set the framebuffer. */
display_init_framebuffer(g_framebuffer);
/* Turn on the backlight after initializing the lfb */
/* to avoid flickering. */
display_backlight(true);
}
static void cleanup_display(void) {
/* Turn off the backlight. */
display_backlight(false);
/* Terminate the display. */
display_end();
}
static void setup_env(void) {
/* Initialize hardware. */
if (fuse_get_soc_type() == 1) {
nx_hwinit_mariko(false);
} else {
nx_hwinit_erista(false);
}
/* Set up the exception handlers. */
setup_exception_handlers();
/* Mount the SD card. */
mount_sd();
}
static void cleanup_env(void) {
/* Unmount the SD card. */
unmount_sd();
}
static void exit_callback(int rc) {
(void)rc;
relocate_and_chainload();
}
int main(void) {
const char *bct0;
const char *stage2_path;
stage2_args_t *stage2_args;
uint32_t stage2_version = 0;
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
/* Initialize the boot environment. */
setup_env();
/* Check for panics. */
check_and_display_panic();
/* Load the BCT0 configuration ini off of the SD. */
bct0 = load_config();
/* Extract the logging level from the BCT.ini file. */
if (ini_parse_string(bct0, config_ini_handler, &log_level) < 0) {
fatal_error("Failed to parse BCT.ini!\n");
}
/* Override the global logging level. */
log_set_log_level(log_level);
if (log_level != SCREEN_LOG_LEVEL_NONE) {
/* Initialize the display for debugging. */
setup_display();
}
/* Say hello. */
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", g_framebuffer);
/* Load the loader payload into DRAM. */
load_stage2(bct0);
/* Setup argument data. */
stage2_path = stage2_get_program_path();
strcpy(g_chainloader_arg_data, stage2_path);
stage2_args = (stage2_args_t *)(g_chainloader_arg_data + strlen(stage2_path) + 1); /* May be unaligned. */
memcpy(&stage2_args->version, &stage2_version, 4);
memcpy(&stage2_args->log_level, &log_level, sizeof(log_level));
strcpy(stage2_args->bct0, bct0);
g_chainloader_argc = 2;
/* Terminate the boot environment. */
cleanup_env();
if (log_level != SCREEN_LOG_LEVEL_NONE) {
/* Wait a while for debugging. */
mdelay(1000);
/* Terminate the display for debugging. */
cleanup_display();
}
/* Finally, after the cleanup routines (__libc_fini_array, etc.) are called, jump to Stage2. */
__program_exit_callback = exit_callback;
return 0;
}

View File

@@ -1,357 +0,0 @@
/*
* Defining registers address and its bit definitions of MAX77620 and MAX20024
*
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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.
*/
#ifndef _MFD_MAX77620_H_
#define _MFD_MAX77620_H_
/* RTC Registers */
#define MAX77620_REG_RTCINT 0x00
#define MAX77620_REG_RTCINTM 0x01
#define MAX77620_REG_RTCCNTLM 0x02
#define MAX77620_REG_RTCCNTL 0x03
#define MAX77620_REG_RTCUPDATE0 0x04
#define MAX77620_REG_RTCUPDATE1 0x05
#define MAX77620_REG_RTCSMPL 0x06
#define MAX77620_REG_RTCSEC 0x07
#define MAX77620_REG_RTCMIN 0x08
#define MAX77620_REG_RTCHOUR 0x09
#define MAX77620_REG_RTCDOW 0x0A
#define MAX77620_REG_RTCMONTH 0x0B
#define MAX77620_REG_RTCYEAR 0x0C
#define MAX77620_REG_RTCDOM 0x0D
#define MAX77620_REG_RTCSECA1 0x0E
#define MAX77620_REG_RTCMINA1 0x0F
#define MAX77620_REG_RTCHOURA1 0x10
#define MAX77620_REG_RTCDOWA1 0x11
#define MAX77620_REG_RTCMONTHA1 0x12
#define MAX77620_REG_RTCYEARA1 0x13
#define MAX77620_REG_RTCDOMA1 0x14
#define MAX77620_REG_RTCSECA2 0x15
#define MAX77620_REG_RTCMINA2 0x16
#define MAX77620_REG_RTCHOURA2 0x17
#define MAX77620_REG_RTCDOWA2 0x18
#define MAX77620_REG_RTCMONTHA2 0x19
#define MAX77620_REG_RTCYEARA2 0x1A
#define MAX77620_REG_RTCDOMA2 0x1B
/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */
#define MAX77620_REG_CNFGGLBL1 0x00
#define MAX77620_REG_CNFGGLBL2 0x01
#define MAX77620_REG_CNFGGLBL3 0x02
#define MAX77620_REG_CNFG1_32K 0x03
#define MAX77620_REG_CNFGBBC 0x04
#define MAX77620_REG_IRQTOP 0x05
#define MAX77620_REG_INTLBT 0x06
#define MAX77620_REG_IRQSD 0x07
#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
#define MAX77620_REG_IRQ_LVL2_L8 0x09
#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
#define MAX77620_REG_ONOFFIRQ 0x0B
#define MAX77620_REG_NVERC 0x0C
#define MAX77620_REG_IRQTOPM 0x0D
#define MAX77620_REG_INTENLBT 0x0E
#define MAX77620_REG_IRQMASKSD 0x0F
#define MAX77620_REG_IRQ_MSK_L0_7 0x10
#define MAX77620_REG_IRQ_MSK_L8 0x11
#define MAX77620_REG_ONOFFIRQM 0x12
#define MAX77620_REG_STATLBT 0x13
#define MAX77620_REG_STATSD 0x14
#define MAX77620_REG_ONOFFSTAT 0x15
/* SD and LDO Registers */
#define MAX77620_REG_SD0 0x16
#define MAX77620_REG_SD1 0x17
#define MAX77620_REG_SD2 0x18
#define MAX77620_REG_SD3 0x19
#define MAX77620_REG_SD4 0x1A
#define MAX77620_REG_DVSSD0 0x1B
#define MAX77620_REG_DVSSD1 0x1C
#define MAX77620_REG_SD0_CFG 0x1D
#define MAX77620_REG_SD1_CFG 0x1E
#define MAX77620_REG_SD2_CFG 0x1F
#define MAX77620_REG_SD3_CFG 0x20
#define MAX77620_REG_SD4_CFG 0x21
#define MAX77620_REG_SD_CFG2 0x22
#define MAX77620_REG_LDO0_CFG 0x23
#define MAX77620_REG_LDO0_CFG2 0x24
#define MAX77620_REG_LDO1_CFG 0x25
#define MAX77620_REG_LDO1_CFG2 0x26
#define MAX77620_REG_LDO2_CFG 0x27
#define MAX77620_REG_LDO2_CFG2 0x28
#define MAX77620_REG_LDO3_CFG 0x29
#define MAX77620_REG_LDO3_CFG2 0x2A
#define MAX77620_REG_LDO4_CFG 0x2B
#define MAX77620_REG_LDO4_CFG2 0x2C
#define MAX77620_REG_LDO5_CFG 0x2D
#define MAX77620_REG_LDO5_CFG2 0x2E
#define MAX77620_REG_LDO6_CFG 0x2F
#define MAX77620_REG_LDO6_CFG2 0x30
#define MAX77620_REG_LDO7_CFG 0x31
#define MAX77620_REG_LDO7_CFG2 0x32
#define MAX77620_REG_LDO8_CFG 0x33
#define MAX77620_REG_LDO8_CFG2 0x34
#define MAX77620_REG_LDO_CFG3 0x35
#define MAX77620_LDO_SLEW_RATE_MASK 0x1
/* LDO Configuration 3 */
#define MAX77620_TRACK4_MASK (1 << 5)
#define MAX77620_TRACK4_SHIFT 5
/* Voltage */
#define MAX77620_SDX_VOLT_MASK 0xFF
#define MAX77620_SD0_VOLT_MASK 0x3F
#define MAX77620_SD1_VOLT_MASK 0x7F
#define MAX77620_LDO_VOLT_MASK 0x3F
#define MAX77620_REG_GPIO0 0x36
#define MAX77620_REG_GPIO1 0x37
#define MAX77620_REG_GPIO2 0x38
#define MAX77620_REG_GPIO3 0x39
#define MAX77620_REG_GPIO4 0x3A
#define MAX77620_REG_GPIO5 0x3B
#define MAX77620_REG_GPIO6 0x3C
#define MAX77620_REG_GPIO7 0x3D
#define MAX77620_REG_PUE_GPIO 0x3E
#define MAX77620_REG_PDE_GPIO 0x3F
#define MAX77620_REG_AME_GPIO 0x40
#define MAX77620_REG_ONOFFCNFG1 0x41
#define MAX77620_REG_ONOFFCNFG2 0x42
/* FPS Registers */
#define MAX77620_REG_FPS_CFG0 0x43
#define MAX77620_REG_FPS_CFG1 0x44
#define MAX77620_REG_FPS_CFG2 0x45
#define MAX77620_REG_FPS_LDO0 0x46
#define MAX77620_REG_FPS_LDO1 0x47
#define MAX77620_REG_FPS_LDO2 0x48
#define MAX77620_REG_FPS_LDO3 0x49
#define MAX77620_REG_FPS_LDO4 0x4A
#define MAX77620_REG_FPS_LDO5 0x4B
#define MAX77620_REG_FPS_LDO6 0x4C
#define MAX77620_REG_FPS_LDO7 0x4D
#define MAX77620_REG_FPS_LDO8 0x4E
#define MAX77620_REG_FPS_SD0 0x4F
#define MAX77620_REG_FPS_SD1 0x50
#define MAX77620_REG_FPS_SD2 0x51
#define MAX77620_REG_FPS_SD3 0x52
#define MAX77620_REG_FPS_SD4 0x53
#define MAX77620_REG_FPS_NONE 0
#define MAX77620_FPS_SRC_MASK 0xC0
#define MAX77620_FPS_SRC_SHIFT 6
#define MAX77620_FPS_PU_PERIOD_MASK 0x38
#define MAX77620_FPS_PU_PERIOD_SHIFT 3
#define MAX77620_FPS_PD_PERIOD_MASK 0x07
#define MAX77620_FPS_PD_PERIOD_SHIFT 0
#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
#define MAX77620_FPS_EN_SRC_MASK 0x06
#define MAX77620_FPS_EN_SRC_SHIFT 1
#define MAX77620_FPS_ENFPS_SW_MASK 0x01
#define MAX77620_FPS_ENFPS_SW 0x01
/* Minimum and maximum FPS period time (in microseconds) are
* different for MAX77620 and Max20024.
*/
#define MAX77620_FPS_PERIOD_MIN_US 40
#define MAX20024_FPS_PERIOD_MIN_US 20
#define MAX77620_FPS_PERIOD_MAX_US 2560
#define MAX20024_FPS_PERIOD_MAX_US 5120
#define MAX77620_REG_FPS_GPIO1 0x54
#define MAX77620_REG_FPS_GPIO2 0x55
#define MAX77620_REG_FPS_GPIO3 0x56
#define MAX77620_REG_FPS_RSO 0x57
#define MAX77620_REG_CID0 0x58
#define MAX77620_REG_CID1 0x59
#define MAX77620_REG_CID2 0x5A
#define MAX77620_REG_CID3 0x5B
#define MAX77620_REG_CID4 0x5C
#define MAX77620_REG_CID5 0x5D
#define MAX77620_REG_DVSSD4 0x5E
#define MAX20024_REG_MAX_ADD 0x70
#define MAX77620_CID_DIDM_MASK 0xF0
#define MAX77620_CID_DIDM_SHIFT 4
/* CNCG2SD */
#define MAX77620_SD_CNF2_ROVS_EN_SD1 (1 << 1)
#define MAX77620_SD_CNF2_ROVS_EN_SD0 (1 << 2)
/* Device Identification Metal */
#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
/* Device Indentification OTP */
#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
/* SD CNFG1 */
#define MAX77620_SD_SR_MASK 0xC0
#define MAX77620_SD_SR_SHIFT 6
#define MAX77620_SD_POWER_MODE_MASK 0x30
#define MAX77620_SD_POWER_MODE_SHIFT 4
#define MAX77620_SD_CFG1_ADE_MASK (1 << 3)
#define MAX77620_SD_CFG1_ADE_DISABLE 0
#define MAX77620_SD_CFG1_ADE_ENABLE (1 << 3)
#define MAX77620_SD_FPWM_MASK 0x04
#define MAX77620_SD_FPWM_SHIFT 2
#define MAX77620_SD_FSRADE_MASK 0x01
#define MAX77620_SD_FSRADE_SHIFT 0
#define MAX77620_SD_CFG1_FPWM_SD_MASK (1 << 2)
#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
#define MAX77620_SD_CFG1_FPWM_SD_FPWM (1 << 2)
#define MAX20024_SD_CFG1_MPOK_MASK (1 << 1)
#define MAX77620_SD_CFG1_FSRADE_SD_MASK (1 << 0)
#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE (1 << 0)
/* LDO_CNFG2 */
#define MAX77620_LDO_POWER_MODE_MASK 0xC0
#define MAX77620_LDO_POWER_MODE_SHIFT 6
#define MAX20024_LDO_CFG2_MPOK_MASK (1 << 2)
#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
#define MAX77620_LDO_CFG2_ADE_DISABLE 0
#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
#define MAX77620_LDO_CFG2_SS_SLOW 0
#define MAX77620_IRQ_TOP_GLBL_MASK (1 << 7)
#define MAX77620_IRQ_TOP_SD_MASK (1 << 6)
#define MAX77620_IRQ_TOP_LDO_MASK (1 << 5)
#define MAX77620_IRQ_TOP_GPIO_MASK (1 << 4)
#define MAX77620_IRQ_TOP_RTC_MASK (1 << 3)
#define MAX77620_IRQ_TOP_32K_MASK (1 << 2)
#define MAX77620_IRQ_TOP_ONOFF_MASK (1 << 1)
#define MAX77620_IRQ_LBM_MASK (1 << 3)
#define MAX77620_IRQ_TJALRM1_MASK (1 << 2)
#define MAX77620_IRQ_TJALRM2_MASK (1 << 1)
#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN 0
#define MAX77620_CNFG_GPIO_DIR_MASK (1 << 1)
#define MAX77620_CNFG_GPIO_DIR_INPUT (1 << 1)
#define MAX77620_CNFG_GPIO_DIR_OUTPUT 0
#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK (1 << 2)
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK (1 << 3)
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH (1 << 3)
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW 0
#define MAX77620_CNFG_GPIO_INT_MASK (0x3 << 4)
#define MAX77620_CNFG_GPIO_INT_FALLING (1 << 4)
#define MAX77620_CNFG_GPIO_INT_RISING (1 << 5)
#define MAX77620_CNFG_GPIO_DBNC_MASK (0x3 << 6)
#define MAX77620_CNFG_GPIO_DBNC_None (0x0 << 6)
#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
#define MAX77620_IRQ_LVL2_GPIO_EDGE0 (1 << 0)
#define MAX77620_IRQ_LVL2_GPIO_EDGE1 (1 << 1)
#define MAX77620_IRQ_LVL2_GPIO_EDGE2 (1 << 2)
#define MAX77620_IRQ_LVL2_GPIO_EDGE3 (1 << 3)
#define MAX77620_IRQ_LVL2_GPIO_EDGE4 (1 << 4)
#define MAX77620_IRQ_LVL2_GPIO_EDGE5 (1 << 5)
#define MAX77620_IRQ_LVL2_GPIO_EDGE6 (1 << 6)
#define MAX77620_IRQ_LVL2_GPIO_EDGE7 (1 << 7)
#define MAX77620_CNFG1_32K_OUT0_EN (1 << 2)
#define MAX77620_ONOFFCNFG1_SFT_RST (1 << 7)
#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
#define MAX77620_ONOFFCNFG1_SLPEN (1 << 2)
#define MAX77620_ONOFFCNFG1_PWR_OFF (1 << 1)
#define MAX20024_ONOFFCNFG1_CLRSE 0x18
#define MAX77620_ONOFFCNFG2_SFT_RST_WK (1 << 7)
#define MAX77620_ONOFFCNFG2_WD_RST_WK (1 << 6)
#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK (1 << 5)
#define MAX77620_ONOFFCNFG2_WK_ALARM1 (1 << 2)
#define MAX77620_ONOFFCNFG2_WK_EN0 (1 << 0)
#define MAX77620_GLBLM_MASK (1 << 0)
#define MAX77620_WDTC_MASK 0x3
#define MAX77620_WDTOFFC (1 << 4)
#define MAX77620_WDTSLPC (1 << 3)
#define MAX77620_WDTEN (1 << 2)
#define MAX77620_TWD_MASK 0x3
#define MAX77620_TWD_2s 0x0
#define MAX77620_TWD_16s 0x1
#define MAX77620_TWD_64s 0x2
#define MAX77620_TWD_128s 0x3
#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
#define MAX77620_CNFGGLBL1_LBHYST_N (1 << 4)
#define MAX77620_CNFGGLBL1_LBDAC 0x0E
#define MAX77620_CNFGGLBL1_LBDAC_N (1 << 1)
#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
/* CNFG BBC registers */
#define MAX77620_CNFGBBC_ENABLE (1 << 0)
#define MAX77620_CNFGBBC_CURRENT_MASK 0x06
#define MAX77620_CNFGBBC_CURRENT_SHIFT 1
#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5)
#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
#define MAX77620_FPS_COUNT 3
/* Interrupts */
enum {
MAX77620_IRQ_TOP_GLBL, /* Low-Battery */
MAX77620_IRQ_TOP_SD, /* SD power fail */
MAX77620_IRQ_TOP_LDO, /* LDO power fail */
MAX77620_IRQ_TOP_GPIO, /* TOP GPIO internal int to MAX77620 */
MAX77620_IRQ_TOP_RTC, /* RTC */
MAX77620_IRQ_TOP_32K, /* 32kHz oscillator */
MAX77620_IRQ_TOP_ONOFF, /* ON/OFF oscillator */
MAX77620_IRQ_LBT_MBATLOW, /* Thermal alarm status, > 120C */
MAX77620_IRQ_LBT_TJALRM1, /* Thermal alarm status, > 120C */
MAX77620_IRQ_LBT_TJALRM2, /* Thermal alarm status, > 140C */
};
/* GPIOs */
enum {
MAX77620_GPIO0,
MAX77620_GPIO1,
MAX77620_GPIO2,
MAX77620_GPIO3,
MAX77620_GPIO4,
MAX77620_GPIO5,
MAX77620_GPIO6,
MAX77620_GPIO7,
MAX77620_GPIO_NR,
};
/* FPS Source */
enum max77620_fps_src {
MAX77620_FPS_SRC_0,
MAX77620_FPS_SRC_1,
MAX77620_FPS_SRC_2,
MAX77620_FPS_SRC_NONE,
MAX77620_FPS_SRC_DEF,
};
enum max77620_chip_id {
MAX77620,
MAX20024,
};
#endif /* _MFD_MAX77620_H_ */

View File

@@ -1,178 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <stdint.h>
#include "max7762x.h"
#include "max77620.h"
#include "i2c.h"
#include "timers.h"
#define REGULATOR_SD 0
#define REGULATOR_LDO 1
typedef struct _max77620_regulator_t
{
uint8_t type;
const char *name;
uint8_t reg_sd;
uint32_t mv_step;
uint32_t mv_min;
uint32_t mv_default;
uint32_t mv_max;
uint8_t volt_addr;
uint8_t cfg_addr;
uint8_t volt_mask;
uint8_t enable_mask;
uint8_t enable_shift;
uint8_t status_mask;
uint8_t fps_addr;
uint8_t fps_src;
uint8_t pd_period;
uint8_t pu_period;
} max77620_regulator_t;
static const max77620_regulator_t _pmic_regulators[] = {
{ REGULATOR_SD, "sd0", 0x16, 12500, 600000, 625000, 1400000, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, 0x3F, 0x30, 4, 0x80, 0x4F, 1, 7, 1 },
{ REGULATOR_SD, "sd1", 0x17, 12500, 600000, 1125000, 1125000, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, 0x3F, 0x30, 4, 0x40, 0x50, 0, 1, 5 },
{ REGULATOR_SD, "sd2", 0x18, 12500, 600000, 1325000, 1350000, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, 0xFF, 0x30, 4, 0x20, 0x51, 1, 5, 2 },
{ REGULATOR_SD, "sd3", 0x19, 12500, 600000, 1800000, 1800000, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, 0xFF, 0x30, 4, 0x10, 0x52, 0, 3, 3 },
{ REGULATOR_LDO, "ldo0", 0x00, 25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, 0x3F, 0xC0, 6, 0x00, 0x46, 3, 7, 0 },
{ REGULATOR_LDO, "ldo1", 0x00, 25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, 0x3F, 0xC0, 6, 0x00, 0x47, 3, 7, 0 },
{ REGULATOR_LDO, "ldo2", 0x00, 50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, 0x3F, 0xC0, 6, 0x00, 0x48, 3, 7, 0 },
{ REGULATOR_LDO, "ldo3", 0x00, 50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, 0x3F, 0xC0, 6, 0x00, 0x49, 3, 7, 0 },
{ REGULATOR_LDO, "ldo4", 0x00, 12500, 800000, 850000, 850000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4A, 0, 7, 1 },
{ REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4B, 3, 7, 0 },
{ REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4C, 3, 7, 0 },
{ REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4D, 1, 4, 3 },
{ REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4E, 3, 7, 0 }
};
int max77620_regulator_get_status(uint32_t id)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
uint8_t val = 0;
if (reg->type == REGULATOR_SD) {
if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_STATSD, &val, 1))
return (val & reg->status_mask) ? 0 : 1;
}
if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, reg->cfg_addr, &val, 1))
return (val & 8) ? 1 : 0;
return 0;
}
int max77620_regulator_config_fps(uint32_t id)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
uint8_t val = ((reg->fps_src << 6) | (reg->pu_period << 3) | (reg->pd_period));
if (i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, reg->fps_addr, &val, 1)) {
return 1;
}
return 0;
}
int max77620_regulator_set_voltage(uint32_t id, uint32_t mv)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
if ((mv < reg->mv_default) || (mv > reg->mv_max))
return 0;
uint32_t mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
uint8_t val = 0;
if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, reg->volt_addr, &val, 1))
{
val = ((val & ~reg->volt_mask) | (mult & reg->volt_mask));
if (i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, reg->volt_addr, &val, 1))
{
udelay(1000);
return 1;
}
}
return 0;
}
int max77620_regulator_enable(uint32_t id, int enable)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
uint32_t addr = (reg->type == REGULATOR_SD) ? reg->cfg_addr : reg->volt_addr;
uint8_t val = 0;
if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, addr, &val, 1))
{
if (enable)
val = ((val & ~reg->enable_mask) | ((3 << reg->enable_shift) & reg->enable_mask));
else
val &= ~reg->enable_mask;
if (i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, addr, &val, 1))
{
udelay(1000);
return 1;
}
}
return 0;
}
void max77620_config_default()
{
for (uint32_t i = 1; i <= REGULATOR_MAX; i++)
{
uint8_t val = 0;
if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CID4, &val, 1))
{
max77620_regulator_config_fps(i);
max77620_regulator_set_voltage(i, _pmic_regulators[i].mv_default);
if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE) {
max77620_regulator_enable(i, 1);
}
}
}
uint8_t val = 4;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD_CFG2, &val, 1);
}
void max77620_low_battery_monitor_config()
{
uint8_t val = (MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_LBHYST_N | MAX77620_CNFGGLBL1_LBDAC_N);
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
}

View File

@@ -1,68 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_MAX7762X_H_
#define FUSEE_MAX7762X_H_
/*
* Switch Power domains (max77620):
* Name | Usage | uV step | uV min | uV default | uV max | Init
*-------+---------------+---------+--------+------------+---------+------------------
* sd0 | core | 12500 | 600000 | 625000 | 1400000 | 1.125V (pkg1.1)
* sd1 | SDRAM | 12500 | 600000 | 1125000 | 1125000 | 1.1V (pkg1.1)
* sd2 | ldo{0-1, 7-8} | 12500 | 600000 | 1325000 | 1350000 | 1.325V (pcv)
* sd3 | 1.8V general | 12500 | 600000 | 1800000 | 1800000 |
* ldo0 | Display Panel | 25000 | 800000 | 1200000 | 1200000 | 1.2V (pkg1.1)
* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
* ldo3 | | 50000 | 800000 | 3100000 | 3100000 |
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
* ldo5 | | 50000 | 800000 | 1800000 | 1800000 |
* ldo6 | | 50000 | 800000 | 2900000 | 2900000 |
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 |
*/
/*
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
* MAX77620_REG_GPIOx: 0x9 sets output and enable
*/
/*! MAX77620 partitions. */
#define REGULATOR_SD0 0
#define REGULATOR_SD1 1
#define REGULATOR_SD2 2
#define REGULATOR_SD3 3
#define REGULATOR_LDO0 4
#define REGULATOR_LDO1 5
#define REGULATOR_LDO2 6
#define REGULATOR_LDO3 7
#define REGULATOR_LDO4 8
#define REGULATOR_LDO5 9
#define REGULATOR_LDO6 10
#define REGULATOR_LDO7 11
#define REGULATOR_LDO8 12
#define REGULATOR_MAX 12
int max77620_regulator_get_status(uint32_t id);
int max77620_regulator_config_fps(uint32_t id);
int max77620_regulator_set_voltage(uint32_t id, uint32_t mv);
int max77620_regulator_enable(uint32_t id, int enable);
void max77620_config_default();
void max77620_low_battery_monitor_config();
#endif

View File

@@ -1,169 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 "mc.h"
#include "car.h"
#include "timers.h"
void mc_config_tsec_carveout(uint32_t bom, uint32_t size1mb, bool lock)
{
MAKE_MC_REG(MC_SEC_CARVEOUT_BOM) = bom;
MAKE_MC_REG(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
if (lock)
MAKE_MC_REG(MC_SEC_CARVEOUT_REG_CTRL) = 1;
}
void mc_config_carveout()
{
*(volatile uint32_t *)0x8005FFFC = 0xC0EDBBCC;
MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
MAKE_MC_REG(MC_VIDEO_PROTECT_BOM) = 0;
MAKE_MC_REG(MC_VIDEO_PROTECT_SIZE_MB) = 0;
MAKE_MC_REG(MC_VIDEO_PROTECT_REG_CTRL) = 1;
mc_config_tsec_carveout(0, 0, true);
MAKE_MC_REG(MC_MTS_CARVEOUT_BOM) = 0;
MAKE_MC_REG(MC_MTS_CARVEOUT_SIZE_MB) = 0;
MAKE_MC_REG(MC_MTS_CARVEOUT_ADR_HI) = 0;
MAKE_MC_REG(MC_MTS_CARVEOUT_REG_CTRL) = 1;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_BOM) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_BOM) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_BOM) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_BOM) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
}
void mc_config_carveout_finalize()
{
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
}
void mc_enable_ahb_redirect()
{
volatile tegra_car_t *car = car_get_regs();
car->lvl2_clk_gate_ovrd = ((car->lvl2_clk_gate_ovrd & 0xFFF7FFFF) | 0x80000);
MAKE_MC_REG(MC_IRAM_BOM) = 0x40000000;
MAKE_MC_REG(MC_IRAM_TOM) = 0x4003F000;
}
void mc_disable_ahb_redirect()
{
volatile tegra_car_t *car = car_get_regs();
MAKE_MC_REG(MC_IRAM_BOM) = 0xFFFFF000;
MAKE_MC_REG(MC_IRAM_TOM) = 0;
car->lvl2_clk_gate_ovrd &= 0xFFF7FFFF;
}
void mc_enable()
{
volatile tegra_car_t *car = car_get_regs();
/* Set EMC clock source. */
car->clk_source_emc = ((car->clk_source_emc & 0x1FFFFFFF) | 0x40000000);
/* Enable MIPI CAL clock. */
car->clk_enb_h_set = ((car->clk_enb_h_set & 0xFDFFFFFF) | 0x2000000);
/* Enable MC clock. */
car->clk_enb_h_set = ((car->clk_enb_h_set & 0xFFFFFFFE) | 1);
/* Enable EMC DLL clock. */
car->clk_enb_x_set = ((car->clk_enb_x_set & 0xFFFFBFFF) | 0x4000);
/* Clear EMC and MC reset. */
/* NOTE: [4.0.0+] This was changed to use the right register. */
/* car->rst_dev_h_set = 0x2000001; */
car->rst_dev_h_clr = 0x2000001;
udelay(5);
mc_disable_ahb_redirect();
}

View File

@@ -1,606 +0,0 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_MC_H_
#define FUSEE_MC_H_
#include <stdint.h>
#include <stdbool.h>
#define MC_BASE 0x70019000
#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8
#define MC_ERR_ADR 0xc
#define MC_SMMU_CONFIG 0x10
#define MC_SMMU_TLB_CONFIG 0x14
#define MC_SMMU_PTC_CONFIG 0x18
#define MC_SMMU_PTB_ASID 0x1c
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH 0x34
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_ASID_SECURITY_1 0x3c
#define MC_SMMU_ASID_SECURITY_2 0x9e0
#define MC_SMMU_ASID_SECURITY_3 0x9e4
#define MC_SMMU_ASID_SECURITY_4 0x9e8
#define MC_SMMU_ASID_SECURITY_5 0x9ec
#define MC_SMMU_ASID_SECURITY_6 0x9f0
#define MC_SMMU_ASID_SECURITY_7 0x9f4
#define MC_SMMU_AFI_ASID 0x238
#define MC_SMMU_AVPC_ASID 0x23c
#define MC_SMMU_TSEC_ASID 0x294
#define MC_SMMU_PPCS1_ASID 0x298
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
#define MC_EMEM_CFG 0x50
#define MC_EMEM_ADR_CFG 0x54
#define MC_EMEM_ADR_CFG_DEV0 0x58
#define MC_EMEM_ADR_CFG_DEV1 0x5c
#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60
#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
#define MC_SECURITY_CFG0 0x70
#define MC_SECURITY_CFG1 0x74
#define MC_SECURITY_CFG3 0x9bc
#define MC_SECURITY_RSV 0x7c
#define MC_EMEM_ARB_CFG 0x90
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
#define MC_EMEM_ARB_TIMING_RCD 0x98
#define MC_EMEM_ARB_TIMING_RP 0x9c
#define MC_EMEM_ARB_TIMING_RC 0xa0
#define MC_EMEM_ARB_TIMING_RAS 0xa4
#define MC_EMEM_ARB_TIMING_FAW 0xa8
#define MC_EMEM_ARB_TIMING_RRD 0xac
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
#define MC_EMEM_ARB_TIMING_R2R 0xb8
#define MC_EMEM_ARB_TIMING_W2W 0xbc
#define MC_EMEM_ARB_TIMING_R2W 0xc0
#define MC_EMEM_ARB_TIMING_W2R 0xc4
#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0
#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4
#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0
#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4
#define MC_EMEM_ARB_DA_TURNS 0xd0
#define MC_EMEM_ARB_DA_COVERS 0xd4
#define MC_EMEM_ARB_MISC0 0xd8
#define MC_EMEM_ARB_MISC1 0xdc
#define MC_EMEM_ARB_MISC2 0xc8
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0
#define MC_EMEM_ARB_OVERRIDE 0xe8
#define MC_EMEM_ARB_RSV 0xec
#define MC_CLKEN_OVERRIDE 0xf4
#define MC_TIMING_CONTROL_DBG 0xf8
#define MC_TIMING_CONTROL 0xfc
#define MC_STAT_CONTROL 0x100
#define MC_STAT_STATUS 0x104
#define MC_STAT_EMC_CLOCK_LIMIT 0x108
#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c
#define MC_STAT_EMC_CLOCKS 0x110
#define MC_STAT_EMC_CLOCKS_MSBS 0x114
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c
#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0
#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0
#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120
#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160
#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128
#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168
#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c
#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c
#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130
#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170
#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134
#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88
#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174
#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c
#define MC_STAT_EMC_SET0_COUNT 0x138
#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c
#define MC_STAT_EMC_SET1_COUNT 0x178
#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c
#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140
#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144
#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180
#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184
#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148
#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c
#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188
#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c
#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150
#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190
#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8
#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc
#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8
#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc
#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0
#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0
#define MC_CLIENT_HOTRESET_CTRL 0x200
#define MC_CLIENT_HOTRESET_CTRL_1 0x970
#define MC_CLIENT_HOTRESET_STATUS 0x204
#define MC_CLIENT_HOTRESET_STATUS_1 0x974
#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214
#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94
#define MC_EMEM_ARB_HYSTERESIS_0 0x218
#define MC_EMEM_ARB_HYSTERESIS_1 0x21c
#define MC_EMEM_ARB_HYSTERESIS_2 0x220
#define MC_EMEM_ARB_HYSTERESIS_3 0x224
#define MC_EMEM_ARB_HYSTERESIS_4 0xb84
#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0
#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4
#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8
#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc
#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0
#define MC_EMEM_ARB_DHYST_CTRL 0xbcc
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec
#define MC_RESERVED_RSV 0x3fc
#define MC_DISB_EXTRA_SNAP_LEVELS 0x408
#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4
#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0
#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18
#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08
#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10
#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c
#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40
#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414
#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc
#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c
#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14
#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0
#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c
#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48
#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8
#define MC_USBX_EXTRA_SNAP_LEVELS 0x404
#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8
#define MC_SD_EXTRA_SNAP_LEVELS 0xa04
#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c
#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8
#define MC_GK_EXTRA_SNAP_LEVELS 0xa00
#define MC_VE2_EXTRA_SNAP_LEVELS 0x410
#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44
#define MC_VIDEO_PROTECT_BOM 0x648
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978
#define MC_VIDEO_PROTECT_REG_CTRL 0x650
#define MC_ERR_VPR_STATUS 0x654
#define MC_ERR_VPR_ADR 0x658
#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590
#define MC_IRAM_BOM 0x65c
#define MC_IRAM_TOM 0x660
#define MC_IRAM_ADR_HI 0x980
#define MC_IRAM_REG_CTRL 0x964
#define MC_EMEM_CFG_ACCESS_CTRL 0x664
#define MC_TZ_SECURITY_CTRL 0x668
#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4
#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc
#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8
#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80
#define MC_SEC_CARVEOUT_BOM 0x670
#define MC_SEC_CARVEOUT_SIZE_MB 0x674
#define MC_SEC_CARVEOUT_ADR_HI 0x9d4
#define MC_SEC_CARVEOUT_REG_CTRL 0x678
#define MC_ERR_SEC_STATUS 0x67c
#define MC_ERR_SEC_ADR 0x680
#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684
#define MC_STUTTER_CONTROL 0x688
#define MC_RESERVED_RSV_1 0x958
#define MC_DVFS_PIPE_SELECT 0x95c
#define MC_AHB_PTSA_MIN 0x4e0
#define MC_AUD_PTSA_MIN 0x54c
#define MC_MLL_MPCORER_PTSA_RATE 0x44c
#define MC_RING2_PTSA_RATE 0x440
#define MC_USBD_PTSA_RATE 0x530
#define MC_USBX_PTSA_MIN 0x528
#define MC_USBD_PTSA_MIN 0x534
#define MC_APB_PTSA_MAX 0x4f0
#define MC_JPG_PTSA_RATE 0x584
#define MC_DIS_PTSA_MIN 0x420
#define MC_AVP_PTSA_MAX 0x4fc
#define MC_AVP_PTSA_RATE 0x4f4
#define MC_RING1_PTSA_MIN 0x480
#define MC_DIS_PTSA_MAX 0x424
#define MC_SD_PTSA_MAX 0x4d8
#define MC_MSE_PTSA_RATE 0x4c4
#define MC_VICPC_PTSA_MIN 0x558
#define MC_PCX_PTSA_MAX 0x4b4
#define MC_ISP_PTSA_RATE 0x4a0
#define MC_A9AVPPC_PTSA_MIN 0x48c
#define MC_RING2_PTSA_MAX 0x448
#define MC_AUD_PTSA_RATE 0x548
#define MC_HOST_PTSA_MIN 0x51c
#define MC_MLL_MPCORER_PTSA_MAX 0x454
#define MC_SD_PTSA_MIN 0x4d4
#define MC_RING1_PTSA_RATE 0x47c
#define MC_JPG_PTSA_MIN 0x588
#define MC_HDAPC_PTSA_MIN 0x62c
#define MC_AVP_PTSA_MIN 0x4f8
#define MC_JPG_PTSA_MAX 0x58c
#define MC_VE_PTSA_MAX 0x43c
#define MC_DFD_PTSA_MAX 0x63c
#define MC_VICPC_PTSA_RATE 0x554
#define MC_GK_PTSA_MAX 0x544
#define MC_VICPC_PTSA_MAX 0x55c
#define MC_SDM_PTSA_MAX 0x624
#define MC_SAX_PTSA_RATE 0x4b8
#define MC_PCX_PTSA_MIN 0x4b0
#define MC_APB_PTSA_MIN 0x4ec
#define MC_GK2_PTSA_MIN 0x614
#define MC_PCX_PTSA_RATE 0x4ac
#define MC_RING1_PTSA_MAX 0x484
#define MC_HDAPC_PTSA_RATE 0x628
#define MC_MLL_MPCORER_PTSA_MIN 0x450
#define MC_GK2_PTSA_MAX 0x618
#define MC_AUD_PTSA_MAX 0x550
#define MC_GK2_PTSA_RATE 0x610
#define MC_ISP_PTSA_MAX 0x4a8
#define MC_DISB_PTSA_RATE 0x428
#define MC_VE2_PTSA_MAX 0x49c
#define MC_DFD_PTSA_MIN 0x638
#define MC_FTOP_PTSA_RATE 0x50c
#define MC_A9AVPPC_PTSA_RATE 0x488
#define MC_VE2_PTSA_MIN 0x498
#define MC_USBX_PTSA_MAX 0x52c
#define MC_DIS_PTSA_RATE 0x41c
#define MC_USBD_PTSA_MAX 0x538
#define MC_A9AVPPC_PTSA_MAX 0x490
#define MC_USBX_PTSA_RATE 0x524
#define MC_FTOP_PTSA_MAX 0x514
#define MC_HDAPC_PTSA_MAX 0x630
#define MC_SD_PTSA_RATE 0x4d0
#define MC_DFD_PTSA_RATE 0x634
#define MC_FTOP_PTSA_MIN 0x510
#define MC_SDM_PTSA_RATE 0x61c
#define MC_AHB_PTSA_RATE 0x4dc
#define MC_SMMU_SMMU_PTSA_MAX 0x460
#define MC_RING2_PTSA_MIN 0x444
#define MC_SDM_PTSA_MIN 0x620
#define MC_APB_PTSA_RATE 0x4e8
#define MC_MSE_PTSA_MIN 0x4c8
#define MC_HOST_PTSA_RATE 0x518
#define MC_VE_PTSA_RATE 0x434
#define MC_AHB_PTSA_MAX 0x4e4
#define MC_SAX_PTSA_MIN 0x4bc
#define MC_SMMU_SMMU_PTSA_MIN 0x45c
#define MC_ISP_PTSA_MIN 0x4a4
#define MC_HOST_PTSA_MAX 0x520
#define MC_SAX_PTSA_MAX 0x4c0
#define MC_VE_PTSA_MIN 0x438
#define MC_GK_PTSA_MIN 0x540
#define MC_MSE_PTSA_MAX 0x4cc
#define MC_DISB_PTSA_MAX 0x430
#define MC_DISB_PTSA_MIN 0x42c
#define MC_SMMU_SMMU_PTSA_RATE 0x458
#define MC_VE2_PTSA_RATE 0x494
#define MC_GK_PTSA_RATE 0x53c
#define MC_PTSA_GRANT_DECREMENT 0x960
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0
#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8
#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0
#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698
#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0
#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4
#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4
#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
#define MC_MIN_LENGTH_APE_0 0xb34
#define MC_MIN_LENGTH_DCB_2 0x8a8
#define MC_MIN_LENGTH_A9AVP_0 0x950
#define MC_MIN_LENGTH_TSEC_0 0x93c
#define MC_MIN_LENGTH_DC_1 0x898
#define MC_MIN_LENGTH_AXIAP_0 0x94c
#define MC_MIN_LENGTH_ISP2B_0 0x930
#define MC_MIN_LENGTH_VI2_0 0x944
#define MC_MIN_LENGTH_DCB_0 0x8a0
#define MC_MIN_LENGTH_DCB_1 0x8a4
#define MC_MIN_LENGTH_PPCS_1 0x8f4
#define MC_MIN_LENGTH_NVJPG_0 0xb3c
#define MC_MIN_LENGTH_HDA_0 0x8c4
#define MC_MIN_LENGTH_NVENC_0 0x8d4
#define MC_MIN_LENGTH_SDMMC_0 0xb18
#define MC_MIN_LENGTH_ISP2B_1 0x934
#define MC_MIN_LENGTH_HC_1 0x8c0
#define MC_MIN_LENGTH_DC_3 0xb20
#define MC_MIN_LENGTH_AVPC_0 0x890
#define MC_MIN_LENGTH_VIC_0 0x940
#define MC_MIN_LENGTH_ISP2_0 0x91c
#define MC_MIN_LENGTH_HC_0 0x8bc
#define MC_MIN_LENGTH_SE_0 0xb38
#define MC_MIN_LENGTH_NVDEC_0 0xb30
#define MC_MIN_LENGTH_SATA_0 0x8fc
#define MC_MIN_LENGTH_DC_0 0x894
#define MC_MIN_LENGTH_XUSB_1 0x92c
#define MC_MIN_LENGTH_DC_2 0x89c
#define MC_MIN_LENGTH_SDMMCAA_0 0xb14
#define MC_MIN_LENGTH_GPU_0 0xb04
#define MC_MIN_LENGTH_ETR_0 0xb44
#define MC_MIN_LENGTH_AFI_0 0x88c
#define MC_MIN_LENGTH_PPCS_0 0x8f0
#define MC_MIN_LENGTH_ISP2_1 0x920
#define MC_MIN_LENGTH_XUSB_0 0x928
#define MC_MIN_LENGTH_MPCORE_0 0x8cc
#define MC_MIN_LENGTH_TSECB_0 0xb48
#define MC_MIN_LENGTH_SDMMCA_0 0xb10
#define MC_MIN_LENGTH_GPU2_0 0xb40
#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c
#define MC_MIN_LENGTH_PTC_0 0x8f8
#define MC_EMEM_ARB_OVERRIDE_1 0x968
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988
#define MC_EMEM_ARB_STATS_0 0x990
#define MC_EMEM_ARB_STATS_1 0x994
#define MC_MTS_CARVEOUT_BOM 0x9a0
#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4
#define MC_MTS_CARVEOUT_ADR_HI 0x9a8
#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac
#define MC_ERR_MTS_STATUS 0x9b0
#define MC_ERR_MTS_ADR 0x9b4
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74
#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10
#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c
#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4
#define MC_SECURITY_CARVEOUT2_CFG0 0xc58
#define MC_SECURITY_CARVEOUT1_CFG0 0xc08
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68
#define MC_SECURITY_CARVEOUT3_BOM 0xcac
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60
#define MC_SECURITY_CARVEOUT3_CFG0 0xca8
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88
#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64
#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50
#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14
#define MC_SECURITY_CARVEOUT1_BOM 0xc0c
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c
#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8
#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60
#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80
#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc
#define MC_SECURITY_CARVEOUT4_BOM 0xcfc
#define MC_SECURITY_CARVEOUT5_CFG0 0xd48
#define MC_SECURITY_CARVEOUT2_BOM 0xc5c
#define MC_SECURITY_CARVEOUT5_BOM 0xd4c
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0
#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
#define MC_DA_CONFIG0 0x9dc
#define MC_UNTRANSLATED_REGION_CHECK 0x948
/* Memory Controller clients */
#define CLIENT_ACCESS_NUM_CLIENTS 32
typedef enum {
/* _ACCESS0 */
CSR_PTCR = (0 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0A = (1 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0AB = (2 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0B = (3 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0BB = (4 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0C = (5 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0CB = (6 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_AFIR = (14 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_AVPCARM7R = (15 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAYHC = (16 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAYHCB = (17 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_HDAR = (21 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_HOST1XDMAR = (22 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_HOST1XR = (23 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_NVENCSRD = (28 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_PPCSAHBDMAR = (29 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_PPCSAHBSLVR = (30 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_SATAR = (31 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
/* _ACCESS1 */
CSR_VDEBSEVR = (34 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSR_VDEMBER = (35 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSR_VDEMCER = (36 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSR_VDETPER = (37 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSR_MPCORELPR = (38 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSR_MPCORER = (39 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_NVENCSWR = (43 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_AFIW = (49 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_AVPCARM7W = (50 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_HDAW = (53 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_HOST1XW = (54 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_MPCORELPW = (56 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_MPCOREW = (57 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_PPCSAHBDMAW = (59 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_PPCSAHBSLVW = (60 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_SATAW = (61 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_VDEBSEVW = (62 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_VDEDBGW = (63 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
/* _ACCESS2 */
CSW_VDEMBEW = (64 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_VDETPMW = (65 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_ISPRA = (68 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_ISPWA = (70 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_ISPWB = (71 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_XUSB_HOSTR = (74 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_XUSB_HOSTW = (75 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_XUSB_DEVR = (76 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_XUSB_DEVW = (77 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_ISPRAB = (78 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_ISPWAB = (80 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_ISPWBB = (81 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_TSECSRD = (84 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_TSECSWR = (85 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_A9AVPSCR = (86 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_A9AVPSCW = (87 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_GPUSRD = (88 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_GPUSWR = (89 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_DISPLAYT = (90 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
/* _ACCESS3 */
CSR_SDMMCRA = (96 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_SDMMCRAA = (97 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_SDMMCR = (98 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_SDMMCRAB = (99 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_SDMMCWA = (100 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_SDMMCWAA = (101 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_SDMMCW = (102 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_SDMMCWAB = (103 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_VICSRD = (108 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_VICSWR = (109 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_VIW = (114 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_DISPLAYD = (115 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_NVDECSRD = (120 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_NVDECSWR = (121 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_APER = (122 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_APEW = (123 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_NVJPGSRD = (126 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_NVJPGSWR = (127 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
/* _ACCESS4 */
CSR_SESRD = (128 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSW_SESWR = (129 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSR_AXIAPR = (130 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSW_AXIAPW = (131 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSR_ETRR = (132 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSW_ETRW = (133 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSR_TSECSRDB = (134 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSW_TSECSWRB = (135 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSR_GPUSRD2 = (136 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSW_GPUSWR2 = (137 - (CLIENT_ACCESS_NUM_CLIENTS * 4))
} McClient;
void mc_config_tsec_carveout(uint32_t bom, uint32_t size1mb, bool lock);
void mc_config_carveout();
void mc_config_carveout_finalize();
void mc_enable_ahb_redirect();
void mc_disable_ahb_redirect();
void mc_enable();
#endif

View File

@@ -1,249 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <stdio.h>
#include "panic.h"
#include "di.h"
#include "pmc.h"
#include "fuse.h"
#include "utils.h"
#include "fs_utils.h"
#include "../../../fusee/common/log.h"
#include "../../../fusee/common/display/video_fb.h"
#define PROGRAM_ID_AMS_MITM 0x010041544D530000ull
#define PROGRAM_ID_BOOT 0x0100000000000005ull
static uint32_t g_panic_code = 0;
static const char *get_error_desc_str(uint32_t error_desc) {
switch (error_desc) {
case 0x100:
return "Instruction Abort";
case 0x101:
return "Data Abort";
case 0x102:
return "PC Misalignment";
case 0x103:
return "SP Misalignment";
case 0x104:
return "Trap";
case 0x106:
return "SError";
case 0x301:
return "Bad SVC";
case 0xF00:
return "Kernel Panic";
case 0xFFD:
return "Stack overflow";
case 0xFFE:
return "std::abort() called";
default:
return "Unknown";
}
}
static void _try_suggest_fix(const atmosphere_fatal_error_ctx *ctx) {
/* Try to recognize certain errors automatically, and suggest fixes for them. */
const char *suggestion = NULL;
if (ctx->error_desc == 0xFFE) {
if (ctx->program_id == PROGRAM_ID_AMS_MITM) {
/* When a user has archive bits set improperly, attempting to create an automatic backup will fail */
/* to create the file path with error 0x202 (fs::ResultPathNotFound()) */
if (ctx->gprs[0] == 0x202) {
/* When the archive bit error is occurring, it manifests as failure to create automatic backup. */
/* Thus, we can search the stack for the automatic backups path. */
const char * const automatic_backups_prefix = "automatic_backups/X" /* ..... */;
const int prefix_len = strlen(automatic_backups_prefix);
for (size_t i = 0; i + prefix_len < ctx->stack_dump_size; ++i) {
if (memcmp(&ctx->stack_dump[i], automatic_backups_prefix, prefix_len) == 0) {
suggestion = "The atmosphere directory may improperly have archive\n"
"bits set. Please try running an archive bit fixer tool\n"
"(for example, the one in Hekate).\n";
break;
}
}
} else if (ctx->gprs[0] == 0x249A02) { /* fs::ResultResultExFatUnavailable() */
/* When a user installs non-exFAT firm but has an exFAT formatted SD card, this error will */
/* be returned on attempt to access the SD card. */
suggestion = "Your console has non-exFAT firmware installed, but your SD card\n"
"is formatted as exFAT. Format your SD card as FAT32, or manually\n"
"flash exFAT firmware to package2.\n";
}
} else if (ctx->program_id == PROGRAM_ID_BOOT) {
/* 9.x -> 10.x updated the API for SvcQueryIoMapping. */
/* This can cause the kernel to reject incorrect-ABI calls by boot when a partial update is applied */
/* (older kernel in package2, for some reason). */
for (size_t i = 0; i < 8; ++i) {
if (ctx->gprs[i] == 0xF201) {
suggestion = "A partial update may have been improperly performed.\n"
"To fix, try manually flashing latest package2 to MMC.\n"
"\n"
"For help doing this, seek support in the ReSwitched or\n"
"Nintendo Homebrew discord servers.\n";
break;
}
}
}
} else if (ctx->error_desc == 0xF00) { /* Kernel Panic */
suggestion = "Please contact SciresM#0524 on Discord, or create an issue\n"
"on the Atmosphere GitHub issue tracker. Thank you very much\n"
"for helping to test mesosphere.\n";
}
if (suggestion != NULL) {
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\n%s", suggestion);
}
}
static void _check_and_display_atmosphere_fatal_error(void) {
/* Check for valid magic. */
if (ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC &&
ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 &&
ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0)
{
return;
}
{
/* Zero-fill the framebuffer and register it as printk provider. */
video_init((void *)0xC0000000);
/* Initialize the display. */
display_init();
/* Set the framebuffer. */
display_init_framebuffer((void *)0xC0000000);
/* Turn on the backlight after initializing the lfb */
/* to avoid flickering. */
display_backlight(true);
/* Override the global logging level. */
log_set_log_level(SCREEN_LOG_LEVEL_ERROR);
/* Copy fatal error context to the stack. */
atmosphere_fatal_error_ctx ctx = *(ATMOSPHERE_FATAL_ERROR_CONTEXT);
/* Change magic to invalid, to prevent double-display of error/bootlooping. */
ATMOSPHERE_FATAL_ERROR_CONTEXT->magic = 0xCCCCCCCC;
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "A fatal error occurred when running Atmosph\xe8re.\n");
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Program ID: %016llx\n", ctx.program_id);
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Error Desc: %s (0x%x)\n", get_error_desc_str(ctx.error_desc), ctx.error_desc);
/* Save context to the SD card. */
{
char filepath[0x40];
snprintf(filepath, sizeof(filepath) - 1, "/atmosphere/fatal_errors/report_%016llx.bin", ctx.report_identifier);
filepath[sizeof(filepath)-1] = 0;
if (write_to_file(&ctx, sizeof(ctx), filepath) != sizeof(ctx)) {
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Failed to save report to the SD card!\n");
} else {
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Report saved to %s\n", filepath);
}
}
/* Try to print a fix suggestion via automatic error detection. */
_try_suggest_fix(&ctx);
/* Display error. */
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nPress POWER to reboot\n");
}
/* Wait for button and reboot. */
wait_for_button_and_reboot();
}
void check_and_display_panic(void) {
/* Handle a panic sent via a stratosphere module. */
_check_and_display_atmosphere_fatal_error();
/* We also handle our own panics. */
bool has_panic = ((APBDEV_PMC_RST_STATUS_0 != 0) || (g_panic_code != 0));
uint32_t code = (g_panic_code == 0) ? APBDEV_PMC_SCRATCH200_0 : g_panic_code;
has_panic = has_panic && !((APBDEV_PMC_RST_STATUS_0 != 1) && (code == PANIC_CODE_SAFEMODE));
if (has_panic) {
uint32_t color;
/* Check for predefined codes: */
switch (code & MASK(20)) {
case 0x01: /* Package2 signature verification failed. */
case 0x02: /* Package2 meta verification failed. */
case 0x03: /* Package2 version check failed. */
case 0x04: /* Package2 payload verification failed. */
color = PANIC_COLOR_KERNEL;
break;
case 0x05: /* Unknown SMC. */
case 0x06: /* Unknown Abort. */
color = PANIC_COLOR_SECMON_GENERIC;
break;
case 0x07: /* Invalid CPU context. */
case 0x08: /* Invalid SE state. */
case 0x09: /* CPU is already awake (2.0.0+). */
color = PANIC_COLOR_SECMON_DEEPSLEEP;
break;
case 0x10: /* Unknown exception. */
color = PANIC_COLOR_SECMON_EXCEPTION;
break;
case 0x30: /* General bootloader error. */
case 0x31: /* Invalid DRAM ID. */
case 0x32: /* Invalid size. */
case 0x33: /* Invalid arguement. */
case 0x34: /* Bad GPT. */
case 0x35: /* Failed to boot SafeMode. */
case 0x36: /* Activity monitor fired (4.0.0+). */
color = PANIC_COLOR_BOOTLOADER_GENERIC;
break;
case 0x40: /* Kernel panic. */
color = PANIC_COLOR_KERNEL;
break;
default:
color = code >> 20;
color |= color << 4;
break;
}
/* Initialize the display. */
display_init();
/* Fill the screen. */
display_color_screen(color);
/* Wait for button and reboot. */
wait_for_button_and_reboot();
} else {
g_panic_code = 0;
APBDEV_PMC_SCRATCH200_0 = 0;
}
}
__attribute__ ((noreturn)) void panic(uint32_t code) {
/* Set panic code. */
if (g_panic_code == 0) {
g_panic_code = code;
APBDEV_PMC_SCRATCH200_0 = code;
}
fuse_disable_programming();
APBDEV_PMC_CRYPTO_OP_0 = 1; /* Disable all SE operations. */
check_and_display_panic();
while(true);
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_PANIC_H
#define FUSEE_PANIC_H
#include <stdint.h>
#define PANIC_COLOR_KERNEL 0x0000FF
#define PANIC_COLOR_SECMON_EXCEPTION 0xFF7700
#define PANIC_COLOR_SECMON_GENERIC 0x00FFFF
#define PANIC_COLOR_SECMON_DEEPSLEEP 0xFF77FF /* 4.0+ color */
#define PANIC_COLOR_BOOTLOADER_GENERIC 0xAA00FF
#define PANIC_COLOR_BOOTLOADER_SAFEMODE 0xFFFFAA /* Removed */
#define PANIC_CODE_SAFEMODE 0x00000020
#define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20
#define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100
#define AMS_FATAL_ERROR_TLS_SIZE 0x100
/* Atmosphere reboot-to-fatal-error. */
typedef struct {
uint32_t magic;
uint32_t error_desc;
uint64_t program_id;
union {
uint64_t gprs[32];
struct {
uint64_t _gprs[29];
uint64_t fp;
uint64_t lr;
uint64_t sp;
};
};
uint64_t pc;
uint64_t module_base;
uint32_t pstate;
uint32_t afsr0;
uint32_t afsr1;
uint32_t esr;
uint64_t far;
uint64_t report_identifier; /* Normally just system tick. */
uint64_t stack_trace_size;
uint64_t stack_dump_size;
uint64_t stack_trace[AMS_FATAL_ERROR_MAX_STACKTRACE];
uint8_t stack_dump[AMS_FATAL_ERROR_MAX_STACKDUMP];
uint8_t tls[AMS_FATAL_ERROR_TLS_SIZE];
} atmosphere_fatal_error_ctx;
/* "AFE2" */
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC 0x32454641
/* "AFE1" */
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 0x31454641
/* "AFE0" */
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0 0x30454641
#define ATMOSPHERE_FATAL_ERROR_CONTEXT ((volatile atmosphere_fatal_error_ctx *)(0x4003E000))
void check_and_display_panic(void);
__attribute__ ((noreturn)) void panic(uint32_t code);
#endif

View File

@@ -1,39 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_PANIC_COLOR_H
#define FUSEE_PANIC_COLOR_H
#define COLOR_0 0x00F00003
#define COLOR_1 0x0F000003
#define COLOR_2 0xF0000003
#define COLOR_3 0x0FF00003
#define COLOR_4 0xF0F00003
#define COLOR_5 0xFF000003
#define COLOR_6 0xFFF00003
#define COLOR_7 0xAAF00003
#define COLOR_8 0xAFA00003
#define COLOR_9 0xFAA00003
#define COLOR_A 0x33300003
#define COLOR_B 0x06F00003
#define COLOR_C 0x14800003
#define COLOR_D 0x00300003
#define COLOR_E 0x03000003
#define COLOR_F 0xB6000003
#define PANIC_REBOOT 0x20
#endif

View File

@@ -1,211 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_PINMUX_H
#define FUSEE_PINMUX_H
#define PINMUX_BASE 0x70003000
#define MAKE_PINMUX_REG(n) MAKE_REG32(PINMUX_BASE + n)
#define PINMUX_TRISTATE (1 << 4)
#define PINMUX_PARKED (1 << 5)
#define PINMUX_INPUT (1 << 6)
#define PINMUX_PULL_NONE (0 << 2)
#define PINMUX_PULL_DOWN (1 << 2)
#define PINMUX_PULL_UP (2 << 2)
#define PINMUX_SELECT_FUNCTION0 0
#define PINMUX_SELECT_FUNCTION1 1
#define PINMUX_SELECT_FUNCTION2 2
#define PINMUX_SELECT_FUNCTION3 3
#define PINMUX_DRIVE_1X (0 << 13)
#define PINMUX_DRIVE_2X (1 << 13)
#define PINMUX_DRIVE_3X (2 << 13)
#define PINMUX_DRIVE_4X (3 << 13)
typedef struct {
uint32_t sdmmc1_clk;
uint32_t sdmmc1_cmd;
uint32_t sdmmc1_dat3;
uint32_t sdmmc1_dat2;
uint32_t sdmmc1_dat1;
uint32_t sdmmc1_dat0;
uint32_t _r18;
uint32_t sdmmc3_clk;
uint32_t sdmmc3_cmd;
uint32_t sdmmc3_dat0;
uint32_t sdmmc3_dat1;
uint32_t sdmmc3_dat2;
uint32_t sdmmc3_dat3;
uint32_t _r34;
uint32_t pex_l0_rst_n;
uint32_t pex_l0_clkreq_n;
uint32_t pex_wake_n;
uint32_t pex_l1_rst_n;
uint32_t pex_l1_clkreq_n;
uint32_t sata_led_active;
uint32_t spi1_mosi;
uint32_t spi1_miso;
uint32_t spi1_sck;
uint32_t spi1_cs0;
uint32_t spi1_cs1;
uint32_t spi2_mosi;
uint32_t spi2_miso;
uint32_t spi2_sck;
uint32_t spi2_cs0;
uint32_t spi2_cs1;
uint32_t spi4_mosi;
uint32_t spi4_miso;
uint32_t spi4_sck;
uint32_t spi4_cs0;
uint32_t qspi_sck;
uint32_t qspi_cs_n;
uint32_t qspi_io0;
uint32_t qspi_io1;
uint32_t qspi_io2;
uint32_t qspi_io3;
uint32_t _ra0;
uint32_t dmic1_clk;
uint32_t dmic1_dat;
uint32_t dmic2_clk;
uint32_t dmic2_dat;
uint32_t dmic3_clk;
uint32_t dmic3_dat;
uint32_t gen1_i2c_scl;
uint32_t gen1_i2c_sda;
uint32_t gen2_i2c_scl;
uint32_t gen2_i2c_sda;
uint32_t gen3_i2c_scl;
uint32_t gen3_i2c_sda;
uint32_t cam_i2c_scl;
uint32_t cam_i2c_sda;
uint32_t pwr_i2c_scl;
uint32_t pwr_i2c_sda;
uint32_t uart1_tx;
uint32_t uart1_rx;
uint32_t uart1_rts;
uint32_t uart1_cts;
uint32_t uart2_tx;
uint32_t uart2_rx;
uint32_t uart2_rts;
uint32_t uart2_cts;
uint32_t uart3_tx;
uint32_t uart3_rx;
uint32_t uart3_rts;
uint32_t uart3_cts;
uint32_t uart4_tx;
uint32_t uart4_rx;
uint32_t uart4_rts;
uint32_t uart4_cts;
uint32_t dap1_fs;
uint32_t dap1_din;
uint32_t dap1_dout;
uint32_t dap1_sclk;
uint32_t dap2_fs;
uint32_t dap2_din;
uint32_t dap2_dout;
uint32_t dap2_sclk;
uint32_t dap4_fs;
uint32_t dap4_din;
uint32_t dap4_dout;
uint32_t dap4_sclk;
uint32_t cam1_mclk;
uint32_t cam2_mclk;
uint32_t jtag_rtck;
uint32_t clk_32k_in;
uint32_t clk_32k_out;
uint32_t batt_bcl;
uint32_t clk_req;
uint32_t cpu_pwr_req;
uint32_t pwr_int_n;
uint32_t shutdown;
uint32_t core_pwr_req;
uint32_t aud_mclk;
uint32_t dvfs_pwm;
uint32_t dvfs_clk;
uint32_t gpio_x1_aud;
uint32_t gpio_x3_aud;
uint32_t pcc7;
uint32_t hdmi_cec;
uint32_t hdmi_int_dp_hpd;
uint32_t spdif_out;
uint32_t spdif_in;
uint32_t usb_vbus_en0;
uint32_t usb_vbus_en1;
uint32_t dp_hpd0;
uint32_t wifi_en;
uint32_t wifi_rst;
uint32_t wifi_wake_ap;
uint32_t ap_wake_bt;
uint32_t bt_rst;
uint32_t bt_wake_ap;
uint32_t ap_wake_nfc;
uint32_t nfc_en;
uint32_t nfc_int;
uint32_t gps_en;
uint32_t gps_rst;
uint32_t cam_rst;
uint32_t cam_af_en;
uint32_t cam_flash_en;
uint32_t cam1_pwdn;
uint32_t cam2_pwdn;
uint32_t cam1_strobe;
uint32_t lcd_te;
uint32_t lcd_bl_pwm;
uint32_t lcd_bl_en;
uint32_t lcd_rst;
uint32_t lcd_gpio1;
uint32_t lcd_gpio2;
uint32_t ap_ready;
uint32_t touch_rst;
uint32_t touch_clk;
uint32_t modem_wake_ap;
uint32_t touch_int;
uint32_t motion_int;
uint32_t als_prox_int;
uint32_t temp_alert;
uint32_t button_power_on;
uint32_t button_vol_up;
uint32_t button_vol_down;
uint32_t button_slide_sw;
uint32_t button_home;
uint32_t pa6;
uint32_t pe6;
uint32_t pe7;
uint32_t ph6;
uint32_t pk0;
uint32_t pk1;
uint32_t pk2;
uint32_t pk3;
uint32_t pk4;
uint32_t pk5;
uint32_t pk6;
uint32_t pk7;
uint32_t pl0;
uint32_t pl1;
uint32_t pz0;
uint32_t pz1;
uint32_t pz2;
uint32_t pz3;
uint32_t pz4;
uint32_t pz5;
} tegra_pinmux_t;
static inline volatile tegra_pinmux_t *pinmux_get_regs(void)
{
return (volatile tegra_pinmux_t *)PINMUX_BASE;
}
#endif

View File

@@ -1,713 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_PMC_H
#define FUSEE_PMC_H
#include <stdint.h>
#define PMC_BASE 0x7000E400
#define MAKE_PMC_REG(n) MAKE_REG32(PMC_BASE + n)
#define PMC_CONTROL_SDMMC1 (1 << 12)
#define PMC_CONTROL_SDMMC3 (1 << 13)
#define PMC_CONTROL_SDMMC4 (1 << 14)
#define APBDEV_PMC_CONTROL MAKE_PMC_REG(0x00)
#define APBDEV_PM_0 MAKE_PMC_REG(0x14)
#define APBDEV_PMC_DPD_ENABLE_0 MAKE_PMC_REG(0x24)
#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x30)
#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x38)
#define APBDEV_PMC_NO_IOPOWER_0 MAKE_PMC_REG(0x44)
#define APBDEV_PMC_SCRATCH0_0 MAKE_PMC_REG(0x50)
#define APBDEV_PMC_SCRATCH1_0 MAKE_PMC_REG(0x54)
#define APBDEV_PMC_SCRATCH20_0 MAKE_PMC_REG(0xA0)
#define APBDEV_PMC_PWR_DET_VAL_0 MAKE_PMC_REG(0xE4)
#define APBDEV_PMC_DDR_PWR_0 MAKE_PMC_REG(0xE8)
#define APBDEV_PMC_CRYPTO_OP_0 MAKE_PMC_REG(0xF4)
#define APBDEV_PMC_WAKE2_STATUS_0 MAKE_PMC_REG(0x168)
#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4)
#define APBDEV_PMC_RST_STATUS_0 MAKE_PMC_REG(0x1B4)
#define APBDEV_PMC_IO_DPD_REQ_0 MAKE_PMC_REG(0x1B8)
#define APBDEV_PMC_IO_DPD2_REQ_0 MAKE_PMC_REG(0x1C0)
#define APBDEV_PMC_VDDP_SEL_0 MAKE_PMC_REG(0x1CC)
#define APBDEV_PMC_SCRATCH49_0 MAKE_PMC_REG(0x244)
#define APBDEV_PMC_TSC_MULT_0 MAKE_PMC_REG(0x2B4)
#define APBDEV_PMC_REG_SHORT_0 MAKE_PMC_REG(0x2CC)
#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8)
#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334)
#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360)
#define APBDEV_PMC_SECURE_SCRATCH49_0 MAKE_PMC_REG(0x3A4)
#define APBDEV_PMC_CNTRL2_0 MAKE_PMC_REG(0x440)
#define APBDEV_PMC_IO_DPD4_REQ_0 MAKE_PMC_REG(0x464)
#define APBDEV_PMC_UTMIP_PAD_CFG1_0 MAKE_PMC_REG(0x4C4)
#define APBDEV_PMC_UTMIP_PAD_CFG3_0 MAKE_PMC_REG(0x4CC)
#define APBDEV_PMC_DDR_CNTRL_0 MAKE_PMC_REG(0x4E4)
#define APBDEV_PMC_SCRATCH43_0 MAKE_PMC_REG(0x22C)
#define APBDEV_PMC_SCRATCH188_0 MAKE_PMC_REG(0x810)
#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818)
#define APBDEV_PMC_SCRATCH200_0 MAKE_PMC_REG(0x840)
#define APBDEV_PMC_SCRATCH45_0 MAKE_PMC_REG(0x234)
#define APBDEV_PMC_SCRATCH46_0 MAKE_PMC_REG(0x238)
#define APBDEV_PMC_SCRATCH33_0 MAKE_PMC_REG(0x120)
#define APBDEV_PMC_SCRATCH40_0 MAKE_PMC_REG(0x13C)
/* Power Management Controller (APBDEV_PMC_) regs */
typedef struct {
uint32_t cntrl; /* _CNTRL_0, 0x00 */
uint32_t sec_disable; /* _SEC_DISABLE_0, 0x04 */
uint32_t pmc_swrst; /* _PMC_SWRST_0, 0x08 */
uint32_t wake_mask; /* _WAKE_MASK_0, 0x0c */
uint32_t wake_lvl; /* _WAKE_LVL_0, 0x10 */
uint32_t wake_status; /* _WAKE_STATUS_0, 0x14 */
uint32_t sw_wake_status; /* _SW_WAKE_STATUS_0, 0x18 */
uint32_t dpd_pads_oride; /* _DPD_PADS_ORIDE_0, 0x1c */
uint32_t dpd_sample; /* _DPD_SAMPLE_0, 0x20 */
uint32_t dpd_enable; /* _DPD_ENABLE_0, 0x24 */
uint32_t pwrgate_timer_off; /* _PWRGATE_TIMER_OFF_0, 0x28 */
uint32_t clamp_status; /* _CLAMP_STATUS_0, 0x2c */
uint32_t pwrgate_toggle; /* _PWRGATE_TOGGLE_0, 0x30 */
uint32_t remove_clamping; /* _REMOVE_CLAMPING_0, 0x34 */
uint32_t pwrgate_status; /* _PWRGATE_STATUS_0, 0x38 */
uint32_t pwrgood_timer; /* _PWRGOOD_TIMER_0, 0x3c */
uint32_t blink_timer; /* _BLINK_TIMER_0, 0x40 */
uint32_t no_iopower; /* _NO_IOPOWER_0, 0x44 */
uint32_t pwr_det; /* _PWR_DET_0, 0x48 */
uint32_t pwr_det_latch; /* _PWR_DET_LATCH_0, 0x4c */
uint32_t scratch0; /* _SCRATCH0_0, 0x50 */
uint32_t scratch1; /* _SCRATCH1_0, 0x54 */
uint32_t scratch2; /* _SCRATCH2_0, 0x58 */
uint32_t scratch3; /* _SCRATCH3_0, 0x5c */
uint32_t scratch4; /* _SCRATCH4_0, 0x60 */
uint32_t scratch5; /* _SCRATCH5_0, 0x64 */
uint32_t scratch6; /* _SCRATCH6_0, 0x68 */
uint32_t scratch7; /* _SCRATCH7_0, 0x6c */
uint32_t scratch8; /* _SCRATCH8_0, 0x70 */
uint32_t scratch9; /* _SCRATCH9_0, 0x74 */
uint32_t scratch10; /* _SCRATCH10_0, 0x78 */
uint32_t scratch11; /* _SCRATCH11_0, 0x7c */
uint32_t scratch12; /* _SCRATCH12_0, 0x80 */
uint32_t scratch13; /* _SCRATCH13_0, 0x84 */
uint32_t scratch14; /* _SCRATCH14_0, 0x88 */
uint32_t scratch15; /* _SCRATCH15_0, 0x8c */
uint32_t scratch16; /* _SCRATCH16_0, 0x90 */
uint32_t scratch17; /* _SCRATCH17_0, 0x94 */
uint32_t scratch18; /* _SCRATCH18_0, 0x98 */
uint32_t scratch19; /* _SCRATCH19_0, 0x9c */
uint32_t scratch20; /* _SCRATCH20_0, 0xa0 */
uint32_t scratch21; /* _SCRATCH21_0, 0xa4 */
uint32_t scratch22; /* _SCRATCH22_0, 0xa8 */
uint32_t scratch23; /* _SCRATCH23_0, 0xac */
uint32_t secure_scratch0; /* _SECURE_SCRATCH0_0, 0xb0 */
uint32_t secure_scratch1; /* _SECURE_SCRATCH1_0, 0xb4 */
uint32_t secure_scratch2; /* _SECURE_SCRATCH2_0, 0xb8 */
uint32_t secure_scratch3; /* _SECURE_SCRATCH3_0, 0xbc */
uint32_t secure_scratch4; /* _SECURE_SCRATCH4_0, 0xc0 */
uint32_t secure_scratch5; /* _SECURE_SCRATCH5_0, 0xc4 */
uint32_t cpupwrgood_timer; /* _CPUPWRGOOD_TIMER_0, 0xc8 */
uint32_t cpupwroff_timer; /* _CPUPWROFF_TIMER_0, 0xcc */
uint32_t pg_mask; /* _PG_MASK_0, 0xd0 */
uint32_t pg_mask_1; /* _PG_MASK_1_0, 0xd4 */
uint32_t auto_wake_lvl; /* _AUTO_WAKE_LVL_0, 0xd8 */
uint32_t auto_wake_lvl_mask; /* _AUTO_WAKE_LVL_MASK_0, 0xdc */
uint32_t wake_delay; /* _WAKE_DELAY_0, 0xe0 */
uint32_t pwr_det_val; /* _PWR_DET_VAL_0, 0xe4 */
uint32_t ddr_pwr; /* _DDR_PWR_0, 0xe8 */
uint32_t usb_debounce_del; /* _USB_DEBOUNCE_DEL_0, 0xec */
uint32_t usb_ao; /* _USB_AO_0, 0xf0 */
uint32_t crypto_op; /* _CRYPTO_OP_0, 0xf4 */
uint32_t pllp_wb0_override; /* _PLLP_WB0_OVERRIDE_0, 0xf8 */
uint32_t scratch24; /* _SCRATCH24_0, 0xfc */
uint32_t scratch25; /* _SCRATCH25_0, 0x100 */
uint32_t scratch26; /* _SCRATCH26_0, 0x104 */
uint32_t scratch27; /* _SCRATCH27_0, 0x108 */
uint32_t scratch28; /* _SCRATCH28_0, 0x10c */
uint32_t scratch29; /* _SCRATCH29_0, 0x110 */
uint32_t scratch30; /* _SCRATCH30_0, 0x114 */
uint32_t scratch31; /* _SCRATCH31_0, 0x118 */
uint32_t scratch32; /* _SCRATCH32_0, 0x11c */
uint32_t scratch33; /* _SCRATCH33_0, 0x120 */
uint32_t scratch34; /* _SCRATCH34_0, 0x124 */
uint32_t scratch35; /* _SCRATCH35_0, 0x128 */
uint32_t scratch36; /* _SCRATCH36_0, 0x12c */
uint32_t scratch37; /* _SCRATCH37_0, 0x130 */
uint32_t scratch38; /* _SCRATCH38_0, 0x134 */
uint32_t scratch39; /* _SCRATCH39_0, 0x138 */
uint32_t scratch40; /* _SCRATCH40_0, 0x13c */
uint32_t scratch41; /* _SCRATCH41_0, 0x140 */
uint32_t scratch42; /* _SCRATCH42_0, 0x144 */
uint32_t bondout_mirror0; /* _BONDOUT_MIRROR0_0, 0x148 */
uint32_t bondout_mirror1; /* _BONDOUT_MIRROR1_0, 0x14c */
uint32_t bondout_mirror2; /* _BONDOUT_MIRROR2_0, 0x150 */
uint32_t sys_33v_en; /* _SYS_33V_EN_0, 0x154 */
uint32_t bondout_mirror_access; /* _BONDOUT_MIRROR_ACCESS_0, 0x158 */
uint32_t gate; /* _GATE_0, 0x15c */
uint32_t wake2_mask; /* _WAKE2_MASK_0, 0x160 */
uint32_t wake2_lvl; /* _WAKE2_LVL_0, 0x164 */
uint32_t wake2_status; /* _WAKE2_STATUS_0, 0x168 */
uint32_t sw_wake2_status; /* _SW_WAKE2_STATUS_0, 0x16c */
uint32_t auto_wake2_lvl_mask; /* _AUTO_WAKE2_LVL_MASK_0, 0x170 */
uint32_t pg_mask_2; /* _PG_MASK_2_0, 0x174 */
uint32_t pg_mask_ce1; /* _PG_MASK_CE1_0, 0x178 */
uint32_t pg_mask_ce2; /* _PG_MASK_CE2_0, 0x17c */
uint32_t pg_mask_ce3; /* _PG_MASK_CE3_0, 0x180 */
uint32_t pwrgate_timer_ce_0; /* _PWRGATE_TIMER_CE_0_0, 0x184 */
uint32_t pwrgate_timer_ce_1; /* _PWRGATE_TIMER_CE_1_0, 0x188 */
uint32_t pwrgate_timer_ce_2; /* _PWRGATE_TIMER_CE_2_0, 0x18c */
uint32_t pwrgate_timer_ce_3; /* _PWRGATE_TIMER_CE_3_0, 0x190 */
uint32_t pwrgate_timer_ce_4; /* _PWRGATE_TIMER_CE_4_0, 0x194 */
uint32_t pwrgate_timer_ce_5; /* _PWRGATE_TIMER_CE_5_0, 0x198 */
uint32_t pwrgate_timer_ce_6; /* _PWRGATE_TIMER_CE_6_0, 0x19c */
uint32_t pcx_edpd_cntrl; /* _PCX_EDPD_CNTRL_0, 0x1a0 */
uint32_t osc_edpd_over; /* _OSC_EDPD_OVER_0, 0x1a4 */
uint32_t clk_out_cntrl; /* _CLK_OUT_CNTRL_0, 0x1a8 */
uint32_t sata_pwrgt; /* _SATA_PWRGT_0, 0x1ac */
uint32_t sensor_ctrl; /* _SENSOR_CTRL_0, 0x1b0 */
uint32_t rst_status; /* _RST_STATUS_0, 0x1b4 */
uint32_t io_dpd_req; /* _IO_DPD_REQ_0, 0x1b8 */
uint32_t io_dpd_status; /* _IO_DPD_STATUS_0, 0x1bc */
uint32_t io_dpd2_req; /* _IO_DPD2_REQ_0, 0x1c0 */
uint32_t io_dpd2_status; /* _IO_DPD2_STATUS_0, 0x1c4 */
uint32_t sel_dpd_tim; /* _SEL_DPD_TIM_0, 0x1c8 */
uint32_t vddp_sel; /* _VDDP_SEL_0, 0x1cc */
uint32_t ddr_cfg; /* _DDR_CFG_0, 0x1d0 */
uint32_t _0x1d4[2];
uint32_t pllm_wb0_override_freq; /* _PLLM_WB0_OVERRIDE_FREQ_0, 0x1dc */
uint32_t _0x1e0;
uint32_t pwrgate_timer_mult; /* _PWRGATE_TIMER_MULT_0, 0x1e4 */
uint32_t dsi_sel_dpd; /* _DSI_SEL_DPD_0, 0x1e8 */
uint32_t utmip_uhsic_triggers; /* _UTMIP_UHSIC_TRIGGERS_0, 0x1ec */
uint32_t utmip_uhsic_saved_state; /* _UTMIP_UHSIC_SAVED_STATE_0, 0x1f0 */
uint32_t _0x1f4;
uint32_t utmip_term_pad_cfg; /* _UTMIP_TERM_PAD_CFG_0, 0x1f8 */
uint32_t utmip_uhsic_sleep_cfg; /* _UTMIP_UHSIC_SLEEP_CFG_0, 0x1fc */
uint32_t utmip_uhsic_sleepwalk_cfg; /* _UTMIP_UHSIC_SLEEPWALK_CFG_0, 0x200 */
uint32_t utmip_sleepwalk_p0; /* _UTMIP_SLEEPWALK_P0_0, 0x204 */
uint32_t utmip_sleepwalk_p1; /* _UTMIP_SLEEPWALK_P1_0, 0x208 */
uint32_t utmip_sleepwalk_p2; /* _UTMIP_SLEEPWALK_P2_0, 0x20c */
uint32_t uhsic_sleepwalk_p0; /* _UHSIC_SLEEPWALK_P0_0, 0x210 */
uint32_t utmip_uhsic_status; /* _UTMIP_UHSIC_STATUS_0, 0x214 */
uint32_t utmip_uhsic_fake; /* _UTMIP_UHSIC_FAKE_0, 0x218 */
uint32_t bondout_mirror3; /* _BONDOUT_MIRROR3_0, 0x21c */
uint32_t bondout_mirror4; /* _BONDOUT_MIRROR4_0, 0x220 */
uint32_t secure_scratch6; /* _SECURE_SCRATCH6_0, 0x224 */
uint32_t secure_scratch7; /* _SECURE_SCRATCH7_0, 0x228 */
uint32_t scratch43; /* _SCRATCH43_0, 0x22c */
uint32_t scratch44; /* _SCRATCH44_0, 0x230 */
uint32_t scratch45; /* _SCRATCH45_0, 0x234 */
uint32_t scratch46; /* _SCRATCH46_0, 0x238 */
uint32_t scratch47; /* _SCRATCH47_0, 0x23c */
uint32_t scratch48; /* _SCRATCH48_0, 0x240 */
uint32_t scratch49; /* _SCRATCH49_0, 0x244 */
uint32_t scratch50; /* _SCRATCH50_0, 0x248 */
uint32_t scratch51; /* _SCRATCH51_0, 0x24c */
uint32_t scratch52; /* _SCRATCH52_0, 0x250 */
uint32_t scratch53; /* _SCRATCH53_0, 0x254 */
uint32_t scratch54; /* _SCRATCH54_0, 0x258 */
uint32_t scratch55; /* _SCRATCH55_0, 0x25c */
uint32_t scratch0_eco; /* _SCRATCH0_ECO_0, 0x260 */
uint32_t por_dpd_ctrl; /* _POR_DPD_CTRL_0, 0x264 */
uint32_t scratch2_eco; /* _SCRATCH2_ECO_0, 0x268 */
uint32_t utmip_uhsic_line_wakeup; /* _UTMIP_UHSIC_LINE_WAKEUP_0, 0x26c */
uint32_t utmip_bias_master_cntrl; /* _UTMIP_BIAS_MASTER_CNTRL_0, 0x270 */
uint32_t utmip_master_config; /* _UTMIP_MASTER_CONFIG_0, 0x274 */
uint32_t td_pwrgate_inter_part_timer; /* _TD_PWRGATE_INTER_PART_TIMER_0, 0x278 */
uint32_t utmip_uhsic2_triggers; /* _UTMIP_UHSIC2_TRIGGERS_0, 0x27c */
uint32_t utmip_uhsic2_saved_state; /* _UTMIP_UHSIC2_SAVED_STATE_0, 0x280 */
uint32_t utmip_uhsic2_sleep_cfg; /* _UTMIP_UHSIC2_SLEEP_CFG_0, 0x284 */
uint32_t utmip_uhsic2_sleepwalk_cfg; /* _UTMIP_UHSIC2_SLEEPWALK_CFG_0, 0x288 */
uint32_t uhsic2_sleepwalk_p1; /* _UHSIC2_SLEEPWALK_P1_0, 0x28c */
uint32_t utmip_uhsic2_status; /* _UTMIP_UHSIC2_STATUS_0, 0x290 */
uint32_t utmip_uhsic2_fake; /* _UTMIP_UHSIC2_FAKE_0, 0x294 */
uint32_t utmip_uhsic2_line_wakeup; /* _UTMIP_UHSIC2_LINE_WAKEUP_0, 0x298 */
uint32_t utmip_master2_config; /* _UTMIP_MASTER2_CONFIG_0, 0x29c */
uint32_t utmip_uhsic_rpd_cfg; /* _UTMIP_UHSIC_RPD_CFG_0, 0x2a0 */
uint32_t pg_mask_ce0; /* _PG_MASK_CE0_0, 0x2a4 */
uint32_t pg_mask_3; /* _PG_MASK_3_0, 0x2a8 */
uint32_t pg_mask_4; /* _PG_MASK_4_0, 0x2ac */
uint32_t pllm_wb0_override2; /* _PLLM_WB0_OVERRIDE2_0, 0x2b0 */
uint32_t tsc_mult; /* _TSC_MULT_0, 0x2b4 */
uint32_t cpu_vsense_override; /* _CPU_VSENSE_OVERRIDE_0, 0x2b8 */
uint32_t glb_amap_cfg; /* _GLB_AMAP_CFG_0, 0x2bc */
uint32_t sticky_bits; /* _STICKY_BITS_0, 0x2c0 */
uint32_t sec_disable2; /* _SEC_DISABLE2_0, 0x2c4 */
uint32_t weak_bias; /* _WEAK_BIAS_0, 0x2c8 */
uint32_t reg_short; /* _REG_SHORT_0, 0x2cc */
uint32_t pg_mask_andor; /* _PG_MASK_ANDOR_0, 0x2d0 */
uint32_t gpu_rg_cntrl; /* _GPU_RG_CNTRL_0, 0x2d4 */
uint32_t sec_disable3; /* _SEC_DISABLE3_0, 0x2d8 */
uint32_t pg_mask_5; /* _PG_MASK_5_0, 0x2dc */
uint32_t pg_mask_6; /* _PG_MASK_6_0, 0x2e0 */
uint32_t _0x2e4[7];
uint32_t secure_scratch8; /* _SECURE_SCRATCH8_0, 0x300 */
uint32_t secure_scratch9; /* _SECURE_SCRATCH9_0, 0x304 */
uint32_t secure_scratch10; /* _SECURE_SCRATCH10_0, 0x308 */
uint32_t secure_scratch11; /* _SECURE_SCRATCH11_0, 0x30c */
uint32_t secure_scratch12; /* _SECURE_SCRATCH12_0, 0x310 */
uint32_t secure_scratch13; /* _SECURE_SCRATCH13_0, 0x314 */
uint32_t secure_scratch14; /* _SECURE_SCRATCH14_0, 0x318 */
uint32_t secure_scratch15; /* _SECURE_SCRATCH15_0, 0x31c */
uint32_t secure_scratch16; /* _SECURE_SCRATCH16_0, 0x320 */
uint32_t secure_scratch17; /* _SECURE_SCRATCH17_0, 0x324 */
uint32_t secure_scratch18; /* _SECURE_SCRATCH18_0, 0x328 */
uint32_t secure_scratch19; /* _SECURE_SCRATCH19_0, 0x32c */
uint32_t secure_scratch20; /* _SECURE_SCRATCH20_0, 0x330 */
uint32_t secure_scratch21; /* _SECURE_SCRATCH21_0, 0x334 */
uint32_t secure_scratch22; /* _SECURE_SCRATCH22_0, 0x338 */
uint32_t secure_scratch23; /* _SECURE_SCRATCH23_0, 0x33c */
uint32_t secure_scratch24; /* _SECURE_SCRATCH24_0, 0x340 */
uint32_t secure_scratch25; /* _SECURE_SCRATCH25_0, 0x344 */
uint32_t secure_scratch26; /* _SECURE_SCRATCH26_0, 0x348 */
uint32_t secure_scratch27; /* _SECURE_SCRATCH27_0, 0x34c */
uint32_t secure_scratch28; /* _SECURE_SCRATCH28_0, 0x350 */
uint32_t secure_scratch29; /* _SECURE_SCRATCH29_0, 0x354 */
uint32_t secure_scratch30; /* _SECURE_SCRATCH30_0, 0x358 */
uint32_t secure_scratch31; /* _SECURE_SCRATCH31_0, 0x35c */
uint32_t secure_scratch32; /* _SECURE_SCRATCH32_0, 0x360 */
uint32_t secure_scratch33; /* _SECURE_SCRATCH33_0, 0x364 */
uint32_t secure_scratch34; /* _SECURE_SCRATCH34_0, 0x368 */
uint32_t secure_scratch35; /* _SECURE_SCRATCH35_0, 0x36c */
uint32_t secure_scratch36; /* _SECURE_SCRATCH36_0, 0x370 */
uint32_t secure_scratch37; /* _SECURE_SCRATCH37_0, 0x374 */
uint32_t secure_scratch38; /* _SECURE_SCRATCH38_0, 0x378 */
uint32_t secure_scratch39; /* _SECURE_SCRATCH39_0, 0x37c */
uint32_t secure_scratch40; /* _SECURE_SCRATCH40_0, 0x380 */
uint32_t secure_scratch41; /* _SECURE_SCRATCH41_0, 0x384 */
uint32_t secure_scratch42; /* _SECURE_SCRATCH42_0, 0x388 */
uint32_t secure_scratch43; /* _SECURE_SCRATCH43_0, 0x38c */
uint32_t secure_scratch44; /* _SECURE_SCRATCH44_0, 0x390 */
uint32_t secure_scratch45; /* _SECURE_SCRATCH45_0, 0x394 */
uint32_t secure_scratch46; /* _SECURE_SCRATCH46_0, 0x398 */
uint32_t secure_scratch47; /* _SECURE_SCRATCH47_0, 0x39c */
uint32_t secure_scratch48; /* _SECURE_SCRATCH48_0, 0x3a0 */
uint32_t secure_scratch49; /* _SECURE_SCRATCH49_0, 0x3a4 */
uint32_t secure_scratch50; /* _SECURE_SCRATCH50_0, 0x3a8 */
uint32_t secure_scratch51; /* _SECURE_SCRATCH51_0, 0x3ac */
uint32_t secure_scratch52; /* _SECURE_SCRATCH52_0, 0x3b0 */
uint32_t secure_scratch53; /* _SECURE_SCRATCH53_0, 0x3b4 */
uint32_t secure_scratch54; /* _SECURE_SCRATCH54_0, 0x3b8 */
uint32_t secure_scratch55; /* _SECURE_SCRATCH55_0, 0x3bc */
uint32_t secure_scratch56; /* _SECURE_SCRATCH56_0, 0x3c0 */
uint32_t secure_scratch57; /* _SECURE_SCRATCH57_0, 0x3c4 */
uint32_t secure_scratch58; /* _SECURE_SCRATCH58_0, 0x3c8 */
uint32_t secure_scratch59; /* _SECURE_SCRATCH59_0, 0x3cc */
uint32_t secure_scratch60; /* _SECURE_SCRATCH60_0, 0x3d0 */
uint32_t secure_scratch61; /* _SECURE_SCRATCH61_0, 0x3d4 */
uint32_t secure_scratch62; /* _SECURE_SCRATCH62_0, 0x3d8 */
uint32_t secure_scratch63; /* _SECURE_SCRATCH63_0, 0x3dc */
uint32_t secure_scratch64; /* _SECURE_SCRATCH64_0, 0x3e0 */
uint32_t secure_scratch65; /* _SECURE_SCRATCH65_0, 0x3e4 */
uint32_t secure_scratch66; /* _SECURE_SCRATCH66_0, 0x3e8 */
uint32_t secure_scratch67; /* _SECURE_SCRATCH67_0, 0x3ec */
uint32_t secure_scratch68; /* _SECURE_SCRATCH68_0, 0x3f0 */
uint32_t secure_scratch69; /* _SECURE_SCRATCH69_0, 0x3f4 */
uint32_t secure_scratch70; /* _SECURE_SCRATCH70_0, 0x3f8 */
uint32_t secure_scratch71; /* _SECURE_SCRATCH71_0, 0x3fc */
uint32_t secure_scratch72; /* _SECURE_SCRATCH72_0, 0x400 */
uint32_t secure_scratch73; /* _SECURE_SCRATCH73_0, 0x404 */
uint32_t secure_scratch74; /* _SECURE_SCRATCH74_0, 0x408 */
uint32_t secure_scratch75; /* _SECURE_SCRATCH75_0, 0x40c */
uint32_t secure_scratch76; /* _SECURE_SCRATCH76_0, 0x410 */
uint32_t secure_scratch77; /* _SECURE_SCRATCH77_0, 0x414 */
uint32_t secure_scratch78; /* _SECURE_SCRATCH78_0, 0x418 */
uint32_t secure_scratch79; /* _SECURE_SCRATCH79_0, 0x41c */
uint32_t _0x420[8];
uint32_t cntrl2; /* _CNTRL2_0, 0x440 */
uint32_t io_dpd_off_mask; /* _IO_DPD_OFF_MASK_0, 0x444 */
uint32_t io_dpd2_off_mask; /* _IO_DPD2_OFF_MASK_0, 0x448 */
uint32_t event_counter; /* _EVENT_COUNTER_0, 0x44c */
uint32_t fuse_control; /* _FUSE_CONTROL_0, 0x450 */
uint32_t scratch1_eco; /* _SCRATCH1_ECO_0, 0x454 */
uint32_t _0x458;
uint32_t io_dpd3_req; /* _IO_DPD3_REQ_0, 0x45c */
uint32_t io_dpd3_status; /* _IO_DPD3_STATUS_0, 0x460 */
uint32_t io_dpd4_req; /* _IO_DPD4_REQ_0, 0x464 */
uint32_t io_dpd4_status; /* _IO_DPD4_STATUS_0, 0x468 */
uint32_t _0x46c[2];
uint32_t direct_thermtrip_cfg; /* _DIRECT_THERMTRIP_CFG_0, 0x474 */
uint32_t tsosc_delay; /* _TSOSC_DELAY_0, 0x478 */
uint32_t set_sw_clamp; /* _SET_SW_CLAMP_0, 0x47c */
uint32_t debug_authentication; /* _DEBUG_AUTHENTICATION_0, 0x480 */
uint32_t aotag_cfg; /* _AOTAG_CFG_0, 0x484 */
uint32_t aotag_thresh1_cfg; /* _AOTAG_THRESH1_CFG_0, 0x488 */
uint32_t aotag_thresh2_cfg; /* _AOTAG_THRESH2_CFG_0, 0x48c */
uint32_t aotag_thresh3_cfg; /* _AOTAG_THRESH3_CFG_0, 0x490 */
uint32_t aotag_status; /* _AOTAG_STATUS_0, 0x494 */
uint32_t aotag_security; /* _AOTAG_SECURITY_0, 0x498 */
uint32_t tsensor_config0; /* _TSENSOR_CONFIG0_0, 0x49c */
uint32_t tsensor_config1; /* _TSENSOR_CONFIG1_0, 0x4a0 */
uint32_t tsensor_config2; /* _TSENSOR_CONFIG2_0, 0x4a4 */
uint32_t tsensor_status0; /* _TSENSOR_STATUS0_0, 0x4a8 */
uint32_t tsensor_status1; /* _TSENSOR_STATUS1_0, 0x4ac */
uint32_t tsensor_status2; /* _TSENSOR_STATUS2_0, 0x4b0 */
uint32_t tsensor_pdiv; /* _TSENSOR_PDIV_0, 0x4b4 */
uint32_t aotag_intr_en; /* _AOTAG_INTR_EN_0, 0x4b8 */
uint32_t aotag_intr_dis; /* _AOTAG_INTR_DIS_0, 0x4bc */
uint32_t utmip_pad_cfg0; /* _UTMIP_PAD_CFG0_0, 0x4c0 */
uint32_t utmip_pad_cfg1; /* _UTMIP_PAD_CFG1_0, 0x4c4 */
uint32_t utmip_pad_cfg2; /* _UTMIP_PAD_CFG2_0, 0x4c8 */
uint32_t utmip_pad_cfg3; /* _UTMIP_PAD_CFG3_0, 0x4cc */
uint32_t utmip_uhsic_sleep_cfg1; /* _UTMIP_UHSIC_SLEEP_CFG1_0, 0x4d0 */
uint32_t cc4_hvc_control; /* _CC4_HVC_CONTROL_0, 0x4d4 */
uint32_t wake_debounce_en; /* _WAKE_DEBOUNCE_EN_0, 0x4d8 */
uint32_t ramdump_ctl_status; /* _RAMDUMP_CTL_STATUS_0, 0x4dc */
uint32_t utmip_sleepwalk_p3; /* _UTMIP_SLEEPWALK_P3_0, 0x4e0 */
uint32_t ddr_cntrl; /* _DDR_CNTRL_0, 0x4e4 */
uint32_t _0x4e8[50];
uint32_t sec_disable4; /* _SEC_DISABLE4_0, 0x5b0 */
uint32_t sec_disable5; /* _SEC_DISABLE5_0, 0x5b4 */
uint32_t sec_disable6; /* _SEC_DISABLE6_0, 0x5b8 */
uint32_t sec_disable7; /* _SEC_DISABLE7_0, 0x5bc */
uint32_t sec_disable8; /* _SEC_DISABLE8_0, 0x5c0 */
uint32_t sec_disable9; /* _SEC_DISABLE9_0, 0x5c4 */
uint32_t sec_disable10; /* _SEC_DISABLE10_0, 0x5c8 */
uint32_t _0x5cc[13];
uint32_t scratch56; /* _SCRATCH56_0, 0x600 */
uint32_t scratch57; /* _SCRATCH57_0, 0x604 */
uint32_t scratch58; /* _SCRATCH58_0, 0x608 */
uint32_t scratch59; /* _SCRATCH59_0, 0x60c */
uint32_t scratch60; /* _SCRATCH60_0, 0x610 */
uint32_t scratch61; /* _SCRATCH61_0, 0x614 */
uint32_t scratch62; /* _SCRATCH62_0, 0x618 */
uint32_t scratch63; /* _SCRATCH63_0, 0x61c */
uint32_t scratch64; /* _SCRATCH64_0, 0x620 */
uint32_t scratch65; /* _SCRATCH65_0, 0x624 */
uint32_t scratch66; /* _SCRATCH66_0, 0x628 */
uint32_t scratch67; /* _SCRATCH67_0, 0x62c */
uint32_t scratch68; /* _SCRATCH68_0, 0x630 */
uint32_t scratch69; /* _SCRATCH69_0, 0x634 */
uint32_t scratch70; /* _SCRATCH70_0, 0x638 */
uint32_t scratch71; /* _SCRATCH71_0, 0x63c */
uint32_t scratch72; /* _SCRATCH72_0, 0x640 */
uint32_t scratch73; /* _SCRATCH73_0, 0x644 */
uint32_t scratch74; /* _SCRATCH74_0, 0x648 */
uint32_t scratch75; /* _SCRATCH75_0, 0x64c */
uint32_t scratch76; /* _SCRATCH76_0, 0x650 */
uint32_t scratch77; /* _SCRATCH77_0, 0x654 */
uint32_t scratch78; /* _SCRATCH78_0, 0x658 */
uint32_t scratch79; /* _SCRATCH79_0, 0x65c */
uint32_t scratch80; /* _SCRATCH80_0, 0x660 */
uint32_t scratch81; /* _SCRATCH81_0, 0x664 */
uint32_t scratch82; /* _SCRATCH82_0, 0x668 */
uint32_t scratch83; /* _SCRATCH83_0, 0x66c */
uint32_t scratch84; /* _SCRATCH84_0, 0x670 */
uint32_t scratch85; /* _SCRATCH85_0, 0x674 */
uint32_t scratch86; /* _SCRATCH86_0, 0x678 */
uint32_t scratch87; /* _SCRATCH87_0, 0x67c */
uint32_t scratch88; /* _SCRATCH88_0, 0x680 */
uint32_t scratch89; /* _SCRATCH89_0, 0x684 */
uint32_t scratch90; /* _SCRATCH90_0, 0x688 */
uint32_t scratch91; /* _SCRATCH91_0, 0x68c */
uint32_t scratch92; /* _SCRATCH92_0, 0x690 */
uint32_t scratch93; /* _SCRATCH93_0, 0x694 */
uint32_t scratch94; /* _SCRATCH94_0, 0x698 */
uint32_t scratch95; /* _SCRATCH95_0, 0x69c */
uint32_t scratch96; /* _SCRATCH96_0, 0x6a0 */
uint32_t scratch97; /* _SCRATCH97_0, 0x6a4 */
uint32_t scratch98; /* _SCRATCH98_0, 0x6a8 */
uint32_t scratch99; /* _SCRATCH99_0, 0x6ac */
uint32_t scratch100; /* _SCRATCH100_0, 0x6b0 */
uint32_t scratch101; /* _SCRATCH101_0, 0x6b4 */
uint32_t scratch102; /* _SCRATCH102_0, 0x6b8 */
uint32_t scratch103; /* _SCRATCH103_0, 0x6bc */
uint32_t scratch104; /* _SCRATCH104_0, 0x6c0 */
uint32_t scratch105; /* _SCRATCH105_0, 0x6c4 */
uint32_t scratch106; /* _SCRATCH106_0, 0x6c8 */
uint32_t scratch107; /* _SCRATCH107_0, 0x6cc */
uint32_t scratch108; /* _SCRATCH108_0, 0x6d0 */
uint32_t scratch109; /* _SCRATCH109_0, 0x6d4 */
uint32_t scratch110; /* _SCRATCH110_0, 0x6d8 */
uint32_t scratch111; /* _SCRATCH111_0, 0x6dc */
uint32_t scratch112; /* _SCRATCH112_0, 0x6e0 */
uint32_t scratch113; /* _SCRATCH113_0, 0x6e4 */
uint32_t scratch114; /* _SCRATCH114_0, 0x6e8 */
uint32_t scratch115; /* _SCRATCH115_0, 0x6ec */
uint32_t scratch116; /* _SCRATCH116_0, 0x6f0 */
uint32_t scratch117; /* _SCRATCH117_0, 0x6f4 */
uint32_t scratch118; /* _SCRATCH118_0, 0x6f8 */
uint32_t scratch119; /* _SCRATCH119_0, 0x6fc */
uint32_t scratch120; /* _SCRATCH120_0, 0x700 */
uint32_t scratch121; /* _SCRATCH121_0, 0x704 */
uint32_t scratch122; /* _SCRATCH122_0, 0x708 */
uint32_t scratch123; /* _SCRATCH123_0, 0x70c */
uint32_t scratch124; /* _SCRATCH124_0, 0x710 */
uint32_t scratch125; /* _SCRATCH125_0, 0x714 */
uint32_t scratch126; /* _SCRATCH126_0, 0x718 */
uint32_t scratch127; /* _SCRATCH127_0, 0x71c */
uint32_t scratch128; /* _SCRATCH128_0, 0x720 */
uint32_t scratch129; /* _SCRATCH129_0, 0x724 */
uint32_t scratch130; /* _SCRATCH130_0, 0x728 */
uint32_t scratch131; /* _SCRATCH131_0, 0x72c */
uint32_t scratch132; /* _SCRATCH132_0, 0x730 */
uint32_t scratch133; /* _SCRATCH133_0, 0x734 */
uint32_t scratch134; /* _SCRATCH134_0, 0x738 */
uint32_t scratch135; /* _SCRATCH135_0, 0x73c */
uint32_t scratch136; /* _SCRATCH136_0, 0x740 */
uint32_t scratch137; /* _SCRATCH137_0, 0x744 */
uint32_t scratch138; /* _SCRATCH138_0, 0x748 */
uint32_t scratch139; /* _SCRATCH139_0, 0x74c */
uint32_t scratch140; /* _SCRATCH140_0, 0x750 */
uint32_t scratch141; /* _SCRATCH141_0, 0x754 */
uint32_t scratch142; /* _SCRATCH142_0, 0x758 */
uint32_t scratch143; /* _SCRATCH143_0, 0x75c */
uint32_t scratch144; /* _SCRATCH144_0, 0x760 */
uint32_t scratch145; /* _SCRATCH145_0, 0x764 */
uint32_t scratch146; /* _SCRATCH146_0, 0x768 */
uint32_t scratch147; /* _SCRATCH147_0, 0x76c */
uint32_t scratch148; /* _SCRATCH148_0, 0x770 */
uint32_t scratch149; /* _SCRATCH149_0, 0x774 */
uint32_t scratch150; /* _SCRATCH150_0, 0x778 */
uint32_t scratch151; /* _SCRATCH151_0, 0x77c */
uint32_t scratch152; /* _SCRATCH152_0, 0x780 */
uint32_t scratch153; /* _SCRATCH153_0, 0x784 */
uint32_t scratch154; /* _SCRATCH154_0, 0x788 */
uint32_t scratch155; /* _SCRATCH155_0, 0x78c */
uint32_t scratch156; /* _SCRATCH156_0, 0x790 */
uint32_t scratch157; /* _SCRATCH157_0, 0x794 */
uint32_t scratch158; /* _SCRATCH158_0, 0x798 */
uint32_t scratch159; /* _SCRATCH159_0, 0x79c */
uint32_t scratch160; /* _SCRATCH160_0, 0x7a0 */
uint32_t scratch161; /* _SCRATCH161_0, 0x7a4 */
uint32_t scratch162; /* _SCRATCH162_0, 0x7a8 */
uint32_t scratch163; /* _SCRATCH163_0, 0x7ac */
uint32_t scratch164; /* _SCRATCH164_0, 0x7b0 */
uint32_t scratch165; /* _SCRATCH165_0, 0x7b4 */
uint32_t scratch166; /* _SCRATCH166_0, 0x7b8 */
uint32_t scratch167; /* _SCRATCH167_0, 0x7bc */
uint32_t scratch168; /* _SCRATCH168_0, 0x7c0 */
uint32_t scratch169; /* _SCRATCH169_0, 0x7c4 */
uint32_t scratch170; /* _SCRATCH170_0, 0x7c8 */
uint32_t scratch171; /* _SCRATCH171_0, 0x7cc */
uint32_t scratch172; /* _SCRATCH172_0, 0x7d0 */
uint32_t scratch173; /* _SCRATCH173_0, 0x7d4 */
uint32_t scratch174; /* _SCRATCH174_0, 0x7d8 */
uint32_t scratch175; /* _SCRATCH175_0, 0x7dc */
uint32_t scratch176; /* _SCRATCH176_0, 0x7e0 */
uint32_t scratch177; /* _SCRATCH177_0, 0x7e4 */
uint32_t scratch178; /* _SCRATCH178_0, 0x7e8 */
uint32_t scratch179; /* _SCRATCH179_0, 0x7ec */
uint32_t scratch180; /* _SCRATCH180_0, 0x7f0 */
uint32_t scratch181; /* _SCRATCH181_0, 0x7f4 */
uint32_t scratch182; /* _SCRATCH182_0, 0x7f8 */
uint32_t scratch183; /* _SCRATCH183_0, 0x7fc */
uint32_t scratch184; /* _SCRATCH184_0, 0x800 */
uint32_t scratch185; /* _SCRATCH185_0, 0x804 */
uint32_t scratch186; /* _SCRATCH186_0, 0x808 */
uint32_t scratch187; /* _SCRATCH187_0, 0x80c */
uint32_t scratch188; /* _SCRATCH188_0, 0x810 */
uint32_t scratch189; /* _SCRATCH189_0, 0x814 */
uint32_t scratch190; /* _SCRATCH190_0, 0x818 */
uint32_t scratch191; /* _SCRATCH191_0, 0x81c */
uint32_t scratch192; /* _SCRATCH192_0, 0x820 */
uint32_t scratch193; /* _SCRATCH193_0, 0x824 */
uint32_t scratch194; /* _SCRATCH194_0, 0x828 */
uint32_t scratch195; /* _SCRATCH195_0, 0x82c */
uint32_t scratch196; /* _SCRATCH196_0, 0x830 */
uint32_t scratch197; /* _SCRATCH197_0, 0x834 */
uint32_t scratch198; /* _SCRATCH198_0, 0x838 */
uint32_t scratch199; /* _SCRATCH199_0, 0x83c */
uint32_t scratch200; /* _SCRATCH200_0, 0x840 */
uint32_t scratch201; /* _SCRATCH201_0, 0x844 */
uint32_t scratch202; /* _SCRATCH202_0, 0x848 */
uint32_t scratch203; /* _SCRATCH203_0, 0x84c */
uint32_t scratch204; /* _SCRATCH204_0, 0x850 */
uint32_t scratch205; /* _SCRATCH205_0, 0x854 */
uint32_t scratch206; /* _SCRATCH206_0, 0x858 */
uint32_t scratch207; /* _SCRATCH207_0, 0x85c */
uint32_t scratch208; /* _SCRATCH208_0, 0x860 */
uint32_t scratch209; /* _SCRATCH209_0, 0x864 */
uint32_t scratch210; /* _SCRATCH210_0, 0x868 */
uint32_t scratch211; /* _SCRATCH211_0, 0x86c */
uint32_t scratch212; /* _SCRATCH212_0, 0x870 */
uint32_t scratch213; /* _SCRATCH213_0, 0x874 */
uint32_t scratch214; /* _SCRATCH214_0, 0x878 */
uint32_t scratch215; /* _SCRATCH215_0, 0x87c */
uint32_t scratch216; /* _SCRATCH216_0, 0x880 */
uint32_t scratch217; /* _SCRATCH217_0, 0x884 */
uint32_t scratch218; /* _SCRATCH218_0, 0x888 */
uint32_t scratch219; /* _SCRATCH219_0, 0x88c */
uint32_t scratch220; /* _SCRATCH220_0, 0x890 */
uint32_t scratch221; /* _SCRATCH221_0, 0x894 */
uint32_t scratch222; /* _SCRATCH222_0, 0x898 */
uint32_t scratch223; /* _SCRATCH223_0, 0x89c */
uint32_t scratch224; /* _SCRATCH224_0, 0x8a0 */
uint32_t scratch225; /* _SCRATCH225_0, 0x8a4 */
uint32_t scratch226; /* _SCRATCH226_0, 0x8a8 */
uint32_t scratch227; /* _SCRATCH227_0, 0x8ac */
uint32_t scratch228; /* _SCRATCH228_0, 0x8b0 */
uint32_t scratch229; /* _SCRATCH229_0, 0x8b4 */
uint32_t scratch230; /* _SCRATCH230_0, 0x8b8 */
uint32_t scratch231; /* _SCRATCH231_0, 0x8bc */
uint32_t scratch232; /* _SCRATCH232_0, 0x8c0 */
uint32_t scratch233; /* _SCRATCH233_0, 0x8c4 */
uint32_t scratch234; /* _SCRATCH234_0, 0x8c8 */
uint32_t scratch235; /* _SCRATCH235_0, 0x8cc */
uint32_t scratch236; /* _SCRATCH236_0, 0x8d0 */
uint32_t scratch237; /* _SCRATCH237_0, 0x8d4 */
uint32_t scratch238; /* _SCRATCH238_0, 0x8d8 */
uint32_t scratch239; /* _SCRATCH239_0, 0x8dc */
uint32_t scratch240; /* _SCRATCH240_0, 0x8e0 */
uint32_t scratch241; /* _SCRATCH241_0, 0x8e4 */
uint32_t scratch242; /* _SCRATCH242_0, 0x8e8 */
uint32_t scratch243; /* _SCRATCH243_0, 0x8ec */
uint32_t scratch244; /* _SCRATCH244_0, 0x8f0 */
uint32_t scratch245; /* _SCRATCH245_0, 0x8f4 */
uint32_t scratch246; /* _SCRATCH246_0, 0x8f8 */
uint32_t scratch247; /* _SCRATCH247_0, 0x8fc */
uint32_t scratch248; /* _SCRATCH248_0, 0x900 */
uint32_t scratch249; /* _SCRATCH249_0, 0x904 */
uint32_t scratch250; /* _SCRATCH250_0, 0x908 */
uint32_t scratch251; /* _SCRATCH251_0, 0x90c */
uint32_t scratch252; /* _SCRATCH252_0, 0x910 */
uint32_t scratch253; /* _SCRATCH253_0, 0x914 */
uint32_t scratch254; /* _SCRATCH254_0, 0x918 */
uint32_t scratch255; /* _SCRATCH255_0, 0x91c */
uint32_t scratch256; /* _SCRATCH256_0, 0x920 */
uint32_t scratch257; /* _SCRATCH257_0, 0x924 */
uint32_t scratch258; /* _SCRATCH258_0, 0x928 */
uint32_t scratch259; /* _SCRATCH259_0, 0x92c */
uint32_t scratch260; /* _SCRATCH260_0, 0x930 */
uint32_t scratch261; /* _SCRATCH261_0, 0x934 */
uint32_t scratch262; /* _SCRATCH262_0, 0x938 */
uint32_t scratch263; /* _SCRATCH263_0, 0x93c */
uint32_t scratch264; /* _SCRATCH264_0, 0x940 */
uint32_t scratch265; /* _SCRATCH265_0, 0x944 */
uint32_t scratch266; /* _SCRATCH266_0, 0x948 */
uint32_t scratch267; /* _SCRATCH267_0, 0x94c */
uint32_t scratch268; /* _SCRATCH268_0, 0x950 */
uint32_t scratch269; /* _SCRATCH269_0, 0x954 */
uint32_t scratch270; /* _SCRATCH270_0, 0x958 */
uint32_t scratch271; /* _SCRATCH271_0, 0x95c */
uint32_t scratch272; /* _SCRATCH272_0, 0x960 */
uint32_t scratch273; /* _SCRATCH273_0, 0x964 */
uint32_t scratch274; /* _SCRATCH274_0, 0x968 */
uint32_t scratch275; /* _SCRATCH275_0, 0x96c */
uint32_t scratch276; /* _SCRATCH276_0, 0x970 */
uint32_t scratch277; /* _SCRATCH277_0, 0x974 */
uint32_t scratch278; /* _SCRATCH278_0, 0x978 */
uint32_t scratch279; /* _SCRATCH279_0, 0x97c */
uint32_t scratch280; /* _SCRATCH280_0, 0x980 */
uint32_t scratch281; /* _SCRATCH281_0, 0x984 */
uint32_t scratch282; /* _SCRATCH282_0, 0x988 */
uint32_t scratch283; /* _SCRATCH283_0, 0x98c */
uint32_t scratch284; /* _SCRATCH284_0, 0x990 */
uint32_t scratch285; /* _SCRATCH285_0, 0x994 */
uint32_t scratch286; /* _SCRATCH286_0, 0x998 */
uint32_t scratch287; /* _SCRATCH287_0, 0x99c */
uint32_t scratch288; /* _SCRATCH288_0, 0x9a0 */
uint32_t scratch289; /* _SCRATCH289_0, 0x9a4 */
uint32_t scratch290; /* _SCRATCH290_0, 0x9a8 */
uint32_t scratch291; /* _SCRATCH291_0, 0x9ac */
uint32_t scratch292; /* _SCRATCH292_0, 0x9b0 */
uint32_t scratch293; /* _SCRATCH293_0, 0x9b4 */
uint32_t scratch294; /* _SCRATCH294_0, 0x9b8 */
uint32_t scratch295; /* _SCRATCH295_0, 0x9bc */
uint32_t scratch296; /* _SCRATCH296_0, 0x9c0 */
uint32_t scratch297; /* _SCRATCH297_0, 0x9c4 */
uint32_t scratch298; /* _SCRATCH298_0, 0x9c8 */
uint32_t scratch299; /* _SCRATCH299_0, 0x9cc */
uint32_t _0x9d0[50];
uint32_t secure_scratch80; /* _SECURE_SCRATCH80_0, 0xa98 */
uint32_t secure_scratch81; /* _SECURE_SCRATCH81_0, 0xa9c */
uint32_t secure_scratch82; /* _SECURE_SCRATCH82_0, 0xaa0 */
uint32_t secure_scratch83; /* _SECURE_SCRATCH83_0, 0xaa4 */
uint32_t secure_scratch84; /* _SECURE_SCRATCH84_0, 0xaa8 */
uint32_t secure_scratch85; /* _SECURE_SCRATCH85_0, 0xaac */
uint32_t secure_scratch86; /* _SECURE_SCRATCH86_0, 0xab0 */
uint32_t secure_scratch87; /* _SECURE_SCRATCH87_0, 0xab4 */
uint32_t secure_scratch88; /* _SECURE_SCRATCH88_0, 0xab8 */
uint32_t secure_scratch89; /* _SECURE_SCRATCH89_0, 0xabc */
uint32_t secure_scratch90; /* _SECURE_SCRATCH90_0, 0xac0 */
uint32_t secure_scratch91; /* _SECURE_SCRATCH91_0, 0xac4 */
uint32_t secure_scratch92; /* _SECURE_SCRATCH92_0, 0xac8 */
uint32_t secure_scratch93; /* _SECURE_SCRATCH93_0, 0xacc */
uint32_t secure_scratch94; /* _SECURE_SCRATCH94_0, 0xad0 */
uint32_t secure_scratch95; /* _SECURE_SCRATCH95_0, 0xad4 */
uint32_t secure_scratch96; /* _SECURE_SCRATCH96_0, 0xad8 */
uint32_t secure_scratch97; /* _SECURE_SCRATCH97_0, 0xadc */
uint32_t secure_scratch98; /* _SECURE_SCRATCH98_0, 0xae0 */
uint32_t secure_scratch99; /* _SECURE_SCRATCH99_0, 0xae4 */
uint32_t secure_scratch100; /* _SECURE_SCRATCH100_0, 0xae8 */
uint32_t secure_scratch101; /* _SECURE_SCRATCH101_0, 0xaec */
uint32_t secure_scratch102; /* _SECURE_SCRATCH102_0, 0xaf0 */
uint32_t secure_scratch103; /* _SECURE_SCRATCH103_0, 0xaf4 */
uint32_t secure_scratch104; /* _SECURE_SCRATCH104_0, 0xaf8 */
uint32_t secure_scratch105; /* _SECURE_SCRATCH105_0, 0xafc */
uint32_t secure_scratch106; /* _SECURE_SCRATCH106_0, 0xb00 */
uint32_t secure_scratch107; /* _SECURE_SCRATCH107_0, 0xb04 */
uint32_t secure_scratch108; /* _SECURE_SCRATCH108_0, 0xb08 */
uint32_t secure_scratch109; /* _SECURE_SCRATCH109_0, 0xb0c */
uint32_t secure_scratch110; /* _SECURE_SCRATCH110_0, 0xb10 */
uint32_t secure_scratch111; /* _SECURE_SCRATCH111_0, 0xb14 */
uint32_t secure_scratch112; /* _SECURE_SCRATCH112_0, 0xb18 */
uint32_t secure_scratch113; /* _SECURE_SCRATCH113_0, 0xb1c */
uint32_t secure_scratch114; /* _SECURE_SCRATCH114_0, 0xb20 */
uint32_t secure_scratch115; /* _SECURE_SCRATCH115_0, 0xb24 */
uint32_t secure_scratch116; /* _SECURE_SCRATCH116_0, 0xb28 */
uint32_t secure_scratch117; /* _SECURE_SCRATCH117_0, 0xb2c */
uint32_t secure_scratch118; /* _SECURE_SCRATCH118_0, 0xb30 */
uint32_t secure_scratch119; /* _SECURE_SCRATCH119_0, 0xb34 */
uint32_t secure_scratch120; /* _SECURE_SCRATCH120_0, 0xb38 */
uint32_t secure_scratch121; /* _SECURE_SCRATCH121_0, 0xb3c */
uint32_t secure_scratch122; /* _SECURE_SCRATCH122_0, 0xb40 */
uint32_t secure_scratch123; /* _SECURE_SCRATCH123_0, 0xb44 */
uint32_t led_breathing_ctrl; /* _LED_BREATHING_CTRL_0, 0xb48 */
uint32_t led_breathing_counter0; /* _LED_BREATHING_COUNTER0_0, 0xb4c */
uint32_t led_breathing_counter1; /* _LED_BREATHING_COUNTER1_0, 0xb50 */
uint32_t led_breathing_counter2; /* _LED_BREATHING_COUNTER2_0, 0xb54 */
uint32_t led_breathing_counter3; /* _LED_BREATHING_COUNTER3_0, 0xb58 */
uint32_t led_breathing_status; /* _LED_BREATHING_STATUS_0, 0xb5c */
uint32_t _0xb60[2];
uint32_t secure_scratch124; /* _SECURE_SCRATCH124_0, 0xb68 */
uint32_t secure_scratch125; /* _SECURE_SCRATCH125_0, 0xb6c */
uint32_t secure_scratch126; /* _SECURE_SCRATCH126_0, 0xb70 */
uint32_t secure_scratch127; /* _SECURE_SCRATCH127_0, 0xb74 */
uint32_t secure_scratch128; /* _SECURE_SCRATCH128_0, 0xb78 */
uint32_t secure_scratch129; /* _SECURE_SCRATCH129_0, 0xb7c */
uint32_t secure_scratch130; /* _SECURE_SCRATCH130_0, 0xb80 */
uint32_t secure_scratch131; /* _SECURE_SCRATCH131_0, 0xb84 */
uint32_t secure_scratch132; /* _SECURE_SCRATCH132_0, 0xb88 */
uint32_t secure_scratch133; /* _SECURE_SCRATCH133_0, 0xb8c */
uint32_t secure_scratch134; /* _SECURE_SCRATCH134_0, 0xb90 */
uint32_t secure_scratch135; /* _SECURE_SCRATCH135_0, 0xb94 */
uint32_t secure_scratch136; /* _SECURE_SCRATCH136_0, 0xb98 */
uint32_t secure_scratch137; /* _SECURE_SCRATCH137_0, 0xb9c */
uint32_t secure_scratch138; /* _SECURE_SCRATCH138_0, 0xba0 */
uint32_t secure_scratch139; /* _SECURE_SCRATCH139_0, 0xba4 */
uint32_t _0xba8[2];
uint32_t sec_disable_ns; /* _SEC_DISABLE_NS_0, 0xbb0 */
uint32_t sec_disable2_ns; /* _SEC_DISABLE2_NS_0, 0xbb4 */
uint32_t sec_disable3_ns; /* _SEC_DISABLE3_NS_0, 0xbb8 */
uint32_t sec_disable4_ns; /* _SEC_DISABLE4_NS_0, 0xbbc */
uint32_t sec_disable5_ns; /* _SEC_DISABLE5_NS_0, 0xbc0 */
uint32_t sec_disable6_ns; /* _SEC_DISABLE6_NS_0, 0xbc4 */
uint32_t sec_disable7_ns; /* _SEC_DISABLE7_NS_0, 0xbc8 */
uint32_t sec_disable8_ns; /* _SEC_DISABLE8_NS_0, 0xbcc */
uint32_t sec_disable9_ns; /* _SEC_DISABLE9_NS_0, 0xbd0 */
uint32_t sec_disable10_ns; /* _SEC_DISABLE10_NS_0, 0xbd4 */
uint32_t _0xbd8[4];
uint32_t tzram_pwr_cntrl; /* _TZRAM_PWR_CNTRL_0, 0xbe8 */
uint32_t tzram_sec_disable; /* _TZRAM_SEC_DISABLE_0, 0xbec */
uint32_t tzram_non_sec_disable; /* _TZRAM_NON_SEC_DISABLE_0, 0xbf0 */
} tegra_pmc_t;
static inline volatile tegra_pmc_t *pmc_get_regs(void)
{
return (volatile tegra_pmc_t *)PMC_BASE;
}
#endif

View File

@@ -1,207 +0,0 @@
/* TuxSH: I added INC/DEC_10 to INC/DEC_32; tuples */
#ifndef FUSEE_PREPROCESSOR_H
#define FUSEE_PREPROCESSOR_H
/*=============================================================================
Copyright (c) 2015 Paul Fultz II
cloak.h
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
/*#ifndef CLOAK_GUARD_H
#define CLOAK_GUARD_H*/
#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
#define COMPL_0 1
#define COMPL_1 0
#define BITAND(x) PRIMITIVE_CAT(BITAND_, x)
#define BITAND_0(y) 0
#define BITAND_1(y) y
#define INC(x) PRIMITIVE_CAT(INC_, x)
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INC_9 10
#define INC_10 11
#define INC_11 12
#define INC_12 13
#define INC_13 14
#define INC_14 15
#define INC_15 16
#define INC_16 17
#define INC_17 18
#define INC_18 19
#define INC_19 20
#define INC_20 21
#define INC_21 22
#define INC_22 23
#define INC_23 24
#define INC_24 25
#define INC_25 26
#define INC_26 27
#define INC_27 28
#define INC_28 29
#define INC_29 30
#define INC_30 31
#define INC_31 32
#define INC_32 32
#define INC_33 33
#define DEC(x) PRIMITIVE_CAT(DEC_, x)
#define DEC_0 0
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
#define DEC_10 9
#define DEC_11 10
#define DEC_12 11
#define DEC_13 12
#define DEC_14 13
#define DEC_15 14
#define DEC_16 15
#define DEC_17 16
#define DEC_18 17
#define DEC_19 18
#define DEC_20 19
#define DEC_21 20
#define DEC_22 21
#define DEC_23 22
#define DEC_24 23
#define DEC_25 24
#define DEC_26 25
#define DEC_27 26
#define DEC_28 27
#define DEC_29 28
#define DEC_30 29
#define DEC_31 30
#define DEC_32 31
#define DEC_33 32
#define CHECK_N(x, n, ...) n
#define CHECK(...) CHECK_N(__VA_ARGS__, 0,)
#define PROBE(x) x, 1,
#define IS_PAREN(x) CHECK(IS_PAREN_PROBE x)
#define IS_PAREN_PROBE(...) PROBE(~)
#define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x))
#define NOT_0 PROBE(~)
#define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
#define COMPL_0 1
#define COMPL_1 0
#define BOOL(x) COMPL(NOT(x))
#define IIF(c) PRIMITIVE_CAT(IIF_, c)
#define IIF_0(t, ...) __VA_ARGS__
#define IIF_1(t, ...) t
#define IF(c) IIF(BOOL(c))
#define EAT(...)
#define EXPAND(...) __VA_ARGS__
#define WHEN(c) IF(c)(EXPAND, EAT)
#define EMPTY()
#define DEFER(id) id EMPTY()
#define OBSTRUCT(id) id DEFER(EMPTY)()
#define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
#define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
#define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
#define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__)))
#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__)))
#define EVAL5(...) __VA_ARGS__
#define REPEAT(count, macro, ...) \
WHEN(count) \
( \
OBSTRUCT(REPEAT_INDIRECT) () \
( \
DEC(count), macro, __VA_ARGS__ \
) \
OBSTRUCT(macro) \
( \
DEC(count), __VA_ARGS__ \
) \
)
#define REPEAT_INDIRECT() REPEAT
#define WHILE(pred, op, ...) \
IF(pred(__VA_ARGS__)) \
( \
OBSTRUCT(WHILE_INDIRECT) () \
( \
pred, op, op(__VA_ARGS__) \
), \
__VA_ARGS__ \
)
#define WHILE_INDIRECT() WHILE
#define PRIMITIVE_COMPARE(x, y) IS_PAREN \
( \
COMPARE_ ## x ( COMPARE_ ## y) (()) \
)
#define IS_COMPARABLE(x) IS_PAREN( CAT(COMPARE_, x) (()) )
#define NOT_EQUAL(x, y) \
IIF(BITAND(IS_COMPARABLE(x))(IS_COMPARABLE(y)) ) \
( \
PRIMITIVE_COMPARE, \
1 EAT \
)(x, y)
#define EQUAL(x, y) COMPL(NOT_EQUAL(x, y))
#define COMMA() ,
#define COMMA_IF(n) IF(n)(COMMA, EAT)()
#define PLUS() +
#define _TUPLE_ELEM_0(a, ...) a
#define _TUPLE_ELEM_1(a, b, ...) b
#define _TUPLE_ELEM_2(a, b, c, ...) c
#define _TUPLE_ELEM_3(a, b, c, d, ...) d
#define _TUPLE_ELEM_4(a, b, c, d, e, ...) e
#define TUPLE_ELEM_0(T) EVAL(_TUPLE_ELEM_0 T)
#define TUPLE_ELEM_1(T) EVAL(_TUPLE_ELEM_1 T)
#define TUPLE_ELEM_2(T) EVAL(_TUPLE_ELEM_2 T)
#define TUPLE_ELEM_3(T) EVAL(_TUPLE_ELEM_3 T)
#define TUPLE_ELEM_4(T) EVAL(_TUPLE_ELEM_4 T)
#define _TUPLE_FOLD_LEFT_0(i, T, op) (_TUPLE_ELEM_0 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_1(i, T, op) (_TUPLE_ELEM_1 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_2(i, T, op) (_TUPLE_ELEM_2 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_3(i, T, op) (_TUPLE_ELEM_3 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_4(i, T, op) (_TUPLE_ELEM_4 CAT(T,i)) op()
#define TUPLE_FOLD_LEFT_0(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_0, T, op))
#define TUPLE_FOLD_LEFT_1(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_1, T, op))
#define TUPLE_FOLD_LEFT_2(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_2, T, op))
#define TUPLE_FOLD_LEFT_3(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_3, T, op))
#define TUPLE_FOLD_LEFT_4(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_4, T, op))
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_SDRAM_H_
#define FUSEE_SDRAM_H_
void sdram_init_erista(void);
void sdram_init_mariko(void);
const void *sdram_get_params_erista(uint32_t dram_id);
const void *sdram_get_params_mariko(uint32_t dram_id);
void sdram_save_params_erista(const void *save_params);
void sdram_save_params_mariko(const void *save_params);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,334 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
static const uint8_t sdram_params_erista_lz[1262] = {
0x17, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
0x00, 0x2C, 0x17, 0x04, 0x09, 0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08,
0x17, 0x10, 0x10, 0x00, 0x00, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00,
0x00, 0x04, 0xB4, 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00,
0x70, 0x17, 0x10, 0x24, 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40,
0x00, 0x00, 0x00, 0x17, 0x04, 0x04, 0x17, 0x09, 0x18, 0xFF, 0xFF, 0x1F,
0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77,
0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08, 0x17, 0x08, 0x08, 0xA6, 0xA6,
0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x04,
0x04, 0x04, 0x17, 0x04, 0x04, 0x17, 0x04, 0x3C, 0x1F, 0x1F, 0x1F, 0x1F,
0x17, 0x04, 0x04, 0x17, 0x06, 0x06, 0x00, 0x00, 0x04, 0x08, 0x17, 0x06,
0x46, 0xA1, 0x01, 0x00, 0x00, 0x32, 0x17, 0x0B, 0x64, 0x01, 0x17, 0x04,
0x7C, 0x17, 0x07, 0x0C, 0x03, 0x17, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1E,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13,
0x17, 0x0B, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x17, 0x05, 0x5D, 0x17, 0x07,
0x10, 0x0B, 0x17, 0x07, 0x28, 0x08, 0x17, 0x07, 0x0C, 0x17, 0x04, 0x1C,
0x20, 0x00, 0x00, 0x00, 0x06, 0x17, 0x04, 0x04, 0x17, 0x07, 0x08, 0x17,
0x04, 0x50, 0x17, 0x04, 0x2C, 0x17, 0x04, 0x1C, 0x17, 0x04, 0x10, 0x17,
0x08, 0x6C, 0x17, 0x04, 0x10, 0x17, 0x04, 0x38, 0x17, 0x04, 0x40, 0x05,
0x17, 0x07, 0x1C, 0x17, 0x08, 0x58, 0x17, 0x04, 0x24, 0x17, 0x04, 0x18,
0x17, 0x08, 0x64, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14,
0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x17, 0x09, 0x0C, 0x17, 0x05, 0x82,
0x58, 0x17, 0x07, 0x61, 0xC1, 0x17, 0x07, 0x50, 0x17, 0x04, 0x04, 0x17,
0x08, 0x81, 0x48, 0x17, 0x04, 0x04, 0x17, 0x04, 0x28, 0x17, 0x04, 0x60,
0x17, 0x08, 0x54, 0x27, 0x17, 0x04, 0x04, 0x17, 0x07, 0x14, 0x17, 0x04,
0x04, 0x04, 0x17, 0x07, 0x81, 0x58, 0x17, 0x0C, 0x0C, 0x1C, 0x03, 0x00,
0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x17, 0x04, 0x5A, 0xF3, 0x0C,
0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05,
0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03,
0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02,
0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08,
0x24, 0x06, 0x07, 0x9A, 0x12, 0x17, 0x05, 0x83, 0x41, 0x00, 0xFF, 0x17,
0x10, 0x83, 0x6C, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00,
0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00,
0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x17, 0x04, 0x20, 0x08, 0x08,
0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x17, 0x06,
0x2C, 0x11, 0x08, 0x17, 0x10, 0x84, 0x67, 0x15, 0x00, 0xCC, 0x00, 0x0A,
0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF,
0x0F, 0xFF, 0x0F, 0x17, 0x08, 0x83, 0x4C, 0x01, 0x03, 0x00, 0x70, 0x00,
0x0C, 0x00, 0x01, 0x17, 0x04, 0x0C, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04,
0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x17, 0x04, 0x10, 0xA0, 0x00, 0x2C,
0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x17, 0x06, 0x48, 0x08, 0x00,
0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28,
0x28, 0x28, 0x17, 0x04, 0x04, 0x11, 0x11, 0x11, 0x11, 0x17, 0x04, 0x04,
0xBE, 0x00, 0x00, 0x17, 0x05, 0x58, 0x17, 0x08, 0x5C, 0x17, 0x22, 0x85,
0x6A, 0x17, 0x1A, 0x1A, 0x14, 0x00, 0x12, 0x00, 0x10, 0x17, 0x05, 0x83,
0x0A, 0x17, 0x16, 0x18, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,
0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x17, 0x05, 0x83, 0x0C, 0x17,
0x04, 0x20, 0x17, 0x18, 0x18, 0x28, 0x00, 0x28, 0x17, 0x04, 0x04, 0x17,
0x08, 0x08, 0x17, 0x10, 0x10, 0x00, 0x14, 0x17, 0x05, 0x5A, 0x17, 0x04,
0x5C, 0x17, 0x04, 0x5E, 0x17, 0x04, 0x0E, 0x17, 0x0E, 0x78, 0x17, 0x09,
0x82, 0x50, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51,
0x17, 0x08, 0x18, 0x80, 0x01, 0x00, 0x00, 0x40, 0x17, 0x04, 0x20, 0x03,
0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x17, 0x08, 0x82, 0x58,
0x17, 0x0C, 0x38, 0x17, 0x1B, 0x81, 0x6C, 0x17, 0x08, 0x85, 0x60, 0x17,
0x08, 0x86, 0x50, 0x17, 0x08, 0x86, 0x60, 0x17, 0x06, 0x83, 0x21, 0x22,
0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x17, 0x0C, 0x86, 0x74, 0x17, 0x08, 0x2C,
0x8B, 0xFF, 0x07, 0x17, 0x06, 0x81, 0x04, 0x32, 0x54, 0x76, 0x10, 0x47,
0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75,
0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45,
0x32, 0x67, 0x17, 0x04, 0x24, 0x49, 0x92, 0x24, 0x17, 0x04, 0x04, 0x17,
0x11, 0x7C, 0x1B, 0x17, 0x04, 0x04, 0x17, 0x13, 0x81, 0x14, 0x2F, 0x41,
0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x17, 0x04, 0x7C, 0xFF, 0xFF, 0xFF,
0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03,
0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x17, 0x06, 0x86, 0x59,
0x17, 0x0F, 0x89, 0x14, 0x37, 0x17, 0x07, 0x82, 0x72, 0x10, 0x17, 0x06,
0x83, 0x0D, 0x00, 0x11, 0x01, 0x17, 0x05, 0x85, 0x39, 0x17, 0x04, 0x0E,
0x0A, 0x17, 0x07, 0x89, 0x29, 0x17, 0x04, 0x1B, 0x17, 0x08, 0x86, 0x77,
0x17, 0x09, 0x12, 0x20, 0x00, 0x00, 0x00, 0x81, 0x10, 0x09, 0x28, 0x93,
0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x17, 0x18, 0x82, 0x2C, 0xFF,
0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0x17, 0x04, 0x04, 0xDC, 0xDC,
0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x17, 0x04, 0x04, 0x17, 0x04, 0x04,
0x17, 0x05, 0x82, 0x24, 0x03, 0x07, 0x17, 0x04, 0x04, 0x00, 0x00, 0x24,
0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10,
0x9C, 0x4B, 0x17, 0x04, 0x64, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00,
0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x17, 0x06, 0x85, 0x60, 0x17,
0x10, 0x82, 0x74, 0x17, 0x08, 0x08, 0x17, 0x08, 0x88, 0x00, 0x17, 0x04,
0x10, 0x04, 0x17, 0x0B, 0x87, 0x6C, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02,
0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x17, 0x08, 0x8B, 0x18,
0x1F, 0x17, 0x09, 0x81, 0x73, 0x00, 0xFF, 0x00, 0xFF, 0x17, 0x05, 0x86,
0x48, 0x17, 0x04, 0x0C, 0x17, 0x07, 0x86, 0x34, 0x00, 0x00, 0xF0, 0x17,
0x09, 0x87, 0x54, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x17, 0x0C, 0x81,
0x52, 0x17, 0x0A, 0x1C, 0x17, 0x10, 0x81, 0x6C, 0x17, 0x0A, 0x82, 0x21,
0x17, 0x07, 0x82, 0x4D, 0x17, 0x0A, 0x8A, 0x1B, 0x17, 0x11, 0x2C, 0x76,
0x0C, 0x17, 0x0A, 0x8A, 0x67, 0x17, 0x0F, 0x84, 0x28, 0x17, 0x06, 0x34,
0x17, 0x17, 0x3A, 0x7E, 0x16, 0x40, 0x17, 0x0C, 0x8B, 0x1F, 0x17, 0x2A,
0x38, 0x1E, 0x17, 0x0A, 0x38, 0x17, 0x13, 0x81, 0x28, 0x00, 0xC0, 0x17,
0x17, 0x55, 0x46, 0x24, 0x17, 0x0A, 0x81, 0x28, 0x17, 0x14, 0x38, 0x17,
0x18, 0x81, 0x60, 0x46, 0x2C, 0x17, 0x06, 0x38, 0xEC, 0x17, 0x0D, 0x16,
0x17, 0x0E, 0x82, 0x3C, 0x17, 0x82, 0x0C, 0x8E, 0x68, 0x17, 0x04, 0x24,
0x17, 0x5C, 0x8E, 0x68, 0x17, 0x07, 0x82, 0x5F, 0x80, 0x17, 0x87, 0x01,
0x8E, 0x68, 0x02, 0x17, 0x81, 0x4A, 0x8E, 0x68, 0x17, 0x0C, 0x87, 0x78,
0x17, 0x85, 0x28, 0x8E, 0x68, 0x17, 0x8E, 0x68, 0x9D, 0x50, 0x17, 0x81,
0x24, 0x8E, 0x68, 0x17, 0x04, 0x2C, 0x17, 0x28, 0x8E, 0x68, 0x17, 0x04,
0x30, 0x17, 0x85, 0x3C, 0x8E, 0x68, 0x12, 0x17, 0x07, 0x85, 0x70, 0x17,
0x88, 0x74, 0x8E, 0x68, 0x17, 0x87, 0x3E, 0x9D, 0x50, 0x0C, 0x17, 0x04,
0x04, 0x17, 0x12, 0x8E, 0x68, 0x18, 0x17, 0x87, 0x12, 0xBB, 0x20, 0x17,
0x83, 0x04, 0x9D, 0x50, 0x15, 0x17, 0x05, 0x8D, 0x76, 0x17, 0x0F, 0x8B,
0x49, 0x17, 0x0B, 0x18, 0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00,
0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x17, 0x09, 0x84, 0x0C, 0x17,
0x18, 0x18, 0x17, 0x20, 0x8E, 0x68, 0x15, 0x17, 0x07, 0x5A, 0x17, 0x06,
0x5E, 0x16, 0x00, 0x15, 0x17, 0x82, 0x40, 0x9D, 0x50, 0x17, 0x86, 0x5F,
0xBB, 0x20, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x17, 0x81, 0x4F, 0xAC, 0x38,
0x3B, 0x17, 0x04, 0x04, 0x17, 0x86, 0x30, 0x8E, 0x68, 0x17, 0x81, 0x53,
0xAC, 0x38, 0x07, 0x17, 0x0D, 0x8E, 0x68, 0xA3, 0x72, 0x17, 0x83, 0x10,
0x8E, 0x68
};
static const uint8_t sdram_params_mariko_lz[1727] = {
0x19, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
0x00, 0x2C, 0x19, 0x04, 0x09, 0x00, 0x19, 0x04, 0x04, 0x19, 0x08, 0x08,
0x19, 0x10, 0x10, 0x19, 0x20, 0x20, 0x19, 0x40, 0x40, 0x19, 0x2A, 0x2A,
0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x19, 0x04, 0x04, 0x19, 0x09,
0x14, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x19, 0x06, 0x0E,
0x88, 0x19, 0x04, 0x04, 0x00, 0x20, 0x12, 0x19, 0x0A, 0x0C, 0x19, 0x06,
0x08, 0x00, 0x00, 0xBC, 0xBC, 0xC5, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x02,
0x03, 0xE0, 0xC1, 0x04, 0x04, 0x04, 0x04, 0x19, 0x04, 0x04, 0x19, 0x04,
0x04, 0x3F, 0x3F, 0x3F, 0x3F, 0x19, 0x04, 0x04, 0x19, 0x04, 0x04, 0x19,
0x04, 0x38, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, 0x01,
0x00, 0x00, 0x30, 0x19, 0x04, 0x39, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90,
0x19, 0x06, 0x81, 0x00, 0x19, 0x07, 0x74, 0x03, 0x19, 0x04, 0x04, 0x00,
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, 0x00,
0x00, 0x00, 0x1D, 0x19, 0x0B, 0x81, 0x14, 0x09, 0x00, 0x00, 0x00, 0x04,
0x19, 0x0B, 0x10, 0x0B, 0x19, 0x07, 0x28, 0x08, 0x19, 0x07, 0x0C, 0x19,
0x04, 0x1C, 0x17, 0x00, 0x00, 0x00, 0x15, 0x19, 0x07, 0x08, 0x1B, 0x19,
0x07, 0x28, 0x20, 0x00, 0x00, 0x00, 0x06, 0x19, 0x04, 0x04, 0x19, 0x07,
0x08, 0x19, 0x04, 0x64, 0x19, 0x04, 0x18, 0x19, 0x04, 0x30, 0x19, 0x04,
0x10, 0x19, 0x08, 0x81, 0x00, 0x19, 0x04, 0x10, 0x19, 0x04, 0x4C, 0x0E,
0x00, 0x00, 0x00, 0x05, 0x19, 0x07, 0x1C, 0x19, 0x09, 0x82, 0x24, 0x19,
0x07, 0x6C, 0x19, 0x07, 0x83, 0x57, 0x80, 0x19, 0x04, 0x0A, 0x12, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x19,
0x07, 0x0C, 0x0A, 0x19, 0x04, 0x48, 0x19, 0x07, 0x61, 0xC1, 0x19, 0x07,
0x50, 0x19, 0x04, 0x04, 0x19, 0x04, 0x13, 0x19, 0x04, 0x1C, 0x19, 0x04,
0x08, 0x14, 0x19, 0x07, 0x60, 0x19, 0x08, 0x54, 0x3B, 0x19, 0x04, 0x04,
0x19, 0x07, 0x14, 0x19, 0x04, 0x04, 0x04, 0x19, 0x07, 0x81, 0x6C, 0x19,
0x0C, 0x0C, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x3A,
0x19, 0x04, 0x5A, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07,
0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E,
0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07,
0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09,
0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0x19, 0x05, 0x83,
0x3F, 0xFF, 0x00, 0xFF, 0x19, 0x10, 0x84, 0x00, 0x04, 0x00, 0x01, 0x88,
0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x00, 0x00, 0x00, 0xC0,
0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, 0x88, 0x5D, 0x5D, 0x0E, 0x8C,
0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, 0x8C,
0x16, 0x16, 0x16, 0x88, 0x19, 0x06, 0x2C, 0x11, 0x08, 0x19, 0x10, 0x85,
0x5F, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20,
0xF3, 0x25, 0x08, 0x11, 0x19, 0x04, 0x69, 0x0F, 0x19, 0x04, 0x18, 0x19,
0x04, 0x28, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x19, 0x04,
0x0C, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x19,
0x06, 0x1C, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x0F, 0x19, 0x05, 0x82,
0x52, 0x02, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20,
0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x29, 0x29, 0x29, 0x19, 0x04, 0x04,
0x19, 0x08, 0x08, 0x78, 0x19, 0x06, 0x85, 0x1A, 0x19, 0x05, 0x58, 0x19,
0x40, 0x85, 0x74, 0x22, 0x00, 0x0E, 0x00, 0x10, 0x19, 0x09, 0x84, 0x22,
0x19, 0x12, 0x18, 0x43, 0x00, 0x49, 0x00, 0x45, 0x00, 0x42, 0x00, 0x47,
0x00, 0x49, 0x00, 0x47, 0x00, 0x46, 0x19, 0x05, 0x83, 0x60, 0x00, 0x00,
0x10, 0x19, 0x18, 0x18, 0x00, 0x28, 0x00, 0x28, 0x19, 0x04, 0x04, 0x19,
0x08, 0x08, 0x19, 0x10, 0x10, 0x00, 0x22, 0x19, 0x05, 0x5A, 0x19, 0x04,
0x5C, 0x19, 0x04, 0x5E, 0x1B, 0x19, 0x05, 0x88, 0x24, 0x19, 0x10, 0x7C,
0x19, 0x09, 0x82, 0x54, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F,
0x00, 0x51, 0x80, 0x19, 0x07, 0x18, 0x19, 0x08, 0x08, 0x19, 0x05, 0x84,
0x40, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x19, 0x08, 0x82, 0x5C, 0x19, 0x0C,
0x38, 0x19, 0x1C, 0x87, 0x64, 0x19, 0x0B, 0x0C, 0x19, 0x08, 0x89, 0x28,
0x19, 0x05, 0x14, 0x01, 0x22, 0x04, 0xFF, 0x9F, 0xAF, 0x4F, 0x19, 0x09,
0x10, 0x19, 0x0B, 0x28, 0x9F, 0xFF, 0x37, 0x19, 0x06, 0x81, 0x18, 0x32,
0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34,
0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23,
0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x19, 0x04, 0x24, 0x49, 0x92, 0x24,
0x19, 0x04, 0x04, 0x19, 0x11, 0x78, 0x12, 0x19, 0x04, 0x04, 0x19, 0x13,
0x81, 0x10, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x19, 0x04,
0x7C, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x19, 0x07, 0x89, 0x00,
0x09, 0x00, 0x00, 0x34, 0x10, 0x19, 0x09, 0x87, 0x70, 0x19, 0x14, 0x81,
0x4C, 0x03, 0x00, 0x05, 0x19, 0x05, 0x86, 0x2B, 0x10, 0x02, 0x19, 0x06,
0x87, 0x5D, 0x21, 0x19, 0x07, 0x88, 0x15, 0x19, 0x07, 0x41, 0x19, 0x06,
0x3D, 0x19, 0x07, 0x2C, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x19,
0x05, 0x88, 0x04, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B,
0x8A, 0x67, 0x76, 0x19, 0x60, 0x8A, 0x54, 0x10, 0x10, 0x19, 0x04, 0x04,
0x00, 0x00, 0x00, 0xEF, 0x00, 0xEF, 0x19, 0x08, 0x14, 0x1C, 0x1C, 0x1C,
0x1C, 0x19, 0x11, 0x83, 0x18, 0x03, 0x08, 0x19, 0x04, 0x04, 0x00, 0x00,
0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00,
0x10, 0x9C, 0x4B, 0x00, 0x10, 0x19, 0x05, 0x83, 0x24, 0x08, 0x4C, 0x00,
0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x19, 0x08,
0x83, 0x68, 0x19, 0x0C, 0x83, 0x40, 0x19, 0x08, 0x08, 0x05, 0x19, 0x0B,
0x84, 0x0C, 0x04, 0x19, 0x07, 0x10, 0x07, 0x19, 0x06, 0x62, 0x02, 0x01,
0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x19,
0x06, 0x42, 0x1F, 0x19, 0x0A, 0x82, 0x28, 0xFF, 0x00, 0xFF, 0x19, 0x05,
0x87, 0x18, 0x19, 0x07, 0x89, 0x56, 0x19, 0x06, 0x20, 0xF0, 0x19, 0x09,
0x88, 0x24, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x19, 0x0C, 0x8A, 0x0B,
0x19, 0x0A, 0x1C, 0x19, 0x10, 0x81, 0x4C, 0x19, 0x05, 0x44, 0x19, 0x09,
0x0E, 0x19, 0x05, 0x8B, 0x66, 0x19, 0x08, 0x8A, 0x6B, 0x19, 0x11, 0x2C,
0x76, 0x0C, 0x19, 0x0A, 0x8B, 0x4B, 0x19, 0x0F, 0x84, 0x78, 0x19, 0x06,
0x34, 0x19, 0x17, 0x3A, 0x7E, 0x16, 0x40, 0x19, 0x0C, 0x8C, 0x03, 0x19,
0x2A, 0x38, 0x1E, 0x19, 0x0A, 0x38, 0x19, 0x13, 0x81, 0x28, 0x00, 0xC0,
0x19, 0x17, 0x55, 0x46, 0x24, 0x19, 0x0A, 0x81, 0x28, 0x19, 0x14, 0x38,
0x19, 0x18, 0x81, 0x60, 0x46, 0x2C, 0x19, 0x06, 0x38, 0xEC, 0x19, 0x0D,
0x16, 0x19, 0x16, 0x82, 0x3C, 0x19, 0x87, 0x2C, 0x90, 0x38, 0x16, 0x00,
0x0D, 0x00, 0x0B, 0x19, 0x05, 0x84, 0x26, 0x19, 0x16, 0x18, 0x43, 0x00,
0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00,
0x46, 0x00, 0x0C, 0x19, 0x05, 0x83, 0x3A, 0x0D, 0x19, 0x18, 0x18, 0x19,
0x21, 0x90, 0x38, 0x16, 0x19, 0x05, 0x5A, 0x19, 0x04, 0x5C, 0x19, 0x04,
0x5E, 0x17, 0x19, 0x07, 0x90, 0x70, 0x19, 0x89, 0x5C, 0x90, 0x38, 0x50,
0x05, 0x19, 0x1E, 0x90, 0x38, 0xAF, 0xC9, 0x19, 0x3C, 0x90, 0x38, 0x19,
0x0C, 0x89, 0x30, 0x19, 0x81, 0x0C, 0x90, 0x38, 0x19, 0x04, 0x18, 0x05,
0x19, 0x0F, 0x83, 0x5C, 0x0C, 0x19, 0x81, 0x5A, 0x90, 0x38, 0x08, 0x00,
0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08, 0x19, 0x07, 0x90, 0x38, 0x08,
0x00, 0x00, 0x0B, 0x08, 0x5D, 0x5D, 0x0E, 0x0C, 0x5D, 0x5D, 0x0C, 0x08,
0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08,
0x19, 0x06, 0x2C, 0x19, 0x56, 0x90, 0x38, 0x19, 0x04, 0x30, 0x19, 0x0C,
0x90, 0x38, 0x35, 0x35, 0x35, 0x35, 0x19, 0x04, 0x04, 0x19, 0x81, 0x24,
0x90, 0x38, 0x10, 0x19, 0x05, 0xA0, 0x4A, 0x19, 0x06, 0x06, 0x19, 0x0C,
0x0C, 0x19, 0x08, 0x08, 0x19, 0x37, 0x90, 0x38, 0x19, 0x08, 0x18, 0x80,
0x01, 0x00, 0x00, 0x40, 0x19, 0x82, 0x34, 0x90, 0x38, 0x19, 0x08, 0x12,
0x19, 0x81, 0x14, 0x90, 0x38, 0x19, 0x05, 0x82, 0x74, 0x19, 0x18, 0x90,
0x38, 0x20, 0x19, 0x32, 0x90, 0x38, 0x19, 0x08, 0x10, 0x19, 0x0C, 0x90,
0x38, 0x01, 0x19, 0x49, 0x90, 0x38, 0x80, 0x2A, 0x19, 0x06, 0x84, 0x20,
0x19, 0x95, 0x3E, 0xA0, 0x70, 0x19, 0x83, 0x2C, 0x90, 0x38, 0x14, 0x14,
0x19, 0x4D, 0x90, 0x38, 0x19, 0x05, 0x8A, 0x08, 0x19, 0x87, 0x2A, 0x90,
0x38, 0x19, 0x84, 0x30, 0xA0, 0x70, 0x19, 0x84, 0x7A, 0x90, 0x38, 0x32,
0x32, 0x32, 0x32, 0x19, 0x04, 0x04, 0x19, 0x54, 0x90, 0x38, 0x18, 0x00,
0x0F, 0x19, 0x15, 0x90, 0x38, 0x19, 0x08, 0x18, 0x48, 0x00, 0x44, 0x00,
0x45, 0x00, 0x44, 0x00, 0x47, 0x19, 0x07, 0x90, 0x20, 0x0D, 0x19, 0x05,
0x83, 0x0E, 0x0D, 0x19, 0x18, 0x18, 0x00, 0x78, 0x00, 0x78, 0x19, 0x04,
0x04, 0x19, 0x08, 0x08, 0x19, 0x10, 0x10, 0x00, 0x18, 0x19, 0x05, 0x5A,
0x19, 0x04, 0x5C, 0x19, 0x06, 0x90, 0x38, 0x18, 0x19, 0x8B, 0x57, 0x90,
0x38, 0x19, 0x81, 0x6F, 0xC1, 0x60, 0x19, 0x8D, 0x31, 0xA0, 0x70, 0x19,
0x82, 0x18, 0xD2, 0x18, 0x19, 0x04, 0x34, 0x19, 0x82, 0x00, 0xD2, 0x18,
0x19, 0x82, 0x03, 0x90, 0x38, 0x19, 0x84, 0x1D, 0xD2, 0x18, 0x19, 0x08,
0x83, 0x7C, 0x19, 0x85, 0x16, 0xD2, 0x18, 0x19, 0x82, 0x76, 0xB1, 0x28,
0x19, 0x6F, 0x90, 0x38, 0x19, 0x81, 0x71, 0xA0, 0x70, 0x19, 0x50, 0xB1,
0x28, 0x19, 0x20, 0x90, 0x38, 0x19, 0x84, 0x54, 0xB1, 0x28, 0x19, 0x10,
0x90, 0x38, 0x19, 0x87, 0x04, 0xA0, 0x70, 0x19, 0x81, 0x6F, 0x90, 0x38,
0x19, 0x81, 0x15, 0xA0, 0x70, 0x19, 0x81, 0x2C, 0xC1, 0x60, 0x19, 0x57,
0x90, 0x38, 0x19, 0x8C, 0x51, 0xA0, 0x70, 0x06, 0x1B, 0x04, 0x1C, 0x07,
0x03, 0x05, 0x02, 0x00, 0x25, 0x25, 0x03, 0x00, 0x1E, 0x1D, 0x08, 0x0D,
0x0A, 0x0C, 0x09, 0x0B, 0x26, 0x26, 0x05, 0x02, 0x04, 0x03, 0x05, 0x00,
0x06, 0x1C, 0x1B, 0x07, 0x25, 0x25, 0x07, 0x0A, 0x0B, 0x1D, 0x0C, 0x0D,
0x09, 0x00, 0x08, 0x1E, 0x26, 0x26, 0x09, 0x24, 0x06, 0x08, 0x2A, 0x19,
0x82, 0x0C, 0xA0, 0x70, 0x10, 0x00, 0x14, 0x00, 0x0B, 0x00, 0x13, 0x19,
0x18, 0x18, 0x00, 0x47, 0x00, 0x45, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x46,
0x00, 0x46, 0x00, 0x48, 0x00, 0x48, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0C,
0x00, 0x0B, 0x19, 0x18, 0x18, 0x19, 0x21, 0x90, 0x38, 0x10, 0x19, 0x05,
0x5A, 0x19, 0x04, 0x5C, 0x19, 0x04, 0x5E, 0x13, 0x19, 0x13, 0x8D, 0x5D,
0x19, 0x78, 0xA0, 0x70, 0x28, 0x40, 0xFF, 0x9F, 0x9F, 0x19, 0x1D, 0x90,
0x38, 0x57, 0x21, 0x03, 0x64, 0x67, 0x04, 0x32, 0x51, 0x21, 0x56, 0x73,
0x04, 0x12, 0x60, 0x35, 0x47, 0x73, 0x56, 0x04, 0x12, 0x10, 0x72, 0x65,
0x43, 0x37, 0x21, 0x40, 0x65, 0x64, 0x21, 0x30, 0x57, 0x19, 0x3E, 0x90,
0x38, 0x9F, 0x19, 0x06, 0x90, 0x38, 0xCF, 0x33, 0x19, 0x54, 0x90, 0x38,
0x10, 0x08, 0x01, 0x03, 0x00, 0x50, 0x00, 0x40, 0x01, 0x19, 0x06, 0x90,
0x38, 0x08, 0x29, 0x32, 0x93, 0xA5, 0x54, 0x4A, 0x6B, 0x76, 0x87, 0x19,
0x82, 0x29, 0xA0, 0x70, 0xCB, 0xFA, 0xE4, 0xD3, 0xFE, 0x19, 0x82, 0x3A,
0x90, 0x38, 0x9C, 0x19, 0x84, 0x6F, 0xD2, 0x18, 0x19, 0x82, 0x60, 0xB1,
0x28, 0x19, 0x85, 0x44, 0xD2, 0x18, 0x19, 0x83, 0x48, 0xB1, 0x28
};
static const uint32_t sdram_params_index_table_erista[28] = {
0,
1,
2,
3,
4,
5,
6,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
};
static const uint32_t sdram_params_index_table_mariko[28] = {
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0,
1,
2,
3,
4,
1,
2,
3,
4,
5,
6,
7,
6,
8,
9,
0xA,
7,
6,
0xB,
0xB,
0xB,
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,649 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 <string.h>
#include "utils.h"
#include "se.h"
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size);
/* Globals for driver. */
static unsigned int g_se_modulus_sizes[KEYSLOT_RSA_MAX];
static unsigned int g_se_exp_sizes[KEYSLOT_RSA_MAX];
/* Initialize a SE linked list. */
void NOINLINE ll_init(volatile se_ll_t *ll, void *buffer, size_t size) {
ll->num_entries = 0; /* 1 Entry. */
if (buffer != NULL) {
ll->addr_info.address = (uint32_t) get_physical_address(buffer);
ll->addr_info.size = (uint32_t) size;
} else {
ll->addr_info.address = 0;
ll->addr_info.size = 0;
}
}
void se_check_error_status_reg(void) {
if (se_get_regs()->SE_ERR_STATUS) {
generic_panic();
}
}
void se_check_for_error(void) {
volatile tegra_se_t *se = se_get_regs();
if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) {
generic_panic();
}
}
void se_verify_flags_cleared(void) {
if (se_get_regs()->SE_STATUS & 3) {
generic_panic();
}
}
/* Set the flags for an AES keyslot. */
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
/* Misc flags. */
if (flags & ~0x80) {
se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags;
}
/* Disable keyslot reads. */
if (flags & 0x80) {
se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot);
}
}
/* Set the flags for an RSA keyslot. */
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_RSA_MAX) {
generic_panic();
}
/* Misc flags. */
if (flags & ~0x80) {
/* TODO: Why are flags assigned this way? */
se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
}
/* Disable keyslot reads. */
if (flags & 0x80) {
se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot);
}
}
void clear_aes_keyslot(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
/* Zero out the whole keyslot and IV. */
for (unsigned int i = 0; i < 0x10; i++) {
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
se->SE_CRYPTO_KEYTABLE_DATA = 0;
}
}
void clear_rsa_keyslot(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_RSA_MAX) {
generic_panic();
}
/* Zero out the whole keyslot. */
for (unsigned int i = 0; i < 0x40; i++) {
/* Select Keyslot Modulus[i] */
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
se->SE_RSA_KEYTABLE_DATA = 0;
}
for (unsigned int i = 0; i < 0x40; i++) {
/* Select Keyslot Expontent[i] */
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
se->SE_RSA_KEYTABLE_DATA = 0;
}
}
void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) {
generic_panic();
}
for (size_t i = 0; i < (key_size >> 2); i++) {
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i);
}
}
void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) {
generic_panic();
}
for (size_t i = 0; i < (modulus_size >> 2); i++) {
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
se->SE_RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4);
}
for (size_t i = 0; i < (exp_size >> 2); i++) {
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
se->SE_RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4);
}
g_se_modulus_sizes[keyslot] = modulus_size;
g_se_exp_sizes[keyslot] = exp_size;
}
void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) {
generic_panic();
}
for (size_t i = 0; i < (iv_size >> 2); i++) {
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i);
}
}
void clear_aes_keyslot_iv(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
for (size_t i = 0; i < (0x10 >> 2); i++) {
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
se->SE_CRYPTO_KEYTABLE_DATA = 0;
}
}
void set_se_ctr(const void *ctr) {
for (unsigned int i = 0; i < 4; i++) {
se_get_regs()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4);
}
}
void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSLOT_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) {
generic_panic();
}
se->SE_CONFIG = (ALG_AES_DEC | DST_KEYTAB);
se->SE_CRYPTO_CONFIG = keyslot_src << 24;
se->SE_CRYPTO_LAST_BLOCK = 0;
se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8;
trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size);
}
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
volatile tegra_se_t *se = se_get_regs();
uint8_t ALIGN(16) stack_buf[KEYSIZE_RSA_MAX];
if (keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) {
generic_panic();
}
/* Endian swap the input. */
for (size_t i = 0; i < src_size; i++) {
stack_buf[i] = *((uint8_t *)src + src_size - i - 1);
}
se->SE_CONFIG = (ALG_RSA | DST_RSAREG);
se->SE_RSA_CONFIG = keyslot << 24;
se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1;
se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2;
trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size);
se_get_exp_mod_output(dst, dst_size);
}
void se_get_exp_mod_output(void *buf, size_t size) {
size_t num_dwords = (size >> 2);
if (num_dwords < 1) {
return;
}
uint32_t *p_out = ((uint32_t *)buf) + num_dwords - 1;
uint32_t offset = 0;
/* Copy endian swapped output. */
while (num_dwords) {
*p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset);
offset += 4;
p_out--;
num_dwords--;
}
}
bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size) {
uint8_t message[RSA_2048_BYTES];
uint8_t h_buf[0x24];
/* Hardcode RSA with keyslot 0. */
const uint8_t public_exponent[4] = {0x00, 0x01, 0x00, 0x01};
set_rsa_keyslot(0, modulus, modulus_size, public_exponent, sizeof(public_exponent));
se_synchronous_exp_mod(0, message, sizeof(message), signature, signature_size);
/* Validate sanity byte. */
if (message[RSA_2048_BYTES - 1] != 0xBC) {
return false;
}
/* Copy Salt into MGF1 Hash Buffer. */
memset(h_buf, 0, sizeof(h_buf));
memcpy(h_buf, message + RSA_2048_BYTES - 0x20 - 0x1, 0x20);
/* Decrypt maskedDB (via inline MGF1). */
uint8_t seed = 0;
uint8_t mgf1_buf[0x20];
for (unsigned int ofs = 0; ofs < RSA_2048_BYTES - 0x20 - 1; ofs += 0x20) {
h_buf[sizeof(h_buf) - 1] = seed++;
se_calculate_sha256(mgf1_buf, h_buf, sizeof(h_buf));
for (unsigned int i = ofs; i < ofs + 0x20 && i < RSA_2048_BYTES - 0x20 - 1; i++) {
message[i] ^= mgf1_buf[i - ofs];
}
}
/* Constant lmask for rsa-2048-pss. */
message[0] &= 0x7F;
/* Validate DB is of the form 0000...0001. */
for (unsigned int i = 0; i < RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1; i++) {
if (message[i] != 0) {
return false;
}
}
if (message[RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1] != 1) {
return false;
}
/* Check hash correctness. */
uint8_t validate_buf[8 + 0x20 + 0x20];
uint8_t validate_hash[0x20];
memset(validate_buf, 0, sizeof(validate_buf));
se_calculate_sha256(&validate_buf[8], data, data_size);
memcpy(&validate_buf[0x28], &message[RSA_2048_BYTES - 0x20 - 0x20 - 1], 0x20);
se_calculate_sha256(validate_hash, validate_buf, sizeof(validate_buf));
return memcmp(h_buf, validate_hash, 0x20) == 0;
}
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size) {
volatile tegra_se_t *se = se_get_regs();
se_ll_t in_ll;
se_ll_t out_ll;
ll_init(&in_ll, (void *)src, src_size);
ll_init(&out_ll, dst, dst_size);
/* Set the LLs. */
se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll);
se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll);
/* Set registers for operation. */
se->SE_ERR_STATUS = se->SE_ERR_STATUS;
se->SE_INT_STATUS = se->SE_INT_STATUS;
se->SE_OPERATION = op;
while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ }
se_check_for_error();
}
/* Secure AES Functionality. */
void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, size_t src_size) {
uint8_t block[0x10] = {0};
if (src_size > sizeof(block) || dst_size > sizeof(block)) {
generic_panic();
}
/* Load src data into block. */
if (src_size != 0) {
memcpy(block, src, src_size);
}
/* Trigger AES operation. */
se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0;
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
/* Copy output data into dst. */
if (dst_size != 0) {
memcpy(dst, block, dst_size);
}
}
void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) {
generic_panic();
}
unsigned int num_blocks = src_size >> 4;
/* Unknown what this write does, but official code writes it for CTR mode. */
se->SE_SPARE = 1;
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY);
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x91E;
set_se_ctr(ctr);
/* Handle any aligned blocks. */
size_t aligned_size = (size_t)num_blocks << 4;
if (aligned_size) {
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1;
trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size);
}
/* Handle final, unaligned block. */
if (aligned_size < dst_size && aligned_size < src_size) {
size_t last_block_size = dst_size - aligned_size;
if (src_size < dst_size) {
last_block_size = src_size - aligned_size;
}
se_perform_aes_block_operation(dst + aligned_size, last_block_size, (uint8_t *)src + aligned_size, src_size - aligned_size);
}
}
void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
generic_panic();
}
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100;
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
}
void se_aes_128_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
se_aes_ecb_encrypt_block(keyslot, dst, dst_size, src, src_size, 0);
}
void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
se_aes_ecb_encrypt_block(keyslot, dst, dst_size, src, src_size, 0x202);
}
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
generic_panic();
}
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
se->SE_CRYPTO_CONFIG = keyslot << 24;
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
}
void shift_left_xor_rb(uint8_t *key) {
uint8_t prev_high_bit = 0;
for (unsigned int i = 0; i < 0x10; i++) {
uint8_t cur_byte = key[0xF - i];
key[0xF - i] = (cur_byte << 1) | (prev_high_bit);
prev_high_bit = cur_byte >> 7;
}
if (prev_high_bit) {
key[0xF] ^= 0x87;
}
}
void shift_left_xor_rb_le(uint8_t *key) {
uint8_t prev_high_bit = 0;
for (unsigned int i = 0; i < 0x10; i++) {
uint8_t cur_byte = key[i];
key[i] = (cur_byte << 1) | (prev_high_bit);
prev_high_bit = cur_byte >> 7;
}
if (prev_high_bit) {
key[0x0] ^= 0x87;
}
}
void aes_128_xts_nintendo_get_tweak(uint8_t *tweak, size_t sector) {
for (int i = 0xF; i >= 0; i--) { /* Nintendo LE custom tweak... */
tweak[i] = (unsigned char)(sector & 0xFF);
sector >>= 8;
}
}
void aes_128_xts_nintendo_xor_with_tweak(unsigned int keyslot, size_t sector, uint8_t *dst, const uint8_t *src, size_t size) {
if ((size & 0xF) || size == 0) {
generic_panic();
}
uint8_t tweak[0x10];
aes_128_xts_nintendo_get_tweak(tweak, sector);
se_aes_128_ecb_encrypt_block(keyslot, tweak, sizeof(tweak), tweak, sizeof(tweak));
for (unsigned int block = 0; block < (size >> 4); block++) {
for (unsigned int i = 0; i < 0x10; i++) {
dst[(block << 4) | i] = src[(block << 4) | i] ^ tweak[i];
}
shift_left_xor_rb_le(tweak);
}
}
void aes_128_xts_nintendo_crypt_sector(unsigned int keyslot_1, unsigned int keyslot_2, size_t sector, bool encrypt, void *dst, const void *src, size_t size) {
volatile tegra_se_t *se = se_get_regs();
if ((size & 0xF) || size == 0) {
generic_panic();
}
/* XOR. */
aes_128_xts_nintendo_xor_with_tweak(keyslot_2, sector, dst, src, size);
/* Encrypt/Decrypt. */
if (encrypt) {
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY);
se->SE_CRYPTO_CONFIG = keyslot_1 << 24 | 0x100;
} else {
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
se->SE_CRYPTO_CONFIG = keyslot_1 << 24;
}
se->SE_CRYPTO_LAST_BLOCK = (size >> 4) - 1;
trigger_se_blocking_op(OP_START, dst, size, src, size);
/* XOR. */
aes_128_xts_nintendo_xor_with_tweak(keyslot_2, sector, dst, dst, size);
}
/* Encrypt with AES-XTS (Nintendo's custom tweak). */
void se_aes_128_xts_nintendo_encrypt(unsigned int keyslot_1, unsigned int keyslot_2, size_t base_sector, void *dst, const void *src, size_t size, unsigned int sector_size) {
if ((size & 0xF) || size == 0) {
generic_panic();
}
size_t sector = base_sector;
for (size_t ofs = 0; ofs < size; ofs += sector_size) {
aes_128_xts_nintendo_crypt_sector(keyslot_1, keyslot_2, sector, true, dst + ofs, src + ofs, sector_size);
sector++;
}
}
/* Decrypt with AES-XTS (Nintendo's custom tweak). */
void se_aes_128_xts_nintendo_decrypt(unsigned int keyslot_1, unsigned int keyslot_2, size_t base_sector, void *dst, const void *src, size_t size, unsigned int sector_size) {
if ((size & 0xF) || size == 0) {
generic_panic();
}
size_t sector = base_sector;
for (size_t ofs = 0; ofs < size; ofs += sector_size) {
aes_128_xts_nintendo_crypt_sector(keyslot_1, keyslot_2, sector, false, dst + ofs, src + ofs, sector_size);
sector++;
}
}
void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
/* Generate the derived key, to be XOR'd with final output block. */
uint8_t ALIGN(16) derived_key[0x10] = {0};
se_aes_ecb_encrypt_block(keyslot, derived_key, sizeof(derived_key), derived_key, sizeof(derived_key), config_high);
shift_left_xor_rb(derived_key);
if (data_size & 0xF) {
shift_left_xor_rb(derived_key);
}
se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145);
clear_aes_keyslot_iv(keyslot);
unsigned int num_blocks = (data_size + 0xF) >> 4;
/* Handle aligned blocks. */
if (num_blocks > 1) {
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2;
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
se->SE_CRYPTO_CONFIG |= 0x80;
}
/* Create final block. */
uint8_t ALIGN(16) last_block[0x10] = {0};
if (data_size & 0xF) {
memcpy(last_block, data + (data_size & ~0xF), data_size & 0xF);
last_block[data_size & 0xF] = 0x80; /* Last block = data || 100...0 */
} else if (data_size >= 0x10) {
memcpy(last_block, data + data_size - 0x10, 0x10);
}
for (unsigned int i = 0; i < 0x10; i++) {
last_block[i] ^= derived_key[i];
}
/* Perform last operation. */
se->SE_CRYPTO_LAST_BLOCK = 0;
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
/* Copy output CMAC. */
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
((uint32_t *)cmac)[i] = read32le(se->SE_HASH_RESULT, i << 2);
}
}
void se_compute_aes_128_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size) {
se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0);
}
void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size) {
se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0x202);
}
void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
generic_panic();
}
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144;
set_aes_keyslot_iv(keyslot, iv, 0x10);
se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1;
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
}
/* SHA256 Implementation. */
void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
volatile tegra_se_t *se = se_get_regs();
/* Setup config for SHA256, size = BITS(src_size) */
se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
se->SE_SHA_CONFIG = 1;
se->SE_SHA_MSG_LENGTH[0] = (uint32_t)(src_size << 3);
se->SE_SHA_MSG_LENGTH[1] = 0;
se->SE_SHA_MSG_LENGTH[2] = 0;
se->SE_SHA_MSG_LENGTH[3] = 0;
se->SE_SHA_MSG_LEFT[0] = (uint32_t)(src_size << 3);
se->SE_SHA_MSG_LEFT[1] = 0;
se->SE_SHA_MSG_LEFT[2] = 0;
se->SE_SHA_MSG_LEFT[3] = 0;
/* Trigger the operation. */
trigger_se_blocking_op(OP_START, NULL, 0, src, src_size);
/* Copy output hash. */
for (unsigned int i = 0; i < (0x20 >> 2); i++) {
((uint32_t *)dst)[i] = read32be(se->SE_HASH_RESULT, i << 2);
}
}
/* RNG API */
void se_initialize_rng(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
/* To initialize the RNG, we'll perform an RNG operation into an output buffer. */
/* This will be discarded, when done. */
uint8_t ALIGN(16) output_buf[0x10];
se->SE_RNG_SRC_CONFIG = 3; /* Entropy enable + Entropy lock enable */
se->SE_RNG_RESEED_INTERVAL = 70001;
se->SE_CONFIG = (ALG_RNG | DST_MEMORY);
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108;
se->SE_RNG_CONFIG = 5;
se->SE_CRYPTO_LAST_BLOCK = 0;
trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0);
}
void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
uint32_t num_blocks = size >> 4;
size_t aligned_size = num_blocks << 4;
se->SE_CONFIG = (ALG_RNG | DST_MEMORY);
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108;
se->SE_RNG_CONFIG = 4;
if (num_blocks >= 1) {
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1;
trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0);
}
if (size > aligned_size) {
se_perform_aes_block_operation(dst + aligned_size, size - aligned_size, NULL, 0);
}
}

View File

@@ -1,207 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_SE_H
#define FUSEE_SE_H
#define SE_BASE 0x70012000
#define MAKE_SE_REG(n) MAKE_REG32(SE_BASE + n)
#define KEYSLOT_SWITCH_LP0TZRAMKEY 0x2
#define KEYSLOT_SWITCH_SRKGENKEY 0x8
#define KEYSLOT_SWITCH_PACKAGE2KEY 0x8
#define KEYSLOT_SWITCH_TEMPKEY 0x9
#define KEYSLOT_SWITCH_SESSIONKEY 0xA
#define KEYSLOT_SWITCH_RNGKEY 0xB
#define KEYSLOT_SWITCH_MASTERKEY 0xC
#define KEYSLOT_SWITCH_DEVICEKEY 0xD
/* This keyslot was added in 4.0.0. */
#define KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY 0xD
#define KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY 0xE
#define KEYSLOT_SWITCH_4XOLDDEVICEKEY 0xF
/* This keyslot was added in 5.0.0. */
#define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA
#define KEYSLOT_AES_MAX 0x10
#define KEYSLOT_RSA_MAX 0x2
#define KEYSIZE_AES_MAX 0x20
#define KEYSIZE_RSA_MAX 0x100
#define ALG_SHIFT (12)
#define ALG_DEC_SHIFT (8)
#define ALG_NOP (0 << ALG_SHIFT)
#define ALG_AES_ENC (1 << ALG_SHIFT)
#define ALG_AES_DEC ((1 << ALG_DEC_SHIFT) | ALG_NOP)
#define ALG_RNG (2 << ALG_SHIFT)
#define ALG_SHA (3 << ALG_SHIFT)
#define ALG_RSA (4 << ALG_SHIFT)
#define DST_SHIFT (2)
#define DST_MEMORY (0 << DST_SHIFT)
#define DST_HASHREG (1 << DST_SHIFT)
#define DST_KEYTAB (2 << DST_SHIFT)
#define DST_SRK (3 << DST_SHIFT)
#define DST_RSAREG (4 << DST_SHIFT)
#define ENCMODE_SHIFT (24)
#define DECMODE_SHIFT (16)
#define ENCMODE_SHA256 (5 << ENCMODE_SHIFT)
#define HASH_DISABLE (0x0)
#define HASH_ENABLE (0x1)
#define OP_ABORT 0
#define OP_START 1
#define OP_RESTART 2
#define OP_CTX_SAVE 3
#define OP_RESTART_IN 4
#define CTX_SAVE_SRC_SHIFT 29
#define CTX_SAVE_SRC_STICKY_BITS (0 << CTX_SAVE_SRC_SHIFT)
#define CTX_SAVE_SRC_KEYTABLE_AES (2 << CTX_SAVE_SRC_SHIFT)
#define CTX_SAVE_SRC_KEYTABLE_RSA (1 << CTX_SAVE_SRC_SHIFT)
#define CTX_SAVE_SRC_MEM (4 << CTX_SAVE_SRC_SHIFT)
#define CTX_SAVE_SRC_SRK (6 << CTX_SAVE_SRC_SHIFT)
#define CTX_SAVE_KEY_LOW_BITS 0
#define CTX_SAVE_KEY_HIGH_BITS 1
#define CTX_SAVE_KEY_ORIGINAL_IV 2
#define CTX_SAVE_KEY_UPDATED_IV 3
#define CTX_SAVE_STICKY_BIT_INDEX_SHIFT 24
#define CTX_SAVE_KEY_INDEX_SHIFT 8
#define CTX_SAVE_RSA_KEY_INDEX_SHIFT 16
#define CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT 12
#define RSA_2048_BYTES 0x100
typedef struct {
uint32_t SE_SE_SECURITY;
uint32_t SE_TZRAM_SECURITY;
uint32_t SE_OPERATION;
uint32_t SE_INT_ENABLE;
uint32_t SE_INT_STATUS;
uint32_t SE_CONFIG;
uint32_t SE_IN_LL_ADDR;
uint32_t SE_IN_CUR_BYTE_ADDR;
uint32_t SE_IN_CUR_LL_ID;
uint32_t SE_OUT_LL_ADDR;
uint32_t SE_OUT_CUR_BYTE_ADDR;
uint32_t SE_OUT_CUR_LL_ID;
uint32_t SE_HASH_RESULT[0x10];
uint32_t SE_CTX_SAVE_CONFIG;
uint32_t _0x74[0x63];
uint32_t SE_SHA_CONFIG;
uint32_t SE_SHA_MSG_LENGTH[0x4];
uint32_t SE_SHA_MSG_LEFT[0x4];
uint32_t _0x224[0x17];
uint32_t SE_CRYPTO_SECURITY_PERKEY;
uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10];
uint32_t _0x2C4[0x10];
uint32_t SE_CRYPTO_CONFIG;
uint32_t SE_CRYPTO_LINEAR_CTR[0x4];
uint32_t SE_CRYPTO_LAST_BLOCK;
uint32_t SE_CRYPTO_KEYTABLE_ADDR;
uint32_t SE_CRYPTO_KEYTABLE_DATA;
uint32_t _0x324[0x3];
uint32_t SE_CRYPTO_KEYTABLE_DST;
uint32_t _0x334[0x3];
uint32_t SE_RNG_CONFIG;
uint32_t SE_RNG_SRC_CONFIG;
uint32_t SE_RNG_RESEED_INTERVAL;
uint32_t _0x34C[0x2D];
uint32_t SE_RSA_CONFIG;
uint32_t SE_RSA_KEY_SIZE;
uint32_t SE_RSA_EXP_SIZE;
uint32_t SE_RSA_SECURITY_PERKEY;
uint32_t SE_RSA_KEYTABLE_ACCESS[0x2];
uint32_t _0x418[0x2];
uint32_t SE_RSA_KEYTABLE_ADDR;
uint32_t SE_RSA_KEYTABLE_DATA;
uint32_t SE_RSA_OUTPUT[0x40];
uint32_t _0x528[0xB6];
uint32_t SE_STATUS;
uint32_t SE_ERR_STATUS;
uint32_t SE_MISC;
uint32_t SE_SPARE;
uint32_t SE_ENTROPY_DEBUG_COUNTER;
uint32_t _0x814;
uint32_t _0x818;
uint32_t _0x81C;
uint32_t _0x820[0x5F8];
} tegra_se_t;
typedef struct {
uint32_t address;
uint32_t size;
} se_addr_info_t;
typedef struct {
uint32_t num_entries; /* Set to total entries - 1 */
se_addr_info_t addr_info; /* This should really be an array...but for our use case it works. */
} se_ll_t;
static inline volatile tegra_se_t *se_get_regs(void) {
return (volatile tegra_se_t *)SE_BASE;
}
void se_check_error_status_reg(void);
void se_check_for_error(void);
void se_trigger_interrupt(void);
void se_validate_stored_vector(void);
void se_generate_stored_vector(void);
void se_verify_flags_cleared(void);
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags);
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags);
void clear_aes_keyslot(unsigned int keyslot);
void clear_rsa_keyslot(unsigned int keyslot);
void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size);
void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size);
void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size);
void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size);
void set_se_ctr(const void *ctr);
/* Secure AES API */
void se_aes_128_xts_nintendo_decrypt(unsigned int keyslot_1, unsigned int keyslot_2, unsigned int base_sector, void *dst, const void *src, size_t size, unsigned int sector_size);
void se_aes_128_xts_nintendo_encrypt(unsigned int keyslot_1, unsigned int keyslot_2, unsigned int base_sector, void *dst, const void *src, size_t size, unsigned int sector_size);
void se_compute_aes_128_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size);
void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size);
void se_aes_128_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size);
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv);
/* Hash API */
void se_calculate_sha256(void *dst, const void *src, size_t src_size);
/* RSA API */
void se_get_exp_mod_output(void *buf, size_t size);
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size);
/* RNG API */
void se_initialize_rng(unsigned int keyslot);
void se_generate_random(unsigned int keyslot, void *dst, size_t size);
#endif

View File

@@ -1,170 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 "stage2.h"
#include "chainloader.h"
#include "fs_utils.h"
#include "utils.h"
char g_stage2_path[0x100] = {0};
const char *stage2_get_program_path(void) {
return g_stage2_path;
}
static int stage2_ini_handler(void *user, const char *section, const char *name, const char *value) {
stage2_config_t *config = (stage2_config_t *)user;
uintptr_t x = 0;
if (strcmp(section, "stage1") == 0) {
if (strcmp(name, STAGE2_NAME_KEY) == 0) {
strncpy(config->path, value, sizeof(config->path) - 1);
config->path[sizeof(config->path) - 1] = '\0';
} else if (strcmp(name, STAGE2_MTC_NAME_KEY) == 0) {
strncpy(config->mtc_path, value, sizeof(config->mtc_path) - 1);
config->mtc_path[sizeof(config->mtc_path) - 1] = '\0';
} else if (strcmp(name, STAGE2_ADDRESS_KEY) == 0) {
/* Read in load address as a hex string. */
sscanf(value, "%x", &x);
config->load_address = x;
if (config->entrypoint == 0) {
config->entrypoint = config->load_address;
}
} else if (strcmp(name, STAGE2_ENTRYPOINT_KEY) == 0) {
/* Read in entrypoint as a hex string. */
sscanf(value, "%x", &x);
config->entrypoint = x;
} else {
return 0;
}
} else {
return 0;
}
return 1;
}
static bool run_mtc(const char *mtc_path, uintptr_t mtc_address) {
FILINFO info;
size_t size;
/* Check if the MTC binary is present. */
if (f_stat(mtc_path, &info) != FR_OK) {
print(SCREEN_LOG_LEVEL_WARNING, "Stage2's MTC binary not found!\n");
return false;
}
size = (size_t)info.fsize;
/* Try to read the MTC binary. */
if (read_from_file((void *)mtc_address, size, mtc_path) != size) {
print(SCREEN_LOG_LEVEL_WARNING, "Failed to read stage2's MTC binary (%s)!\n", mtc_path);
return false;
}
ScreenLogLevel mtc_log_level = log_get_log_level();
bool mtc_res = false;
int mtc_argc = 1;
char mtc_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE] = {0};
stage2_mtc_args_t *mtc_args = (stage2_mtc_args_t *)mtc_arg_data;
/* Setup argument data. */
memcpy(&mtc_args->log_level, &mtc_log_level, sizeof(mtc_log_level));
/* Run the MTC binary. */
mtc_res = (((int (*)(int, void *))mtc_address)(mtc_argc, mtc_arg_data) == 0);
/* Cleanup right away. */
memset((void *)mtc_address, 0, size);
return mtc_res;
}
void load_stage2(const char *bct0) {
stage2_config_t config = {0};
FILINFO info;
size_t size;
uintptr_t tmp_addr;
if (ini_parse_string(bct0, stage2_ini_handler, &config) < 0) {
fatal_error("Failed to parse BCT.ini!\n");
}
if (config.load_address == 0 || config.path[0] == '\x00') {
fatal_error("Failed to determine where to load stage2!\n");
}
if (strlen(config.path) + 1 + sizeof(stage2_args_t) > CHAINLOADER_ARG_DATA_MAX_SIZE) {
fatal_error("Stage2's path name is too big!\n");
}
if (!check_32bit_address_loadable(config.entrypoint)) {
fatal_error("Stage2's entrypoint is invalid!\n");
}
if (!check_32bit_address_loadable(config.load_address)) {
fatal_error("Stage2's load address is invalid!\n");
}
print(SCREEN_LOG_LEVEL_DEBUG, "Stage 2 Config:\n");
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " File Path: %s\n", config.path);
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " MTC File Path: %s\n", config.mtc_path);
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Load Address: 0x%08x\n", config.load_address);
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Entrypoint: 0x%p\n", config.entrypoint);
/* Run the MTC binary. */
if (!run_mtc(config.mtc_path, config.load_address)) {
print(SCREEN_LOG_LEVEL_WARNING, "DRAM training failed! Continuing with untrained DRAM.\n");
}
if (f_stat(config.path, &info) != FR_OK) {
fatal_error("Failed to stat stage2 (%s)!\n", config.path);
}
size = (size_t)info.fsize;
/* the LFB is located at 0xC0000000 atm */
if (size > 0xC0000000u - 0x80000000u) {
fatal_error("Stage2 is way too big!\n");
}
if (!check_32bit_address_range_loadable(config.load_address, size)) {
fatal_error("Stage2 has an invalid load address & size combination (0x%08x 0x%08x)!\n", config.load_address, size);
}
if (config.entrypoint < config.load_address || config.entrypoint >= config.load_address + size) {
fatal_error("Stage2's entrypoint is outside Stage2!\n");
}
if (check_32bit_address_range_in_program(config.load_address, size)) {
tmp_addr = 0x80000000u;
} else {
tmp_addr = config.load_address;
}
/* Try to read stage2. */
if (read_from_file((void *)tmp_addr, size, config.path) != size) {
fatal_error("Failed to read stage2 (%s)!\n", config.path);
}
g_chainloader_num_entries = 1;
g_chainloader_entries[0].load_address = config.load_address;
g_chainloader_entries[0].src_address = tmp_addr;
g_chainloader_entries[0].size = size;
g_chainloader_entries[0].num = 0;
g_chainloader_entrypoint = config.entrypoint;
strncpy(g_stage2_path, config.path, sizeof(g_stage2_path) - 1);
g_stage2_path[sizeof(g_stage2_path) - 1] = '\0';
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_STAGE2_H
#define FUSEE_STAGE2_H
#include <stdbool.h>
#include <stdint.h>
#include "../../../fusee/common/display/video_fb.h"
#include "../../../fusee/common/log.h"
#include "../../../fusee/common/vsprintf.h"
#include "../../../fusee/common/ini.h"
#include "../../../fusee/common/fatfs/ff.h"
/* TODO: Is there a more concise way to do this? */
#define STAGE2_ARGV_PROGRAM_PATH 0
#define STAGE2_ARGV_ARGUMENT_STRUCT 1
#define STAGE2_ARGC 2
#define STAGE2_NAME_KEY "stage2_path"
#define STAGE2_MTC_NAME_KEY "stage2_mtc_path"
#define STAGE2_ADDRESS_KEY "stage2_addr"
#define STAGE2_ENTRYPOINT_KEY "stage2_entrypoint"
#define BCTO_MAX_SIZE 0x5800
typedef struct {
char path[0x100];
char mtc_path[0x100];
uintptr_t load_address;
uintptr_t entrypoint;
} stage2_config_t;
typedef struct {
uint32_t version;
ScreenLogLevel log_level;
char bct0[BCTO_MAX_SIZE];
} stage2_args_t;
typedef struct {
ScreenLogLevel log_level;
} stage2_mtc_args_t;
const char *stage2_get_program_path(void);
void load_stage2(const char *bct0);
#endif

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
.macro CLEAR_GPR_REG_ITER
mov r\@, #0
.endm
@@ -27,46 +27,35 @@ _start:
/* Switch to system mode, mask all interrupts, clear all flags */
msr cpsr_cxsf, #0xDF
/* Relocate ourselves if necessary */
ldr r2, =__start__
adr r3, _start
cmp r2, r3
bne _relocation_loop_end
/* Relocate loader stub. */
ldr r0, =_start
adr r1, _start
ldr r2, =__loader_stub_lma__
sub r2, r2, r0
add r2, r2, r1
ldr r4, =__bss_start__
sub r4, r4, r2 /* size >= 32, obviously, and we've declared 32-byte-alignment */
ldr r3, =__loader_stub_start__
ldr r4, =__loader_stub_end__
sub r4, r4, r3
_relocation_loop:
ldmia r3!, {r5-r12}
stmia r2!, {r5-r12}
ldmia r2!, {r5-r12}
stmia r3!, {r5-r12}
subs r4, #0x20
bne _relocation_loop
ldr r12, =_relocation_loop_end
bx r12
_relocation_loop_end:
/* Set the stack pointer */
ldr sp, =__stack_top__
mov fp, #0
bl __program_init
/* Set r0 to r12 to 0 (for debugging) & call main */
.rept 13
CLEAR_GPR_REG_ITER
.endr
ldr r0, =__program_argc
ldr r1, =__program_argv
ldr lr, =__program_exit
ldr r0, [r0]
ldr r1, [r1]
b main
/* Generate arguments. */
ldr r3, =fusee_primary_main_lz4
ldr r4, =fusee_primary_main_lz4_end
sub r4, r4, r3
sub r3, r3, r0
add r3, r3, r1
mov r0, r3
mov r1, r4
/* No need to include this in normal programs: */
.section .chainloader.text.start, "ax", %progbits
.arm
.align 5
.global relocate_and_chainload
.type relocate_and_chainload, %function
relocate_and_chainload:
ldr sp, =__stack_top__
b relocate_and_chainload_main
/* Jump to the loader stub. */
ldr r3, =load_fusee_primary_main
bx r3

View File

@@ -1,44 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_SYSCTR0_H
#define FUSEE_SYSCTR0_H
#include <stdint.h>
#define SYSCTR0_BASE 0x700F0000
#define MAKE_SYSCTR0_REG(n) MAKE_REG32(SYSCTR0_BASE + n)
#define SYSCTR0_CNTCR_0 MAKE_SYSCTR0_REG(0x00)
#define SYSCTR0_CNTSR_0 MAKE_SYSCTR0_REG(0x04)
#define SYSCTR0_CNTCV0_0 MAKE_SYSCTR0_REG(0x08)
#define SYSCTR0_CNTCV1_0 MAKE_SYSCTR0_REG(0x0C)
#define SYSCTR0_CNTFID0_0 MAKE_SYSCTR0_REG(0x20)
#define SYSCTR0_CNTFID1_0 MAKE_SYSCTR0_REG(0x24)
#define SYSCTR0_COUNTERID4_0 MAKE_SYSCTR0_REG(0xFD0)
#define SYSCTR0_COUNTERID5_0 MAKE_SYSCTR0_REG(0xFD4)
#define SYSCTR0_COUNTERID6_0 MAKE_SYSCTR0_REG(0xFD8)
#define SYSCTR0_COUNTERID7_0 MAKE_SYSCTR0_REG(0xFDC)
#define SYSCTR0_COUNTERID0_0 MAKE_SYSCTR0_REG(0xFE0)
#define SYSCTR0_COUNTERID1_0 MAKE_SYSCTR0_REG(0xFE4)
#define SYSCTR0_COUNTERID2_0 MAKE_SYSCTR0_REG(0xFE8)
#define SYSCTR0_COUNTERID3_0 MAKE_SYSCTR0_REG(0xFEC)
#define SYSCTR0_COUNTERID8_0 MAKE_SYSCTR0_REG(0xFF0)
#define SYSCTR0_COUNTERID9_0 MAKE_SYSCTR0_REG(0xFF4)
#define SYSCTR0_COUNTERID10_0 MAKE_SYSCTR0_REG(0xFF8)
#define SYSCTR0_COUNTERID11_0 MAKE_SYSCTR0_REG(0xFFC)
#endif

View File

@@ -1,48 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_SYSREG_H
#define FUSEE_SYSREG_H
#include <stdint.h>
#define SYSREG_BASE 0x6000C000
#define SB_BASE (SYSREG_BASE + 0x200)
#define EXCP_VEC_BASE 0x6000F000
#define MAKE_SYSREG(n) MAKE_REG32(SYSREG_BASE + n)
#define MAKE_SB_REG(n) MAKE_REG32(SB_BASE + n)
#define MAKE_EXCP_VEC_REG(n) MAKE_REG32(EXCP_VEC_BASE + n)
#define AHB_ARBITRATION_DISABLE_0 MAKE_SYSREG(0x004)
#define AHB_ARBITRATION_XBAR_CTRL_0 MAKE_SYSREG(0x0E0)
#define AHB_AHB_SPARE_REG_0 MAKE_SYSREG(0x110)
#define SB_CSR_0 MAKE_SB_REG(0x00)
#define SB_PIROM_START_0 MAKE_SB_REG(0x04)
#define SB_PFCFG_0 MAKE_SB_REG(0x08)
#define SB_SECURE_SPAREREG_0_0 MAKE_SB_REG(0x0C)
#define SB_SECURE_SPAREREG_1_0 MAKE_SB_REG(0x10)
#define SB_SECURE_SPAREREG_2_0 MAKE_SB_REG(0x14)
#define SB_SECURE_SPAREREG_3_0 MAKE_SB_REG(0x18)
#define SB_SECURE_SPAREREG_4_0 MAKE_SB_REG(0x1C)
#define SB_SECURE_SPAREREG_5_0 MAKE_SB_REG(0x20)
#define SB_SECURE_SPAREREG_6_0 MAKE_SB_REG(0x24)
#define SB_SECURE_SPAREREG_7_0 MAKE_SB_REG(0x28)
#define SB_AA64_RESET_LOW_0 MAKE_SB_REG(0x30)
#define SB_AA64_RESET_HIGH_0 MAKE_SB_REG(0x34)
#endif

View File

@@ -1,94 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_TIMERS_H
#define FUSEE_TIMERS_H
#include "utils.h"
#define TIMERS_BASE 0x60005000
#define MAKE_TIMERS_REG(n) MAKE_REG32(TIMERS_BASE + n)
#define TIMERUS_CNTR_1US_0 MAKE_TIMERS_REG(0x10)
#define TIMERUS_USEC_CFG_0 MAKE_TIMERS_REG(0x14)
#define SHARED_INTR_STATUS_0 MAKE_TIMERS_REG(0x1A0)
#define SHARED_TIMER_SECURE_CFG_0 MAKE_TIMERS_REG(0x1A4)
#define RTC_BASE 0x7000E000
#define MAKE_RTC_REG(n) MAKE_REG32(RTC_BASE + n)
#define RTC_SECONDS MAKE_RTC_REG(0x08)
#define RTC_SHADOW_SECONDS MAKE_RTC_REG(0x0C)
#define RTC_MILLI_SECONDS MAKE_RTC_REG(0x10)
typedef struct {
uint32_t CONFIG;
uint32_t STATUS;
uint32_t COMMAND;
uint32_t PATTERN;
} watchdog_timers_t;
#define GET_WDT(n) ((volatile watchdog_timers_t *)(TIMERS_BASE + 0x100 + 0x20 * n))
#define WDT_REBOOT_PATTERN 0xC45A
#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8 * n)
void wait(uint32_t microseconds);
static inline uint32_t get_time_s(void) {
return RTC_SECONDS;
}
static inline uint32_t get_time_ms(void) {
return (RTC_MILLI_SECONDS | (RTC_SHADOW_SECONDS << 10));
}
static inline uint32_t get_time_us(void) {
return TIMERUS_CNTR_1US_0;
}
/**
* Returns the time in microseconds.
*/
static inline uint32_t get_time(void) {
return get_time_us();
}
/**
* Returns the number of microseconds that have passed since a given get_time().
*/
static inline uint32_t get_time_since(uint32_t base) {
return get_time_us() - base;
}
/**
* Delays for a given number of microseconds.
*/
static inline void udelay(uint32_t usecs) {
uint32_t start = get_time_us();
while (get_time_us() - start < usecs);
}
/**
* Delays for a given number of milliseconds.
*/
static inline void mdelay(uint32_t msecs) {
uint32_t start = get_time_ms();
while (get_time_ms() - start < msecs);
}
__attribute__ ((noreturn)) void watchdog_reboot(void);
#endif

View File

@@ -1,135 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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 "uart.h"
#include "timers.h"
#include "pinmux.h"
static inline void uart_wait_cycles(uint32_t baud, uint32_t num)
{
udelay((num * 1000000 + 16 * baud - 1) / (16 * baud));
}
static inline void uart_wait_syms(uint32_t baud, uint32_t num)
{
udelay((num * 1000000 + baud - 1) / baud);
}
void uart_config(UartDevice dev) {
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
switch (dev) {
case UART_A:
pinmux->uart1_tx = (0 | 0 | PINMUX_PULL_NONE | PINMUX_SELECT_FUNCTION0);
pinmux->uart1_rx = (PINMUX_INPUT | PINMUX_TRISTATE | PINMUX_PULL_UP | PINMUX_SELECT_FUNCTION0);
pinmux->uart1_rts = (0 | 0 | PINMUX_PULL_NONE | PINMUX_SELECT_FUNCTION0);
pinmux->uart1_cts = (PINMUX_INPUT | PINMUX_TRISTATE | PINMUX_PULL_DOWN | PINMUX_SELECT_FUNCTION0);
break;
case UART_B:
pinmux->uart2_tx = (0 | 0 | PINMUX_PULL_NONE | PINMUX_SELECT_FUNCTION0);
pinmux->uart2_rx = (PINMUX_INPUT | PINMUX_TRISTATE | PINMUX_PULL_NONE | PINMUX_SELECT_FUNCTION0);
pinmux->uart2_rts = (0 | 0 | PINMUX_PULL_DOWN | PINMUX_SELECT_FUNCTION0);
pinmux->uart2_cts = (PINMUX_INPUT | PINMUX_TRISTATE | PINMUX_PULL_NONE | PINMUX_SELECT_FUNCTION0);
break;
case UART_C:
pinmux->uart3_tx = (0 | 0 | PINMUX_PULL_NONE | PINMUX_SELECT_FUNCTION0);
pinmux->uart3_rx = (PINMUX_INPUT | PINMUX_TRISTATE | PINMUX_PULL_NONE | PINMUX_SELECT_FUNCTION0);
pinmux->uart3_rts = (0 | 0 | PINMUX_PULL_DOWN | PINMUX_SELECT_FUNCTION0);
pinmux->uart3_cts = (PINMUX_INPUT | PINMUX_TRISTATE | PINMUX_PULL_NONE | PINMUX_SELECT_FUNCTION0);
break;
case UART_D:
pinmux->uart4_tx = (0 | 0 | PINMUX_PULL_DOWN | PINMUX_SELECT_FUNCTION0);
pinmux->uart4_rx = (PINMUX_INPUT | PINMUX_TRISTATE | PINMUX_PULL_DOWN | PINMUX_SELECT_FUNCTION0);
pinmux->uart4_rts = (0 | 0 | PINMUX_PULL_DOWN | PINMUX_SELECT_FUNCTION0);
pinmux->uart4_cts = (PINMUX_INPUT | PINMUX_TRISTATE | PINMUX_PULL_DOWN | PINMUX_SELECT_FUNCTION0);
break;
case UART_E:
/* Unused. */
break;
default: break;
}
}
void uart_init(UartDevice dev, uint32_t baud) {
volatile tegra_uart_t *uart = uart_get_regs(dev);
/* Wait for idle state. */
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE);
/* Calculate baud rate, round to nearest. */
uint32_t rate = (8 * baud + 408000000) / (16 * baud);
/* Setup UART in FIFO mode. */
uart->UART_IER_DLAB = 0;
uart->UART_MCR = 0;
uart->UART_LCR = (UART_LCR_DLAB | UART_LCR_WD_LENGTH_8); /* Enable DLAB and set word length 8. */
uart->UART_THR_DLAB = (uint8_t)rate; /* Divisor latch LSB. */
uart->UART_IER_DLAB = (uint8_t)(rate >> 8); /* Divisor latch MSB. */
uart->UART_LCR &= ~(UART_LCR_DLAB); /* Disable DLAB. */
uart->UART_SPR; /* Dummy read. */
uart_wait_syms(baud, 3); /* Wait for 3 symbols at the new baudrate. */
/* Enable FIFO with default settings. */
uart->UART_IIR_FCR = UART_FCR_FCR_EN_FIFO;
uart->UART_SPR; /* Dummy read as mandated by TRM. */
uart_wait_cycles(baud, 3); /* Wait for 3 baud cycles, as mandated by TRM (erratum). */
/* Flush FIFO. */
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE); /* Make sure there's no data being written in TX FIFO (TRM). */
uart->UART_IIR_FCR |= UART_FCR_RX_CLR | UART_FCR_TX_CLR; /* Clear TX and RX FIFOs. */
uart_wait_cycles(baud, 32); /* Wait for 32 baud cycles (TRM, erratum). */
/* Wait for idle state (TRM). */
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE | UART_VENDOR_STATE_RX_IDLE);
}
/* This function blocks until the UART device is in the desired state. */
void uart_wait_idle(UartDevice dev, UartVendorStatus status) {
volatile tegra_uart_t *uart = uart_get_regs(dev);
if (status & UART_VENDOR_STATE_TX_IDLE) {
while (!(uart->UART_LSR & UART_LSR_TMTY)) {
/* Wait */
}
}
if (status & UART_VENDOR_STATE_RX_IDLE) {
while (uart->UART_LSR & UART_LSR_RDR) {
/* Wait */
}
}
}
void uart_send(UartDevice dev, const void *buf, size_t len) {
volatile tegra_uart_t *uart = uart_get_regs(dev);
for (size_t i = 0; i < len; i++) {
while (!(uart->UART_LSR & UART_LSR_THRE)) {
/* Wait until it's possible to send data. */
}
uart->UART_THR_DLAB = *((const uint8_t *)buf + i);
}
}
void uart_recv(UartDevice dev, void *buf, size_t len) {
volatile tegra_uart_t *uart = uart_get_regs(dev);
for (size_t i = 0; i < len; i++) {
while (!(uart->UART_LSR & UART_LSR_RDR)) {
/* Wait until it's possible to receive data. */
}
*((uint8_t *)buf + i) = uart->UART_THR_DLAB;
}
}

View File

@@ -1,171 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 Atmosphère-NX
*
* 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/>.
*/
#ifndef FUSEE_UART_H
#define FUSEE_UART_H
#include <string.h>
#define UART_BASE 0x70006000
#define BAUD_115200 115200
/* UART devices */
typedef enum {
UART_A = 0,
UART_B = 1,
UART_C = 2,
UART_D = 3,
UART_E = 4,
} UartDevice;
/* 36.3.12 UART_VENDOR_STATUS_0_0 */
typedef enum {
UART_VENDOR_STATE_TX_IDLE = 1 << 0,
UART_VENDOR_STATE_RX_IDLE = 1 << 1,
/* This bit is set to 1 when a read is issued to an empty FIFO and gets cleared on register read (sticky bit until read)
0 = NO_UNDERRUN
1 = UNDERRUN
*/
UART_VENDOR_STATE_RX_UNDERRUN = 1 << 2,
/* This bit is set to 1 when write data is issued to the TX FIFO when it is already full and gets cleared on register read (sticky bit until read)
0 = NO_OVERRUN
1 = OVERRUN
*/
UART_VENDOR_STATE_TX_OVERRUN = 1 << 3,
UART_VENDOR_STATE_RX_FIFO_COUNTER = 0b111111 << 16, /* reflects number of current entries in RX FIFO */
UART_VENDOR_STATE_TX_FIFO_COUNTER = 0b111111 << 24 /* reflects number of current entries in TX FIFO */
} UartVendorStatus;
/* 36.3.6 UART_LSR_0 */
typedef enum {
UART_LSR_RDR = 1 << 0, /* Receiver Data Ready */
UART_LSR_OVRF = 1 << 1, /* Receiver Overrun Error */
UART_LSR_PERR = 1 << 2, /* Parity Error */
UART_LSR_FERR = 1 << 3, /* Framing Error */
UART_LSR_BRK = 1 << 4, /* BREAK condition detected on line */
UART_LSR_THRE = 1 << 5, /* Transmit Holding Register is Empty -- OK to write data */
UART_LSR_TMTY = 1 << 6, /* Transmit Shift Register empty status */
UART_LSR_FIFOE = 1 << 7, /* Receive FIFO Error */
UART_LSR_TX_FIFO_FULL = 1 << 8, /* Transmitter FIFO full status */
UART_LSR_RX_FIFO_EMPTY = 1 << 9, /* Receiver FIFO empty status */
} UartLineStatus;
/* 36.3.4 UART_LCR_0 */
typedef enum {
UART_LCR_WD_LENGTH_5 = 0, /* word length 5 */
UART_LCR_WD_LENGTH_6 = 1, /* word length 6 */
UART_LCR_WD_LENGTH_7 = 2, /* word length 7 */
UART_LCR_WD_LENGTH_8 = 3, /* word length 8 */
/* STOP:
0 = Transmit 1 stop bit
1 = Transmit 2 stop bits (receiver always checks for 1 stop bit)
*/
UART_LCR_STOP = 1 << 2,
UART_LCR_PAR = 1 << 3, /* Parity enabled */
UART_LCR_EVEN = 1 << 4, /* Even parity format. There will always be an even number of 1s in the binary representation (PAR = 1) */
UART_LCR_SET_P = 1 << 5, /* Set (force) parity to value in LCR[4] */
UART_LCR_SET_B = 1 << 6, /* Set BREAK condition -- Transmitter sends all zeroes to indicate BREAK */
UART_LCR_DLAB = 1 << 7, /* Divisor Latch Access Bit (set to allow programming of the DLH, DLM Divisors) */
} UartLineControl;
/* 36.3.3 UART_IIR_FCR_0 */
typedef enum {
UART_FCR_FCR_EN_FIFO = 1 << 0, /* Enable the transmit and receive FIFOs. This bit should be enabled */
UART_FCR_RX_CLR = 1 << 1, /* Clears the contents of the receive FIFO and resets its counter logic to 0 (the receive shift register is not cleared or altered). This bit returns to 0 after clearing the FIFOs */
UART_FCR_TX_CLR = 1 << 2, /* Clears the contents of the transmit FIFO and resets its counter logic to 0 (the transmit shift register is not cleared or altered). This bit returns to 0 after clearing the FIFOs */
/* DMA:
0 = DMA_MODE_0
1 = DMA_MODE_1
*/
UART_FCR_DMA = 1 << 3,
/* TX_TRIG
0 = FIFO_COUNT_GREATER_16
1 = FIFO_COUNT_GREATER_8
2 = FIFO_COUNT_GREATER_4
3 = FIFO_COUNT_GREATER_1
*/
UART_FCR_TX_TRIG = 3 << 4,
UART_FCR_TX_TRIG_FIFO_COUNT_GREATER_16 = 0 << 4,
UART_FCR_TX_TRIG_FIFO_COUNT_GREATER_8 = 1 << 4,
UART_FCR_TX_TRIG_FIFO_COUNT_GREATER_4 = 2 << 4,
UART_FCR_TX_TRIG_FIFO_COUNT_GREATER_1 = 3 << 4,
/* RX_TRIG
0 = FIFO_COUNT_GREATER_1
1 = FIFO_COUNT_GREATER_4
2 = FIFO_COUNT_GREATER_8
3 = FIFO_COUNT_GREATER_16
*/
UART_FCR_RX_TRIG = 3 << 6,
UART_FCR_RX_TRIG_FIFO_COUNT_GREATER_1 = 0 << 6,
UART_FCR_RX_TRIG_FIFO_COUNT_GREATER_4 = 1 << 6,
UART_FCR_RX_TRIG_FIFO_COUNT_GREATER_8 = 2 << 6,
UART_FCR_RX_TRIG_FIFO_COUNT_GREATER_16 = 3 << 6,
} UartFifoControl;
/* 36.3.3 UART_IIR_FCR_0 */
typedef enum {
UART_IIR_IS_STA = 1 << 0, /* Interrupt Pending if ZERO */
UART_IIR_IS_PRI0 = 1 << 1, /* Encoded Interrupt ID Refer to IIR[3:0] table [36.3.3] */
UART_IIR_IS_PRI1 = 1 << 2, /* Encoded Interrupt ID Refer to IIR[3:0] table */
UART_IIR_IS_PRI2 = 1 << 3, /* Encoded Interrupt ID Refer to IIR[3:0] table */
/* FIFO Mode Status
0 = 16450 mode (no FIFO)
1 = 16550 mode (FIFO)
*/
UART_IIR_EN_FIFO = 3 << 6,
UART_IIR_MODE_16450 = 0 << 6,
UART_IIR_MODE_16550 = 1 << 6,
} UartInterruptIdentification;
typedef struct {
uint32_t UART_THR_DLAB;
uint32_t UART_IER_DLAB;
uint32_t UART_IIR_FCR;
uint32_t UART_LCR;
uint32_t UART_MCR;
uint32_t UART_LSR;
uint32_t UART_MSR;
uint32_t UART_SPR;
uint32_t UART_IRDA_CSR;
uint32_t UART_RX_FIFO_CFG;
uint32_t UART_MIE;
uint32_t UART_VENDOR_STATUS;
uint8_t _0x30[0x0C];
uint32_t UART_ASR;
} tegra_uart_t;
void uart_config(UartDevice dev);
void uart_init(UartDevice dev, uint32_t baud);
void uart_wait_idle(UartDevice dev, UartVendorStatus status);
void uart_send(UartDevice dev, const void *buf, size_t len);
void uart_recv(UartDevice dev, void *buf, size_t len);
static inline volatile tegra_uart_t *uart_get_regs(UartDevice dev) {
static const size_t offsets[] = {0, 0x40, 0x200, 0x300, 0x400};
return (volatile tegra_uart_t *)(UART_BASE + offsets[dev]);
}
#endif

View File

@@ -13,128 +13,36 @@
* 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 <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdarg.h>
#include "utils.h"
#include "di.h"
#include "se.h"
#include "fuse.h"
#include "pmc.h"
#include "timers.h"
#include "panic.h"
#include "car.h"
#include "btn.h"
#include "../../../fusee/common/log.h"
#include "../../../fusee/common/vsprintf.h"
#include "../../../fusee/common/display/video_fb.h"
#include <inttypes.h>
#define u8 uint8_t
#define u32 uint32_t
#include "rebootstub_bin.h"
#undef u8
#undef u32
void wait(uint32_t microseconds) {
uint32_t old_time = TIMERUS_CNTR_1US_0;
while (TIMERUS_CNTR_1US_0 - old_time <= microseconds) {
/* Spin-lock. */
static void copy_forwards(uint8_t *dst, const uint8_t *src, size_t size) {
for (int i = 0; i < size; ++i) {
dst[i] = src[i];
}
}
__attribute__((noreturn)) void watchdog_reboot(void) {
volatile watchdog_timers_t *wdt = GET_WDT(4);
wdt->PATTERN = WDT_REBOOT_PATTERN;
wdt->COMMAND = 2; /* Disable Counter. */
GET_WDT_REBOOT_CFG_REG(4) = 0xC0000000;
wdt->CONFIG = 0x8019; /* Full System Reset after Fourth Counter expires, using TIMER(9). */
wdt->COMMAND = 1; /* Enable Counter. */
while (true) {
/* Wait for reboot. */
static void copy_backwards(uint8_t *dst, const uint8_t *src, size_t size) {
for (int i = size - 1; i >= 0; --i) {
dst[i] = src[i];
}
}
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0) {
APBDEV_PMC_SCRATCH0_0 = scratch0;
void loader_memcpy(void *dst, const void *src, size_t size) {
copy_forwards(dst, src, size);
}
/* Reset the processor. */
APBDEV_PMC_CONTROL = BIT(4);
void loader_memmove(void *dst, const void *src, size_t size) {
const uintptr_t dst_u = (uintptr_t)dst;
const uintptr_t src_u = (uintptr_t)src;
while (true) {
/* Wait for reboot. */
if (dst_u < src_u) {
copy_forwards(dst, src, size);
} else if (dst_u > src_u) {
copy_backwards(dst, src, size);
} else {
/* Nothing to do */
}
}
__attribute__((noreturn)) void reboot_to_self(void) {
/* Patch SDRAM init to perform an SVC immediately after second write */
APBDEV_PMC_SCRATCH45_0 = 0x2E38DFFF;
APBDEV_PMC_SCRATCH46_0 = 0x6001DC28;
/* Set SVC handler to jump to reboot stub in IRAM. */
APBDEV_PMC_SCRATCH33_0 = 0x4003F000;
APBDEV_PMC_SCRATCH40_0 = 0x6000F208;
/* Copy reboot stub into IRAM high. */
for (size_t i = 0; i < rebootstub_bin_size; i += sizeof(uint32_t)) {
write32le((void *)0x4003F000, i, read32le(rebootstub_bin, i));
}
/* Trigger warm reboot. */
pmc_reboot(1 << 0);
}
__attribute__((noreturn)) void wait_for_button_and_reboot(void) {
uint32_t button;
while (true) {
button = btn_read();
if (button & BTN_POWER) {
reboot_to_self();
}
}
}
__attribute__ ((noreturn)) void generic_panic(void) {
panic(0xFF000006);
}
__attribute__((noreturn)) void fatal_error(const char *fmt, ...) {
/* Forcefully initialize the screen if logging is disabled. */
if (log_get_log_level() == SCREEN_LOG_LEVEL_NONE) {
/* Zero-fill the framebuffer and register it as printk provider. */
video_init((void *)0xC0000000);
/* Initialize the display. */
display_init();
/* Set the framebuffer. */
display_init_framebuffer((void *)0xC0000000);
/* Turn on the backlight after initializing the lfb */
/* to avoid flickering. */
display_backlight(true);
}
/* Override the global logging level. */
log_set_log_level(SCREEN_LOG_LEVEL_ERROR);
/* Display fatal error. */
va_list args;
print(SCREEN_LOG_LEVEL_ERROR, "Fatal error: ");
va_start(args, fmt);
vprint(SCREEN_LOG_LEVEL_ERROR, fmt, args);
va_end(args);
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"\nPress POWER to reboot\n");
/* Wait for button and reboot. */
wait_for_button_and_reboot();
}
__attribute__((noinline)) bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be)
{
if(as <= bs && bs <= ae)
return true;
if(bs <= as && as <= be)
return true;
return false;
}
}

View File

@@ -13,116 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FUSEE_UTILS_H
#define FUSEE_UTILS_H
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#define BIT(n) (1u << (n))
#define BITL(n) (1ull << (n))
#define MASK(n) (BIT(n) - 1)
#define MASKL(n) (BITL(n) - 1)
#define MASK2(a,b) (MASK(a) & ~MASK(b))
#define MASK2L(a,b) (MASKL(a) & ~MASKL(b))
#define MAKE_REG32(a) (*(volatile uint32_t *)(a))
#define ALIGN(m) __attribute__((aligned(m)))
#define PACKED __attribute__((packed))
#define ALINLINE __attribute__((always_inline))
#define NOINLINE __attribute__((noinline))
#define SET_SYSREG(reg, val) do { temp_reg = (val); __asm__ __volatile__ ("msr " #reg ", %0" :: "r"(temp_reg) : "memory"); } while(false)
static inline uintptr_t get_physical_address(const void *addr) {
return (uintptr_t)addr;
}
static inline uint32_t read32le(const volatile void *dword, size_t offset) {
uintptr_t addr = (uintptr_t)dword + offset;
volatile uint32_t *target = (uint32_t *)addr;
return *target;
}
static inline uint32_t read32be(const volatile void *dword, size_t offset) {
return __builtin_bswap32(read32le(dword, offset));
}
static inline uint64_t read64le(const volatile void *qword, size_t offset) {
uintptr_t addr = (uintptr_t)qword + offset;
volatile uint64_t *target = (uint64_t *)addr;
return *target;
}
static inline uint64_t read64be(const volatile void *qword, size_t offset) {
return __builtin_bswap64(read64le(qword, offset));
}
static inline void write32le(volatile void *dword, size_t offset, uint32_t value) {
uintptr_t addr = (uintptr_t)dword + offset;
volatile uint32_t *target = (uint32_t *)addr;
*target = value;
}
static inline void write32be(volatile void *dword, size_t offset, uint32_t value) {
write32le(dword, offset, __builtin_bswap32(value));
}
static inline void write64le(volatile void *qword, size_t offset, uint64_t value) {
uintptr_t addr = (uintptr_t)qword + offset;
volatile uint64_t *target = (uint64_t *)addr;
*target = value;
}
static inline void write64be(volatile void *qword, size_t offset, uint64_t value) {
write64le(qword, offset, __builtin_bswap64(value));
}
static inline bool check_32bit_additive_overflow(uint32_t a, uint32_t b) {
return __builtin_add_overflow_p(a, b, (uint32_t)0);
}
static inline bool check_32bit_address_loadable(uintptr_t addr) {
/* FWIW the bootROM forbids loading anything between 0x40000000 and 0x40010000, using it for itself... */
return (addr >= 0x40010000u && addr < 0x40040000u) || addr >= 0x80000000u;
}
static inline bool check_32bit_address_range_loadable(uintptr_t addr, size_t size) {
return
!__builtin_add_overflow_p(addr, size, (uintptr_t)0) && /* the range doesn't overflow */
check_32bit_address_loadable(addr) && check_32bit_address_loadable(addr + size) && /* bounds are valid */
!(addr >= 0x40010000u && addr < 0x40040000u && addr + size >= 0x40040000u) /* the range doesn't cross MMIO */
;
}
bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be);
static inline bool overlaps_a(const void *as, const void *ae, const void *bs, const void *be) {
return overlaps((uint64_t)(uintptr_t)as, (uint64_t)(uintptr_t)ae, (uint64_t)(uintptr_t)bs, (uint64_t)(uintptr_t)be);
}
static inline bool check_32bit_address_range_in_program(uintptr_t addr, size_t size) {
extern uint8_t __chainloader_start__[], __chainloader_end__[];
extern uint8_t __stack_bottom__[], __stack_top__[];
extern uint8_t __start__[], __end__[];
uint8_t *start = (uint8_t *)addr, *end = start + size;
return overlaps_a(start, end, __chainloader_start__, __chainloader_end__) ||
overlaps_a(start, end, __stack_bottom__, __stack_top__) ||
overlaps_a(start, end, (void *)0xC0000000, (void *)0xC03C0000) || /* framebuffer */
overlaps_a(start, end, __start__, __end__);
}
__attribute__((noreturn)) void watchdog_reboot(void);
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0);
__attribute__((noreturn)) void reboot_to_self(void);
__attribute__((noreturn)) void wait_for_button_and_reboot(void);
__attribute__((noreturn)) void generic_panic(void);
__attribute__((noreturn)) void fatal_error(const char *fmt, ...);
#endif
void loader_memcpy(void *dst, const void *src, size_t size);
void loader_memmove(void *dst, const void *src, size_t size);