So it has come to this.

This commit is contained in:
nwert 2018-05-01 17:15:48 +12:00
parent 6181b39f14
commit 8365426fc3
94 changed files with 23324 additions and 1283 deletions

3
.gitignore vendored Executable file
View File

@ -0,0 +1,3 @@
.vs
.vscode
build_ipl/*

69
Makefile Executable file
View File

@ -0,0 +1,69 @@
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
CC = $(DEVKITARM)/bin/arm-none-eabi-gcc
LD = $(DEVKITARM)/bin/arm-none-eabi-ld
OBJCOPY = $(DEVKITARM)/bin/arm-none-eabi-objcopy
TARGET := ipl
BUILD := build_ipl
SOURCEDIR := ipl
OBJS = $(addprefix $(BUILD)/, \
start.o \
main.o \
btn.o \
clock.o \
cluster.o \
fuse.o \
gpio.o \
heap.o \
hos.o \
i2c.o \
kfuse.o \
lz.o \
max7762x.o \
mc.o \
nx_emmc.o \
sdmmc.o \
sdmmc_driver.o \
sdram.o \
sdram_lp0.o \
tui.o \
util.o \
di.o \
gfx.o \
pinmux.o \
pkg1.o \
pkg2.o \
se.o \
tsec.o \
uart.o \
ini.o \
)
OBJS += $(addprefix $(BUILD)/, diskio.o ff.o ffunicode.o)
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11# -Wall
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections
.PHONY: all clean
all: $(BUILD)/$(TARGET)
clean:
@rm -rf $(OBJS)
@rm -rf $(BUILD)/$(TARGET).elf
@rm -rf $(BUILD)/$(TARGET)
$(BUILD)/$(TARGET): $(BUILD)/$(TARGET).elf
$(OBJCOPY) -S -O binary $< $@
$(BUILD)/$(TARGET).elf: $(OBJS)
$(CC) $(LDFLAGS) -T ipl/link.ld $^ -o $@
$(BUILD)/%.o: $(SOURCEDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
$(BUILD)/%.o: $(SOURCEDIR)/%.S
$(CC) $(CFLAGS) -c $< -o $@

View File

@ -1,2 +1,16 @@
# hekate
Low level hardware init (for now) for Nintendo Switch.
![Image of Hekate](https://upload.wikimedia.org/wikipedia/commons/f/fc/H%C3%A9cate_-_Mallarm%C3%A9.png)
Nintendo Switch bootloader, firmware patcher, and more.
## ipl config
The ipl can be configured via 'hekate_ipl.ini' (if it is present on the SD card). Each ini section represents a boot entry, except for the special section 'config' that controls the global configuration.
Possible key/value combinations:
- warmboot={SD path}
- secmon={SD path}
- kernel={SD path}
- kip1={SD path}

View File

@ -1,161 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "clock.h"
#include "t210.h"
#include "util.h"
static const clock_t _clock_uart[] = {
/* UART A */ { 4, 0x10, 0x178, 6, 0, 0 },
/* UART B */ { 4, 0x10, 0x17C, 7, 0, 0 },
/* UART C */ { 8, 0x14, 0x1A0, 0x17, 0, 0 },
/* UART D */ { 0 },
/* UART E */ { 0 }
};
static const clock_t _clock_i2c[] = {
/* I2C1 */ { 4, 0x10, 0x124, 0xC, 6, 0 },
/* I2C2 */ { 0 },
/* I2C3 */ { 0 },
/* I2C4 */ { 0 },
/* I2C5 */ { 8, 0x14, 0x128, 0xF, 6, 0 },
/* I2C6 */ { 0 }
};
static clock_t _clock_se = { 0x358, 0x360, 0x42C, 0x1F, 0, 0 };
static clock_t _clock_host1x = { 4, 0x10, 0x180, 0x1C, 4, 3 };
static clock_t _clock_tsec = { 0xC, 0x18, 0x1F4, 0x13, 0, 2 };
static clock_t _clock_sor_safe = { 0x2A4, 0x298, 0, 0x1E, 0, 0 };
static clock_t _clock_sor0 = { 0x28C, 0x280, 0, 0x16, 0, 0 };
static clock_t _clock_sor1 = { 0x28C, 0x280, 0x410, 0x17, 0, 2 };
static clock_t _clock_kfuse = { 8, 0x14, 0, 8, 0, 0 };
static clock_t _clock_coresight = { 0xC, 0x18, 0x1D4, 9, 0, 4};
void clock_enable(const clock_t *clk)
{
//Put clock into reset.
CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index);
//Disable.
CLOCK(clk->enable) &= ~(1 << clk->index);
//Configure clock source if required.
if (clk->source)
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
//Enable.
CLOCK(clk->enable) = CLOCK(clk->enable) & ~(1 << clk->index) | (1 << clk->index);
//Take clock off reset.
CLOCK(clk->reset) &= ~(1 << clk->index);
}
void clock_disable(const clock_t *clk)
{
//Put clock into reset.
CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index);
//Disable.
CLOCK(clk->enable) &= ~(1 << clk->index);
}
void clock_enable_fuse(u32 enable)
{
CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF | ((enable & 1) << 28) & 0x10000000;
}
void clock_enable_uart(u32 idx)
{
clock_enable(&_clock_uart[idx]);
}
void clock_enable_i2c(u32 idx)
{
clock_enable(&_clock_i2c[idx]);
}
void clock_enable_se()
{
clock_enable(&_clock_se);
}
void clock_enable_host1x()
{
clock_enable(&_clock_host1x);
}
void clock_enable_tsec()
{
clock_enable(&_clock_tsec);
}
void clock_enable_sor_safe()
{
clock_enable(&_clock_sor_safe);
}
void clock_enable_sor0()
{
clock_enable(&_clock_sor0);
}
void clock_enable_sor1()
{
clock_enable(&_clock_sor1);
}
void clock_enable_kfuse()
{
//clock_enable(&_clock_kfuse);
CLOCK(0x8) = CLOCK(0x8) & 0xFFFFFEFF | 0x100;
CLOCK(0x14) &= 0xFFFFFEFF;
CLOCK(0x14) = CLOCK(0x14) & 0xFFFFFEFF | 0x100;
sleep(10);
CLOCK(0x8) &= 0xFFFFFEFF;
sleep(20);
}
void clock_disable_host1x()
{
clock_disable(&_clock_host1x);
}
void clock_disable_tsec()
{
clock_disable(&_clock_tsec);
}
void clock_disable_sor_safe()
{
clock_disable(&_clock_sor_safe);
}
void clock_disable_sor0()
{
clock_disable(&_clock_sor0);
}
void clock_disable_sor1()
{
clock_disable(&_clock_sor1);
}
void clock_disable_kfuse()
{
clock_disable(&_clock_kfuse);
}
void clock_enable_coresight()
{
clock_enable(&_clock_coresight);
}

View File

@ -1,296 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "clock.h"
#include "uart.h"
#include "i2c.h"
#include "sdram.h"
#include "di.h"
#include "mc.h"
#include "t210.h"
#include "pmc.h"
#include "pinmux.h"
#include "fuse.h"
#include "util.h"
void config_oscillators()
{
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3 | 4;
SYSCTR0(SYSCTR0_CNTFID0) = 19200000;
TMR(0x14) = 0x45F;
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81 | 0xE;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF | 0x400000;
PMC(APBDEV_PMC_CNTRL2) = PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF | 0x1000;
PMC(APBDEV_PMC_SCRATCH188) = PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF | 0x2000000;
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF;
PMC(APBDEV_PMC_TSC_MULT) = PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000 | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444;
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2;
}
void config_gpios()
{
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = 0x40;
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = 0x40;
GPIO_2(0x8) = GPIO_2(0x8) & 0xFFFFFFFE | 1;
GPIO_1(0xC) = GPIO_1(0xC) & 0xFFFFFFFD | 2;
GPIO_2(0x0) = GPIO_2(0x0) & 0xFFFFFFBF | 0x40;
GPIO_2(0xC) = GPIO_2(0xC) & 0xFFFFFFBF | 0x40;
GPIO_2(0x18) &= 0xFFFFFFFE;
GPIO_1(0x1C) &= 0xFFFFFFFD;
GPIO_2(0x10) &= 0xFFFFFFBF;
GPIO_2(0x1C) &= 0xFFFFFFBF;
pinmux_config_i2c(I2C_1);
pinmux_config_i2c(I2C_5);
pinmux_config_uart(UART_A);
GPIO_6(0xC) = GPIO_6(0xC) & 0xFFFFFFBF | 0x40;
GPIO_6(0xC) = GPIO_6(0xC) & 0xFFFFFF7F | 0x80;
GPIO_6(0x1C) &= 0xFFFFFFBF;
GPIO_6(0x1C) &= 0xFFFFFF7F;
}
void config_pmc_scratch()
{
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF;
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE;
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= 0x10;
}
void mc_config_tsec_carveout(u32 bom, u32 size1mb, int lock)
{
MC(0x670) = bom;
MC(0x674) = size1mb;
if (lock)
MC(0x678) = 1;
}
void mc_config_carveout()
{
*(vu32 *)0x8005FFFC = 0xC0EDBBCC;
MC(0x984) = 1;
MC(0x988) = 0;
MC(0x648) = 0;
MC(0x64C) = 0;
MC(0x650) = 1;
//Official code disables and locks the carveout here.
//mc_config_tsec_carveout(0, 0, 1);
MC(0x9A0) = 0;
MC(0x9A4) = 0;
MC(0x9A8) = 0;
MC(0x9AC) = 1;
MC(0xC0C) = 0;
MC(0xC10) = 0;
MC(0xC14) = 0;
MC(0xC18) = 0;
MC(0xC1C) = 0;
MC(0xC20) = 0;
MC(0xC24) = 0;
MC(0xC28) = 0;
MC(0xC2C) = 0;
MC(0xC30) = 0;
MC(0xC34) = 0;
MC(0xC38) = 0;
MC(0xC3C) = 0;
MC(0xC08) = 0x4000006;
MC(0xC5C) = 0x80020000;
MC(0xC60) = 0;
MC(0xC64) = 2;
MC(0xC68) = 0;
MC(0xC6C) = 0;
MC(0xC70) = 0x3000000;
MC(0xC74) = 0;
MC(0xC78) = 0x300;
MC(0xC7C) = 0;
MC(0xC80) = 0;
MC(0xC84) = 0;
MC(0xC88) = 0;
MC(0xC8C) = 0;
MC(0xC58) = 0x440167E;
MC(0xCAC) = 0;
MC(0xCB0) = 0;
MC(0xCB4) = 0;
MC(0xCB8) = 0;
MC(0xCBC) = 0;
MC(0xCC0) = 0x3000000;
MC(0xCC4) = 0;
MC(0xCC8) = 0x300;
MC(0xCCC) = 0;
MC(0xCD0) = 0;
MC(0xCD4) = 0;
MC(0xCD8) = 0;
MC(0xCDC) = 0;
MC(0xCA8) = 0x4401E7E;
MC(0xCFC) = 0;
MC(0xD00) = 0;
MC(0xD04) = 0;
MC(0xD08) = 0;
MC(0xD0C) = 0;
MC(0xD10) = 0;
MC(0xD14) = 0;
MC(0xD18) = 0;
MC(0xD1C) = 0;
MC(0xD20) = 0;
MC(0xD24) = 0;
MC(0xD28) = 0;
MC(0xD2C) = 0;
MC(0xCF8) = 0x8F;
MC(0xD4C) = 0;
MC(0xD50) = 0;
MC(0xD54) = 0;
MC(0xD58) = 0;
MC(0xD5C) = 0;
MC(0xD60) = 0;
MC(0xD64) = 0;
MC(0xD68) = 0;
MC(0xD6C) = 0;
MC(0xD70) = 0;
MC(0xD74) = 0;
MC(0xD78) = 0;
MC(0xD7C) = 0;
MC(0xD48) = 0x8F;
}
void enable_clocks()
{
CLOCK(0x410) = (CLOCK(0x410) | 0x8000) & 0xFFFFBFFF;
CLOCK(0xD0) |= 0x40800000u;
CLOCK(0x2AC) = 64;
CLOCK(0x294) = 0x40000;
CLOCK(0x304) = 0x18000000;
sleep(2);
I2S(0x0A0) |= 0x400;
I2S(0x088) &= 0xFFFFFFFE;
I2S(0x1A0) |= 0x400;
I2S(0x188) &= 0xFFFFFFFE;
I2S(0x2A0) |= 0x400;
I2S(0x288) &= 0xFFFFFFFE;
I2S(0x3A0) |= 0x400;
I2S(0x388) &= 0xFFFFFFFE;
I2S(0x4A0) |= 0x400;
I2S(0x488) &= 0xFFFFFFFE;
DISPLAY_A(0xCF8) |= 4;
VIC(0x8C) = 0xFFFFFFFF;
sleep(2);
CLOCK(0x2A8) = 0x40;
CLOCK(0x300) = 0x18000000;
CLOCK(0x290) = 0x40000;
CLOCK(0x14) = 0xC0;
CLOCK(0x10) = 0x80000130;
CLOCK(0x18) = 0x1F00200;
CLOCK(0x360) = 0x80400808;
CLOCK(0x364) = 0x402000FC;
CLOCK(0x280) = 0x23000780;
CLOCK(0x298) = 0x300;
CLOCK(0xF8) = 0;
CLOCK(0xFC) = 0;
CLOCK(0x3A0) = 0;
CLOCK(0x3A4) = 0;
CLOCK(0x554) = 0;
CLOCK(0xD0) &= 0x1F7FFFFFu;
CLOCK(0x410) &= 0xFFFF3FFF;
CLOCK(0x148) = CLOCK(0x148) & 0x1FFFFFFF | 0x80000000;
CLOCK(0x180) = CLOCK(0x180) & 0x1FFFFFFF | 0x80000000;
CLOCK(0x6A0) = CLOCK(0x6A0) & 0x1FFFFFFF | 0x80000000;
}
void mc_enable_ahb_redirect()
{
CLOCK(0x3A4) = CLOCK(0x3A4) & 0xFFF7FFFF | 0x80000;
//MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE;
MC(MC_IRAM_BOM) = 0x40000000;
MC(MC_IRAM_TOM) = 0x4003F000;
}
void mc_disable_ahb_redirect()
{
MC(MC_IRAM_BOM) = 0xFFFFF000;
MC(MC_IRAM_TOM) = 0;
//Disable IRAM_CFG_WRITE_ACCESS (sticky).
//MC(MC_IRAM_REG_CTRL) = MC(MC_IRAM_REG_CTRL) & 0xFFFFFFFE | 1;
CLOCK(0x3A4) &= 0xFFF7FFFF;
}
void mc_enable()
{
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF | 0x40000000;
//Enable MIPI CAL clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF | 0x2000000;
//Enable MC clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE | 1;
//Enable EMC DLL clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & 0xFFFFBFFF | 0x4000;
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x2000001; //Clear EMC and MC reset.
sleep(5);
}
clock_t clock_unk1 = { 0x358, 0x360, 0x42C, 0x1F, 0, 0 };
clock_t clock_unk2 = { 0x358, 0x360, 0, 0x1E, 0, 0 };
void nx_hwinit()
{
enable_clocks();
clock_enable_se();
clock_enable_fuse(1);
fuse_disable_program();
mc_enable();
config_oscillators();
_REG(0x70000000, 0x40) = 0;
config_gpios();
clock_enable_i2c(I2C_1);
clock_enable_i2c(I2C_5);
clock_enable(&clock_unk1);
clock_enable(&clock_unk2);
i2c_init(I2C_1);
i2c_init(I2C_5);
//Config PMIC (TODO: use max77620.h)
i2c_send_byte(I2C_5, 0x3C, 4, 0x40);
i2c_send_byte(I2C_5, 0x3C, 0x41, 0x78);
i2c_send_byte(I2C_5, 0x3C, 0x43, 0x38);
i2c_send_byte(I2C_5, 0x3C, 0x44, 0x3A);
i2c_send_byte(I2C_5, 0x3C, 0x45, 0x38);
i2c_send_byte(I2C_5, 0x3C, 0x4A, 0xF);
i2c_send_byte(I2C_5, 0x3C, 0x4E, 0xC7);
i2c_send_byte(I2C_5, 0x3C, 0x4F, 0x4F);
i2c_send_byte(I2C_5, 0x3C, 0x50, 0x29);
i2c_send_byte(I2C_5, 0x3C, 0x52, 0x1B);
i2c_send_byte(I2C_5, 0x3C, 0x16, 42); //42 = (1000 * 1125 - 600000) / 12500
config_pmc_scratch();
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888 | 0x3333;
mc_config_carveout();
sdram_init();
}

View File

@ -1,131 +0,0 @@
/*
* Defining registers address and its bit definitions of MAX77620 and MAX20024
*
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
*
* 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 _MAX77620_H_
#define _MAX77620_H_
/* 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 BIT(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_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
#endif

View File

@ -1,504 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "t210.h"
#include "mc.h"
//#include "emc.h"
#include "pmc.h"
#include "util.h"
#include "fuse.h"
#include "sdram.inl"
static u32 _get_sdram_id()
{
return (fuse_read_odm(4) & 0x38) >> 3;
}
static void _sdram_config(const u32 *_cfg)
{
const u32 *_cfg_120 = _cfg + 0x120;
const u32 *_cfg_100 = _cfg + 0x100;
PMC(0x45C) = (((4 * _cfg[0x12F] >> 2) + 0x80000000) ^ 0xFFFF) & 0xC000FFFF;
sleep(_cfg[0x111]);
u32 req = (4 * _cfg_120[0x10] >> 2) + 0x80000000;
PMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0x3FFF0000) >> 16 << 16;
sleep(_cfg_100[0x12]);
PMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0xFFFF) & 0xC000FFFF;
sleep(_cfg_100[0x12]);
PMC(APBDEV_PMC_WEAK_BIAS) = 0;
sleep(1);
CLOCK(0x98) = _cfg[4];
CLOCK(0x9C) = 0;
CLOCK(0x90) = (_cfg[2] << 8) | (*((u16 *)_cfg + 0xA) << 20) | _cfg[1] | 0x40000000;
u32 wait_end = TMR(0x10) + 300;
while (!((CLOCK(0x90) >> 27) & 1))
{
if (TMR(0x10) >= wait_end)
goto break_nosleep;
}
sleep(10);
break_nosleep:
CLOCK(0x19C) = _cfg[0x16] & 0xFFFEFFFF | (_cfg[0x175] >> 11) & 0x10000;
if (_cfg[0x17])
CLOCK(0x664) = _cfg[0x17];
if (_cfg[0x1A])
CLOCK(0x44C) = 0x40000000;
CLOCK(0x328) = 0x2000001;
CLOCK(0x284) = 0x4000;
CLOCK(0x30C) = 0x2000001;
EMC(0xC34) = _cfg_120[0x13];
EMC(0xC38) = _cfg_120[0x14];
EMC(0xCF0) = _cfg_120[0x15];
EMC(0x28) = 1;
sleep(1);
EMC(0x8) = _cfg[0xA9] | 2 * _cfg[0xAA];
if (_cfg[0xA])
*(vu32 *)_cfg[0xA] = _cfg[0xB];
EMC(0x584) = _cfg[0x7B];
EMC(0x380) = _cfg[0x7D];
EMC(0x384) = _cfg[0x7E];
EMC(0x388) = _cfg[0x7F];
EMC(0x38C) = _cfg[0x80];
EMC(0x390) = _cfg[0x81];
EMC(0x394) = _cfg[0x82];
EMC(0x398) = _cfg[0x83];
EMC(0x39C) = _cfg[0x84];
EMC(0x3A0) = _cfg[0x85];
EMC(0x3A4) = _cfg[0x86];
EMC(0x3A8) = _cfg[0x87];
EMC(0x3AC) = _cfg[0x88];
EMC(0x3B0) = _cfg[0x89];
EMC(0xC80) = _cfg[0x14A];
EMC(0xC84) = _cfg[0x14B];
EMC(0xC88) = _cfg[0x14C];
EMC(0x330) = (_cfg_120[0x16] | 0xFEEDFEED) & 0x1FFF1FFF;
EMC(0x5F0) = _cfg[0x149];
EMC(0x5C8) = _cfg[0x7C];
EMC(0x404) = _cfg_100[0x18];
EMC(0x408) = _cfg_100[0x19];
EMC(0x40C) = _cfg_100[0x1A];
EMC(0x410) = _cfg_100[0x1B];
EMC(0x418) = _cfg_100[0x1C];
EMC(0x41C) = _cfg_100[0x1D];
EMC(0x420) = _cfg_100[0x1E];
EMC(0x424) = _cfg_100[0x1F];
if (_cfg[0xE])
*(vu32 *)_cfg[0xE] = _cfg[0xF];
EMC(0x30C) = _cfg[0x31];
EMC(0x578) = _cfg[0x32];
EMC(0x2F4) = _cfg[0x33];
EMC(0x458) = _cfg[0x1D];
EMC(0x45C) = _cfg[0x1E];
EMC(0x5B0) = _cfg[0x1F];
EMC(0x5B4) = _cfg[0x20];
EMC(0x5CC) = _cfg[0x21];
EMC(0x574) = _cfg[0x22];
EMC(0x2DC) = _cfg[0x23];
EMC(0xC48) = _cfg[0x2A];
EMC(0xC70) = _cfg[0x2B];
EMC(0xC74) = _cfg[0x2C];
EMC(0xC4C) = _cfg[0x2D];
EMC(0xC78) = _cfg[0x2E];
EMC(0x464) = _cfg[0x26];
EMC(0xC44) = _cfg[0x2F];
EMC(0x5E4) = _cfg_120[0xD];
EMC(0x5E8) = _cfg_120[0xE];
EMC(0x2C8) = _cfg[0xB0];
EMC(0x588) = _cfg_120[1];
EMC(0x58C) = _cfg_120[2];
EMC(0x594) = _cfg_120[3];
EMC(0x598) = _cfg_120[4];
EMC(0x59C) = _cfg_120[5];
EMC(0x5A0) = _cfg_120[6];
EMC(0x5A4) = _cfg_120[7];
EMC(0x5A8) = _cfg_120[8];
EMC(0x5AC) = _cfg_120[9];
EMC(0x5B8) = _cfg_120[0xA];
EMC(0x5BC) = _cfg_120[0xB];
EMC(0x5C4) = _cfg_120[0xC];
EMC(0x330) = (_cfg_120[0x16] | 0xFE40FE40) & 0x1FFF1FFF;
EMC(0xC40) = _cfg_120[0x12];
EMC(0x318) = _cfg_120[0x17];
EMC(0x334) = _cfg_120[0x18] & 0xFF7FFF7F;
EMC(0x31C) = _cfg_120[0x19];
EMC(0xC3C) = _cfg_120[0x1A];
EMC(0xC54) = _cfg_120[0x1B];
EMC(0xC50) = _cfg_120[0x1C];
EMC(0xC64) = _cfg_120[0x1F];
EMC(0xC5C) = _cfg_120[0x1D];
EMC(0xC58) = _cfg_120[0x1E];
EMC(0xC60) = _cfg[0x141];
EMC(0x49C) = _cfg[0x142];
EMC(0x720) = _cfg[0x143];
EMC(0x724) = _cfg[0x144];
EMC(0x728) = _cfg[0x145];
EMC(0x72C) = _cfg[0x146];
EMC(0x730) = _cfg[0x147];
EMC(0x734) = _cfg[0x148];
EMC(0x740) = _cfg[0x14D];
EMC(0x744) = _cfg[0x14E];
EMC(0x748) = _cfg[0x14F];
EMC(0x74C) = _cfg[0x150];
EMC(0x750) = _cfg[0x151];
EMC(0x754) = _cfg[0x152];
EMC(0x760) = _cfg[0x153];
EMC(0x770) = _cfg[0x154];
EMC(0x774) = _cfg[0x155];
EMC(0x778) = _cfg[0x156];
EMC(0x780) = _cfg[0x157];
EMC(0x784) = _cfg[0x158];
EMC(0x788) = _cfg[0x159];
EMC(0xBE0) = _cfg[0xB6];
EMC(0xBE4) = _cfg[0xB7];
EMC(0xBF0) = _cfg[0xB8];
EMC(0xBF4) = _cfg[0xB9];
EMC(0xCF4) = _cfg[0xBA];
EMC(0x600) = _cfg[0xBD];
EMC(0x604) = _cfg[0xBE];
EMC(0x608) = _cfg[0xBF];
EMC(0x60C) = _cfg[0xC0];
EMC(0x610) = _cfg[0xC1];
EMC(0x614) = _cfg[0xC2];
EMC(0x620) = _cfg[0xC3];
EMC(0x624) = _cfg[0xC4];
EMC(0x628) = _cfg[0xC5];
EMC(0x62C) = _cfg[0xC6];
EMC(0x630) = _cfg[0xC7];
EMC(0x634) = _cfg[0xC8];
EMC(0x330) = _cfg_120[0x16];
EMC(0x640) = _cfg[0xC9];
EMC(0x644) = _cfg[0xCA];
EMC(0x648) = _cfg[0xCB];
EMC(0x64C) = _cfg[0xCC];
EMC(0x650) = _cfg[0xCD];
EMC(0x654) = _cfg[0xCE];
EMC(0x660) = _cfg[0xCF];
EMC(0x664) = _cfg[0xD0];
EMC(0x668) = _cfg[0xD1];
EMC(0x66C) = _cfg[0xD2];
EMC(0x670) = _cfg[0xD3];
EMC(0x674) = _cfg[0xD4];
EMC(0x680) = _cfg[0xD5];
EMC(0x684) = _cfg[0xD6];
EMC(0x688) = _cfg[0xD7];
EMC(0x68C) = _cfg[0xD8];
EMC(0x690) = _cfg[0xD9];
EMC(0x694) = _cfg[0xDA];
EMC(0x6A0) = _cfg[0xDB];
EMC(0x6A4) = _cfg[0xDC];
EMC(0x6A8) = _cfg[0xDD];
EMC(0x6AC) = _cfg[0xDE];
EMC(0x6B0) = _cfg[0xDF];
EMC(0x6B4) = _cfg[0xE0];
EMC(0x6C0) = _cfg[0xE1];
EMC(0x6C4) = _cfg[0xE2];
EMC(0x6C8) = _cfg[0xE3];
EMC(0x6CC) = _cfg[0xE4];
EMC(0x6E0) = _cfg[0xE5];
EMC(0x6E4) = _cfg[0xE6];
EMC(0x6E8) = _cfg[0xE7];
EMC(0x6EC) = _cfg[0xE8];
EMC(0xC00) = _cfg[0xE9];
EMC(0xC04) = _cfg[0xEA];
EMC(0xC08) = _cfg[0xEB];
EMC(0xC0C) = _cfg[0xEC];
EMC(0xC10) = _cfg[0xED];
EMC(0xC20) = _cfg[0xEE];
EMC(0xC24) = _cfg[0xEF];
EMC(0xC28) = _cfg[0xF0];
EMC(0xC68) = (*((u8 *)_cfg + 0x500) | 0xFFFFFFFE) & 0xF;
if (_cfg[0xC])
*(vu32 *)_cfg[0xC] = _cfg[0xD];
EMC(0x28) = 1;
MC(0x648) = _cfg[0x180];
MC(0x978) = _cfg[0x181];
MC(0x64C) = _cfg[0x182];
MC(0x418) = _cfg[0x183];
MC(0x590) = _cfg[0x184];
MC(0x984) = _cfg[0x185];
MC(0x988) = _cfg[0x186];
MC(0x54) = _cfg[0x15A];
MC(0x58) = _cfg[0x15B];
MC(0x5C) = _cfg[0x15C];
MC(0x60) = _cfg[0x15D];
MC(0x64) = _cfg[0x15E];
MC(0x68) = _cfg[0x15F];
MC(0x6C) = _cfg[0x160];
MC(0x50) = _cfg[0x161];
MC(0x670) = _cfg[0x187];
MC(0x9D4) = _cfg[0x188];
MC(0x674) = _cfg[0x189];
MC(0x9A0) = _cfg[0x1D6];
MC(0x9A8) = _cfg[0x1D7];
MC(0x9A4) = _cfg[0x1D8];
MC(0x90) = _cfg[0x162];
MC(0x94) = _cfg[0x163];
MC(0x6F0) = _cfg[0x164];
MC(0x6F4) = _cfg[0x165];
MC(0x98) = _cfg[0x166];
MC(0x9C) = _cfg[0x167];
MC(0xA0) = _cfg[0x168];
MC(0xA4) = _cfg[0x169];
MC(0xA8) = _cfg[0x16A];
MC(0xAC) = _cfg[0x16B];
MC(0xB0) = _cfg[0x16C];
MC(0xB4) = _cfg[0x16D];
MC(0xB8) = _cfg[0x16E];
MC(0xBC) = _cfg[0x16F];
MC(0x6C4) = _cfg[0x17D];
MC(0xC0) = _cfg[0x170];
MC(0xC4) = _cfg[0x171];
MC(0x6C0) = _cfg[0x172];
MC(0xD0) = _cfg[0x173];
MC(0xD4) = _cfg[0x174];
MC(0xD8) = _cfg[0x175];
MC(0xDC) = _cfg[0x176];
MC(0xC8) = _cfg[0x177];
MC(0xE0) = _cfg[0x178];
MC(0xE8) = _cfg[0x179];
MC(0x968) = _cfg[0x17A];
MC(0xEC) = _cfg[0x17B];
MC(0x9DC) = _cfg[0x17C];
MC(0xFC) = 1;
MC(0xF4) = _cfg[0x17E];
MC(0x100) = _cfg[0x17F];
EMC(0x10) = _cfg[0x34];
EMC(0x140) = _cfg_100[7];
EMC(0x700) = _cfg[0x27];
EMC(0x704) = _cfg[0x28];
EMC(0x708) = _cfg[0x29];
EMC(0x2F8) = _cfg[0x24];
EMC(0x300) = _cfg[0x25];
EMC(0x2A8) = _cfg[0x1B];
EMC(0x2A4) = _cfg[0x1C];
sleep(_cfg[0x30]);
if (_cfg[0x10])
*(vu32 *)_cfg[0x10] = _cfg[0x11];
EMC(0x2B8) = _cfg[0xA4];
EMC(0x560) = _cfg[0xA5];
EMC(0x55C) = _cfg[0xBB];
EMC(0x554) = _cfg[0xBC];
EMC(0xF0) = _cfg[0xAB];
EMC(0xF4) = _cfg[0xAC];
EMC(0xC8) = _cfg[0xA1];
EMC(0xC4) = _cfg[0xA2];
EMC(0x104) = _cfg[0x7A];
EMC(0x2C) = _cfg[0x3A];
EMC(0x30) = _cfg[0x3B];
EMC(0x590) = _cfg[0x3C];
EMC(0x580) = _cfg[0x3D];
EMC(0xC0) = _cfg[0x3E];
EMC(0x34) = _cfg[0x3F];
EMC(0x38) = _cfg[0x40];
EMC(0xAC) = _cfg[0x47];
EMC(0x144) = _cfg[0x41];
EMC(0x148) = _cfg[0x42];
EMC(0x3C) = _cfg[0x43];
EMC(0x40) = _cfg[0x44];
EMC(0x44) = _cfg[0x45];
EMC(0x48) = _cfg[0x46];
EMC(0x5C0) = _cfg[0x48];
EMC(0x4C) = _cfg[0x49];
EMC(0x50) = _cfg[0x4A];
EMC(0x54) = _cfg[0x4B];
EMC(0x58) = _cfg[0x4C];
EMC(0xB8) = _cfg[0x4D];
EMC(0x5C) = _cfg[0x4E];
EMC(0x4E0) = _cfg[0x4F];
EMC(0x498) = _cfg[0x50];
EMC(0x494) = _cfg[0x51];
EMC(0x2D0) = _cfg[0x52];
EMC(0x490) = _cfg[0x53];
EMC(0x48C) = _cfg[0x54];
EMC(0x60) = _cfg[0x55];
EMC(0x568) = _cfg[0x56];
EMC(0x468) = _cfg[0x57];
EMC(0x46C) = _cfg[0x58];
EMC(0x14C) = _cfg[0x59];
EMC(0x150) = _cfg[0x5A];
EMC(0x154) = _cfg[0x5B];
EMC(0x56C) = _cfg[0x5C];
EMC(0xC68) = _cfg[0x140];
EMC(0x8) = _cfg[0xA9];
EMC(0x64) = _cfg[0x5D];
EMC(0x428) = 0;
EMC(0x68) = _cfg[0x5E];
EMC(0x6C) = _cfg[0x5F];
EMC(0x2CC) = _cfg[0x60];
EMC(0x2D8) = _cfg[0x61];
EMC(0x2D4) = _cfg[0x62];
EMC(0x564) = _cfg[0x63];
EMC(0x70) = _cfg[0x64];
EMC(0x74) = _cfg[0x65];
EMC(0x3DC) = _cfg[0x66];
EMC(0x78) = _cfg[0x67];
EMC(0x7C) = _cfg[0x68];
EMC(0x80) = _cfg[0x69];
EMC(0x84) = _cfg[0x6A];
EMC(0x88) = _cfg[0x6B];
EMC(0x8C) = _cfg[0x6C];
EMC(0x11C) = _cfg[0x6D];
EMC(0x118) = _cfg[0x6E];
EMC(0xB4) = _cfg[0x6F];
EMC(0x90) = _cfg[0x70];
EMC(0x3E4) = _cfg[0x71];
EMC(0x94) = _cfg[0x72];
EMC(0x158) = _cfg[0x73];
EMC(0x15C) = _cfg[0x74];
EMC(0x98) = _cfg[0x75];
EMC(0x9C) = _cfg[0x76];
EMC(0xA0) = _cfg[0x77];
EMC(0xA4) = _cfg[0x78];
EMC(0xA8) = _cfg[0x79];
EMC(0xB0) = _cfg[0xF2];
EMC(0x2BC) = _cfg[0xAF];
EMC(0x2C0) = _cfg[0xB1];
EMC(0x100) = _cfg[0x8A] & 0xFFFFFFFD;
EMC(0x120) = _cfg[0x8B];
EMC(0x440) = _cfg_120[0xF];
EMC(0x444) = _cfg_120[0x10];
EMC(0x448) = _cfg_120[0x11];
EMC(0x124) = _cfg_100[0x17];
EMC(0x480) = *_cfg_120;
EMC(0xC) = ((_cfg[0xA3] & 4 | 0x3C00000) & 0xFFFFFFF7 | _cfg[0xA3] & 8) & 0xFFFFFFFD | _cfg[0xA3] & 2;
if ((_cfg[0x1D4] & 0x80000000) != 0)
{
*(vu32 *)(4 * _cfg[0x1D4] + 0x70000000) = _cfg[0x1D5];
MC(0xFC) = 1;
}
PMC(0x45C) = ((4 * _cfg_120[0xF] >> 2) + 0x40000000) & 0xCFFF0000;
sleep(_cfg_100[0x11]);
if (!_cfg[0x1B])
EMC(0x2A4) = _cfg[0x1C] | 0x200;
EMC(0x334) = _cfg_120[0x18];
if (_cfg[0xFA] << 31)
{
if (*_cfg == 2)
EMC(0x2E4) = 8 * _cfg[0xF4];
if (*_cfg == 3)
{
EMC(0x2E4) = _cfg[0xF4];
EMC(0x2E8) = _cfg[0xF5];
}
}
EMC(0x28) = 1;
sleep(_cfg[0x39]);
PMC(0x4E4) &= 0xFFF8007F;
sleep(_cfg_100[0x15]);
if (*_cfg == 2)
{
EMC(0x24) = (_cfg[0x37] << 16) | (_cfg[0x38] << 12);
sleep(_cfg[0x36] + 200);
EMC(0x24) = ((_cfg[0x37] << 16) | (_cfg[0x38] << 12)) + 0x100;
sleep(_cfg[0x36] + 500);
}
if (*_cfg == 3)
{
EMC(0x24) = (_cfg[0x37] << 16) | (_cfg[0x38] << 12);
sleep(_cfg[0x36] + 200);
EMC(0x24) = ((_cfg[0x37] << 16) | (_cfg[0x38] << 12)) + 0x100;
sleep(_cfg[0x36] + 2000);
}
EMC(0x24) = ((_cfg[0x37] << 16) | (_cfg[0x38] << 12)) + 0x101;
sleep(_cfg[0x35]);
if (*_cfg != 3)
EMC(0xDC) = (_cfg[0xB2] << 30) + 1;
if (*_cfg == 1)
sleep(_cfg[0x36] + 200);
if (*_cfg == 3)
{
if (_cfg[0x12])
*(vu32 *)_cfg[0x12] = _cfg[0x13];
EMC(0x134) = _cfg[0x91];
EMC(0xE8) = _cfg[0x90];
EMC(0x138) = _cfg[0x92];
EMC(0x13C) = _cfg[0x93];
EMC(0x4A4) = _cfg[0x94];
EMC(0x4C4) = _cfg[0x9A];
EMC(0x4AC) = _cfg[0x95];
EMC(0x4BC) = _cfg[0x98];
EMC(0x4B0) = _cfg[0x96];
EMC(0x4C0) = _cfg[0x99];
if (_cfg[0xFA] << 31)
{
EMC(0x2EC) = _cfg[0xF7];
sleep(_cfg[0xF9]);
EMC(0x2EC) = _cfg[0xF7] ^ 3;
if (!(_cfg[0xB2] & 2))
{
EMC(0x2EC) = _cfg[0xF8];
sleep(_cfg[0xF9]);
EMC(0x2EC) = _cfg[0xF8] ^ 3;
}
}
}
PMC(0x1D0) = _cfg_100[0xF];
if (_cfg[0] == 1 || _cfg[0] == 2 || _cfg[0] == 3)
{
EMC(0x2E0) = _cfg[0xF3];
EMC(0x2E4) = _cfg[0xF4];
EMC(0x2E8) = _cfg[0xF5];
}
if (_cfg[0x14])
*(vu32 *)_cfg[0x14] = _cfg[0x15];
EMC(0x28) = 1;
if (_cfg_100[8])
EMC(0xD4) = ((1 << _cfg_100[8] << 8) - 0xFD) | (_cfg[0x38] << 30);
EMC(0x20) = _cfg[0xB2] | 0x80000000;
EMC(0x3E0) = _cfg[0xAD];
EMC(0x5F4) = _cfg[0xA8];
EMC(0xC) = _cfg[0xA3];
EMC(0x310) = _cfg[0xB4];
EMC(0x314) = _cfg[0xB5];
EMC(0x3D8) = _cfg[0xB3];
EMC(0x100) = _cfg[0x8A] | 2;
EMC(0x28) = 1;
EMC(0x558) = _cfg[0xA6];
EMC(0x4D8) = _cfg[0xA7];
SYSREG(AHB_ARBITRATION_XBAR_CTRL) = SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF | (*((u16 *)_cfg + 0x15C) << 16);
MC(0x650) = _cfg[0x18A];
MC(0x678) = _cfg[0x18B];
MC(0x9AC) = _cfg[0x1D9];
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1; //Disable write access to a bunch of MC registers.
}
void sdram_init()
{
u32 sdram_id = _get_sdram_id();
const u32 *cfg = _dram_cfgs[sdram_id]; //TODO: sdram_id should be in [0,4].
i2c_send_byte(I2C_5, 0x3C, 0x22, 0x05);
i2c_send_byte(I2C_5, 0x3C, 0x17, 40); //40 = (1000 * 1100 - 600000) / 12500
PMC(APBDEV_PMC_VDDP_SEL) = cfg[0x10C];
sleep(cfg[0x10D]);
PMC(APBDEV_PMC_DDR_PWR) = PMC(0xE8);
PMC(APBDEV_PMC_NO_IOPOWER) = cfg[0x114];
PMC(APBDEV_PMC_REG_SHORT) = cfg[0x113];
PMC(APBDEV_PMC_DDR_CNTRL) = cfg[0x116];
if (cfg[8])
*(vu32 *)cfg[8] = cfg[9];
_sdram_config(cfg);
}

1667
ipl/ELF.h Executable file

File diff suppressed because it is too large Load Diff

7
hwinit/btn.c → ipl/btn.c Normal file → Executable file
View File

@ -16,16 +16,17 @@
#include "btn.h"
#include "i2c.h"
#include "gpio.h"
#include "t210.h"
u32 btn_read()
{
u32 res = 0;
if(!(GPIO_6(0x3C) & 0x80))
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_7))
res |= BTN_VOL_DOWN;
if(!(GPIO_6(0x3C) & 0x40))
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))
res |= BTN_VOL_UP;
if(i2c_recv_byte(4, 0x3C, 0x15) & 0x4)
if (i2c_recv_byte(4, 0x3C, 0x15) & 0x4)
res |= BTN_POWER;
return res;
}

0
hwinit/btn.h → ipl/btn.h Normal file → Executable file
View File

449
ipl/clock.c Executable file
View File

@ -0,0 +1,449 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "clock.h"
#include "t210.h"
#include "util.h"
#include "sdmmc.h"
static const clock_t _clock_uart[] = {
/* UART A */ { 4, 0x10, 0x178, 6, 0, 0 },
/* UART B */ { 4, 0x10, 0x17C, 7, 0, 0 },
/* UART C */ { 8, 0x14, 0x1A0, 0x17, 0, 0 },
/* UART D */ { 0 },
/* UART E */ { 0 }
};
static const clock_t _clock_i2c[] = {
/* I2C1 */ { 4, 0x10, 0x124, 0xC, 6, 0 },
/* I2C2 */ { 0 },
/* I2C3 */ { 0 },
/* I2C4 */ { 0 },
/* I2C5 */ { 8, 0x14, 0x128, 0xF, 6, 0 },
/* I2C6 */ { 0 }
};
static clock_t _clock_se = { 0x358, 0x360, 0x42C, 0x1F, 0, 0 };
static clock_t _clock_host1x = { 4, 0x10, 0x180, 0x1C, 4, 3 };
static clock_t _clock_tsec = { 0xC, 0x18, 0x1F4, 0x13, 0, 2 };
static clock_t _clock_sor_safe = { 0x2A4, 0x298, 0, 0x1E, 0, 0 };
static clock_t _clock_sor0 = { 0x28C, 0x280, 0, 0x16, 0, 0 };
static clock_t _clock_sor1 = { 0x28C, 0x280, 0x410, 0x17, 0, 2 };
static clock_t _clock_kfuse = { 8, 0x14, 0, 8, 0, 0 };
static clock_t _clock_cl_dvfs = { 0x35C, 0x364, 0, 0x1B, 0, 0 };
static clock_t _clock_coresight = { 0xC, 0x18, 0x1D4, 9, 0, 4};
void clock_enable(const clock_t *clk)
{
//Put clock into reset.
CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index);
//Disable.
CLOCK(clk->enable) &= ~(1 << clk->index);
//Configure clock source if required.
if (clk->source)
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
//Enable.
CLOCK(clk->enable) = CLOCK(clk->enable) & ~(1 << clk->index) | (1 << clk->index);
//Take clock off reset.
CLOCK(clk->reset) &= ~(1 << clk->index);
}
void clock_disable(const clock_t *clk)
{
//Put clock into reset.
CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index);
//Disable.
CLOCK(clk->enable) &= ~(1 << clk->index);
}
void clock_enable_fuse(u32 enable)
{
CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF | ((enable & 1) << 28) & 0x10000000;
}
void clock_enable_uart(u32 idx)
{
clock_enable(&_clock_uart[idx]);
}
void clock_enable_i2c(u32 idx)
{
clock_enable(&_clock_i2c[idx]);
}
void clock_enable_se()
{
clock_enable(&_clock_se);
}
void clock_enable_host1x()
{
clock_enable(&_clock_host1x);
}
void clock_disable_host1x()
{
clock_disable(&_clock_host1x);
}
void clock_enable_tsec()
{
clock_enable(&_clock_tsec);
}
void clock_disable_tsec()
{
clock_disable(&_clock_tsec);
}
void clock_enable_sor_safe()
{
clock_enable(&_clock_sor_safe);
}
void clock_disable_sor_safe()
{
clock_disable(&_clock_sor_safe);
}
void clock_enable_sor0()
{
clock_enable(&_clock_sor0);
}
void clock_disable_sor0()
{
clock_disable(&_clock_sor0);
}
void clock_enable_sor1()
{
clock_enable(&_clock_sor1);
}
void clock_disable_sor1()
{
clock_disable(&_clock_sor1);
}
void clock_enable_kfuse()
{
//clock_enable(&_clock_kfuse);
CLOCK(0x8) = CLOCK(0x8) & 0xFFFFFEFF | 0x100;
CLOCK(0x14) &= 0xFFFFFEFF;
CLOCK(0x14) = CLOCK(0x14) & 0xFFFFFEFF | 0x100;
sleep(10);
CLOCK(0x8) &= 0xFFFFFEFF;
sleep(20);
}
void clock_disable_kfuse()
{
clock_disable(&_clock_kfuse);
}
void clock_enable_cl_dvfs()
{
clock_enable(&_clock_cl_dvfs);
}
void clock_enable_coresight()
{
clock_enable(&_clock_coresight);
}
#define L_SWR_SDMMC1_RST (1<<14)
#define L_SWR_SDMMC2_RST (1<<9)
#define L_SWR_SDMMC4_RST (1<<15)
#define U_SWR_SDMMC3_RST (1<<5)
#define L_CLK_ENB_SDMMC1 (1<<14)
#define L_CLK_ENB_SDMMC2 (1<<9)
#define L_CLK_ENB_SDMMC4 (1<<15)
#define U_CLK_ENB_SDMMC3 (1<<5)
#define L_SET_SDMMC1_RST (1<<14)
#define L_SET_SDMMC2_RST (1<<9)
#define L_SET_SDMMC4_RST (1<<15)
#define U_SET_SDMMC3_RST (1<<5)
#define L_CLR_SDMMC1_RST (1<<14)
#define L_CLR_SDMMC2_RST (1<<9)
#define L_CLR_SDMMC4_RST (1<<15)
#define U_CLR_SDMMC3_RST (1<<5)
#define L_SET_CLK_ENB_SDMMC1 (1<<14)
#define L_SET_CLK_ENB_SDMMC2 (1<<9)
#define L_SET_CLK_ENB_SDMMC4 (1<<15)
#define U_SET_CLK_ENB_SDMMC3 (1<<5)
#define L_CLR_CLK_ENB_SDMMC1 (1<<14)
#define L_CLR_CLK_ENB_SDMMC2 (1<<9)
#define L_CLR_CLK_ENB_SDMMC4 (1<<15)
#define U_CLR_CLK_ENB_SDMMC3 (1<<5)
static int _clock_sdmmc_is_reset(u32 id)
{
switch (id)
{
case SDMMC_1:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC1_RST;
case SDMMC_2:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC2_RST;
case SDMMC_3:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & U_SWR_SDMMC3_RST;
case SDMMC_4:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC4_RST;
}
return 0;
}
static void _clock_sdmmc_set_reset(u32 id)
{
switch (id)
{
case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC1_RST;
case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC2_RST;
case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = U_SET_SDMMC3_RST;
case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC4_RST;
}
}
static void _clock_sdmmc_clear_reset(u32 id)
{
switch (id)
{
case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC1_RST;
case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC2_RST;
case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = U_CLR_SDMMC3_RST;
case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC4_RST;
}
}
static int _clock_sdmmc_is_enabled(u32 id)
{
switch (id)
{
case SDMMC_1:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC1;
case SDMMC_2:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC2;
case SDMMC_3:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & U_CLK_ENB_SDMMC3;
case SDMMC_4:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC4;
}
return 0;
}
static int _clock_sdmmc_set_enable(u32 id)
{
switch (id)
{
case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC1;
case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC2;
case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = U_SET_CLK_ENB_SDMMC3;
case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC4;
}
}
static int _clock_sdmmc_clear_enable(u32 id)
{
switch (id)
{
case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC1;
case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC2;
case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = U_CLR_CLK_ENB_SDMMC3;
case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC4;
}
}
static u32 _clock_sdmmc_table[8] = { 0 };
static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
{
u32 divisor = 0;
u32 source = 0;
switch (val)
{
case 25000:
*pout = 24728;
divisor = 31;
break;
case 26000:
*pout = 25500;
divisor = 30;
break;
case 40800:
*pout = 40800;
divisor = 18;
break;
case 50000:
*pout = 48000;
divisor = 15;
break;
case 52000:
*pout = 51000;
divisor = 14;
break;
case 100000:
*pout = 90667;
divisor = 7;
break;
case 200000:
*pout = 163200;
divisor = 3;
break;
case 208000:
*pout = 204000;
divisor = 2;
break;
default:
return 0;
}
_clock_sdmmc_table[2 * id] = val;
_clock_sdmmc_table[2 * id + 1] = *pout;
switch (id)
{
case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = source | divisor;
break;
case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = source | divisor;
break;
case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = source | divisor;
break;
case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = source | divisor;
break;
}
return 1;
}
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val)
{
if (_clock_sdmmc_table[2 * id] == val)
{
*pout = _clock_sdmmc_table[2 * id + 1];
}
else
{
int is_enabled = _clock_sdmmc_is_enabled(id);
if (is_enabled)
_clock_sdmmc_clear_enable(id);
_clock_sdmmc_config_clock_source_inner(pout, id, val);
if (is_enabled)
_clock_sdmmc_set_enable(id);
_clock_sdmmc_is_reset(id);
}
}
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type)
{
switch (type)
{
case 0:
*pout = 26000;
*pdivisor = 66;
break;
case 1:
*pout = 26000;
*pdivisor = 1;
break;
case 2:
*pout = 52000;
*pdivisor = 1;
break;
case 3:
case 4:
case 11:
*pout = 200000;
*pdivisor = 1;
break;
case 5:
*pout = 25000;
*pdivisor = 64;
case 6:
case 8:
*pout = 25000;
*pdivisor = 1;
break;
case 7:
*pout = 50000;
*pdivisor = 1;
case 10:
*pout = 100000;
*pdivisor = 1;
case 13:
*pout = 40800;
*pdivisor = 1;
break;
case 14:
*pout = 200000;
*pdivisor = 2;
break;
}
}
int clock_sdmmc_is_not_reset_and_enabled(u32 id)
{
return !_clock_sdmmc_is_reset(id) && _clock_sdmmc_is_enabled(id);
}
void clock_sdmmc_enable(u32 id, u32 val)
{
u32 div = 0;
if (_clock_sdmmc_is_enabled(id))
_clock_sdmmc_clear_enable(id);
_clock_sdmmc_set_reset(id);
_clock_sdmmc_config_clock_source_inner(&div, id, val);
_clock_sdmmc_set_enable(id);
_clock_sdmmc_is_reset(id);
sleep((100000 + div - 1) / div);
_clock_sdmmc_clear_reset(id);
_clock_sdmmc_is_reset(id);
}
void clock_sdmmc_disable(u32 id)
{
_clock_sdmmc_set_reset(id);
_clock_sdmmc_clear_enable(id);
_clock_sdmmc_is_reset(id);
}

51
hwinit/clock.h → ipl/clock.h Normal file → Executable file
View File

@ -20,20 +20,52 @@
#include "types.h"
/*! Clock registers. */
#define CLK_RST_CONTROLLER_RST_DEVICES_L 0x4
#define CLK_RST_CONTROLLER_RST_DEVICES_U 0xC
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_L 0x10
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_H 0x14
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_U 0x18
#define CLK_RST_CONTROLLER_CCLK_BURST_POLICY 0x20
#define CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER 0x24
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28
#define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2C
#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30
#define CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48
#define CLK_RST_CONTROLLER_OSC_CTRL 0x50
#define CLK_RST_CONTROLLER_PLLX_BASE 0xE0
#define CLK_RST_CONTROLLER_PLLX_MISC 0xE4
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1 0x150
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2 0x154
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 0x164
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 0x1BC
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X 0x280
#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_Y 0x298
#define CLK_RST_CONTROLLER_CLK_ENB_Y_SET 0x29C
#define CLK_RST_CONTROLLER_RST_DEV_L_SET 0x300
#define CLK_RST_CONTROLLER_RST_DEV_L_CLR 0x304
#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308
#define CLK_RST_CONTROLLER_RST_DEV_U_SET 0x310
#define CLK_RST_CONTROLLER_RST_DEV_U_CLR 0x314
#define CLK_RST_CONTROLLER_CLK_ENB_L_SET 0x320
#define CLK_RST_CONTROLLER_CLK_ENB_L_CLR 0x324
#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328
#define CLK_RST_CONTROLLER_CLK_ENB_U_SET 0x330
#define CLK_RST_CONTROLLER_CLK_ENB_U_CLR 0x334
#define CLK_RST_CONTROLLER_RST_DEVICES_V 0x358
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_V 0x360
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_W 0x364
#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2 0x388
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4
#define CLK_RST_CONTROLLER_CLK_ENB_V_SET 0x440
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR 0x454
#define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518
#define CLK_RST_CONTROLLER_SPARE_REG0 0x55C
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694
/*! Generic clock descriptor. */
typedef struct _clock_t
{
u32 reset;
@ -44,24 +76,33 @@ typedef struct _clock_t
u8 clk_div;
} clock_t;
/*! Generic clock enable/disable. */
void clock_enable(const clock_t *clk);
void clock_disable(const clock_t *clk);
/*! Clock control for specific hardware portions. */
void clock_enable_fuse(u32 enable);
void clock_enable_uart(u32 idx);
void clock_enable_i2c(u32 idx);
void clock_enable_se();
void clock_enable_host1x();
void clock_enable_tsec();
void clock_enable_sor_safe();
void clock_enable_sor0();
void clock_enable_sor1();
void clock_enable_kfuse();
void clock_disable_host1x();
void clock_enable_tsec();
void clock_disable_tsec();
void clock_enable_sor_safe();
void clock_disable_sor_safe();
void clock_enable_sor0();
void clock_disable_sor0();
void clock_enable_sor1();
void clock_disable_sor1();
void clock_enable_kfuse();
void clock_disable_kfuse();
void clock_enable_cl_dvfs();
void clock_enable_coresight();
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val);
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type);
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
void clock_sdmmc_enable(u32 id, u32 val);
void clock_sdmmc_disable(u32 id);
#endif

62
hwinit/cluster.c → ipl/cluster.c Normal file → Executable file
View File

@ -20,30 +20,26 @@
#include "util.h"
#include "pmc.h"
#include "t210.h"
#include "max77620.h"
void _cluster_enable_power()
{
u8 tmp;
if (i2c_recv_buf_small(&tmp, 1, I2C_5, 0x3C, 0x40))
{
tmp &= 0xDFu;
i2c_send_byte(I2C_5, 0x3C, 0x40, tmp);
}
i2c_send_byte(I2C_5, 0x3C, 0x3B, 0x09);
u8 tmp = i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_AME_GPIO);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_AME_GPIO, tmp & 0xDF);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_GPIO5, 0x09);
//Enable cores power.
i2c_send_byte(I2C_5, 0x1B, 0x02, 0x20);
i2c_send_byte(I2C_5, 0x1B, 0x03, 0x8D);
i2c_send_byte(I2C_5, 0x1B, 0x00, 0xB7);
i2c_send_byte(I2C_5, 0x1B, 0x01, 0xB7);
i2c_send_byte(I2C_5, 0x1B, 0x2, 0x20);
i2c_send_byte(I2C_5, 0x1B, 0x3, 0x8D);
i2c_send_byte(I2C_5, 0x1B, 0x0, 0xB7);
i2c_send_byte(I2C_5, 0x1B, 0x1, 0xB7);
}
int _cluster_pmc_enable_partition(u32 part, u32 toggle)
{
//Check if the partition has already been turned on.
if (PMC(APBDEV_PMC_PWRGATE_STATUS) & part)
return 0;
return 1;
u32 i = 5001;
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
@ -68,32 +64,38 @@ int _cluster_pmc_enable_partition(u32 part, u32 toggle)
return 1;
}
void cluster_enable_cpu0(u32 entry)
void cluster_boot_cpu0(u32 entry)
{
//Set ACTIVE_CLUSER to FAST.
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;
_cluster_enable_power();
if (!(CLOCK(0xE0) & 0x40000000))
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000))
{
CLOCK(0x518) &= 0xFFFFFFF7;
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7;
sleep(2);
CLOCK(0xE4) = CLOCK(0xE4) & 0xFFFBFFFF | 0x40000;
CLOCK(0xE0) = 0x40404E02;
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x80404E02;
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x404E02;
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) = CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) & 0xFFFBFFFF | 0x40000;
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x40404E02;
}
while (!(CLOCK(0xE0) & 0x8000000))
while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x8000000))
;
CLOCK(0x3B4) = CLOCK(0x3B4) & 0x1FFFFF00 | 6;
CLOCK(0x360) = CLOCK(0x360) & 0xFFFFFFF7 | 8;
CLOCK(0x20) = 0x20008888;
CLOCK(0x24) = 0x80000000;
CLOCK(0x440) = 1;
//Configure MSELECT source and enable clock.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00 | 6;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) & 0xFFFFFFF7 | 8;
//Configure initial CPU clock frequency and enable clock.
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888;
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = 1;
clock_enable_coresight();
CLOCK(0x388) = CLOCK(0x388) & 0xFFFFE000;
//CAR2PMC_CPU_ACK_WIDTH should be set to 0.
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) = CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) & 0xFFFFF000;
//Enable CPU rail.
_cluster_pmc_enable_partition(1, 0);
@ -109,13 +111,17 @@ void cluster_enable_cpu0(u32 entry)
EXCP_VEC(0x100) = 0;
//Set reset vectors.
//Set reset vector.
SB(SB_AA64_RESET_LOW) = entry | 1;
SB(SB_AA64_RESET_HIGH) = 0;
//Non-secure reset vector write disable.
SB(SB_CSR_0) = 2;
SB(SB_CSR) = 2;
(void)SB(SB_CSR);
//Until here the CPU was in reset, this kicks execution.
//Clear MSELECT reset.
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7;
//Clear NONCPU reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
//Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x411F000F;
}

0
hwinit/cluster.h → ipl/cluster.h Normal file → Executable file
View File

5
hwinit/di.c → ipl/di.c Normal file → Executable file
View File

@ -19,6 +19,7 @@
#include "util.h"
#include "i2c.h"
#include "pmc.h"
#include "max77620.h"
#include "di.inl"
@ -35,8 +36,8 @@ static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
void display_init()
{
//Power on.
i2c_send_byte(I2C_5, 0x3C, 0x23, 0xD0);
i2c_send_byte(I2C_5, 0x3C, 0x3D, 0x09);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_LDO0_CFG, 0xD0); //Configure to 1.2V.
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_GPIO7, 0x09);
//Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks.
CLOCK(0x30C) = 0x1010000;

0
hwinit/di.h → ipl/di.h Normal file → Executable file
View File

0
hwinit/di.inl → ipl/di.inl Normal file → Executable file
View File

71
ipl/diskio.c Executable file
View File

@ -0,0 +1,71 @@
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include <string.h>
#include "diskio.h" /* FatFs lower layer API */
#include "sdmmc.h"
extern sdmmc_storage_t sd_storage;
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
return 0;
}
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
return 0;
}
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
if ((u32)buff >= 0x90000000)
return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;
u8 *buf = (u8 *)0x98000000; //TODO: define this somewhere.
if (sdmmc_storage_read(&sd_storage, sector, count, buf))
{
memcpy(buff, buf, 512 * count);
return RES_OK;
}
return RES_ERROR;
}
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
if ((u32)buff >= 0x90000000)
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
u8 *buf = (u8 *)0x98000000; //TODO: define this somewhere.
memcpy(buf, buff, 512 * count);
if (sdmmc_storage_write(&sd_storage, sector, count, buf))
return RES_OK;
return RES_ERROR;
}
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
return RES_OK;
}

80
ipl/diskio.h Executable file
View File

@ -0,0 +1,80 @@
/*-----------------------------------------------------------------------/
/ Low level disk interface modlue include file (C)ChaN, 2014 /
/-----------------------------------------------------------------------*/
#ifndef _DISKIO_DEFINED
#define _DISKIO_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h"
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (Used by FatFs) */
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
/* Generic command (Not used by FatFs) */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_FORMAT 8 /* Create physical format on the media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
#ifdef __cplusplus
}
#endif
#endif

2
hwinit/emc.h → ipl/emc.h Normal file → Executable file
View File

@ -22,6 +22,8 @@
#ifndef _EMC_H_
#define _EMC_H_
#define EMC_DBG 0x8
#define EMC_CFG 0xC
#define EMC_CONFIG_SAMPLE_DELAY 0x5f0
#define EMC_CFG_UPDATE 0x5f4
#define EMC_ADR_CFG 0x10

6555
ipl/ff.c Executable file

File diff suppressed because it is too large Load Diff

366
ipl/ff.h Executable file
View File

@ -0,0 +1,366 @@
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem module R0.13a /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2017, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/
/----------------------------------------------------------------------------*/
#ifndef FF_DEFINED
#define FF_DEFINED 89352 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#if FF_DEFINED != FFCONF_DEF
#error Wrong configuration file (ffconf.h).
#endif
/* Definitions of volume management */
#if FF_MULTI_PARTITION /* Multiple partition configuration */
typedef struct {
BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
#endif
/* Type of path name strings on FatFs API */
#ifndef _INC_TCHAR
#define _INC_TCHAR
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
typedef WCHAR TCHAR;
#define _T(x) L ## x
#define _TEXT(x) L ## x
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
typedef char TCHAR;
#define _T(x) u8 ## x
#define _TEXT(x) u8 ## x
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 2)
#error Wrong FF_LFN_UNICODE setting
#else /* ANSI/OEM code in SBCS/DBCS */
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
#endif
/* Type of file size variables */
#if FF_FS_EXFAT
typedef QWORD FSIZE_t;
#else
typedef DWORD FSIZE_t;
#endif
/* Filesystem object structure (FATFS) */
typedef struct {
BYTE fs_type; /* Filesystem type (0:N/A) */
BYTE pdrv; /* Physical drive number */
BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id; /* Volume mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
WORD csize; /* Cluster size [sectors] */
#if FF_MAX_SS != FF_MIN_SS
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
#endif
#if FF_USE_LFN
WCHAR* lfnbuf; /* LFN working buffer */
#endif
#if FF_FS_EXFAT
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
#endif
#if FF_FS_REENTRANT
FF_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !FF_FS_READONLY
DWORD last_clst; /* Last allocated cluster */
DWORD free_clst; /* Number of free clusters */
#endif
#if FF_FS_RPATH
DWORD cdir; /* Current directory start cluster (0:root) */
#if FF_FS_EXFAT
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
#endif
#endif
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
DWORD fsize; /* Size of an FAT [sectors] */
DWORD volbase; /* Volume base sector */
DWORD fatbase; /* FAT base sector */
DWORD dirbase; /* Root directory base sector/cluster */
DWORD database; /* Data base sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS;
/* Object ID and allocation information (FFOBJID) */
typedef struct {
FATFS* fs; /* Pointer to the hosting volume of this object */
WORD id; /* Hosting volume mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
#if FF_FS_EXFAT
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
#endif
#if FF_FS_LOCK
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
} FFOBJID;
/* File object structure (FIL) */
typedef struct {
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
BYTE flag; /* File status flags */
BYTE err; /* Abort flag (error code) */
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
#if !FF_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
#endif
#if FF_USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
#if !FF_FS_TINY
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
/* Directory object structure (DIR) */
typedef struct {
FFOBJID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector (0:Read operation has terminated) */
BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if FF_USE_LFN
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
#endif
#if FF_USE_FIND
const TCHAR* pat; /* Pointer to the name matching pattern */
#endif
} DIR;
/* File information structure (FILINFO) */
typedef struct {
FSIZE_t fsize; /* File size */
WORD fdate; /* Modified date */
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if FF_USE_LFN
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
#else
TCHAR fname[12 + 1]; /* File name */
#endif
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
FR_EXIST, /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
FRESULT f_truncate (FIL* fp); /* Truncate the file */
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
FRESULT f_setcp (WORD cp); /* Set current code page */
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->obj.objsize)
#define f_rewind(fp) f_lseek((fp), 0)
#define f_rewinddir(dp) f_readdir((dp), 0)
#define f_rmdir(path) f_unlink(path)
#define f_unmount(path) f_mount(0, path, 0)
#ifndef EOF
#define EOF (-1)
#endif
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* RTC function */
#if !FF_FS_READONLY && !FF_FS_NORTC
DWORD get_fattime (void);
#endif
/* LFN support functions */
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
#endif
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
/* Sync functions */
#if FF_FS_REENTRANT
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
#endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* File access mode and open method flags (3rd argument of f_open) */
#define FA_READ 0x01
#define FA_WRITE 0x02
#define FA_OPEN_EXISTING 0x00
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA_OPEN_APPEND 0x30
/* Fast seek controls (2nd argument of f_lseek) */
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
/* Format options (2nd argument of f_mkfs) */
#define FM_FAT 0x01
#define FM_FAT32 0x02
#define FM_EXFAT 0x04
#define FM_ANY 0x07
#define FM_SFD 0x08
/* Filesystem type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
#define FS_EXFAT 4
/* File attribute bits for directory entry (FILINFO.fattrib) */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#ifdef __cplusplus
}
#endif
#endif /* FF_DEFINED */

283
ipl/ffconf.h Executable file
View File

@ -0,0 +1,283 @@
/*---------------------------------------------------------------------------/
/ FatFs - Configuration file
/---------------------------------------------------------------------------*/
#define FFCONF_DEF 89352 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_READONLY 0
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define FF_FS_MINIMIZE 0
/* This option defines minimization level to remove some basic API functions.
/
/ 0: Basic functions are fully enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define FF_USE_STRFUNC 2
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define FF_USE_FIND 0
/* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define FF_USE_MKFS 0
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define FF_USE_FASTSEEK 0
/* This option switches fast seek function. (0:Disable or 1:Enable) */
#define FF_USE_EXPAND 0
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#define FF_USE_CHMOD 0
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
#define FF_USE_LABEL 0
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define FF_USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
#define FF_CODE_PAGE 850
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect code page setting can cause a file open failure.
/
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
/ 0 - Include all code pages above and configured by f_setcp()
*/
#define FF_USE_LFN 1
#define FF_MAX_LFN 255
/* The FF_USE_LFN switches the support for LFN (long file name).
/
/ 0: Disable LFN. FF_MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
/ specification.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree() in ffsystem.c, need to be added to the project. */
#define FF_LFN_UNICODE 0
/* This option switches the character encoding on the API when LFN is enabled.
/
/ 0: ANSI/OEM in current CP (TCHAR = char)
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
/ 2: Unicode in UTF-8 (TCHAR = char)
/
/ Also behavior of string I/O functions will be affected by this option.
/ When LFN is not enabled, this option has no effect. */
#define FF_LFN_BUF 255
#define FF_SFN_BUF 12
/* This set of options defines size of file name members in the FILINFO structure
/ which is used to read out directory items. These values should be suffcient for
/ the file names to read. The maximum possible length of the read file name depends
/ on character encoding. When LFN is not enabled, these options have no effect. */
#define FF_STRF_ENCODE 0
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
/ This option selects assumption of character encoding ON THE FILE to be
/ read/written via those functions.
/
/ 0: ANSI/OEM in current CP
/ 1: Unicode in UTF-16LE
/ 2: Unicode in UTF-16BE
/ 3: Unicode in UTF-8
*/
#define FF_FS_RPATH 0
/* This option configures support for relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
*/
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define FF_VOLUMES 1
/* Number of volumes (logical drives) to be used. (1-10) */
#define FF_STR_VOLUME_ID 0
#define FF_VOLUME_STRS "sd"
/* FF_STR_VOLUME_ID switches string support for volume ID.
/ When FF_STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the drive ID strings for each
/ logical drives. Number of items must be equal to FF_VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
#define FF_MULTI_PARTITION 0
/* This option switches support for multiple volumes on the physical drive.
/ By default (0), each logical drive number is bound to the same physical drive
/ number and only an FAT volume found on the physical drive will be mounted.
/ When this function is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
#define FF_MIN_SS 512
#define FF_MAX_SS 512
/* This set of options configures the range of sector size to be supported. (512,
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
/ for variable sector size mode and disk_ioctl() function needs to implement
/ GET_SECTOR_SIZE command. */
#define FF_USE_TRIM 0
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define FF_FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
/*---------------------------------------------------------------------------/
/ System Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_TINY 0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
/ Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
#define FF_FS_EXFAT 0
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled.
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
#define FF_FS_NORTC 1
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2018
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
#define FF_FS_LOCK 0
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
#define FF_FS_REENTRANT 0
#define FF_FS_TIMEOUT 1000
#define FF_SYNC_t HANDLE
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/* #include <windows.h> // O/S definitions */
/*--- End of configuration options ---*/

608
ipl/ffunicode.c Executable file
View File

@ -0,0 +1,608 @@
/*------------------------------------------------------------------------*/
/* Unicode handling functions for FatFs R0.13a */
/*------------------------------------------------------------------------*/
/* This module will occupy a huge memory in the .const section when the /
/ FatFs is configured for LFN with DBCS. If the system has any Unicode /
/ utilitiy for the code conversion, this module should be modified to use /
/ that function to avoid silly memory consumption. /
/-------------------------------------------------------------------------*/
/*
/ Copyright (C) 2017, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
/
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
*/
#include "ff.h"
#if FF_USE_LFN /* This module is blanked when non-LFN configuration */
#if FF_DEFINED != 89352 /* Revision ID */
#error Wrong include file (ff.h).
#endif
#define MERGE2(a, b) a ## b
#define CVTBL(tbl, cp) MERGE2(tbl, cp)
/*------------------------------------------------------------------------*/
/* Code Conversion Tables */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0
static
const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0
static
const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0
static
const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0
static
const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0
static
const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0
static
const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0
static
const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0
static
const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0
static
const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0
static
const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0
static
const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0
static
const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0
static
const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0
static
const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */
0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,
0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,
0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,
0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
};
#endif
#if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0
static
const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0
static
const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0
static
const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,
0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,
0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
};
#endif
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for static code page configuration */
/* SBCS fixed code page */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
DWORD uni, /* UTF-16 encoded character to be converted */
WORD cp /* Code page for the conversion */
)
{
WCHAR c = 0;
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
if (uni < 0x80) { /* ASCII? */
c = (WCHAR)uni;
} else { /* Non-ASCII */
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it a valid code? */
for (c = 0; c < 0x80 && uni != p[c]; c++) ;
c = (c + 0x80) & 0xFF;
}
}
return c;
}
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
WCHAR oem, /* OEM code to be converted */
WORD cp /* Code page for the conversion */
)
{
WCHAR c = 0;
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
if (oem < 0x80) { /* ASCII? */
c = oem;
} else { /* Extended char */
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */
if (oem < 0x100) c = p[oem - 0x80];
}
}
return c;
}
#endif
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for static code page configuration */
/* DBCS fixed code page */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE >= 900
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
DWORD uni, /* UTF-16 encoded character to be converted */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
WCHAR c = 0, uc;
UINT i, n, li, hi;
if (uni < 0x80) { /* ASCII? */
c = (WCHAR)uni;
} else { /* Non-ASCII */
if (uni < 0x10000) { /* Is it in BMP? */
if (cp == FF_CODE_PAGE) { /* Is it a valid code? */
uc = (WCHAR)uni;
p = CVTBL(uni2oem, FF_CODE_PAGE);
hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;
li = 0;
for (n = 16; n; n--) {
i = li + (hi - li) / 2;
if (uc == p[i * 2]) break;
if (uc > p[i * 2]) {
li = i;
} else {
hi = i;
}
}
if (n != 0) c = p[i * 2 + 1];
}
}
}
return c;
}
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
WCHAR oem, /* OEM code to be converted */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
WCHAR c = 0;
UINT i, n, li, hi;
if (oem < 0x80) { /* ASCII? */
c = oem;
} else { /* Extended char */
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */
p = CVTBL(oem2uni, FF_CODE_PAGE);
hi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1;
li = 0;
for (n = 16; n; n--) {
i = li + (hi - li) / 2;
if (oem == p[i * 2]) break;
if (oem > p[i * 2]) {
li = i;
} else {
hi = i;
}
}
if (n != 0) c = p[i * 2 + 1];
}
}
return c;
}
#endif
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for dynamic code page configuration */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE == 0
static const WORD cp_code[] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 0};
static const WCHAR *const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0};
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
DWORD uni, /* UTF-16 encoded character to be converted */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
WCHAR c = 0, uc;
UINT i, n, li, hi;
if (uni < 0x80) { /* ASCII? */
c = (WCHAR)uni;
} else { /* Non-ASCII */
if (uni < 0x10000) { /* Is it in BMP? */
uc = (WCHAR)uni;
p = 0;
if (cp < 900) { /* SBCS */
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */
p = cp_table[i];
if (p) { /* Is it a valid CP ? */
for (c = 0; c < 0x80 && uc != p[c]; c++) ; /* Find OEM code in the table */
c = (c + 0x80) & 0xFF;
}
} else { /* DBCS */
switch (cp) {
case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break;
case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break;
case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break;
case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break;
}
if (p) { /* Is it a valid code page? */
li = 0;
for (n = 16; n; n--) { /* Find OEM code */
i = li + (hi - li) / 2;
if (uc == p[i * 2]) break;
if (uc > p[i * 2]) {
li = i;
} else {
hi = i;
}
}
if (n != 0) c = p[i * 2 + 1];
}
}
}
}
return c;
}
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
WCHAR c = 0;
UINT i, n, li, hi;
if (oem < 0x80) { /* ASCII? */
c = oem;
} else { /* Extended char */
p = 0;
if (cp < 900) { /* SBCS */
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */
p = cp_table[i];
if (p) { /* Is it a valid CP ? */
if (oem < 0x100) c = p[oem - 0x80];
}
} else { /* DBCS */
switch (cp) {
case 932 : p = oem2uni932; hi = sizeof oem2uni932 / 4 - 1; break;
case 936 : p = oem2uni936; hi = sizeof oem2uni936 / 4 - 1; break;
case 949 : p = oem2uni949; hi = sizeof oem2uni949 / 4 - 1; break;
case 950 : p = oem2uni950; hi = sizeof oem2uni950 / 4 - 1; break;
}
if (p) {
li = 0;
for (n = 16; n; n--) {
i = li + (hi - li) / 2;
if (oem == p[i * 2]) break;
if (oem > p[i * 2]) {
li = i;
} else {
hi = i;
}
}
if (n != 0) c = p[i * 2 + 1];
}
}
}
return c;
}
#endif
/*------------------------------------------------------------------------*/
/* Unicode up-case conversion */
/*------------------------------------------------------------------------*/
DWORD ff_wtoupper ( /* Returns up-converted code point */
DWORD uni /* Unicode code point to be up-converted */
)
{
/* Compressed upper conversion table */
static const WORD cvt1[] = { /* U+0000 - U+0FFF */
/* Basic Latin */
0x0061,0x031A,
/* Latin-1 Supplement */
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
/* Latin Extended-A */
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
/* Latin Extended-B */
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
/* IPA Extensions */
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
/* Greek, Coptic */
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
/* Cyrillic */
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
/* Armenian */
0x0561,0x0426,
0x0000
};
static const WORD cvt2[] = { /* U+1000 - U+FFFF */
/* Phonetic Extensions */
0x1D7D,0x0001,0x2C63,
/* Latin Extended Additional */
0x1E00,0x0196, 0x1EA0,0x015A,
/* Greek Extended */
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF3,0x0001,0x1FFC,
/* Letterlike Symbols */
0x214E,0x0001,0x2132,
/* Number forms */
0x2170,0x0210, 0x2184,0x0001,0x2183,
/* Enclosed Alphanumerics */
0x24D0,0x051A, 0x2C30,0x042F,
/* Latin Extended-C */
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
/* Coptic */
0x2C80,0x0164,
/* Georgian Supplement */
0x2D00,0x0826,
/* Full-width */
0xFF41,0x031A,
0x0000
};
const WORD *p;
WORD uc, bc, nc, cmd;
if (uni < 0x10000) { /* Is it in BMP? */
uc = (WORD)uni;
p = uc < 0x1000 ? cvt1 : cvt2;
for (;;) {
bc = *p++; /* Get block base */
if (!bc || uc < bc) break;
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
if (uc < bc + nc) { /* In the block? */
switch (cmd) {
case 0: uc = p[uc - bc]; break; /* Table conversion */
case 1: uc -= (uc - bc) & 1; break; /* Case pairs */
case 2: uc -= 16; break; /* Shift -16 */
case 3: uc -= 32; break; /* Shift -32 */
case 4: uc -= 48; break; /* Shift -48 */
case 5: uc -= 26; break; /* Shift -26 */
case 6: uc += 8; break; /* Shift +8 */
case 7: uc -= 80; break; /* Shift -80 */
case 8: uc -= 0x1C60; break; /* Shift -0x1C60 */
}
break;
}
if (!cmd) p += nc;
}
uni = uc;
}
return uni;
}
#endif /* #if FF_USE_LFN */

56
hwinit/fuse.c → ipl/fuse.c Normal file → Executable file
View File

@ -1,28 +1,28 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "fuse.h"
#include "t210.h"
void fuse_disable_program()
{
FUSE(FUSE_DISABLEREGPROGRAM) = 1;
}
u32 fuse_read_odm(u32 idx)
{
return FUSE(FUSE_RESERVED_ODMX(idx));
}
/*
* Copyright (c) 2018 naehrwert
*
* 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 "fuse.h"
#include "t210.h"
void fuse_disable_program()
{
FUSE(FUSE_DISABLEREGPROGRAM) = 1;
}
u32 fuse_read_odm(u32 idx)
{
return FUSE(FUSE_RESERVED_ODMX(idx));
}

88
hwinit/fuse.h → ipl/fuse.h Normal file → Executable file
View File

@ -1,44 +1,44 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _FUSE_H_
#define _FUSE_H_
#include "types.h"
/*! Fuse registers. */
#define FUSE_CTRL 0x0
#define FUSE_ADDR 0x4
#define FUSE_RDATA 0x8
#define FUSE_WDATA 0xC
#define FUSE_TIME_RD1 0x10
#define FUSE_TIME_RD2 0x14
#define FUSE_TIME_PGM1 0x18
#define FUSE_TIME_PGM2 0x1C
#define FUSE_PRIV2INTFC 0x20
#define FUSE_FUSEBYPASS 0x24
#define FUSE_PRIVATEKEYDISABLE 0x28
#define FUSE_DISABLEREGPROGRAM 0x2C
#define FUSE_WRITE_ACCESS_SW 0x30
#define FUSE_PWR_GOOD_SW 0x34
/*! Fuse cache registers. */
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
void fuse_disable_program();
u32 fuse_read_odm(u32 idx);
#endif
/*
* Copyright (c) 2018 naehrwert
*
* 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 _FUSE_H_
#define _FUSE_H_
#include "types.h"
/*! Fuse registers. */
#define FUSE_CTRL 0x0
#define FUSE_ADDR 0x4
#define FUSE_RDATA 0x8
#define FUSE_WDATA 0xC
#define FUSE_TIME_RD1 0x10
#define FUSE_TIME_RD2 0x14
#define FUSE_TIME_PGM1 0x18
#define FUSE_TIME_PGM2 0x1C
#define FUSE_PRIV2INTFC 0x20
#define FUSE_FUSEBYPASS 0x24
#define FUSE_PRIVATEKEYDISABLE 0x28
#define FUSE_DISABLEREGPROGRAM 0x2C
#define FUSE_WRITE_ACCESS_SW 0x30
#define FUSE_PWR_GOOD_SW 0x34
/*! Fuse cache registers. */
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
void fuse_disable_program();
u32 fuse_read_odm(u32 idx);
#endif

308
ipl/gfx.c Executable file
View File

@ -0,0 +1,308 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 <stdarg.h>
#include "gfx.h"
static const u8 _gfx_font[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00,
0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66,
0x00, 0x18, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x18, 0x10, 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62,
0x00, 0x3C, 0x66, 0x3C, 0x1C, 0xE6, 0x66, 0xFC, 0x00, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00,
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00,
0x00, 0x3C, 0x66, 0x76, 0x6E, 0x66, 0x3C, 0x00, 0x00, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x7E, 0x00,
0x00, 0x3C, 0x62, 0x30, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x62, 0x38, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x6C, 0x6C, 0x66, 0xFE, 0x60, 0x60, 0x00, 0x00, 0x7E, 0x06, 0x7E, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x7E, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00,
0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x3C, 0x66, 0x7C, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x00,
0x00, 0x70, 0x1C, 0x06, 0x06, 0x1C, 0x70, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x38, 0x60, 0x60, 0x38, 0x0E, 0x00, 0x00, 0x3C, 0x66, 0x30, 0x18, 0x00, 0x18, 0x00,
0x00, 0x3C, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3C, 0x00, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x06, 0x66, 0x3C, 0x00,
0x00, 0x1E, 0x36, 0x66, 0x66, 0x36, 0x1E, 0x00, 0x00, 0x7E, 0x06, 0x1E, 0x06, 0x06, 0x7E, 0x00,
0x00, 0x3E, 0x06, 0x1E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x76, 0x66, 0x3C, 0x00,
0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00,
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, 0x00, 0x46, 0x6E, 0x7E, 0x56, 0x46, 0x46, 0x00,
0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x70, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x1E, 0x36, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x0C, 0x30, 0x66, 0x3C, 0x00,
0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x46, 0x46, 0x56, 0x7E, 0x6E, 0x46, 0x00,
0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00,
0x00, 0x7E, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C,
0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C,
0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
0x00, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00,
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00,
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00,
0x00, 0x38, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x7C, 0x40, 0x3C, 0x00,
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x18, 0x00, 0x1C, 0x18, 0x18, 0x3C, 0x00,
0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1E, 0x00, 0x00, 0x06, 0x06, 0x36, 0x1E, 0x36, 0x66, 0x00,
0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x66, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00,
0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00,
0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x7C, 0x60, 0x3C, 0x00,
0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0C, 0x08, 0x08, 0x10, 0x08, 0x08,
};
void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride)
{
ctxt->fb = fb;
ctxt->width = width;
ctxt->height = height;
ctxt->stride = stride;
}
void gfx_clear(gfx_ctxt_t *ctxt, u32 color)
{
for (u32 i = 0; i < ctxt->height * ctxt->stride; i++)
ctxt->fb[i] = color;
}
void gfx_con_init(gfx_con_t *con, gfx_ctxt_t *ctxt)
{
con->gfx_ctxt = ctxt;
con->x = 0;
con->y = 0;
con->fgcol = 0xFFFFFFFF;
con->fillbg = 0;
con->bgcol = 0xFF000000;
}
void gfx_con_setcol(gfx_con_t *con, u32 fgcol, int fillbg, u32 bgcol)
{
con->fgcol = fgcol;
con->fillbg = fillbg;
con->bgcol = bgcol;
}
void gfx_con_getpos(gfx_con_t *con, u32 *x, u32 *y)
{
*x = con->x;
*y = con->y;
}
void gfx_con_setpos(gfx_con_t *con, u32 x, u32 y)
{
con->x = x;
con->y = y;
}
void gfx_putc(gfx_con_t *con, char c)
{
if (c >= 32 && c < 128)
{
u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];
u32 *fb = con->gfx_ctxt->fb + con->x + con->y * con->gfx_ctxt->stride;
for (u32 i = 0; i < 8; i++)
{
u8 v = *cbuf++;
for (u32 j = 0; j < 8; j++)
{
if (v & 1)
*fb = con->fgcol;
else if (con->fillbg)
*fb = con->bgcol;
v >>= 1;
fb++;
}
fb += con->gfx_ctxt->stride - 8;
}
con->x += 8;
}
else if (c == '\n')
{
con->x = 0;
con->y += 8;
if (con->y > con->gfx_ctxt->height - 8)
con->y = 0;
}
}
void gfx_puts(gfx_con_t *con, const char *s)
{
if (!s)
return;
for (; *s; s++)
gfx_putc(con, *s);
}
static void _gfx_putn(gfx_con_t *con, u32 v, int base, char fill, int fcnt)
{
char buf[65];
static const char digits[] = "0123456789ABCDEFghijklmnopqrstuvwxyz";
char *p;
int c = fcnt;
if (base > 36)
return;
p = buf + 64;
*p = 0;
do
{
c--;
*--p = digits[v % base];
v /= base;
} while (v);
if (fill != 0)
{
while (c > 0)
{
*--p = fill;
c--;
}
}
gfx_puts(con, p);
}
void gfx_printf(gfx_con_t *con, const char *fmt, ...)
{
va_list ap;
int fill, fcnt;
va_start(ap, fmt);
while(*fmt)
{
if(*fmt == '%')
{
fmt++;
fill = 0;
fcnt = 0;
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
{
fcnt = *fmt;
fmt++;
if (*fmt >= '0' && *fmt <= '9')
{
fill = fcnt;
fcnt = *fmt - '0';
fmt++;
}
else
{
fill = ' ';
fcnt -= '0';
}
}
switch(*fmt)
{
case 'c':
gfx_putc(con, va_arg(ap, u32));
break;
case 's':
gfx_puts(con, va_arg(ap, char *));
break;
case 'd':
_gfx_putn(con, va_arg(ap, u32), 10, fill, fcnt);
break;
case 'x':
case 'X':
_gfx_putn(con, va_arg(ap, u32), 16, fill, fcnt);
break;
case 'k':
con->fgcol = va_arg(ap, u32);
break;
case 'K':
con->bgcol = va_arg(ap, u32);
con->fillbg = fcnt;
break;
case '%':
gfx_putc(con, '%');
break;
case '\0':
goto out;
default:
gfx_putc(con, '%');
gfx_putc(con, *fmt);
break;
}
}
else
gfx_putc(con, *fmt);
fmt++;
}
out:
va_end(ap);
}
void gfx_hexdump(gfx_con_t *con, u32 base, const u8 *buf, u32 len)
{
for(u32 i = 0; i < len; i++)
{
if(i % 0x10 == 0)
{
if(i != 0)
{
gfx_puts(con, "| ");
for(u32 j = 0; j < 0x10; j++)
{
u8 c = buf[i - 0x10 + j];
if(c >= 32 && c < 128)
gfx_putc(con, c);
else
gfx_putc(con, '.');
}
gfx_putc(con, '\n');
}
gfx_printf(con, "%08x: ", base + i);
}
gfx_printf(con, "%02x ", buf[i]);
}
gfx_putc(con, '\n');
}
static int abs(int x)
{
if (x < 0)
return -x;
return x;
}
void gfx_set_pixel(gfx_ctxt_t *ctxt, u32 x, u32 y, u32 color)
{
ctxt->fb[x + y * ctxt->stride] = color;
}
void gfx_line(gfx_ctxt_t *ctxt, int x0, int y0, int x1, int y1, u32 color)
{
int dx = abs(x1-x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1-y0), sy = y0 < y1 ? 1 : -1;
int err = (dx > dy ? dx : -dy) / 2, e2;
while (1)
{
gfx_set_pixel(ctxt, x0, y0, color);
if (x0 == x1 && y0 == y1)
break;
e2 = err;
if (e2 >-dx) { err -= dy; x0 += sx; }
if (e2 < dy) { err += dx; y0 += sy; }
}
}

54
ipl/gfx.h Executable file
View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _GFX_H_
#define _GFX_H_
#include "types.h"
typedef struct _gfx_ctxt_t
{
u32 *fb;
u32 width;
u32 height;
u32 stride;
} gfx_ctxt_t;
typedef struct _gfx_con_t
{
gfx_ctxt_t *gfx_ctxt;
u32 x;
u32 y;
u32 fgcol;
int fillbg;
u32 bgcol;
} gfx_con_t;
void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride);
void gfx_clear(gfx_ctxt_t *ctxt, u32 color);
void gfx_con_init(gfx_con_t *con, gfx_ctxt_t *ctxt);
void gfx_con_setcol(gfx_con_t *con, u32 fgcol, int fillbg, u32 bgcol);
void gfx_con_getpos(gfx_con_t *con, u32 *x, u32 *y);
void gfx_con_setpos(gfx_con_t *con, u32 x, u32 y);
void gfx_putc(gfx_con_t *con, char c);
void gfx_puts(gfx_con_t *con, const char *s);
void gfx_printf(gfx_con_t *con, const char *fmt, ...);
void gfx_hexdump(gfx_con_t *con, u32 base, const u8 *buf, u32 len);
void gfx_set_pixel(gfx_ctxt_t *ctxt, u32 x, u32 y, u32 color);
void gfx_line(gfx_ctxt_t *ctxt, int x0, int y0, int x1, int y1, u32 color);
#endif

94
ipl/gpio.c Executable file
View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "gpio.h"
#include "t210.h"
static const u16 _gpio_cnf[31] = {
0x000, 0x004, 0x008, 0x00C,
0x100, 0x104, 0x108, 0x10C,
0x200, 0x204, 0x208, 0x20C,
0x300, 0x304, 0x308, 0x30C,
0x400, 0x404, 0x408, 0x40C,
0x500, 0x504, 0x508, 0x50C,
0x600, 0x604, 0x608, 0x60C,
0x700, 0x704, 0x708
};
static const u16 _gpio_oe[31] = {
0x010, 0x014, 0x018, 0x01C,
0x110, 0x114, 0x118, 0x11C,
0x210, 0x214, 0x218, 0x21C,
0x310, 0x314, 0x318, 0x31C,
0x410, 0x414, 0x418, 0x41C,
0x510, 0x514, 0x518, 0x51C,
0x610, 0x614, 0x618, 0x61C,
0x710, 0x714, 0x718
};
static const u16 _gpio_out[31] = {
0x020, 0x024, 0x028, 0x02C,
0x120, 0x124, 0x128, 0x12C,
0x220, 0x224, 0x228, 0x22C,
0x320, 0x324, 0x328, 0x32C,
0x420, 0x424, 0x428, 0x42C,
0x520, 0x524, 0x528, 0x52C,
0x620, 0x624, 0x628, 0x62C,
0x720, 0x724, 0x728
};
static const u16 _gpio_in[31] = {
0x030, 0x034, 0x038, 0x03C,
0x130, 0x134, 0x138, 0x13C,
0x230, 0x234, 0x238, 0x23C,
0x330, 0x334, 0x338, 0x33C,
0x430, 0x434, 0x438, 0x43C,
0x530, 0x534, 0x538, 0x53C,
0x630, 0x634, 0x638, 0x63C,
0x730, 0x734, 0x738
};
void gpio_config(u32 port, u32 pins, int mode)
{
if (mode)
GPIO(_gpio_cnf[port]) |= pins;
else
GPIO(_gpio_cnf[port]) &= ~pins;
(void)GPIO(_gpio_cnf[port]);
}
void gpio_output_enable(u32 port, u32 pins, int enable)
{
if (enable)
GPIO(_gpio_oe[port]) |= pins;
else
GPIO(_gpio_oe[port]) &= ~pins;
(void)GPIO(_gpio_oe[port]);
}
void gpio_write(u32 port, u32 pins, int high)
{
if (high)
GPIO(_gpio_out[port]) |= pins;
else
GPIO(_gpio_out[port]) &= ~pins;
(void)GPIO(_gpio_out[port]);
}
int gpio_read(u32 port, u32 pins)
{
return GPIO(_gpio_in[port]) & pins ? 1 : 0;
}

77
ipl/gpio.h Executable file
View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _GPIO_H_
#define _GPIO_H_
#include "types.h"
#define GPIO_MODE_SPIO 0
#define GPIO_MODE_GPIO 1
#define GPIO_OUTPUT_DISABLE 0
#define GPIO_OUTPUT_ENABLE 1
#define GPIO_LOW 0
#define GPIO_HIGH 1
/*! GPIO pins (0-7 for each port). */
#define GPIO_PIN_0 (1 << 0)
#define GPIO_PIN_1 (1 << 1)
#define GPIO_PIN_2 (1 << 2)
#define GPIO_PIN_3 (1 << 3)
#define GPIO_PIN_4 (1 << 4)
#define GPIO_PIN_5 (1 << 5)
#define GPIO_PIN_6 (1 << 6)
#define GPIO_PIN_7 (1 << 7)
/*! GPIO ports (A-EE). */
#define GPIO_PORT_A 0
#define GPIO_PORT_B 1
#define GPIO_PORT_C 2
#define GPIO_PORT_D 3
#define GPIO_PORT_E 4
#define GPIO_PORT_F 5
#define GPIO_PORT_G 6
#define GPIO_PORT_H 7
#define GPIO_PORT_I 8
#define GPIO_PORT_J 9
#define GPIO_PORT_K 10
#define GPIO_PORT_L 11
#define GPIO_PORT_M 12
#define GPIO_PORT_N 13
#define GPIO_PORT_O 14
#define GPIO_PORT_P 15
#define GPIO_PORT_Q 16
#define GPIO_PORT_R 17
#define GPIO_PORT_S 18
#define GPIO_PORT_T 19
#define GPIO_PORT_U 20
#define GPIO_PORT_V 21
#define GPIO_PORT_W 22
#define GPIO_PORT_X 23
#define GPIO_PORT_Y 24
#define GPIO_PORT_Z 25
#define GPIO_PORT_AA 26
#define GPIO_PORT_BB 27
#define GPIO_PORT_CC 28
#define GPIO_PORT_DD 29
#define GPIO_PORT_EE 30
void gpio_config(u32 port, u32 pins, int mode);
void gpio_output_enable(u32 port, u32 pins, int enable);
void gpio_write(u32 port, u32 pins, int high);
int gpio_read(u32 port, u32 pins);
#endif

133
ipl/heap.c Executable file
View File

@ -0,0 +1,133 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "heap.h"
typedef struct _hnode
{
int used;
u32 size;
struct _hnode *prev;
struct _hnode *next;
} hnode_t;
typedef struct _heap
{
u32 start;
hnode_t *first;
} heap_t;
static void _heap_create(heap_t *heap, u32 start)
{
heap->start = start;
heap->first = NULL;
}
static u32 _heap_alloc(heap_t *heap, u32 size)
{
hnode_t *node, *new;
int search = 1;
size = ALIGN(size, 0x10);
if (!heap->first)
{
node = (hnode_t *)heap->start;
node->used = 1;
node->size = size;
node->prev = NULL;
node->next = NULL;
heap->first = node;
return (u32)node + sizeof(hnode_t);
}
node = heap->first;
while (search)
{
if (!node->used && size + sizeof(hnode_t) < node->size)
{
new = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
new->size = node->size - sizeof(hnode_t) - size;
node->size = size;
node->used = 1;
new->used = 0;
new->next = node->next;
new->prev = node;
node->next = new;
return (u32)node + sizeof(hnode_t);
}
if (node->next)
node = node->next;
else
search = 0;
}
new = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
new->used = 1;
new->size = size;
new->prev = node;
new->next = NULL;
node->next = new;
return (u32)new + sizeof(hnode_t);
}
static void _heap_free(heap_t *heap, u32 addr)
{
hnode_t *node = (hnode_t *)(addr - sizeof(hnode_t));
node->used = 0;
node = heap->first;
while (node)
{
if (!node->used)
if (node->prev && !node->prev->used)
{
node->prev->size += node->size + sizeof(hnode_t);
node->prev->next = node->next;
if (node->next)
node->next->prev = node->prev;
}
node = node->next;
}
}
static heap_t _heap;
void heap_init(u32 base)
{
_heap_create(&_heap, base);
}
void *malloc(u32 size)
{
return (void *)_heap_alloc(&_heap, size);
}
void *calloc(u32 num, u32 size)
{
void *res = (void *)_heap_alloc(&_heap, num * size);
memset(res, 0, num * size);
return res;
}
void free(void *buf)
{
_heap_free(&_heap, (u32)buf);
}

52
hwinit/hwinit.h → ipl/heap.h Normal file → Executable file
View File

@ -1,25 +1,27 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _HWINIT_H_
#define _HWINIT_H_
void mc_config_tsec_carveout(u32 bom, u32 size1mb, int lock);
void mc_enable_ahb_redirect();
void mc_disable_ahb_redirect();
void nx_hwinit();
#endif
/*
* Copyright (c) 2018 naehrwert
*
* 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 _HEAP_H_
#define _HEAP_H_
#include "types.h"
void heap_init(u32 base);
void *malloc(u32 size);
void *calloc(u32 num, u32 size);
void free(void *buf);
#endif

436
ipl/hos.c Executable file
View File

@ -0,0 +1,436 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "hos.h"
#include "sdmmc.h"
#include "nx_emmc.h"
#include "t210.h"
#include "se.h"
#include "se_t210.h"
#include "pmc.h"
#include "cluster.h"
#include "heap.h"
#include "tsec.h"
#include "pkg2.h"
#include "nx_emmc.h"
#include "util.h"
#include "pkg1.h"
#include "pkg2.h"
#include "ff.h"
/*#include "gfx.h"
extern gfx_ctxt_t gfx_ctxt;
extern gfx_con_t gfx_con;
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)*/
#define DPRINTF(...)
#define NUM_KEYBLOB_KEYS 5
static const u8 keyblob_keyseeds[NUM_KEYBLOB_KEYS][0x10] = {
{ 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3 }, //1.0.0
{ 0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC }, //3.0.0
{ 0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B }, //3.0.1
{ 0x2D, 0x1F, 0x48, 0x80, 0xED, 0xEC, 0xED, 0x3E, 0x3C, 0xF2, 0x48, 0xB5, 0x65, 0x7D, 0xF7, 0xBE }, //4.0.0
{ 0xBB, 0x5A, 0x01, 0xF9, 0x88, 0xAF, 0xF5, 0xFC, 0x6C, 0xFF, 0x07, 0x9E, 0x13, 0x3C, 0x39, 0x80 } //5.0.0
};
static const u8 cmac_keyseed[0x10] =
{ 0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5 };
static const u8 mkey_keyseed_retail[0x10] =
{ 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C };
static const u8 ckey_keyseed[0x10] =
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
static const u8 key8_keyseed[] =
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
static void _se_lock()
{
for (u32 i = 0; i < 16; i++)
se_key_acc_ctrl(i, 0x15);
for (u32 i = 0; i < 2; i++)
se_rsa_acc_ctrl(i, 1);
SE(0x4) = 0; //Make this reg secure only.
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = 0; //Make all key access regs secure only.
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = 0; //Make all rsa access regs secure only.
SE(SE_SECURITY_0) &= 0xFFFFFFFB; //Make access lock regs secure only.
//This is useful for documenting the bits in the SE config registers, so we can keep it around.
/*gfx_printf(&gfx_con, "SE(SE_SECURITY_0) = %08X\n", SE(SE_SECURITY_0));
gfx_printf(&gfx_con, "SE(0x4) = %08X\n", SE(0x4));
gfx_printf(&gfx_con, "SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = %08X\n", SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET));
gfx_printf(&gfx_con, "SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = %08X\n", SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET));
for(u32 i = 0; i < 16; i++)
gfx_printf(&gfx_con, "%02X ", SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + i * 4) & 0xFF);
gfx_putc(&gfx_con, '\n');
for(u32 i = 0; i < 2; i++)
gfx_printf(&gfx_con, "%02X ", SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + i * 4) & 0xFF);
gfx_putc(&gfx_con, '\n');
gfx_hexdump(&gfx_con, SE_BASE, (void *)SE_BASE, 0x400);*/
}
//Key derivation for < 4.0.0
static int _keygen_1(u8 *keyblob, u32 kb, void *tsec_fw)
{
u8 *tmp = (u8 *)malloc(0x10);
se_key_acc_ctrl(12, 0x15);
se_key_acc_ctrl(13, 0x15);
//Get TSEC key.
if (tsec_query(tmp, 1, tsec_fw) < 0)
return 0;
se_aes_key_set(13, tmp, 0x10);
//Derive keyblob key from TSEC+SBK.
memcpy(tmp, keyblob_keyseeds[kb], 0x10);
se_aes_crypt_block_ecb(13, 0, tmp, tmp);
se_aes_unwrap_key(13, 14, tmp);
se_aes_key_clear(14);
//TODO: verify keyblob CMAC.
//se_aes_unwrap_key(11, 13, cmac_keyseed);
//se_aes_cmac(tmp, 0x10, 11, keyblob + 0x10, 0xA0);
//if (!memcmp(keyblob, tmp, 0x10))
// return 0;
//Decrypt keyblob and set keyslots.
se_aes_crypt_ctr(13, keyblob + 0x20, 0x90, keyblob + 0x20, 0x90, keyblob + 0x10);
se_aes_key_set(11, keyblob + 0x20 + 0x80, 0x10);
se_aes_key_set(12, keyblob + 0x20, 0x10);
//TODO: for some reason SE likes to hang if we don't execute an operation here.
memcpy(tmp, mkey_keyseed_retail, 0x10);
se_aes_crypt_block_ecb(12, 0, tmp, tmp);
//Generate retail master key.
memcpy(tmp, mkey_keyseed_retail, 0x10);
se_aes_unwrap_key(12, 12, tmp);
memcpy(tmp, key8_keyseed, 0x10);
se_key_acc_ctrl(8, 0x15);
se_aes_unwrap_key(8, 12, tmp);
//Generate console specific key.
memcpy(tmp, ckey_keyseed, 0x10);
se_aes_unwrap_key(13, 13, tmp);
se_key_acc_ctrl(12, 0xFF);
se_key_acc_ctrl(13, 0xFF);
free(tmp);
}
typedef struct _launch_ctxt_t
{
void *keyblob;
void *pkg1;
const pkg1_id_t *pkg1_id;
void *warmboot;
u32 warmboot_size;
void *secmon;
u32 secmon_size;
void *pkg2;
u32 pkg2_size;
void *kernel;
u32 kernel_size;
link_t kip1_list;
} launch_ctxt_t;
typedef struct _merge_kip_t
{
void *kip1;
link_t link;
} merge_kip_t;
static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
{
int res = 0;
sdmmc_storage_t storage;
sdmmc_t sdmmc;
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
//Read package1.
ctxt->pkg1 = (u8 *)malloc(0x40000);
sdmmc_storage_set_mmc_partition(&storage, 1);
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, ctxt->pkg1);
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1);
if (!ctxt->pkg1_id)
{
DPRINTF("%kCould not identify package 1 version (= '%s').%k\n", 0xFF0000FF, (char *)ctxt->pkg1 + 0x10, 0xFFFFFFFF);
goto out;
}
DPRINTF("Identified package1 ('%s'), keyblob version %d\n", (char *)(ctxt->pkg1 + 0x10), ctxt->pkg1_id->kb);
//Read the correct keyblob.
ctxt->keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
res = 1;
out:;
sdmmc_storage_end(&storage);
return res;
}
static int _read_emmc_pkg2(launch_ctxt_t *ctxt)
{
int res = 0;
sdmmc_storage_t storage;
sdmmc_t sdmmc;
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
sdmmc_storage_set_mmc_partition(&storage, 0);
//Parse eMMC GPT.
LIST_INIT(gpt);
nx_emmc_gpt_parse(&gpt, &storage);
DPRINTF("parsed GPT\n");
//Find package2 partition.
emmc_part_t *pkg2_part = nx_emmc_part_find(&gpt, "BCPKG2-1-Normal-Main");
if (!pkg2_part)
goto out;
//Read in package2 header and get package2 real size.
//TODO: implement memalign for DMA buffers.
u8 *tmp = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE, 1, tmp);
u32 *hdr = (u32 *)(tmp + 0x100);
u32 pkg2_size = hdr[0] ^ hdr[2] ^ hdr[3];
free(tmp);
DPRINTF("pkg2 size on emmc is %08X\n", pkg2_size);
//Read in package2.
u32 pkg2_size_aligned = ALIGN(pkg2_size, NX_EMMC_BLOCKSIZE);
DPRINTF("pkg2 size aligned is %08X\n", pkg2_size_aligned);
ctxt->pkg2 = malloc(pkg2_size_aligned);
ctxt->pkg2_size = pkg2_size;
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE,
pkg2_size_aligned / NX_EMMC_BLOCKSIZE, ctxt->pkg2);
res = 1;
out:;
nx_emmc_gpt_free(&gpt);
sdmmc_storage_end(&storage);
return res;
}
static int _config_warmboot(launch_ctxt_t *ctxt, const char *value)
{
FIL fp;
if (f_open(&fp, value, FA_READ) != FR_OK)
return 0;
ctxt->warmboot_size = f_size(&fp);
ctxt->warmboot = malloc(ctxt->warmboot_size);
f_read(&fp, ctxt->warmboot, ctxt->warmboot_size, NULL);
f_close(&fp);
return 1;
}
static int _config_secmon(launch_ctxt_t *ctxt, const char *value)
{
FIL fp;
if (f_open(&fp, value, FA_READ) != FR_OK)
return 0;
ctxt->secmon_size = f_size(&fp);
ctxt->secmon = malloc(ctxt->secmon_size);
f_read(&fp, ctxt->secmon, ctxt->secmon_size, NULL);
f_close(&fp);
return 1;
}
static int _config_kernel(launch_ctxt_t *ctxt, const char *value)
{
FIL fp;
if (f_open(&fp, value, FA_READ) != FR_OK)
return 0;
ctxt->kernel_size = f_size(&fp);
ctxt->kernel = malloc(ctxt->kernel_size);
f_read(&fp, ctxt->kernel, ctxt->kernel_size, NULL);
f_close(&fp);
return 1;
}
static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
{
FIL fp;
if (f_open(&fp, value, FA_READ) != FR_OK)
return 0;
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
mkip1->kip1 = malloc(f_size(&fp));
f_read(&fp, mkip1->kip1, f_size(&fp), NULL);
DPRINTF("loaded kip from SD (size %08X)\n", f_size(&fp));
f_close(&fp);
list_append(&ctxt->kip1_list, &mkip1->link);
return 1;
}
typedef struct _cfg_handler_t
{
const char *key;
int (*handler)(launch_ctxt_t *ctxt, const char *value);
} cfg_handler_t;
static const cfg_handler_t _config_handlers[] = {
{ "warmboot", _config_warmboot },
{ "secmon", _config_secmon },
{ "kernel", _config_kernel },
{ "kip1", _config_kip1 },
{ NULL, NULL },
};
static int _config(launch_ctxt_t *ctxt, ini_sec_t *cfg)
{
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
for(u32 i = 0; _config_handlers[i].key; i++)
if (!strcmp(_config_handlers[i].key, kv->key) &&
!_config_handlers[i].handler(ctxt, kv->val))
return 0;
return 1;
}
int hos_launch(ini_sec_t *cfg)
{
launch_ctxt_t ctxt;
memset(&ctxt, 0, sizeof(launch_ctxt_t));
list_init(&ctxt.kip1_list);
if (cfg && !_config(&ctxt, cfg))
return 0;
//Read package1 and the correct keyblob.
if (!_read_emmc_pkg1(&ctxt))
return 0;
//XXX: remove this once we support 3+.
if (ctxt.pkg1_id->kb > 0)
return 0;
DPRINTF("loaded pkg1 and keyblob\n");
//Generate keys.
_keygen_1(ctxt.keyblob, ctxt.pkg1_id->kb, (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off);
DPRINTF("generated keys\n");
//Decrypt and unpack package1 if we require parts of it.
if (!ctxt.warmboot || !ctxt.secmon)
{
pkg1_decrypt(ctxt.pkg1_id, ctxt.pkg1);
pkg1_unpack((void *)0x8000D000, (void *)ctxt.pkg1_id->secmon_base, ctxt.pkg1_id, ctxt.pkg1);
//gfx_hexdump(&gfx_con, 0x8000D000, (void *)0x8000D000, 0x100);
//gfx_hexdump(&gfx_con, ctxt.pkg1_id->secmon_base, (void *)ctxt.pkg1_id->secmon_base, 0x100);
DPRINTF("decrypted and unpacked pkg1\n");
}
//Replace 'warmboot.bin' if requested.
if (ctxt.warmboot)
memcpy((void *)0x8000D000, ctxt.warmboot, ctxt.warmboot_size);
//Set warmboot address in PMC.
PMC(APBDEV_PMC_SCRATCH1) = 0x8000D000;
//Replace 'SecureMonitor' if requested.
if (ctxt.secmon)
memcpy((void *)ctxt.pkg1_id->secmon_base, ctxt.secmon, ctxt.secmon_size);
else
{
//Else we patch it to allow for an unsigned package2.
patch_t *secmon_patchset = ctxt.pkg1_id->secmon_patchset;
for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++)
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
}
DPRINTF("loaded warmboot.bin and secmon\n");
//Read package2.
if (!_read_emmc_pkg2(&ctxt))
return 0;
DPRINTF("read pkg2\n");
//Decrypt package2 and parse KIP1 blobs in INI1 section.
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(ctxt.pkg2);
LIST_INIT(kip1_info);
pkg2_parse_kips(&kip1_info, pkg2_hdr);
DPRINTF("parsed ini1\n");
//Use the kernel included in package2 in case we didn't load one already.
if (!ctxt.kernel)
{
ctxt.kernel = pkg2_hdr->data;
ctxt.kernel_size = pkg2_hdr->sec_size[PKG2_SEC_KERNEL];
}
//Merge extra KIP1s into loaded ones.
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
//Rebuild and encrypt package2.
pkg2_build_encrypt((void *)0xA9800000, ctxt.kernel, ctxt.kernel_size, &kip1_info);
DPRINTF("rebuilt pkg2\n");
//Clear 'BootConfig'.
memset((void *)0x4003D000, 0, 0x3000);
//pkg2_decrypt((void *)0xA9800000);
//sleep(10000);
//btn_wait();
//return 0;
//Lock SE before starting 'SecureMonitor'.
_se_lock();
vu32 *mb_in = (vu32 *)0x40002EF8;
vu32 *mb_out = (vu32 *)0x40002EFC;
*mb_in = 0;
*mb_out = 0;
//Wait for secmon to get ready.
cluster_boot_cpu0(ctxt.pkg1_id->secmon_base);
while (!*mb_out)
sleep(1);
//Signal 'BootConfig'.
*mb_in = 1;
sleep(100);
//Signal package2 available.
*mb_in = 2;
sleep(100);
/*PMC(0x4) = 0x7FFFF3;
PMC(0x2C4) = 0xFFFFFFFF;
PMC(0x2D8) = 0xFFAFFFFF;
PMC(0x5B0) = 0xFFFFFFFF;
PMC(0x5B4) = 0xFFFFFFFF;
PMC(0x5B8) = 0xFFFFFFFF;
PMC(0x5BC) = 0xFFFFFFFF;
PMC(0x5C0) = 0xFFAAFFFF;*/
//TODO: Cleanup.
//display_end();
//Signal to continue boot.
*mb_in = 3;
sleep(100);
//Halt ourselves in waitevent state.
while (1)
FLOW_CTLR(0x4) = 0x50000000;
return 0;
}

12
hwinit/types.h → ipl/hos.h Normal file → Executable file
View File

@ -14,12 +14,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TYPES_H_
#define _TYPES_H_
#ifndef _HOS_H_
#define _HOS_H_
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef volatile unsigned int vu32;
#include "types.h"
#include "ini.h"
int hos_launch(ini_sec_t *cfg);
#endif

0
hwinit/i2c.c → ipl/i2c.c Normal file → Executable file
View File

0
hwinit/i2c.h → ipl/i2c.h Normal file → Executable file
View File

93
ipl/ini.c Executable file
View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "ini.h"
#include "ff.h"
#include "heap.h"
static char *_strdup(char *str)
{
char *res = malloc(strlen(str) + 1);
strcpy(res, str);
return res;
}
int ini_parse(link_t *dst, char *ini_path)
{
u32 lblen;
char lbuf[512];
FIL fp;
ini_sec_t *csec = NULL;
if (f_open(&fp, ini_path, FA_READ) != FR_OK)
return 0;
do
{
//Fetch one line.
lbuf[0] = 0;
f_gets(lbuf, 512, &fp);
lblen = strlen(lbuf);
//Skip empty lines and comments.
if (lblen <= 1 || lbuf[0] == '#')
continue;
//Remove trailing newline.
if (lbuf[lblen - 1] == '\n')
lbuf[lblen - 1] = 0;
if (lblen > 2 && lbuf[0] == '[') //Create new section.
{
if (csec)
{
list_append(dst, &csec->link);
csec = NULL;
}
u32 i;
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != ']'; i++)
;
lbuf[i] = 0;
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
csec->name = _strdup(&lbuf[1]);
list_init(&csec->kvs);
}
else if (csec) //Extract key/value.
{
u32 i;
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != '='; i++)
;
lbuf[i] = 0;
ini_kv_t *kv = (ini_kv_t *)malloc(sizeof(ini_kv_t));
kv->key = _strdup(&lbuf[0]);
kv->val = _strdup(&lbuf[i + 1]);
list_append(&csec->kvs, &kv->link);
}
} while (!f_eof(&fp));
f_close(&fp);
if (csec)
list_append(dst, &csec->link);
return 1;
}

39
ipl/ini.h Executable file
View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _INI_H_
#define _INI_H_
#include "types.h"
#include "list.h"
typedef struct _ini_kv_t
{
char *key;
char *val;
link_t link;
} ini_kv_t;
typedef struct _ini_sec_t
{
char *name;
link_t kvs;
link_t link;
} ini_sec_t;
int ini_parse(link_t *dst, char *ini_path);
#endif

38
ipl/integer.h Executable file
View File

@ -0,0 +1,38 @@
/*-------------------------------------------*/
/* Integer type definitions for FatFs module */
/*-------------------------------------------*/
#ifndef FF_INTEGER
#define FF_INTEGER
#ifdef _WIN32 /* FatFs development platform */
#include <windows.h>
#include <tchar.h>
typedef unsigned __int64 QWORD;
#else /* Embedded platform */
/* These types MUST be 16-bit or 32-bit */
typedef int INT;
typedef unsigned int UINT;
/* This type MUST be 8-bit */
typedef unsigned char BYTE;
/* These types MUST be 16-bit */
typedef short SHORT;
typedef unsigned short WORD;
typedef unsigned short WCHAR;
/* These types MUST be 32-bit */
typedef long LONG;
typedef unsigned long DWORD;
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
typedef unsigned long long QWORD;
#endif
#endif

42
ipl/kfuse.c Executable file
View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "kfuse.h"
#include "clock.h"
#include "t210.h"
int kfuse_read(u32 *buf)
{
int res = 0;
clock_enable_kfuse();
while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE))
;
if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
goto out;
KFUSE(KFUSE_KEYADDR) = KFUSE_KEYADDR_AUTOINC;
for (int i = 0; i < KFUSE_NUM_WORDS; i++)
buf[i] = KFUSE(KFUSE_KEYS);
res = 1;
out:;
clock_disable_kfuse();
return res;
}

41
ipl/kfuse.h Executable file
View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _KFUSE_H_
#define _KFUSE_H_
#include "types.h"
#define KFUSE_STATE_SOFTRESET (1<<31)
#define KFUSE_STATE_STOP (1<<25)
#define KFUSE_STATE_RESTART (1<<24)
#define KFUSE_STATE_CRCPASS (1<<17)
#define KFUSE_STATE_DONE (1<<16)
#define KFUSE_STATE_ERRBLOCK_MASK 0x3F00
#define KFUSE_STATE_ERRBLOCK_SHIFT 8
#define KFUSE_STATE_CURBLOCK_MASK 0x3F
#define KFUSE_KEYADDR_AUTOINC (1<<16)
#define KFUSE_STATE 0x80
#define KFUSE_KEYADDR 0x88
#define KFUSE_KEYS 0x8C
#define KFUSE_NUM_WORDS 144
int kfuse_read(u32 *buf);
#endif

21
ipl/link.ld Executable file
View File

@ -0,0 +1,21 @@
ENTRY(_start)
SECTIONS {
PROVIDE(__ipl_start = 0x40003000);
. = __ipl_start;
.text : {
*(.text*);
}
.data : {
*(.data*);
*(.rodata*);
}
. = ALIGN(0x10);
__ipl_end = .;
.bss : {
__bss_start = .;
*(COMMON)
*(.bss*)
__bss_end = .;
}
}

95
ipl/list.h Executable file
View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _LIST_H_
#define _LIST_H_
#include "types.h"
/*! Initialize list. */
#define LIST_INIT(name) link_t name = {&name, &name}
/*! Initialize static list. */
#define LIST_INIT_STATIC(name) static link_t name = {&name, &name}
/*! Iterate over all list links. */
#define LIST_FOREACH(iter, list) \
for(link_t *iter = (list)->next; iter != (list); iter = iter->next)
/*! Safely iterate over all list links. */
#define LIST_FOREACH_SAFE(iter, list) \
for(link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next)
/*! Iterate over all list members. */
#define LIST_FOREACH_ENTRY(etype, iter, list, mn) \
for(etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn))
typedef struct _link_t
{
struct _link_t *prev;
struct _link_t *next;
} link_t;
static inline void link_init(link_t *l)
{
l->prev = NULL;
l->next = NULL;
}
static inline int link_used(link_t *l)
{
if(l->next == NULL)
return 1;
return 0;
}
static inline void list_init(link_t *lh)
{
lh->prev = lh;
lh->next = lh;
}
static inline void list_prepend(link_t *lh, link_t *l)
{
l->next = lh->next;
l->prev = lh;
lh->next->prev = l;
lh->next = l;
}
static inline void list_append(link_t *lh, link_t *l)
{
l->prev = lh->prev;
l->next = lh;
lh->prev->next = l;
lh->prev = l;
}
static inline void list_remove(link_t *l)
{
l->next->prev = l->prev;
l->prev->next = l->next;
link_init(l);
}
static inline int list_empty(link_t *lh)
{
if(lh->next == lh)
return 1;
return 0;
}
#endif

179
ipl/lz.c Executable file
View File

@ -0,0 +1,179 @@
/*************************************************************************
* Name: lz.c
* Author: Marcus Geelnard
* Description: LZ77 coder/decoder implementation.
* Reentrant: Yes
*
* The LZ77 compression scheme is a substitutional compression scheme
* proposed by Abraham Lempel and Jakob Ziv in 1977. It is very simple in
* its design, and uses no fancy bit level compression.
*
* This is my first attempt at an implementation of a LZ77 code/decoder.
*
* The principle of the LZ77 compression algorithm is to store repeated
* occurrences of strings as references to previous occurrences of the same
* string. The point is that the reference consumes less space than the
* string itself, provided that the string is long enough (in this
* implementation, the string has to be at least 4 bytes long, since the
* minimum coded reference is 3 bytes long). Also note that the term
* "string" refers to any kind of byte sequence (it does not have to be
* an ASCII string, for instance).
*
* The coder uses a brute force approach to finding string matches in the
* history buffer (or "sliding window", if you wish), which is very, very
* slow. I recon the complexity is somewhere between O(n^2) and O(n^3),
* depending on the input data.
*
* There is also a faster implementation that uses a large working buffer
* in which a "jump table" is stored, which is used to quickly find
* possible string matches (see the source code for LZ_CompressFast() for
* more information). The faster method is an order of magnitude faster,
* but still quite slow compared to other compression methods.
*
* The upside is that decompression is very fast, and the compression ratio
* is often very good.
*
* The reference to a string is coded as a (length,offset) pair, where the
* length indicates the length of the string, and the offset gives the
* offset from the current data position. To distinguish between string
* references and literal strings (uncompressed bytes), a string reference
* is preceded by a marker byte, which is chosen as the least common byte
* symbol in the input data stream (this marker byte is stored in the
* output stream as the first byte).
*
* Occurrences of the marker byte in the stream are encoded as the marker
* byte followed by a zero byte, which means that occurrences of the marker
* byte have to be coded with two bytes.
*
* The lengths and offsets are coded in a variable length fashion, allowing
* values of any magnitude (up to 4294967295 in this implementation).
*
* With this compression scheme, the worst case compression result is
* (257/256)*insize + 1.
*
*-------------------------------------------------------------------------
* Copyright (c) 2003-2006 Marcus Geelnard
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Marcus Geelnard
* marcus.geelnard at home.se
*************************************************************************/
/*************************************************************************
* INTERNAL FUNCTIONS *
*************************************************************************/
/*************************************************************************
* _LZ_ReadVarSize() - Read unsigned integer with variable number of
* bytes depending on value.
*************************************************************************/
static int _LZ_ReadVarSize( unsigned int * x, const unsigned char * buf )
{
unsigned int y, b, num_bytes;
/* Read complete value (stop when byte contains zero in 8:th bit) */
y = 0;
num_bytes = 0;
do
{
b = (unsigned int) (*buf ++);
y = (y << 7) | (b & 0x0000007f);
++ num_bytes;
}
while( b & 0x00000080 );
/* Store value in x */
*x = y;
/* Return number of bytes read */
return num_bytes;
}
/*************************************************************************
* PUBLIC FUNCTIONS *
*************************************************************************/
/*************************************************************************
* LZ_Uncompress() - Uncompress a block of data using an LZ77 decoder.
* in - Input (compressed) buffer.
* out - Output (uncompressed) buffer. This buffer must be large
* enough to hold the uncompressed data.
* insize - Number of input bytes.
*************************************************************************/
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
unsigned int insize )
{
unsigned char marker, symbol;
unsigned int i, inpos, outpos, length, offset;
/* Do we have anything to uncompress? */
if( insize < 1 )
{
return;
}
/* Get marker symbol from input stream */
marker = in[ 0 ];
inpos = 1;
/* Main decompression loop */
outpos = 0;
do
{
symbol = in[ inpos ++ ];
if( symbol == marker )
{
/* We had a marker byte */
if( in[ inpos ] == 0 )
{
/* It was a single occurrence of the marker byte */
out[ outpos ++ ] = marker;
++ inpos;
}
else
{
/* Extract true length and offset */
inpos += _LZ_ReadVarSize( &length, &in[ inpos ] );
inpos += _LZ_ReadVarSize( &offset, &in[ inpos ] );
/* Copy corresponding data from history window */
for( i = 0; i < length; ++ i )
{
out[ outpos ] = out[ outpos - offset ];
++ outpos;
}
}
}
else
{
/* No marker, plain copy */
out[ outpos ++ ] = symbol;
}
}
while( inpos < insize );
}

52
ipl/lz.h Executable file
View File

@ -0,0 +1,52 @@
/*************************************************************************
* Name: lz.h
* Author: Marcus Geelnard
* Description: LZ77 coder/decoder interface.
* Reentrant: Yes
*-------------------------------------------------------------------------
* Copyright (c) 2003-2006 Marcus Geelnard
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Marcus Geelnard
* marcus.geelnard at home.se
*************************************************************************/
#ifndef _lz_h_
#define _lz_h_
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
* Function prototypes
*************************************************************************/
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
unsigned int insize );
#ifdef __cplusplus
}
#endif
#endif /* _lz_h_ */

624
ipl/main.c Executable file
View File

@ -0,0 +1,624 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "clock.h"
#include "uart.h"
#include "i2c.h"
#include "sdram.h"
#include "di.h"
#include "mc.h"
#include "t210.h"
#include "pmc.h"
#include "pinmux.h"
#include "fuse.h"
#include "util.h"
#include "gfx.h"
#include "btn.h"
#include "tsec.h"
#include "kfuse.h"
#include "max77620.h"
#include "max7762x.h"
#include "gpio.h"
#include "sdmmc.h"
#include "ff.h"
#include "tui.h"
#include "heap.h"
#include "list.h"
#include "nx_emmc.h"
#include "se.h"
#include "se_t210.h"
#include "hos.h"
#include "pkg1.h"
void panic(u32 val)
{
//Set panic code.
PMC(APBDEV_PMC_SCRATCH200) = val;
//PMC(APBDEV_PMC_CRYPTO_OP) = 1; //Disable SE.
TMR(0x18C) = 0xC45A;
TMR(0x80) = 0xC0000000;
TMR(0x180) = 0x8019;
TMR(0x188) = 1;
while (1)
;
}
void config_oscillators()
{
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3 | 4;
SYSCTR0(SYSCTR0_CNTFID0) = 19200000;
TMR(0x14) = 0x45F;
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81 | 0xE;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF | 0x400000;
PMC(APBDEV_PMC_CNTRL2) = PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF | 0x1000;
PMC(APBDEV_PMC_SCRATCH188) = PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF | 0x2000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10;
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF;
PMC(APBDEV_PMC_TSC_MULT) = PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000 | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444;
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2;
}
void config_gpios()
{
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = 0x40;
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = 0x40;
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
pinmux_config_i2c(I2C_1);
pinmux_config_i2c(I2C_5);
pinmux_config_uart(UART_A);
//Configure volume up/down as inputs.
gpio_config(GPIO_PORT_X, GPIO_PIN_6, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_X, GPIO_PIN_7, GPIO_MODE_GPIO);
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
}
void config_pmc_scratch()
{
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF;
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE;
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= 0x10;
}
void mbist_workaround()
{
CLOCK(0x410) = (CLOCK(0x410) | 0x8000) & 0xFFFFBFFF;
CLOCK(0xD0) |= 0x40800000u;
CLOCK(0x2AC) = 0x40;
CLOCK(0x294) = 0x40000;
CLOCK(0x304) = 0x18000000;
sleep(2);
I2S(0x0A0) |= 0x400;
I2S(0x088) &= 0xFFFFFFFE;
I2S(0x1A0) |= 0x400;
I2S(0x188) &= 0xFFFFFFFE;
I2S(0x2A0) |= 0x400;
I2S(0x288) &= 0xFFFFFFFE;
I2S(0x3A0) |= 0x400;
I2S(0x388) &= 0xFFFFFFFE;
I2S(0x4A0) |= 0x400;
I2S(0x488) &= 0xFFFFFFFE;
DISPLAY_A(0xCF8) |= 4;
VIC(0x8C) = 0xFFFFFFFF;
sleep(2);
CLOCK(0x2A8) = 0x40;
CLOCK(0x300) = 0x18000000;
CLOCK(0x290) = 0x40000;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = 0xC0;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80000130;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = 0x1F00200;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = 0x80400808;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = 0x402000FC;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = 0x23000780;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = 0x300;
CLOCK(0xF8) = 0;
CLOCK(0xFC) = 0;
CLOCK(0x3A0) = 0;
CLOCK(0x3A4) = 0;
CLOCK(0x554) = 0;
CLOCK(0xD0) &= 0x1F7FFFFF;
CLOCK(0x410) &= 0xFFFF3FFF;
CLOCK(0x148) = CLOCK(0x148) & 0x1FFFFFFF | 0x80000000;
CLOCK(0x180) = CLOCK(0x180) & 0x1FFFFFFF | 0x80000000;
CLOCK(0x6A0) = CLOCK(0x6A0) & 0x1FFFFFFF | 0x80000000;
}
void config_se_brom()
{
//Bootrom part we skipped.
u32 sbk[4] = { FUSE(0x1A4), FUSE(0x1A8), FUSE(0x1AC), FUSE(0x1B0) };
se_aes_key_set(14, sbk, 0x10);
//Lock SBK from being read.
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 14 * 4) = 0x7E;
//This memset needs to happen here, else TZRAM will behave weirdly later on.
memset((void *)0x7C010000, 0, 0x10000);
PMC(APBDEV_PMC_CRYPTO_OP) = 0;
SE(SE_INT_STATUS_REG_OFFSET) = 0x1F;
//Lock SSK (although it's not set and unused anyways).
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 15 * 4) = 0x7E;
}
void config_hw()
{
//Bootrom stuff we skipped by going thru rcm.
config_se_brom();
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
SYSREG(0x110) &= 0xFFFFFF9F;
PMC(0x244) = ((PMC(0x244) >> 1) << 1) & 0xFFFFFFFD;
mbist_workaround();
clock_enable_se();
//Enable fuse clock.
clock_enable_fuse(1);
//Disable fuse programming.
fuse_disable_program();
mc_enable();
config_oscillators();
APB_MISC(0x40) = 0;
config_gpios();
//clock_enable_uart(UART_C);
//uart_init(UART_C, 115200);
clock_enable_cl_dvfs();
clock_enable_i2c(I2C_1);
clock_enable_i2c(I2C_5);
static const clock_t clock_unk1 = { 0x358, 0x360, 0x42C, 0x1F, 0, 0 };
static const clock_t clock_unk2 = { 0x358, 0x360, 0, 0x1E, 0, 0 };
clock_enable(&clock_unk1);
clock_enable(&clock_unk2);
i2c_init(I2C_1);
i2c_init(I2C_5);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_CNFGBBC, 0x40);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_ONOFFCNFG1, 0x78);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_CFG0, 0x38);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_CFG1, 0x3A);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_CFG2, 0x38);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_LDO4, 0xF);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_LDO8, 0xC7);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_SD0, 0x4F);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_SD1, 0x29);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_FPS_SD3, 0x1B);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_SD0, 42); //42 = (1125000 - 600000) / 12500 -> 1.125V
config_pmc_scratch();
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888 | 0x3333;
mc_config_carveout();
sdram_init();
//TODO: test this with LP0 wakeup.
sdram_lp0_save_params(sdram_get_params());
}
//TODO: ugly.
gfx_ctxt_t gfx_ctxt;
gfx_con_t gfx_con;
void print_fuseinfo()
{
gfx_clear(&gfx_ctxt, 0xFF000000);
gfx_con_setpos(&gfx_con, 0, 0);
gfx_printf(&gfx_con, "%k(Unlocked) fuse cache:\n\n%k", 0xFFFF9955, 0xFFFFFFFF);
gfx_hexdump(&gfx_con, 0x7000F900, (u8 *)0x7000F900, 0x2FC);
sleep(100000);
btn_wait();
}
void print_kfuseinfo()
{
gfx_clear(&gfx_ctxt, 0xFF000000);
gfx_con_setpos(&gfx_con, 0, 0);
gfx_printf(&gfx_con, "%kKFuse contents:\n\n%k", 0xFFFF9955, 0xFFFFFFFF);
u32 buf[KFUSE_NUM_WORDS];
if (!kfuse_read(buf))
gfx_printf(&gfx_con, "%kCRC fail.\n", 0xFF0000FF);
else
gfx_hexdump(&gfx_con, 0, (u8 *)buf, KFUSE_NUM_WORDS * 4);
sleep(100000);
btn_wait();
}
void print_tsec_key()
{
gfx_clear(&gfx_ctxt, 0xFF000000);
gfx_con_setpos(&gfx_con, 0, 0);
sdmmc_storage_t storage;
sdmmc_t sdmmc;
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
//Read package1.
u8 *pkg1 = (u8 *)malloc(0x40000);
sdmmc_storage_set_mmc_partition(&storage, 1);
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
if (!pkg1_id)
{
gfx_printf(&gfx_con, "%kCould not identify package 1 version to read TSEC firmware (= '%s').%k\n", 0xFF0000FF, (char *)pkg1 + 0x10, 0xFFFFFFFF);
goto out;
}
for(u32 i = 1; i <= 3; i++)
{
u8 key[0x10];
int res = tsec_query(key, i, pkg1 + pkg1_id->tsec_off);
gfx_printf(&gfx_con, "%kTSEC key %d: %k", 0xFFFF9955, i, 0xFFFFFFFF);
if (res >= 0)
{
for (u32 i = 0; i < 0x10; i++)
gfx_printf(&gfx_con, "%02X", key[i]);
}
else
gfx_printf(&gfx_con, "%kERROR %X", 0xFF0000FF, res);
gfx_putc(&gfx_con, '\n');
}
out:;
free(pkg1);
sdmmc_storage_end(&storage);
sleep(100000);
btn_wait();
}
void reboot_normal()
{
panic(0x21); //Bypass fuse programming in package1.
}
void reboot_rcm()
{
PMC(APBDEV_PMC_SCRATCH0) = 2; //Reboot into rcm.
PMC(0) |= 0x10;
while (1)
sleep(1);
}
void power_off()
{
//TODO: we should probably make sure all regulators are powered off properly.
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);
}
//TODO: ugly.
sdmmc_t sd_sdmmc;
sdmmc_storage_t sd_storage;
FATFS sd_fs;
int sd_mounted;
int sd_mount()
{
if (sd_mounted)
return 1;
if (sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, SDMMC_1, SDMMC_BUS_WIDTH_4, 11) &&
f_mount(&sd_fs, "", 1) == FR_OK)
{
sd_mounted = 1;
return 1;
}
return 0;
}
void *sd_file_read(char *path)
{
FIL fp;
if (f_open(&fp, path, FA_READ) != FR_OK)
return NULL;
u32 size = f_size(&fp);
void *buf = malloc(size);
u8 *ptr = buf;
while (size > 0)
{
u32 rsize = MIN(size, 512);
if (f_read(&fp, ptr, rsize, NULL) != FR_OK)
{
free(buf);
return NULL;
}
ptr += rsize;
size -= rsize;
}
f_close(&fp);
return buf;
}
int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
{
FIL fp;
if (f_open(&fp, sd_path, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
return 0;
u8 *buf = (u8 *)malloc(NX_EMMC_BLOCKSIZE * 512);
u32 total = part->lba_end - part->lba_start + 1;
u32 lba_curr = part->lba_start;
while(total > 0)
{
u32 num = MIN(total, 512);
if(!sdmmc_storage_read(storage, lba_curr, num, buf))
{
gfx_printf(&gfx_con, "%kError reading %d blocks @ LBA %08X%k\n",
0xFF0000FF, num, lba_curr, 0xFFFFFFFF);
goto out;
}
f_write(&fp, buf, NX_EMMC_BLOCKSIZE * num, NULL);
u32 pct = ((lba_curr - part->lba_start) * 100) / (part->lba_end - part->lba_start);
tui_pbar(&gfx_con, 0, gfx_con.y, pct);
lba_curr += num;
total -= num;
}
tui_pbar(&gfx_con, 0, gfx_con.y, 100);
out:;
free(buf);
f_close(&fp);
return 1;
}
void dump_emmc()
{
gfx_clear(&gfx_ctxt, 0xFF000000);
gfx_con_setpos(&gfx_con, 0, 0);
if (!sd_mount())
{
gfx_printf(&gfx_con, "%kFailed to mount SD card (make sure that it is inserted).%k\n", 0xFF0000FF, 0xFFFFFFFF);
goto out;
}
sdmmc_storage_t storage;
sdmmc_t sdmmc;
if(!sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4))
{
gfx_printf(&gfx_con, "%kFailed to init eMMC.%k\n", 0xFF0000FF, 0xFFFFFFFF);
goto out;
}
sdmmc_storage_set_mmc_partition(&storage, 0);
LIST_INIT(gpt);
nx_emmc_gpt_parse(&gpt, &storage);
int i = 0;
LIST_FOREACH_ENTRY(emmc_part_t, part, &gpt, link)
{
gfx_printf(&gfx_con, "%02d: %s (%08X-%08X)\n", i++,
part->name, part->lba_start, part->lba_end);
//XXX: skip these for now.
if (//!strcmp(part->name, "SYSTEM") ||
!strcmp(part->name, "USER"))
{
gfx_puts(&gfx_con, "Skipped.\n");
continue;
}
dump_emmc_part(part->name, &storage, part);
gfx_putc(&gfx_con, '\n');
}
sdmmc_storage_end(&storage);
out:;
sleep(100000);
btn_wait();
}
void launch_firmware()
{
ini_sec_t *cfg_sec = NULL;
LIST_INIT(ini_sections);
gfx_clear(&gfx_ctxt, 0xFF000000);
gfx_con_setpos(&gfx_con, 0, 0);
if (sd_mount())
{
if (ini_parse(&ini_sections, "hekate_ipl.ini"))
{
//Build configuration menu.
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 16);
ments[0].type = MENT_BACK;
ments[0].caption = "Back";
u32 i = 1;
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
{
if (!strcmp(ini_sec->name, "config"))
continue;
ments[i].type = MENT_CHOICE;
ments[i].caption = ini_sec->name;
ments[i].data = ini_sec;
i++;
}
if (i > 1)
{
memset(&ments[i], 0, sizeof(ment_t));
menu_t menu = {
ments, "Launch configurations", 0, 0
};
cfg_sec = (ini_sec_t *)tui_do_menu(&gfx_con, &menu);
if (!cfg_sec)
return;
}
else
gfx_printf(&gfx_con, "%kNo launch configurations found.%k\n", 0xFF0000FF, 0xFFFFFFFF);
free(ments);
}
else
gfx_printf(&gfx_con, "%kFailed to load 'hekate_ipl.ini'.%k\n", 0xFF0000FF, 0xFFFFFFFF);
}
else
gfx_printf(&gfx_con, "%kFailed to mount SD card (make sure that it is inserted).%k\n", 0xFF0000FF, 0xFFFFFFFF);
if (!cfg_sec)
gfx_printf(&gfx_con, "Using default launch configuration.\n");
if (!hos_launch(cfg_sec))
gfx_printf(&gfx_con, "%kFailed to launch firmware.%k\n", 0xFF0000FF, 0xFFFFFFFF);
//TODO: free ini.
out:;
sleep(200000);
btn_wait();
}
void about()
{
static const char octopus[] =
"hekate (c) 2018 naehrwert, st4rk\n\n"
"Thanks to: %kderrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8%k\n\n"
"Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute\n\n"
"Open source and free packages used:\n"
" - FatFs R0.13a (Copyright (C) 2017, ChaN)\n"
" - bcl-1.2.0 (Copyright (c) 2003-2006 Marcus Geelnard)\n\n"
" %k___\n"
" .-' `'.\n"
" / \\\n"
" | ;\n"
" | | ___.--,\n"
" _.._ |0) = (0) | _.---'`__.-( (_.\n"
" __.--'`_.. '.__.\\ '--. \\_.-' ,.--'` `\"\"`\n"
" ( ,.--'` ',__ /./; ;, '.__.'` __\n"
" _`) ) .---.__.' / | |\\ \\__..--\"\" \"\"\"--.,_\n"
" `---' .'.''-._.-'`_./ /\\ '. \\ _.--''````'''--._`-.__.'\n"
" | | .' _.-' | | \\ \\ '. `----`\n"
" \\ \\/ .' \\ \\ '. '-._)\n"
" \\/ / \\ \\ `=.__`'-.\n"
" / /\\ `) ) / / `\"\".`\\\n"
" , _.-'.'\\ \\ / / ( ( / /\n"
" `--'` ) ) .-'.' '.'. | (\n"
" (/` ( (` ) ) '-; %k[switchbrew]%k\n"
" ` '-; (-'%k";
gfx_clear(&gfx_ctxt, 0xFF000000);
gfx_con_setpos(&gfx_con, 0, 0);
gfx_printf(&gfx_con, octopus, 0xFFFFCC00, 0xFFFFFFFF,
0xFFFFCC00, 0xFFCCFF00, 0xFFFFCC00, 0xFFFFFFFF);
sleep(1000000);
btn_wait();
}
ment_t ment_cinfo[] = {
MDEF_BACK(),
MDEF_HANDLER("Print fuse info", print_fuseinfo),
MDEF_HANDLER("Print kfuse info", print_kfuseinfo),
MDEF_HANDLER("Print TSEC keys", print_tsec_key),
MDEF_END()
};
menu_t menu_cinfo = {
ment_cinfo,
"Console info", 0, 0
};
ment_t ment_tools[] = {
MDEF_BACK(),
MDEF_HANDLER("Dump eMMC", dump_emmc),
MDEF_END()
};
menu_t menu_tools = {
ment_tools,
"Tools", 0, 0
};
ment_t ment_top[] = {
MDEF_HANDLER("Launch firmware", launch_firmware),
MDEF_MENU("Tools", &menu_tools),
MDEF_MENU("Console info", &menu_cinfo),
MDEF_HANDLER("Reboot (normal)", reboot_normal),
MDEF_HANDLER("Reboot (rcm)", reboot_rcm),
MDEF_HANDLER("Power off", power_off),
MDEF_HANDLER("About", about),
MDEF_END()
};
menu_t menu_top = {
ment_top,
"hekate - ipl", 0, 0
};
extern void pivot_stack(u32 stack_top);
void ipl_main()
{
config_hw();
//Pivot the stack so we have enough space.
pivot_stack(0x90010000);
//Tegra/Horizon configuration goes to 0x80000000+, package2 goes to 0xA9800000, we place our heap in between.
heap_init(0x90020000);
//uart_send(UART_C, (u8 *)0x40000000, 0x10000);
//uart_wait_idle(UART_C, UART_TX_IDLE);
display_init();
//display_color_screen(0xAABBCCDD);
u32 *fb = display_init_framebuffer();
gfx_init_ctxt(&gfx_ctxt, fb, 720, 1280, 768);
gfx_clear(&gfx_ctxt, 0xFF000000);
gfx_con_init(&gfx_con, &gfx_ctxt);
while (1)
tui_do_menu(&gfx_con, &menu_top);
while (1)
;
}

324
ipl/max77620.h Executable file
View File

@ -0,0 +1,324 @@
/*
* Defining registers address and its bit definitions of MAX77620 and MAX20024
*
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
*
* 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_
/* 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_LBDAC 0x0E
#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_ */

141
ipl/max7762x.c Executable file
View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "max7762x.h"
#include "max77620.h"
#include "i2c.h"
#include "util.h"
#include "gfx.h"
extern gfx_ctxt_t gfx_ctxt;
extern gfx_con_t gfx_con;
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
#define REGULATOR_SD 0
#define REGULATOR_LDO 1
typedef struct _max77620_regulator_t
{
u8 type;
const char *name;
u8 reg_sd;
u32 mv_step;
u32 mv_min;
u32 mv_default;
u32 mv_max;
u8 volt_addr;
u8 cfg_addr;
u8 volt_mask;
u8 enable_mask;
u8 enable_shift;
u8 status_mask;
u8 fps_addr;
u8 fps_src;
u8 pd_period;
u8 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(u32 id)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
if (reg->type == REGULATOR_SD)
return i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_STATSD) & reg->status_mask ? 0 : 1;
return i2c_recv_byte(I2C_5, 0x3C, reg->cfg_addr) & 8 ? 1 : 0;
}
int max77620_regulator_config_fps(u32 id)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
i2c_send_byte(I2C_5, 0x3C, reg->fps_addr, (reg->fps_src << 6) | (reg->pu_period << 3) | (reg->pd_period));
return 1;
}
int max77620_regulator_set_voltage(u32 id, u32 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;
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
u8 val = i2c_recv_byte(I2C_5, 0x3C, reg->volt_addr);
val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
i2c_send_byte(I2C_5, 0x3C, reg->volt_addr, val);
sleep(1000);
return 1;
}
int max77620_regulator_enable(u32 id, int enable)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
u32 addr = reg->type == REGULATOR_SD ? reg->cfg_addr : reg->volt_addr;
u8 val = i2c_recv_byte(I2C_5, 0x3C, addr);
if (enable)
val = (val & ~reg->enable_mask) | ((3 << reg->enable_shift) & reg->enable_mask);
else
val &= ~reg->enable_mask;
i2c_send_byte(I2C_5, 0x3C, addr, val);
sleep(1000);
return 1;
}
void max77620_config_default()
{
for (u32 i = 1; i <= REGULATOR_MAX; i++)
{
i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_CID4);
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);
}
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_SD_CFG2, 4);
}

68
ipl/max7762x.h Executable file
View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _MAX7762X_H_
#define _MAX7762X_H_
#include "types.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 | 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(u32 id);
int max77620_regulator_config_fps(u32 id);
int max77620_regulator_set_voltage(u32 id, u32 mv);
int max77620_regulator_enable(u32 id, int enable);
void max77620_config_default();
#endif

136
ipl/mc.c Executable file
View File

@ -0,0 +1,136 @@
#include "mc.h"
#include "t210.h"
#include "clock.h"
#include "util.h"
void mc_config_tsec_carveout(u32 bom, u32 size1mb, int lock)
{
MC(MC_SEC_CARVEOUT_BOM) = bom;
MC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
if (lock)
MC(MC_SEC_CARVEOUT_REG_CTRL) = 1;
}
void mc_config_carveout()
{
*(vu32 *)0x8005FFFC = 0xC0EDBBCC;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
MC(MC_VIDEO_PROTECT_BOM) = 0;
MC(MC_VIDEO_PROTECT_SIZE_MB) = 0;
MC(MC_VIDEO_PROTECT_REG_CTRL) = 1;
//Configure TSEC carveout @ 0x90000000, 1MB.
//mc_config_tsec_carveout(0x90000000, 1, 0);
mc_config_tsec_carveout(0, 0, 1);
MC(MC_MTS_CARVEOUT_BOM) = 0;
MC(MC_MTS_CARVEOUT_SIZE_MB) = 0;
MC(MC_MTS_CARVEOUT_ADR_HI) = 0;
MC(MC_MTS_CARVEOUT_REG_CTRL) = 1;
MC(MC_SECURITY_CARVEOUT1_BOM) = 0;
MC(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
MC(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
MC(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = 0x3000000;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = 0x300;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
MC(MC_SECURITY_CARVEOUT3_BOM) = 0;
MC(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = 0x3000000;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = 0x300;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
MC(MC_SECURITY_CARVEOUT4_BOM) = 0;
MC(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
MC(MC_SECURITY_CARVEOUT5_BOM) = 0;
MC(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
}
void mc_enable_ahb_redirect()
{
CLOCK(0x3A4) = CLOCK(0x3A4) & 0xFFF7FFFF | 0x80000;
//MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE;
MC(MC_IRAM_BOM) = 0x40000000;
MC(MC_IRAM_TOM) = 0x4003F000;
}
void mc_disable_ahb_redirect()
{
MC(MC_IRAM_BOM) = 0xFFFFF000;
MC(MC_IRAM_TOM) = 0;
//Disable IRAM_CFG_WRITE_ACCESS (sticky).
//MC(MC_IRAM_REG_CTRL) = MC(MC_IRAM_REG_CTRL) & 0xFFFFFFFE | 1;
CLOCK(0x3A4) &= 0xFFF7FFFF;
}
void mc_enable()
{
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF | 0x40000000;
//Enable MIPI CAL clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF | 0x2000000;
//Enable MC clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE | 1;
//Enable EMC DLL clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & 0xFFFFBFFF | 0x4000;
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x2000001; //Clear EMC and MC reset.
sleep(5);
//#ifdef CONFIG_ENABLE_AHB_REDIRECT
mc_disable_ahb_redirect();
//mc_enable_ahb_redirect();
//#endif
}

13
ipl/mc.h Executable file
View File

@ -0,0 +1,13 @@
#ifndef _MC_H_
#define _MC_H_
#include "types.h"
#include "mc_t210.h"
void mc_config_tsec_carveout(u32 bom, u32 size1mb, int lock);
void mc_config_carveout();
void mc_enable_ahb_redirect();
void mc_disable_ahb_redirect();
void mc_enable();
#endif

4
hwinit/mc.h → ipl/mc_t210.h Normal file → Executable file
View File

@ -11,8 +11,8 @@
* GNU General Public License for more details.
*/
#ifndef _MC_H_
#define _MC_
#ifndef _MC_T210_H_
#define _MC_T210_H_
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4

431
ipl/mmc.h Executable file
View File

@ -0,0 +1,431 @@
/*
* Header for MultiMediaCard (MMC)
*
* Copyright 2002 Hewlett-Packard Company
*
* Use consistent with the GNU GPL is permitted,
* provided that this copyright notice is
* preserved in its entirety in all copies and derived works.
*
* HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
* FITNESS FOR ANY PARTICULAR PURPOSE.
*
* Many thanks to Alessandro Rubini and Jonathan Corbet!
*
* Based strongly on code by:
*
* Author: Yong-iL Joh <tolkien@mizi.com>
*
* Author: Andrew Christian
* 15 May 2002
*/
#ifndef LINUX_MMC_MMC_H
#define LINUX_MMC_MMC_H
/* Standard MMC commands (4.1) type argument response */
/* class 1 */
#define MMC_GO_IDLE_STATE 0 /* bc */
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
#define MMC_BUS_TEST_R 14 /* adtc R1 */
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
#define MMC_BUS_TEST_W 19 /* adtc R1 */
#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */
#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
/* class 2 */
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
/* class 3 */
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
/* class 4 */
#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
#define MMC_PROGRAM_CID 26 /* adtc R1 */
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
/* class 6 */
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
/* class 5 */
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
#define MMC_ERASE 38 /* ac R1b */
/* class 9 */
#define MMC_FAST_IO 39 /* ac <Complex> R4 */
#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
/* class 7 */
#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
/* class 8 */
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
/* class 11 */
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
#define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr R1 */
#define MMC_EXECUTE_READ_TASK 46 /* adtc [20:16] task id R1 */
#define MMC_EXECUTE_WRITE_TASK 47 /* adtc [20:16] task id R1 */
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
/*
* MMC_SWITCH argument format:
*
* [31:26] Always 0
* [25:24] Access Mode
* [23:16] Location of target Byte in EXT_CSD
* [15:08] Value Byte
* [07:03] Always 0
* [02:00] Command Set
*/
/*
MMC status in R1, for native mode (SPI bits are different)
Type
e : error bit
s : status bit
r : detected and set for the actual command response
x : detected and set during command execution. the host must poll
the card by sending status command in order to read these bits.
Clear condition
a : according to the card state
b : always related to the previous command. Reception of
a valid command will clear it (with a delay of one command)
c : clear by read
*/
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
#define R1_CC_ERROR (1 << 20) /* erx, c */
#define R1_ERROR (1 << 19) /* erx, c */
#define R1_UNDERRUN (1 << 18) /* ex, c */
#define R1_OVERRUN (1 << 17) /* ex, c */
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
#define R1_ERASE_RESET (1 << 13) /* sr, c */
#define R1_STATUS(x) (x & 0xFFFFE000)
#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
#define R1_APP_CMD (1 << 5) /* sr, c */
#define R1_STATE_IDLE 0
#define R1_STATE_READY 1
#define R1_STATE_IDENT 2
#define R1_STATE_STBY 3
#define R1_STATE_TRAN 4
#define R1_STATE_DATA 5
#define R1_STATE_RCV 6
#define R1_STATE_PRG 7
#define R1_STATE_DIS 8
/*
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
* R1 is the low order byte; R2 is the next highest byte, when present.
*/
#define R1_SPI_IDLE (1 << 0)
#define R1_SPI_ERASE_RESET (1 << 1)
#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
#define R1_SPI_COM_CRC (1 << 3)
#define R1_SPI_ERASE_SEQ (1 << 4)
#define R1_SPI_ADDRESS (1 << 5)
#define R1_SPI_PARAMETER (1 << 6)
/* R1 bit 7 is always zero */
#define R2_SPI_CARD_LOCKED (1 << 8)
#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */
#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP
#define R2_SPI_ERROR (1 << 10)
#define R2_SPI_CC_ERROR (1 << 11)
#define R2_SPI_CARD_ECC_ERROR (1 << 12)
#define R2_SPI_WP_VIOLATION (1 << 13)
#define R2_SPI_ERASE_PARAM (1 << 14)
#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */
#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
/*
* OCR bits are mostly in host.h
*/
#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
/*
* Card Command Classes (CCC)
*/
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
/* (and for SPI, CMD58,59) */
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
/* (CMD11) */
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
/* (CMD16,17,18) */
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
/* (CMD20) */
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
/* (CMD16,24,25,26,27) */
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
/* (CMD32,33,34,35,36,37,38,39) */
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
/* (CMD28,29,30) */
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
/* (CMD16,CMD42) */
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
/* (CMD55,56,57,ACMD*) */
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
/* (CMD5,39,40,52,53) */
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
/* (CMD6,34,35,36,37,50) */
/* (11) Reserved */
/* (CMD?) */
/*
* CSD field definitions
*/
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
/*
* EXT_CSD fields
*/
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
#define EXT_CSD_FLUSH_CACHE 32 /* W */
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
#define EXT_CSD_HPI_MGMT 161 /* R/W */
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
#define EXT_CSD_BKOPS_EN 163 /* R/W */
#define EXT_CSD_BKOPS_START 164 /* W */
#define EXT_CSD_SANITIZE_START 165 /* W */
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
#define EXT_CSD_RPMB_MULT 168 /* RO */
#define EXT_CSD_FW_CONFIG 169 /* R/W */
#define EXT_CSD_BOOT_WP 173 /* R/W */
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
#define EXT_CSD_PART_CONFIG 179 /* R/W */
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
#define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_POWER_CLASS 187 /* R/W */
#define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_STRUCTURE 194 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */
#define EXT_CSD_DRIVER_STRENGTH 197 /* RO */
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
#define EXT_CSD_BOOT_MULT 226 /* RO */
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
#define EXT_CSD_TRIM_MULT 232 /* RO */
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
#define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */
#define EXT_CSD_PRE_EOL_INFO 267 /* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */
#define EXT_CSD_CMDQ_DEPTH 307 /* RO */
#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */
#define EXT_CSD_SUPPORTED_MODE 493 /* RO */
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
#define EXT_CSD_HPI_FEATURES 503 /* RO */
/*
* EXT_CSD field definitions
*/
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
#define EXT_CSD_CMD_SET_SECURE (1<<1)
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
EXT_CSD_CARD_TYPE_HS_52)
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
/* DDR mode @1.8V or 3V I/O */
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
/* DDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
| EXT_CSD_CARD_TYPE_DDR_1_2V)
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
/* SDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
EXT_CSD_CARD_TYPE_HS200_1_2V)
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
EXT_CSD_CARD_TYPE_HS400_1_2V)
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
#define EXT_CSD_BUS_WIDTH_STROBE (1<<7) /* Enhanced strobe mode */
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
#define EXT_CSD_TIMING_HS 1 /* High speed */
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
#define EXT_CSD_SEC_ER_EN (1<<0)
#define EXT_CSD_SEC_BD_BLK_EN (1<<2)
#define EXT_CSD_SEC_GB_CL_EN (1<<4)
#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 only */
#define EXT_CSD_RST_N_EN_MASK 0x3
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
#define EXT_CSD_NO_POWER_NOTIFICATION 0
#define EXT_CSD_POWER_ON 1
#define EXT_CSD_POWER_OFF_SHORT 2
#define EXT_CSD_POWER_OFF_LONG 3
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
#define EXT_CSD_PACKED_EVENT_EN (1<<3)
/*
* EXCEPTION_EVENT_STATUS field
*/
#define EXT_CSD_URGENT_BKOPS (1<<0)
#define EXT_CSD_DYNCAP_NEEDED (1<<1)
#define EXT_CSD_SYSPOOL_EXHAUSTED (1<<2)
#define EXT_CSD_PACKED_FAILURE (1<<3)
#define EXT_CSD_PACKED_GENERIC_ERROR (1<<0)
#define EXT_CSD_PACKED_INDEXED_ERROR (1<<1)
/*
* BKOPS status level
*/
#define EXT_CSD_BKOPS_LEVEL_2 0x2
/*
* BKOPS modes
*/
#define EXT_CSD_MANUAL_BKOPS_MASK 0x01
#define EXT_CSD_AUTO_BKOPS_MASK 0x02
/*
* Command Queue
*/
#define EXT_CSD_CMDQ_MODE_ENABLED (1<<0)
#define EXT_CSD_CMDQ_DEPTH_MASK 0x1F
#define EXT_CSD_CMDQ_SUPPORTED (1<<0)
/*
* MMC_SWITCH access modes
*/
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
/*
* Erase/trim/discard
*/
#define MMC_ERASE_ARG 0x00000000
#define MMC_SECURE_ERASE_ARG 0x80000000
#define MMC_TRIM_ARG 0x00000001
#define MMC_DISCARD_ARG 0x00000003
#define MMC_SECURE_TRIM1_ARG 0x80000001
#define MMC_SECURE_TRIM2_ARG 0x80008000
#define MMC_SECURE_ARGS 0x80000000
#define MMC_TRIM_ARGS 0x00008001
#endif /* LINUX_MMC_MMC_H */

76
ipl/nx_emmc.c Executable file
View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "nx_emmc.h"
#include "heap.h"
#include "list.h"
void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
{
u8 *buf = (u8 *)malloc(NX_GPT_NUM_BLOCKS * NX_EMMC_BLOCKSIZE);
sdmmc_storage_read(storage, NX_GPT_FIRST_LBA, NX_GPT_NUM_BLOCKS, buf);
gpt_header_t *hdr = (gpt_header_t *)buf;
for (u32 i = 0; i < hdr->num_part_ents; i++)
{
gpt_entry_t *ent = (gpt_entry_t *)(buf + (hdr->part_ent_lba - 1) * NX_EMMC_BLOCKSIZE + i * sizeof(gpt_entry_t));
emmc_part_t *part = (emmc_part_t *)malloc(sizeof(emmc_part_t));
part->lba_start = ent->lba_start;
part->lba_end = ent->lba_end;
part->attrs = ent->attrs;
//HACK
for (u32 i = 0; i < 36; i++)
part->name[i] = ent->name[i];
part->name[37] = 0;
list_append(gpt, &part->link);
}
free(buf);
}
void nx_emmc_gpt_free(link_t *gpt)
{
LIST_FOREACH_SAFE(iter, gpt)
free(CONTAINER_OF(iter, emmc_part_t, link));
}
emmc_part_t *nx_emmc_part_find(link_t *gpt, const char *name)
{
LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link)
if (!strcmp(part->name, name))
return part;
return NULL;
}
int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf)
{
//The last LBA is inclusive.
if (part->lba_start + sector_off > part->lba_end)
return 0;
return sdmmc_storage_read(storage, part->lba_start + sector_off, num_sectors, buf);
}
int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf)
{
//The last LBA is inclusive.
if (part->lba_start + sector_off > part->lba_end)
return 0;
return sdmmc_storage_write(storage, part->lba_start + sector_off, num_sectors, buf);
}

72
ipl/nx_emmc.h Executable file
View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _NX_EMMC_H_
#define _NX_EMMC_H_
#include "types.h"
#include "list.h"
#include "sdmmc.h"
typedef struct _gpt_entry_t
{
u8 type_guid[0x10];
u8 part_guid[0x10];
u64 lba_start;
u64 lba_end;
u64 attrs;
u16 name[36];
} gpt_entry_t;
typedef struct _gpt_header_t
{
u64 signature;
u32 revision;
u32 size;
u32 crc32;
u32 res1;
u64 my_lba;
u64 alt_lba;
u64 first_use_lba;
u64 last_use_lba;
u8 disk_guid[0x10];
u64 part_ent_lba;
u32 num_part_ents;
u32 part_ent_size;
u32 part_ents_crc32;
u8 res2[420];
} gpt_header_t;
#define NX_GPT_FIRST_LBA 1
#define NX_GPT_NUM_BLOCKS 33
#define NX_EMMC_BLOCKSIZE 512
typedef struct _emmc_part_t
{
u32 lba_start;
u32 lba_end;
u64 attrs;
u8 name[37];
link_t link;
} emmc_part_t;
void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage);
void nx_emmc_gpt_free(link_t *gpt);
emmc_part_t *nx_emmc_part_find(link_t *gpt, const char *name);
int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
#endif

64
hwinit/pinmux.c → ipl/pinmux.c Normal file → Executable file
View File

@ -1,32 +1,32 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "pinmux.h"
#include "t210.h"
void pinmux_config_uart(u32 idx)
{
PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = 0;
PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0x48;
PINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0;
PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = 0x44;
}
void pinmux_config_i2c(u32 idx)
{
PINMUX_AUX(PINMUX_AUX_X_I2C_SCL(idx)) = 0x40;
PINMUX_AUX(PINMUX_AUX_X_I2C_SDA(idx)) = 0x40;
}
/*
* Copyright (c) 2018 naehrwert
*
* 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 "pinmux.h"
#include "t210.h"
void pinmux_config_uart(u32 idx)
{
PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = 0;
PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0x48;
PINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0;
PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = 0x44;
}
void pinmux_config_i2c(u32 idx)
{
PINMUX_AUX(PINMUX_AUX_X_I2C_SCL(idx)) = 0x40;
PINMUX_AUX(PINMUX_AUX_X_I2C_SDA(idx)) = 0x40;
}

20
hwinit/pinmux.h → ipl/pinmux.h Normal file → Executable file
View File

@ -19,11 +19,31 @@
#include "types.h"
/*! APB MISC registers. */
#define APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL 0x8D4
#define APB_MISC_GP_SDMMC3_CLK_LPBK_CONTROL 0x8D8
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
#define APB_MISC_GP_VGPIO_GPIO_MUX_SEL 0xB74
/*! Pinmux registers. */
#define PINMUX_AUX_SDMMC1_CLK 0x00
#define PINMUX_AUX_SDMMC1_CMD 0x04
#define PINMUX_AUX_SDMMC1_DAT3 0x08
#define PINMUX_AUX_SDMMC1_DAT2 0x0C
#define PINMUX_AUX_SDMMC1_DAT1 0x10
#define PINMUX_AUX_SDMMC1_DAT0 0x14
#define PINMUX_AUX_SDMMC3_CLK 0x1C
#define PINMUX_AUX_SDMMC3_CMD 0x20
#define PINMUX_AUX_SDMMC3_DAT0 0x24
#define PINMUX_AUX_SDMMC3_DAT1 0x28
#define PINMUX_AUX_SDMMC3_DAT2 0x2C
#define PINMUX_AUX_SDMMC3_DAT3 0x30
#define PINMUX_AUX_DMIC3_CLK 0xB4
#define PINMUX_AUX_UART2_TX 0xF4
#define PINMUX_AUX_UART3_TX 0x104
#define PINMUX_AUX_GPIO_PE6 0x248
#define PINMUX_AUX_GPIO_PH6 0x250
#define PINMUX_AUX_GPIO_PZ1 0x280
/*! 0:UART-A, 1:UART-B, 3:UART-C, 3:UART-D */
#define PINMUX_AUX_UARTX_TX(x) (0xE4 + 0x10 * (x))
#define PINMUX_AUX_UARTX_RX(x) (0xE8 + 0x10 * (x))

108
ipl/pkg1.c Executable file
View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "pkg1.h"
#include "se.h"
#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F)
#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
#define _BL(a, o) 0x94000000 | (((o) - (a)) >> 2) & 0x3FFFFFF
#define _NOP() 0xD503201F
PATCHSET_DEF(_secmon_1_patchset,
//Patch the relocator to be able to run from 0x4002D000.
//{ 0x1E0, _ADRP(0, 0x7C013000 - 0x4002D000) }
//Patch package2 decryption and signature/hash checks.
{ 0x9F0 + 0xADC, _NOP() }, //Header signature.
{ 0x9F0 + 0xB8C, _NOP() }, //Version.
{ 0x9F0 + 0xBB0, _NOP() } //Sections SHA2.
);
PATCHSET_DEF(_secmon_2_patchset,
//Patch package2 decryption and signature/hash checks.
{ 0xAC8 + 0xAAC, _NOP() }, //Header signature.
{ 0xAC8 + 0xB3C, _NOP() }, //Version.
{ 0xAC8 + 0xB58, _NOP() } //Sections SHA2.
);
/*
* package1.1 header: <wb, ldr, sm>
* package1.1 layout:
* 1.0: {sm, ldr, wb} { 2, 1, 0 }
* 2.0: {wb, ldr, sm} { 0, 1, 2 }
* 3.0: {wb, ldr, sm} { 0, 1, 2 }
* 3.1: {wb, ldr, sm} { 0, 1, 2 }
* 4.0: {ldr, sm, wb} { 1, 2, 0 }
* 5.0: {ldr, sm, wb} { 1, 2, 0 }
*/
static const pkg1_id_t _pkg1_ids[] = {
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, _secmon_1_patchset }, //1.0.0
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_2_patchset }, //2.0.0
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, NULL }, //3.0.0
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, NULL }, //3.0.1
{ "20170921172629", 3, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, NULL }, //4.0.0
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, NULL }, //5.0.0
{ NULL, 0, 0, 0, 0 } //End.
};
typedef struct _pk11_hdr_t
{
u32 magic;
u32 wb_size;
u32 wb_off;
u32 pad;
u32 ldr_size;
u32 ldr_off;
u32 sm_size;
u32 sm_off;
} pk11_hdr_t;
const pkg1_id_t *pkg1_identify(u8 *pkg1)
{
for (u32 i = 0; _pkg1_ids[i].id; i++)
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 12))
return &_pkg1_ids[i];
return NULL;
}
void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1)
{
//Decrypt package1.
u8 *pkg11 = pkg1 + id->pkg11_off;
u32 pkg11_size = *(u32 *)pkg11;
se_aes_crypt_ctr(11, pkg11 + 0x20, pkg11_size, pkg11 + 0x20, pkg11_size, pkg11 + 0x10);
}
void pkg1_unpack(void *warmboot_dst, void *secmon_dst, const pkg1_id_t *id, u8 *pkg1)
{
pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + id->pkg11_off + 0x20);
u32 sec_size[3] = { hdr->wb_size, hdr->ldr_size, hdr->sm_size };
//u32 sec_off[3] = { hdr->wb_off, hdr->ldr_off, hdr->sm_off };
u8 *pdata = (u8 *)hdr + sizeof(pk11_hdr_t);
for (u32 i = 0; i < 3; i++)
{
if (id->sec_map[i] == 0 && warmboot_dst)
memcpy(warmboot_dst, pdata, sec_size[id->sec_map[i]]);
else if (id->sec_map[i] == 2 && secmon_dst)
memcpy(secmon_dst, pdata, sec_size[id->sec_map[i]]);
pdata += sec_size[id->sec_map[i]];
}
}

49
ipl/pkg1.h Executable file
View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _PKG1_H_
#define _PKG1_H_
#include "types.h"
#define PATCHSET_DEF(name, ...) \
patch_t name[] = { \
__VA_ARGS__, \
{ 0xFFFFFFFF, 0xFFFFFFFF } \
}
typedef struct _patch_t
{
u32 off;
u32 val;
} patch_t;
typedef struct _pkg1_id_t
{
const char *id;
u32 kb;
u32 tsec_off;
u32 pkg11_off;
u32 sec_map[3];
u32 secmon_base;
patch_t *secmon_patchset;
} pkg1_id_t;
const pkg1_id_t *pkg1_identify(u8 *pkg1);
void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1);
void pkg1_unpack(void *warmboot_dst, void *secmon_dst, const pkg1_id_t *id, u8 *pkg1);
#endif

174
ipl/pkg2.c Executable file
View File

@ -0,0 +1,174 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "pkg2.h"
#include "heap.h"
#include "se.h"
/*#include "gfx.h"
extern gfx_ctxt_t gfx_ctxt;
extern gfx_con_t gfx_con;
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)*/
#define DPRINTF(...)
static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
{
u32 size = sizeof(pkg2_kip1_t);
for (u32 j = 0; j < KIP1_NUM_SECTIONS; j++)
size += kip1->sections[j].size_comp;
return size;
}
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2)
{
u8 *ptr = pkg2->data + pkg2->sec_size[PKG2_SEC_KERNEL];
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)ptr;
ptr += sizeof(pkg2_ini1_t);
for (u32 i = 0; i < ini1->num_procs; i++)
{
pkg2_kip1_t *kip1 = (pkg2_kip1_t *)ptr;
pkg2_kip1_info_t *ki = (pkg2_kip1_info_t *)malloc(sizeof(pkg2_kip1_info_t));
ki->kip1 = kip1;
ki->size = _pkg2_calc_kip1_size(kip1);
list_append(info, &ki->link);
ptr += ki->size;
DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size);
}
}
int pkg2_has_kip(link_t *info, u64 tid)
{
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
if(ki->kip1->tid == tid)
return 1;
return 0;
}
void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1)
{
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
if (ki->kip1->tid == tid)
{
ki->kip1 = kip1;
ki->size = _pkg2_calc_kip1_size(kip1);
DPRINTF("replaced kip (new size %08X)\n", ki->size);
return;
}
}
void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1)
{
pkg2_kip1_info_t *ki = (pkg2_kip1_info_t *)malloc(sizeof(pkg2_kip1_info_t));
ki->kip1 = kip1;
ki->size = _pkg2_calc_kip1_size(kip1);
DPRINTF("added kip (size %08X)\n", ki->size);
list_append(info, &ki->link);
}
void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1)
{
if (pkg2_has_kip(info, kip1->tid))
pkg2_replace_kip(info, kip1->tid, kip1);
else
pkg2_add_kip(info, kip1);
}
pkg2_hdr_t *pkg2_decrypt(void *data)
{
u8 *pdata = (u8 *)data;
//Skip signature.
pdata += 0x100;
pkg2_hdr_t *hdr = (pkg2_hdr_t *)pdata;
//Skip header.
pdata += sizeof(pkg2_hdr_t);
//Decrypt header.
se_aes_crypt_ctr(8, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
//gfx_hexdump(&gfx_con, (u32)hdr, hdr, 0x100);
if (hdr->magic != PKG2_MAGIC)
return NULL;
for (u32 i = 0; i < 4; i++)
{
DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]);
if (!hdr->sec_size[i])
continue;
se_aes_crypt_ctr(8, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]);
//gfx_hexdump(&gfx_con, (u32)pdata, pdata, 0x100);
pdata += hdr->sec_size[i];
}
return hdr;
}
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info)
{
u8 *pdst = (u8 *)dst;
//Signature.
memset(pdst, 0, 0x100);
pdst += 0x100;
//Header.
pkg2_hdr_t *hdr = (pkg2_hdr_t *)pdst;
memset(hdr, 0, sizeof(pkg2_hdr_t));
pdst += sizeof(pkg2_hdr_t);
hdr->magic = PKG2_MAGIC;
hdr->base = 0x10000000;
DPRINTF("kernel @ %08X (%08X)\n", (u32)kernel, kernel_size);
//Kernel.
memcpy(pdst, kernel, kernel_size);
hdr->sec_size[PKG2_SEC_KERNEL] = kernel_size;
hdr->sec_off[PKG2_SEC_KERNEL] = 0x10000000;
se_aes_crypt_ctr(8, pdst, kernel_size, pdst, kernel_size, &hdr->sec_ctr[PKG2_SEC_KERNEL * 0x10]);
pdst += kernel_size;
DPRINTF("kernel encrypted\n");
//INI1.
u32 ini1_size = sizeof(pkg2_ini1_t);
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)pdst;
memset(ini1, 0, sizeof(pkg2_ini1_t));
ini1->magic = INI1_MAGIC;
pdst += sizeof(pkg2_ini1_t);
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link)
{
DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->size);
memcpy(pdst, ki->kip1, ki->size);
pdst += ki->size;
ini1_size += ki->size;
ini1->num_procs++;
}
ini1->size = ini1_size;
hdr->sec_size[PKG2_SEC_INI1] = ini1_size;
hdr->sec_off[PKG2_SEC_INI1] = 0x14080000;
se_aes_crypt_ctr(8, ini1, ini1_size, ini1, ini1_size, &hdr->sec_ctr[PKG2_SEC_INI1 * 0x10]);
DPRINTF("INI1 encrypted\n");
//Encrypt header.
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
se_aes_crypt_ctr(8, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
memset(hdr->ctr, 0 , 0x10);
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
}

94
ipl/pkg2.h Executable file
View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _PKG2_H_
#define _PKG2_H_
#include "types.h"
#include "list.h"
#define PKG2_MAGIC 0x31324B50
#define PKG2_SEC_BASE 0x80000000
#define PKG2_SEC_KERNEL 0
#define PKG2_SEC_INI1 1
#define INI1_MAGIC 0x31494E49
typedef struct _pkg2_hdr_t
{
u8 ctr[0x10];
u8 sec_ctr[0x40];
u32 magic;
u32 base;
u32 pad0;
u16 version;
u16 pad1;
u32 sec_size[4];
u32 sec_off[4];
u8 sec_sha256[0x80];
u8 data[];
} pkg2_hdr_t;
typedef struct _pkg2_ini1_t
{
u32 magic;
u32 size;
u32 num_procs;
u32 pad;
} pkg2_ini1_t;
typedef struct _pkg2_kip1_sec_t
{
u32 offset;
u32 size_decomp;
u32 size_comp;
u32 attrib;
} pkg2_kip1_sec_t;
#define KIP1_NUM_SECTIONS 6
typedef struct _pkg2_kip1_t
{
u32 magic;
u8 name[12];
u64 tid;
u32 proc_cat;
u8 main_thrd_prio;
u8 def_cpu_core;
u8 res;
u8 flags;
pkg2_kip1_sec_t sections[KIP1_NUM_SECTIONS];
u32 caps[0x20];
u8 data[];
} pkg2_kip1_t;
typedef struct _pkg2_kip1_info_t
{
pkg2_kip1_t *kip1;
u32 size;
link_t link;
} pkg2_kip1_info_t;
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2);
int pkg2_has_kip(link_t *info, u64 tid);
void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1);
void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1);
void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1);
pkg2_hdr_t *pkg2_decrypt(void *data);
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info);
#endif

3
hwinit/pmc.h → ipl/pmc.h Normal file → Executable file
View File

@ -21,7 +21,10 @@
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
#define APBDEV_PMC_PWRGATE_STATUS 0x38
#define APBDEV_PMC_NO_IOPOWER 0x44
#define APBDEV_PMC_SCRATCH0 0x50
#define APBDEV_PMC_SCRATCH1 0x54
#define APBDEV_PMC_SCRATCH20 0xA0
#define APBDEV_PMC_PWR_DET_VAL 0xE4
#define APBDEV_PMC_DDR_PWR 0xE8
#define APBDEV_PMC_CRYPTO_OP 0xF4
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4

563
ipl/pmc_t210_lp0.h Executable file
View File

@ -0,0 +1,563 @@
/*
* Copyright (c) 2010-2015, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#ifndef _TEGRA210_PMC_H_
#define _TEGRA210_PMC_H_
#include "types.h"
struct tegra_pmc_regs {
u32 cntrl;
u32 sec_disable;
u32 pmc_swrst;
u32 wake_mask;
u32 wake_lvl;
u32 wake_status;
u32 sw_wake_status;
u32 dpd_pads_oride;
u32 dpd_sample;
u32 dpd_enable;
u32 pwrgate_timer_off;
u32 clamp_status;
u32 pwrgate_toggle;
u32 remove_clamping_cmd;
u32 pwrgate_status;
u32 pwrgood_timer;
u32 blink_timer;
u32 no_iopower;
u32 pwr_det;
u32 pwr_det_latch;
u32 scratch0;
u32 scratch1;
u32 scratch2;
u32 scratch3;
u32 scratch4;
u32 scratch5;
u32 scratch6;
u32 scratch7;
u32 scratch8;
u32 scratch9;
u32 scratch10;
u32 scratch11;
u32 scratch12;
u32 scratch13;
u32 scratch14;
u32 scratch15;
u32 scratch16;
u32 scratch17;
u32 scratch18;
u32 scratch19;
u32 odmdata;
u32 scratch21;
u32 scratch22;
u32 scratch23;
u32 secure_scratch0;
u32 secure_scratch1;
u32 secure_scratch2;
u32 secure_scratch3;
u32 secure_scratch4;
u32 secure_scratch5;
u32 cpupwrgood_timer;
u32 cpupwroff_timer;
u32 pg_mask;
u32 pg_mask_1;
u32 auto_wake_lvl;
u32 auto_wake_lvl_mask;
u32 wake_delay;
u32 pwr_det_val;
u32 ddr_pwr;
u32 usb_debounce_del;
u32 usb_a0;
u32 crypto_op;
u32 pllp_wb0_override;
u32 scratch24;
u32 scratch25;
u32 scratch26;
u32 scratch27;
u32 scratch28;
u32 scratch29;
u32 scratch30;
u32 scratch31;
u32 scratch32;
u32 scratch33;
u32 scratch34;
u32 scratch35;
u32 scratch36;
u32 scratch37;
u32 scratch38;
u32 scratch39;
u32 scratch40;
u32 scratch41;
u32 scratch42;
u32 bondout_mirror[3];
u32 sys_33v_en;
u32 bondout_mirror_access;
u32 gate;
u32 wake2_mask;
u32 wake2_lvl;
u32 wake2_status;
u32 sw_wake2_status;
u32 auto_wake2_lvl_mask;
u32 pg_mask_2;
u32 pg_mask_ce1;
u32 pg_mask_ce2;
u32 pg_mask_ce3;
u32 pwrgate_timer_ce[7];
u32 pcx_edpd_cntrl;
u32 osc_edpd_over;
u32 clk_out_cntrl;
u32 sata_pwrgt;
u32 sensor_ctrl;
u32 rst_status;
u32 io_dpd_req;
u32 io_dpd_status;
u32 io_dpd2_req;
u32 io_dpd2_status;
u32 sel_dpd_tim;
u32 vddp_sel;
u32 ddr_cfg;
u32 e_no_vttgen;
u8 _rsv0[4];
u32 pllm_wb0_override_freq;
u32 test_pwrgate;
u32 pwrgate_timer_mult;
u32 dis_sel_dpd;
u32 utmip_uhsic_triggers;
u32 utmip_uhsic_saved_state;
u32 utmip_pad_cfg;
u32 utmip_term_pad_cfg;
u32 utmip_uhsic_sleep_cfg;
u32 utmip_uhsic_sleepwalk_cfg;
u32 utmip_sleepwalk_p[3];
u32 uhsic_sleepwalk_p0;
u32 utmip_uhsic_status;
u32 utmip_uhsic_fake;
u32 bondout_mirror3[5 - 3];
u32 secure_scratch6;
u32 secure_scratch7;
u32 scratch43;
u32 scratch44;
u32 scratch45;
u32 scratch46;
u32 scratch47;
u32 scratch48;
u32 scratch49;
u32 scratch50;
u32 scratch51;
u32 scratch52;
u32 scratch53;
u32 scratch54;
u32 scratch55;
u32 scratch0_eco;
u32 por_dpd_ctrl;
u32 scratch2_eco;
u32 utmip_uhsic_line_wakeup;
u32 utmip_bias_master_cntrl;
u32 utmip_master_config;
u32 td_pwrgate_inter_part_timer;
u32 utmip_uhsic2_triggers;
u32 utmip_uhsic2_saved_state;
u32 utmip_uhsic2_sleep_cfg;
u32 utmip_uhsic2_sleepwalk_cfg;
u32 uhsic2_sleepwalk_p1;
u32 utmip_uhsic2_status;
u32 utmip_uhsic2_fake;
u32 utmip_uhsic2_line_wakeup;
u32 utmip_master2_config;
u32 utmip_uhsic_rpd_cfg;
u32 pg_mask_ce0;
u32 pg_mask3[5 - 3];
u32 pllm_wb0_override2;
u32 tsc_mult;
u32 cpu_vsense_override;
u32 glb_amap_cfg;
u32 sticky_bits;
u32 sec_disable2;
u32 weak_bias;
u32 reg_short;
u32 pg_mask_andor;
u8 _rsv1[0x2c];
u32 secure_scratch8; /* offset 0x300 */
u32 secure_scratch9;
u32 secure_scratch10;
u32 secure_scratch11;
u32 secure_scratch12;
u32 secure_scratch13;
u32 secure_scratch14;
u32 secure_scratch15;
u32 secure_scratch16;
u32 secure_scratch17;
u32 secure_scratch18;
u32 secure_scratch19;
u32 secure_scratch20;
u32 secure_scratch21;
u32 secure_scratch22;
u32 secure_scratch23;
u32 secure_scratch24;
u32 secure_scratch25;
u32 secure_scratch26;
u32 secure_scratch27;
u32 secure_scratch28;
u32 secure_scratch29;
u32 secure_scratch30;
u32 secure_scratch31;
u32 secure_scratch32;
u32 secure_scratch33;
u32 secure_scratch34;
u32 secure_scratch35;
u32 secure_scratch36;
u32 secure_scratch37;
u32 secure_scratch38;
u32 secure_scratch39;
u32 secure_scratch40;
u32 secure_scratch41;
u32 secure_scratch42;
u32 secure_scratch43;
u32 secure_scratch44;
u32 secure_scratch45;
u32 secure_scratch46;
u32 secure_scratch47;
u32 secure_scratch48;
u32 secure_scratch49;
u32 secure_scratch50;
u32 secure_scratch51;
u32 secure_scratch52;
u32 secure_scratch53;
u32 secure_scratch54;
u32 secure_scratch55;
u32 secure_scratch56;
u32 secure_scratch57;
u32 secure_scratch58;
u32 secure_scratch59;
u32 secure_scratch60;
u32 secure_scratch61;
u32 secure_scratch62;
u32 secure_scratch63;
u32 secure_scratch64;
u32 secure_scratch65;
u32 secure_scratch66;
u32 secure_scratch67;
u32 secure_scratch68;
u32 secure_scratch69;
u32 secure_scratch70;
u32 secure_scratch71;
u32 secure_scratch72;
u32 secure_scratch73;
u32 secure_scratch74;
u32 secure_scratch75;
u32 secure_scratch76;
u32 secure_scratch77;
u32 secure_scratch78;
u32 secure_scratch79;
u32 _rsv0x420[8];
u32 cntrl2; /* 0x440 */
u32 _rsv0x444[2];
u32 event_counter; /* 0x44C */
u32 fuse_control;
u32 scratch1_eco;
u32 _rsv0x458[1];
u32 io_dpd3_req; /* 0x45C */
u32 io_dpd3_status;
u32 io_dpd4_req;
u32 io_dpd4_status;
u32 _rsv0x46C[30];
u32 ddr_cntrl; /* 0x4E4 */
u32 _rsv0x4E8[70];
u32 scratch56; /* 0x600 */
u32 scratch57;
u32 scratch58;
u32 scratch59;
u32 scratch60;
u32 scratch61;
u32 scratch62;
u32 scratch63;
u32 scratch64;
u32 scratch65;
u32 scratch66;
u32 scratch67;
u32 scratch68;
u32 scratch69;
u32 scratch70;
u32 scratch71;
u32 scratch72;
u32 scratch73;
u32 scratch74;
u32 scratch75;
u32 scratch76;
u32 scratch77;
u32 scratch78;
u32 scratch79;
u32 scratch80;
u32 scratch81;
u32 scratch82;
u32 scratch83;
u32 scratch84;
u32 scratch85;
u32 scratch86;
u32 scratch87;
u32 scratch88;
u32 scratch89;
u32 scratch90;
u32 scratch91;
u32 scratch92;
u32 scratch93;
u32 scratch94;
u32 scratch95;
u32 scratch96;
u32 scratch97;
u32 scratch98;
u32 scratch99;
u32 scratch100;
u32 scratch101;
u32 scratch102;
u32 scratch103;
u32 scratch104;
u32 scratch105;
u32 scratch106;
u32 scratch107;
u32 scratch108;
u32 scratch109;
u32 scratch110;
u32 scratch111;
u32 scratch112;
u32 scratch113;
u32 scratch114;
u32 scratch115;
u32 scratch116;
u32 scratch117;
u32 scratch118;
u32 scratch119;
u32 scratch120; /* 0x700 */
u32 scratch121;
u32 scratch122;
u32 scratch123;
u32 scratch124;
u32 scratch125;
u32 scratch126;
u32 scratch127;
u32 scratch128;
u32 scratch129;
u32 scratch130;
u32 scratch131;
u32 scratch132;
u32 scratch133;
u32 scratch134;
u32 scratch135;
u32 scratch136;
u32 scratch137;
u32 scratch138;
u32 scratch139;
u32 scratch140;
u32 scratch141;
u32 scratch142;
u32 scratch143;
u32 scratch144;
u32 scratch145;
u32 scratch146;
u32 scratch147;
u32 scratch148;
u32 scratch149;
u32 scratch150;
u32 scratch151;
u32 scratch152;
u32 scratch153;
u32 scratch154;
u32 scratch155;
u32 scratch156;
u32 scratch157;
u32 scratch158;
u32 scratch159;
u32 scratch160;
u32 scratch161;
u32 scratch162;
u32 scratch163;
u32 scratch164;
u32 scratch165;
u32 scratch166;
u32 scratch167;
u32 scratch168;
u32 scratch169;
u32 scratch170;
u32 scratch171;
u32 scratch172;
u32 scratch173;
u32 scratch174;
u32 scratch175;
u32 scratch176;
u32 scratch177;
u32 scratch178;
u32 scratch179;
u32 scratch180;
u32 scratch181;
u32 scratch182;
u32 scratch183;
u32 scratch184;
u32 scratch185;
u32 scratch186;
u32 scratch187;
u32 scratch188;
u32 scratch189;
u32 scratch190;
u32 scratch191;
u32 scratch192;
u32 scratch193;
u32 scratch194;
u32 scratch195;
u32 scratch196;
u32 scratch197;
u32 scratch198;
u32 scratch199;
u32 scratch200;
u32 scratch201;
u32 scratch202;
u32 scratch203;
u32 scratch204;
u32 scratch205;
u32 scratch206;
u32 scratch207;
u32 scratch208;
u32 scratch209;
u32 scratch210;
u32 scratch211;
u32 scratch212;
u32 scratch213;
u32 scratch214;
u32 scratch215;
u32 scratch216;
u32 scratch217;
u32 scratch218;
u32 scratch219;
u32 scratch220;
u32 scratch221;
u32 scratch222;
u32 scratch223;
u32 scratch224;
u32 scratch225;
u32 scratch226;
u32 scratch227;
u32 scratch228;
u32 scratch229;
u32 scratch230;
u32 scratch231;
u32 scratch232;
u32 scratch233;
u32 scratch234;
u32 scratch235;
u32 scratch236;
u32 scratch237;
u32 scratch238;
u32 scratch239;
u32 scratch240;
u32 scratch241;
u32 scratch242;
u32 scratch243;
u32 scratch244;
u32 scratch245;
u32 scratch246;
u32 scratch247;
u32 scratch248;
u32 scratch249;
u32 scratch250;
u32 scratch251;
u32 scratch252;
u32 scratch253;
u32 scratch254;
u32 scratch255;
u32 scratch256;
u32 scratch257;
u32 scratch258;
u32 scratch259;
u32 scratch260;
u32 scratch261;
u32 scratch262;
u32 scratch263;
u32 scratch264;
u32 scratch265;
u32 scratch266;
u32 scratch267;
u32 scratch268;
u32 scratch269;
u32 scratch270;
u32 scratch271;
u32 scratch272;
u32 scratch273;
u32 scratch274;
u32 scratch275;
u32 scratch276;
u32 scratch277;
u32 scratch278;
u32 scratch279;
u32 scratch280;
u32 scratch281;
u32 scratch282;
u32 scratch283;
u32 scratch284;
u32 scratch285;
u32 scratch286;
u32 scratch287;
u32 scratch288;
u32 scratch289;
u32 scratch290;
u32 scratch291;
u32 scratch292;
u32 scratch293;
u32 scratch294;
u32 scratch295;
u32 scratch296;
u32 scratch297;
u32 scratch298;
u32 scratch299; /* 0x9CC */
u32 _rsv0x9D0[50];
u32 secure_scratch80; /* 0xa98 */
u32 secure_scratch81;
u32 secure_scratch82;
u32 secure_scratch83;
u32 secure_scratch84;
u32 secure_scratch85;
u32 secure_scratch86;
u32 secure_scratch87;
u32 secure_scratch88;
u32 secure_scratch89;
u32 secure_scratch90;
u32 secure_scratch91;
u32 secure_scratch92;
u32 secure_scratch93;
u32 secure_scratch94;
u32 secure_scratch95;
u32 secure_scratch96;
u32 secure_scratch97;
u32 secure_scratch98;
u32 secure_scratch99;
u32 secure_scratch100;
u32 secure_scratch101;
u32 secure_scratch102;
u32 secure_scratch103;
u32 secure_scratch104;
u32 secure_scratch105;
u32 secure_scratch106;
u32 secure_scratch107;
u32 secure_scratch108;
u32 secure_scratch109;
u32 secure_scratch110;
u32 secure_scratch111;
u32 secure_scratch112;
u32 secure_scratch113;
u32 secure_scratch114;
u32 secure_scratch115;
u32 secure_scratch116;
u32 secure_scratch117;
u32 secure_scratch118;
u32 secure_scratch119;
};
#endif /* _TEGRA210_PMC_H_ */

34
ipl/reloc.S Executable file
View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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/>.
*/
/*
* TODO: the placement of the relocator is a bit fragile atm, maybe we
* should include it in start.S and copy it to some known good
* place in IRAM instead. Basically we want it as far back atm
* as it might be overwritten during relocation.
*/
.section .text.reloc
.arm
.globl _reloc_ipl
.type _reloc_ipl, %function
_reloc_ipl:
LDMIA R0!, {R4-R7}
STMIA R1!, {R4-R7}
SUBS R2, #0x10
BNE _reloc_ipl
BX R3

95
ipl/sd.h Executable file
View File

@ -0,0 +1,95 @@
/*
* include/linux/mmc/sd.h
*
* Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#ifndef LINUX_MMC_SD_H
#define LINUX_MMC_SD_H
/* SD commands type argument response */
/* class 0 */
/* This is basically the same command as for MMC with some quirks. */
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
#define SD_SWITCH_VOLTAGE 11 /* ac R1 */
/* class 10 */
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
/* class 5 */
#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */
#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
/* Application commands */
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
#define SD_APP_SD_STATUS 13 /* adtc R1 */
#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
#define SD_APP_SET_CLR_CARD_DETECT 42
#define SD_APP_SEND_SCR 51 /* adtc R1 */
/* OCR bit definitions */
#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
#define SD_OCR_XPC (1 << 28) /* SDXC power control */
#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */
/*
* SD_SWITCH argument format:
*
* [31] Check (0) or switch (1)
* [30:24] Reserved (0)
* [23:20] Function group 6
* [19:16] Function group 5
* [15:12] Function group 4
* [11:8] Function group 3
* [7:4] Function group 2
* [3:0] Function group 1
*/
/*
* SD_SEND_IF_COND argument format:
*
* [31:12] Reserved (0)
* [11:8] Host Voltage Supply Flags
* [7:0] Check Pattern (0xAA)
*/
/*
* SCR field definitions
*/
#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */
#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00-3.0X */
/*
* SD bus widths
*/
#define SD_BUS_WIDTH_1 0
#define SD_BUS_WIDTH_4 2
/*
* SD_SWITCH mode
*/
#define SD_SWITCH_CHECK 0
#define SD_SWITCH_SET 1
/*
* SD_SWITCH function groups
*/
#define SD_SWITCH_GRP_ACCESS 0
/*
* SD_SWITCH access modes
*/
#define SD_SWITCH_ACCESS_DEF 0
#define SD_SWITCH_ACCESS_HS 1
#endif /* LINUX_MMC_SD_H */

883
ipl/sdmmc.c Executable file
View File

@ -0,0 +1,883 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "sdmmc.h"
#include "mmc.h"
#include "sd.h"
#include "util.h"
#include "heap.h"
/*#include "gfx.h"
extern gfx_ctxt_t gfx_ctxt;
extern gfx_con_t gfx_con;
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)*/
#define DPRINTF(...)
static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
{
const u32 mask = (size < 32 ? 1 << size : 0) - 1;
const u32 off = 3 - ((start) / 32);
const u32 shft = (start) & 31;
u32 res = resp[off] >> shft;
if (size + shft > 32)
res |= resp[off - 1] << ((32 - shft) % 32);
return res & mask;
}
/*
* Common functions for SD and MMC.
*/
static int _sdmmc_storage_check_result(u32 res)
{
//Error mask:
//R1_OUT_OF_RANGE, R1_ADDRESS_ERROR, R1_BLOCK_LEN_ERROR,
//R1_ERASE_SEQ_ERROR, R1_ERASE_PARAM, R1_WP_VIOLATION,
//R1_LOCK_UNLOCK_FAILED, R1_COM_CRC_ERROR, R1_ILLEGAL_COMMAND,
//R1_CARD_ECC_FAILED, R1_CC_ERROR, R1_ERROR, R1_CID_CSD_OVERWRITE,
//R1_WP_ERASE_SKIP, R1_ERASE_RESET, R1_SWITCH_ERROR
if (!(res & 0xFDF9A080))
return 1;
//TODO: R1_SWITCH_ERROR we can skip for certain card types.
return 0;
}
static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state, u32 mask)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, cmd, arg, SDMMC_RSP_TYPE_1, check_busy);
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))
return 0;
sdmmc_get_rsp(storage->sdmmc, resp, 4, SDMMC_RSP_TYPE_1);
if (mask)
*resp &= ~mask;
if (_sdmmc_storage_check_result(*resp))
if (expected_state == 0x10 || R1_CURRENT_STATE(*resp) == expected_state)
return 1;
return 0;
}
static int _sdmmc_storage_execute_cmd_type1(sdmmc_storage_t *storage, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)
{
u32 tmp;
return _sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, cmd, arg, check_busy, expected_state, 0);
}
static int _sdmmc_storage_go_idle_state(sdmmc_storage_t *storage)
{
sdmmc_cmd_t cmd;
sdmmc_init_cmd(&cmd, MMC_GO_IDLE_STATE, 0, SDMMC_RSP_TYPE_0, 0);
return sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0);
}
static int _sdmmc_storage_get_cid(sdmmc_storage_t *storage, void *buf)
{
sdmmc_cmd_t cmd;
sdmmc_init_cmd(&cmd, MMC_ALL_SEND_CID, 0, SDMMC_RSP_TYPE_2, 0);
if (!sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0))
return 0;
sdmmc_get_rsp(storage->sdmmc, buf, 0x10, SDMMC_RSP_TYPE_2);
return 1;
}
static int _sdmmc_storage_select_card(sdmmc_storage_t *storage)
{
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SELECT_CARD, storage->rca << 16, 1, 0x10);
}
static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage, void *buf)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, MMC_SEND_CSD, storage->rca << 16, SDMMC_RSP_TYPE_2, 0);
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))
return 0;
sdmmc_get_rsp(storage->sdmmc, buf, 0x10, SDMMC_RSP_TYPE_2);
return 1;
}
static int _sdmmc_storage_set_blocklen(sdmmc_storage_t *storage, u32 blocklen)
{
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SET_BLOCKLEN, blocklen, 0, R1_STATE_TRAN);
}
static int _sdmmc_storage_get_status(sdmmc_storage_t *storage, u32 *resp, u32 mask)
{
return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, MMC_SEND_STATUS, storage->rca << 16, 0, R1_STATE_TRAN, mask);
}
static int _sdmmc_storage_check_status(sdmmc_storage_t *storage)
{
u32 tmp;
return _sdmmc_storage_get_status(storage, &tmp, 0);
}
static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out, u32 sector, u32 num_sectors, void *buf, u32 is_write)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, is_write ? MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK, sector, SDMMC_RSP_TYPE_1, 0);
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
reqbuf.num_sectors = num_sectors;
reqbuf.blksize = 512;
reqbuf.is_write = is_write;
reqbuf.is_multi_block = 1;
reqbuf.is_auto_cmd12 = 1;
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, blkcnt_out))
{
u32 tmp = 0;
sdmmc_stop_transmission(storage->sdmmc, &tmp);
_sdmmc_storage_get_status(storage, &tmp, 0);
return 0;
}
return 1;
}
int sdmmc_storage_end(sdmmc_storage_t *storage)
{
if (!_sdmmc_storage_go_idle_state(storage))
return 0;
sdmmc_end(storage->sdmmc);
return 1;
}
static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write)
{
u8 *bbuf = (u8 *)buf;
while (num_sectors)
{
u32 blkcnt = 0;
//Retry once on error.
if (!_sdmmc_storage_readwrite_ex(storage, &blkcnt, sector, MIN(num_sectors, 0xFFFF), bbuf, is_write))
if (!_sdmmc_storage_readwrite_ex(storage, &blkcnt, sector, MIN(num_sectors, 0xFFFF), bbuf, is_write))
return 0;
DPRINTF("readwrite: %08X\n", blkcnt);
sector += blkcnt;
num_sectors -= blkcnt;
bbuf += 512 * blkcnt;
}
}
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)
{
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0);
}
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)
{
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1);
}
/*
* MMC specific functions.
*/
static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u32 power)
{
sdmmc_cmd_t cmd;
u32 arg = 0;
switch (power)
{
case SDMMC_POWER_1_8:
arg = 0x40000080; //Sector access, voltage.
break;
case SDMMC_POWER_3_3:
arg = 0x403F8000; //Sector access, voltage.
break;
default:
return 0;
}
sdmmc_init_cmd(&cmd, MMC_SEND_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
if (!sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0))
return 0;
return sdmmc_get_rsp(storage->sdmmc, pout, 4, SDMMC_RSP_TYPE_3);
}
static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
{
u32 timeout = get_tmr() + 1500000;
while (1)
{
u32 cond = 0;
if (!_mmc_storage_get_op_cond_inner(storage, &cond, power))
break;
if (cond & 0x80000000)
{
if (cond & 0x40000000)
storage->has_sector_access = 1;
return 1;
}
if (get_tmr() > timeout)
break;
sleep(1000);
}
return 0;
}
static int _mmc_storage_set_relative_addr(sdmmc_storage_t *storage)
{
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SET_RELATIVE_ADDR, storage->rca << 16, 0, 0x10);
}
static int _mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, MMC_SEND_EXT_CSD, 0, SDMMC_RSP_TYPE_1, 0);
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
reqbuf.blksize = 512;
reqbuf.num_sectors = 1;
reqbuf.is_write = 0;
reqbuf.is_multi_block = 0;
reqbuf.is_auto_cmd12 = 0;
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))
return 0;
u32 tmp = 0;
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
return _sdmmc_storage_check_result(tmp);
}
static int _mmc_storage_switch(sdmmc_storage_t *storage, u32 arg)
{
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SWITCH, arg, 1, 0x10);
}
static int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width)
{
if (bus_width == SDMMC_BUS_WIDTH_1)
return 1;
u32 arg = 0;
switch (bus_width)
{
case SDMMC_BUS_WIDTH_4:
arg = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
break;
case SDMMC_BUS_WIDTH_8:
arg = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8);
break;
}
if (_mmc_storage_switch(storage, arg))
if (_sdmmc_storage_check_status(storage))
{
sdmmc_set_bus_width(storage->sdmmc, bus_width);
return 1;
}
return 0;
}
static int _mmc_storage_enable_HS(sdmmc_storage_t *storage, int check)
{
if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS)))
return 0;
if (check && !_sdmmc_storage_check_status(storage))
return 0;
if (!sdmmc_setup_clock(storage->sdmmc, 2))
return 0;
DPRINTF("[mmc] switched to HS\n");
if (check || _sdmmc_storage_check_status(storage))
return 1;
return 0;
}
static int _mmc_storage_enable_HS200(sdmmc_storage_t *storage)
{
if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200)))
return 0;
if (!sdmmc_setup_clock(storage->sdmmc, 3))
return 0;
if (!sdmmc_config_tuning(storage->sdmmc, 3, MMC_SEND_TUNING_BLOCK_HS200))
return 0;
DPRINTF("[mmc] switched to HS200\n");
return _sdmmc_storage_check_status(storage);
}
static int _mmc_storage_enable_HS400(sdmmc_storage_t *storage)
{
if (!_mmc_storage_enable_HS200(storage))
return 0;
sdmmc_get_venclkctl(storage->sdmmc);
if (!_mmc_storage_enable_HS(storage, 0))
return 0;
if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_DDR_BUS_WIDTH_8)))
return 0;
if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400)))
return 0;
if (!sdmmc_setup_clock(storage->sdmmc, 4))
return 0;
DPRINTF("[mmc] switched to HS400\n");
return _sdmmc_storage_check_status(storage);
}
static int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type, u32 type)
{
//TODO: this should be a config item.
//---v
if (!1 || sdmmc_get_voltage(storage->sdmmc) != SDMMC_POWER_1_8)
goto out;
if (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 &&
card_type & EXT_CSD_CARD_TYPE_HS400_1_8V &&
type == 4)
return _mmc_storage_enable_HS400(storage);
if (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 ||
sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_4
&& card_type & EXT_CSD_CARD_TYPE_HS200_1_8V
&& (type == 4 || type == 3))
return _mmc_storage_enable_HS200(storage);
out:;
if (card_type & EXT_CSD_CARD_TYPE_HS_52)
return _mmc_storage_enable_HS(storage, 1);
return 1;
}
static int _mmc_storage_enable_bkops(sdmmc_storage_t *storage)
{
if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_SET_BITS, EXT_CSD_BKOPS_EN, EXT_CSD_BKOPS_LEVEL_2)))
return 0;
return _sdmmc_storage_check_status(storage);
}
int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type)
{
memset(storage, 0, sizeof(sdmmc_storage_t));
storage->sdmmc = sdmmc;
storage->rca = 2; //TODO: this could be a config item.
if (!sdmmc_init(sdmmc, id, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, 0, 0))
return 0;
DPRINTF("[mmc] after init\n");
sleep(1000 + (74000 + sdmmc->divisor - 1) / sdmmc->divisor);
if (!_sdmmc_storage_go_idle_state(storage))
return 0;
DPRINTF("[mmc] went to idle state\n");
if (!_mmc_storage_get_op_cond(storage, SDMMC_POWER_1_8))
return 0;
DPRINTF("[mmc] got op cond\n");
if (!_sdmmc_storage_get_cid(storage, storage->cid))
return 0;
DPRINTF("[mmc] got cid\n");
if (!_mmc_storage_set_relative_addr(storage))
return 0;
DPRINTF("[mmc] set relative addr\n");
if (!_sdmmc_storage_get_csd(storage, storage->csd))
return 0;
DPRINTF("[mmc] got csd\n");
if (!sdmmc_setup_clock(storage->sdmmc, 1))
return 0;
DPRINTF("[mmc] after setup clock\n");
if (!_sdmmc_storage_select_card(storage))
return 0;
DPRINTF("[mmc] card selected\n");
if (!_sdmmc_storage_set_blocklen(storage, 512))
return 0;
DPRINTF("[mmc] set blocklen to 512\n");
u32 *csd = (u32 *)storage->csd;
//Check system specification version, only version 4.0 and later support below features.
if (unstuff_bits(csd, 122, 4) < CSD_SPEC_VER_4)
{
storage->sec_cnt = (1 + unstuff_bits(csd, 62, 12)) << (unstuff_bits(csd, 47, 3) + 2);
return 1;
}
if (!_mmc_storage_switch_buswidth(storage, bus_width))
return 0;
DPRINTF("[mmc] switched buswidth\n");
u8 *ext_csd = (u8 *)malloc(512);
if (!_mmc_storage_get_ext_csd(storage, ext_csd))
{
free(ext_csd);
return 0;
}
//gfx_hexdump(&gfx_con, 0, ext_csd, 512);
storage->sec_cnt = *(u32 *)&ext_csd[EXT_CSD_SEC_CNT];
if (storage->cid[0xE] == 0x11 && ext_csd[EXT_CSD_BKOPS_EN] & EXT_CSD_BKOPS_LEVEL_2)
_mmc_storage_enable_bkops(storage);
if (!_mmc_storage_enable_highspeed(storage, ext_csd[EXT_CSD_CARD_TYPE], type))
{
free(ext_csd);
return 0;
}
DPRINTF("[mmc] switched to possible highspeed mode\n");
sdmmc_sd_clock_ctrl(storage->sdmmc, 1);
free(ext_csd);
return 1;
}
int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition)
{
if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_PART_CONFIG, partition)))
return 0;
if (!_sdmmc_storage_check_status(storage))
return 0;
storage->partition = partition;
return 1;
}
/*
* SD specific functions.
*/
static int _sd_storage_execute_app_cmd(sdmmc_storage_t *storage, u32 expected_state, u32 mask, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out)
{
u32 tmp;
if (!_sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask))
return 0;
return sdmmc_execute_cmd(storage->sdmmc, cmd, req, blkcnt_out);
}
static int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)
{
if (!_sdmmc_storage_execute_cmd_type1(storage, MMC_APP_CMD, storage->rca << 16, 0, R1_STATE_TRAN))
return 0;
return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0);
}
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, 0x1AA, SDMMC_RSP_TYPE_5, 0);
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))
return 0;
//TODO: we may have received a timeout error in the above request, which indicates a version 1 card.
u32 resp = 0;
if (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_5))
return 0;
return (resp & 0xFFF) == 0x1AA ? 1 : 0;
}
static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int is_version_1, int supports_low_voltage)
{
sdmmc_cmd_t cmdbuf;
u32 arg = (((~is_version_1 & 1) << 28) & 0xBFFFFFFF | ((~is_version_1 & 1) << 30)) & 0xFEFFFFFF | ((supports_low_voltage & ~is_version_1 & 1) << 24) | 0x100000;
sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
if (!_sd_storage_execute_app_cmd(storage, 0x10, is_version_1 ? 0x400000 : 0, &cmdbuf, 0, 0))
return 0;
return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3);
}
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, int supports_low_voltage)
{
u32 timeout = get_tmr() + 1500000;
while (1)
{
u32 cond = 0;
if (!_sd_storage_get_op_cond_once(storage, &cond, is_version_1, supports_low_voltage))
break;
if (cond & 0x80000000)
{
if (cond & 0x40000000)
storage->has_sector_access = 1;
if (cond & 0x1000000 && supports_low_voltage)
{
//The low voltage regulator configuration is valid for SDMMC1 only.
if (storage->sdmmc->id == SDMMC_1 &&
_sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY))
{
if (!sdmmc_enable_low_voltage(storage->sdmmc))
return 0;
storage->is_low_voltage = 1;
DPRINTF("-> switched to low voltage\n");
}
}
return 1;
}
if (get_tmr() > timeout)
break;
sleep(1000);
}
return 0;
}
static int _sd_storage_get_rca(sdmmc_storage_t *storage)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, SD_SEND_RELATIVE_ADDR, 0, SDMMC_RSP_TYPE_4, 0);
u32 timeout = get_tmr() + 1500000;
while (1)
{
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))
break;
u32 resp = 0;
if (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_4))
break;
if (resp >> 16)
{
storage->rca = resp >> 16;
return 1;
}
if (get_tmr() > timeout)
break;
sleep(1000);
}
return 0;
}
int _sd_storage_get_scr(sdmmc_storage_t *storage, void *buf)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, SD_APP_SEND_SCR, 0, SDMMC_RSP_TYPE_1, 0);
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
reqbuf.blksize = 8;
reqbuf.num_sectors = 1;
reqbuf.is_write = 0;
reqbuf.is_multi_block = 0;
reqbuf.is_auto_cmd12 = 0;
if (!_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, 0))
return 0;
u32 tmp = 0;
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
return _sdmmc_storage_check_result(tmp);
}
int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, SD_SWITCH, 0xFFFFFF, SDMMC_RSP_TYPE_1, 0);
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
reqbuf.blksize = 64;
reqbuf.num_sectors = 1;
reqbuf.is_write = 0;
reqbuf.is_multi_block = 0;
reqbuf.is_auto_cmd12 = 0;
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))
return 0;
u32 tmp = 0;
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
return _sdmmc_storage_check_result(tmp);
}
int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int flag, u32 arg)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, SD_SWITCH, arg | (flag << 31) | 0xFFFFF0, SDMMC_RSP_TYPE_1, 0);
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
reqbuf.blksize = 64;
reqbuf.num_sectors = 1;
reqbuf.is_write = 0;
reqbuf.is_multi_block = 0;
reqbuf.is_auto_cmd12 = 0;
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))
return 0;
u32 tmp = 0;
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
return _sdmmc_storage_check_result(tmp);
}
int _sd_storage_enable_highspeed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf)
{
if (!_sd_storage_switch(storage, buf, 0, hs_type))
return 0;
u32 type_out = buf[16] & 0xF;
if (type_out != hs_type)
return 0;
if (((u16)buf[0] << 8) | buf[1] < 0x320)
{
if (!_sd_storage_switch(storage, buf, 1, hs_type))
return 0;
if (type_out != buf[16] & 0xF)
return 0;
}
return 1;
}
int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)
{
if (sdmmc_get_bus_width(storage->sdmmc) != SDMMC_BUS_WIDTH_4)
return 0;
if (!_sd_storage_switch_get(storage, buf))
return 0;
u32 hs_type = 0;
switch (type)
{
case 11:
if (buf[13] & 8)
{
type = 11;
hs_type = 3;
break;
}
//Fall through.
case 10:
if (!(buf[13] & 4))
return 0;
type = 10;
hs_type = 2;
break;
default:
return 0;
break;
}
if (!_sd_storage_enable_highspeed(storage, hs_type, buf))
return 0;
if (!sdmmc_setup_clock(storage->sdmmc, type))
return 0;
if (!sdmmc_config_tuning(storage->sdmmc, type, MMC_SEND_TUNING_BLOCK))
return 0;
return _sdmmc_storage_check_status(storage);
}
int _sd_storage_enable_highspeed_high_volt(sdmmc_storage_t *storage, u8 *buf)
{
if (!_sd_storage_switch_get(storage, buf))
return 0;
if (!(buf[13] & 2))
return 1;
if (!_sd_storage_enable_highspeed(storage, 1, buf))
return 0;
if (!_sdmmc_storage_check_status(storage))
return 0;
return sdmmc_setup_clock(storage->sdmmc, 7);
}
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type)
{
memset(storage, 0, sizeof(sdmmc_storage_t));
storage->sdmmc = sdmmc;
if (!sdmmc_init(sdmmc, id, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, 5, 0))
return 0;
DPRINTF("[sd] after init\n");
sleep(1000 + (74000 + sdmmc->divisor - 1) / sdmmc->divisor);
if (!_sdmmc_storage_go_idle_state(storage))
return 0;
DPRINTF("[sd] went to idle state\n");
if (!_sd_storage_send_if_cond(storage))
return 0;
DPRINTF("[sd] after send if cond\n");
//TODO: use correct version here -----v
if (!_sd_storage_get_op_cond(storage, 0, bus_width == SDMMC_BUS_WIDTH_4 && (type | 1) == 11))
return 0;
DPRINTF("[sd] got op cond\n");
if (!_sdmmc_storage_get_cid(storage, storage->cid))
return 0;
DPRINTF("[sd] got cid\n");
if (!_sd_storage_get_rca(storage))
return 0;
DPRINTF("[sd] got rca (= %04X)\n", storage->rca);
if (!_sdmmc_storage_get_csd(storage, storage->csd))
return 0;
DPRINTF("[sd] got csd\n");
//Parse CSD.
u32 *csd = (u32 *)storage->csd;
u32 csd_struct = unstuff_bits(csd, 126, 2);
switch (csd_struct)
{
case 0:
storage->sec_cnt = (1 + unstuff_bits(csd, 62, 12)) << (unstuff_bits(csd, 47, 3) + 2);
break;
case 1:
storage->sec_cnt = (1 + unstuff_bits(csd, 48, 22)) << 10;
break;
default:
DPRINTF("[sd] Unknown CSD structure %d\n", csd_struct);
//TODO: I've encountered this with one of my SD cards, but
// according to the spec only version 0 and 1 are
// supposed to be in use (mine was version 2).
//return 0;
break;
}
if (!storage->is_low_voltage)
{
if (!sdmmc_setup_clock(storage->sdmmc, 6))
return 0;
DPRINTF("[sd] after setup clock\n");
}
if (!_sdmmc_storage_select_card(storage))
return 0;
DPRINTF("[sd] card selected\n");
if (!_sdmmc_storage_set_blocklen(storage, 512))
return 0;
DPRINTF("[sd] set blocklen to 512\n");
u32 tmp = 0;
if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN))
return 0;
DPRINTF("[sd] cleared card detect\n");
u8 *buf = (u8 *)malloc(512);
if (!_sd_storage_get_scr(storage, buf))
return 0;
memcpy(storage->scr, buf, 8);
DPRINTF("[sd] got scr\n");
if (bus_width == SDMMC_BUS_WIDTH_4 && storage->scr[1] & 4)
{
if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, 0, R1_STATE_TRAN))
{
free(buf);
return 0;
}
sdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4);
DPRINTF("[sd] switched to wide bus width\n");
}
else
DPRINTF("[sd] SD does not support wide bus width\n");
if (storage->is_low_voltage)
{
if (!_sd_storage_enable_highspeed_low_volt(storage, type, buf))
{
free(buf);
return 0;
}
DPRINTF("[sd] enabled highspeed (low voltage)\n");
}
else if (type != 6 && storage->scr[0] & 0xF != 0)
{
if (!_sd_storage_enable_highspeed_high_volt(storage, buf))
{
free(buf);
return 0;
}
DPRINTF("[sd] enabled highspeed (high voltage)\n");
}
sdmmc_sd_clock_ctrl(sdmmc, 1);
free(buf);
return 1;
}
/*
* Gamecard specific functions.
*/
int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
{
u32 resp;
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, 60, 0, SDMMC_RSP_TYPE_1, 1);
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
reqbuf.blksize = 0x40;
reqbuf.num_sectors = 1;
reqbuf.is_write = 1;
reqbuf.is_multi_block = 0;
reqbuf.is_auto_cmd12 = 0;
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))
{
sdmmc_stop_transmission(storage->sdmmc, &resp);
return 0;
}
if (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_1))
return 0;
if (!_sdmmc_storage_check_result(resp))
return 0;
return _sdmmc_storage_check_status(storage);
}
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc)
{
memset(storage, 0, sizeof(sdmmc_storage_t));
storage->sdmmc = sdmmc;
if (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, 14, 0))
return 0;
DPRINTF("[gc] after init\n");
sleep(1000 + (10000 + sdmmc->divisor - 1) / sdmmc->divisor);
if (!sdmmc_config_tuning(storage->sdmmc, 14, MMC_SEND_TUNING_BLOCK_HS200))
return 0;
DPRINTF("[gc] after tuning\n");
sdmmc_sd_clock_ctrl(sdmmc, 1);
return 1;
}

45
ipl/sdmmc.h Executable file
View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _SDMMC_H_
#define _SDMMC_H_
#include "types.h"
#include "sdmmc_driver.h"
/*! SDMMC storage context. */
typedef struct _sdmmc_storage_t
{
sdmmc_t *sdmmc;
u32 rca;
int has_sector_access;
u32 sec_cnt;
int is_low_voltage;
u32 partition;
u8 cid[0x10];
u8 csd[0x10];
u8 scr[8];
} sdmmc_storage_t;
int sdmmc_storage_end(sdmmc_storage_t *storage);
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);
int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition);
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
#endif

1063
ipl/sdmmc_driver.c Executable file

File diff suppressed because it is too large Load Diff

107
ipl/sdmmc_driver.h Executable file
View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _SDMMC_DRIVER_H_
#define _SDMMC_DRIVER_H_
#include "types.h"
#include "sdmmc_t210.h"
/*! SDMMC controller IDs. */
#define SDMMC_1 0
#define SDMMC_2 1
#define SDMMC_3 2
#define SDMMC_4 3
/*! SDMMC power types. */
#define SDMMC_POWER_OFF 0
#define SDMMC_POWER_1_8 1
#define SDMMC_POWER_3_3 2
/*! SDMMC bus widths. */
#define SDMMC_BUS_WIDTH_1 0
#define SDMMC_BUS_WIDTH_4 1
#define SDMMC_BUS_WIDTH_8 2
/*! SDMMC response types. */
#define SDMMC_RSP_TYPE_0 0
#define SDMMC_RSP_TYPE_1 1
#define SDMMC_RSP_TYPE_2 2
#define SDMMC_RSP_TYPE_3 3
#define SDMMC_RSP_TYPE_4 4
#define SDMMC_RSP_TYPE_5 5
/*! SDMMC mask interrupt status. */
#define SDMMC_MASKINT_MASKED 0
#define SDMMC_MASKINT_NOERROR -1
#define SDMMC_MASKINT_ERROR -2
/*! Helper for SWITCH command argument. */
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))
/*! SDMMC controller context. */
typedef struct _sdmmc_t
{
t210_sdmmc_t *regs;
u32 id;
u32 divisor;
u32 clock_stopped;
int no_sd;
int sd_clock_enabled;
int venclkctl_set;
u32 venclkctl_tap;
u32 expected_rsp_type;
u32 dma_addr_next;
u32 rsp[4];
u32 rsp3;
} sdmmc_t;
/*! SDMMC command. */
typedef struct _sdmmc_cmd_t
{
u16 cmd;
u32 arg;
u32 rsp_type;
u32 check_busy;
} sdmmc_cmd_t;
/*! SDMMC request. */
typedef struct _sdmmc_req_t
{
void *buf;
u32 blksize;
u32 num_sectors;
int is_write;
int is_multi_block;
int is_auto_cmd12;
} sdmmc_req_t;
int sdmmc_get_voltage(sdmmc_t *sdmmc);
u32 sdmmc_get_bus_width(sdmmc_t *sdmmc);
void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width);
void sdmmc_get_venclkctl(sdmmc_t *sdmmc);
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type);
void sdmmc_sd_clock_ctrl(sdmmc_t *sdmmc, int no_sd);
int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type);
int sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd);
int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp);
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int no_sd);
void sdmmc_end(sdmmc_t *sdmmc);
void sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy);
int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out);
int sdmmc_enable_low_voltage(sdmmc_t *sdmmc);
#endif

132
ipl/sdmmc_t210.h Executable file
View File

@ -0,0 +1,132 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _SDMMC_T210_H_
#define _SDMMC_T210_H_
#include "types.h"
#define TEGRA_MMC_PWRCTL_SD_BUS_POWER 0x1
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8 0xA
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0 0xC
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3 0xE
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_MASK 0xF1
#define TEGRA_MMC_HOSTCTL_1BIT 0x00
#define TEGRA_MMC_HOSTCTL_4BIT 0x02
#define TEGRA_MMC_HOSTCTL_8BIT 0x20
#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE 0x1
#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE 0x2
#define TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE 0x4
#define TEGRA_MMC_CLKCON_CLKGEN_SELECT 0x20
#define TEGRA_MMC_SWRST_SW_RESET_FOR_ALL 0x1
#define TEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE 0x2
#define TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE 0x4
#define TEGRA_MMC_TRNMOD_DMA_ENABLE 0x1
#define TEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE 0x2
#define TEGRA_MMC_TRNMOD_AUTO_CMD12 0x4
#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_WRITE 0x0
#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ 0x10
#define TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT 0x20
#define TEGRA_MMC_TRNMOD_CMD_CRC_CHECK 0x8
#define TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK 0x10
#define TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER 0x20
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_MASK 0x3
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE 0x0
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136 0x1
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48 0x2
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY 0x3
#define TEGRA_MMC_NORINTSTS_CMD_COMPLETE 0x1
#define TEGRA_MMC_NORINTSTS_XFER_COMPLETE 0x2
#define TEGRA_MMC_NORINTSTS_DMA_INTERRUPT 0x8
#define TEGRA_MMC_NORINTSTS_ERR_INTERRUPT 0x8000
#define TEGRA_MMC_NORINTSTS_CMD_TIMEOUT 0x10000
#define TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY 0x20
typedef struct _t210_sdmmc_t
{
vu32 sysad;
vu16 blksize;
vu16 blkcnt;
vu32 argument;
vu16 trnmod;
vu16 cmdreg;
vu32 rspreg0;
vu32 rspreg1;
vu32 rspreg2;
vu32 rspreg3;
vu32 bdata;
vu32 prnsts;
vu8 hostctl;
vu8 pwrcon;
vu8 blkgap;
vu8 wakcon;
vu16 clkcon;
vu8 timeoutcon;
vu8 swrst;
vu16 norintsts;
vu16 errintsts;
vu16 norintstsen;
vu16 errintstsen;
vu16 norintsigen;
vu16 errintsigen;
vu16 acmd12errsts;
vu16 hostctl2;
vu32 capareg;
vu32 capareg_1;
vu32 maxcurr;
vu8 res3[4];
vu16 setacmd12err;
vu16 setinterr;
vu8 admaerr;
vu8 res4[3];
vu32 admaaddr;
vu32 admaaddr_hi;
vu8 res5[156];
vu16 slotintstatus;
vu16 hcver;
vu32 venclkctl;
vu32 venspictl;
vu32 venspiintsts;
vu32 venceatactl;
vu32 venbootctl;
vu32 venbootacktout;
vu32 venbootdattout;
vu32 vendebouncecnt;
vu32 venmiscctl;
vu32 res6[34];
vu32 field_1AC;
vu32 field_1B0;
vu8 res7[8];
vu32 field_1BC;
vu32 field_1C0;
vu32 field_1C4;
vu8 field_1C8[24];
vu32 sdmemcmppadctl;
vu32 autocalcfg;
vu32 autocalintval;
vu32 autocalsts;
vu32 field_1F0;
} t210_sdmmc_t;
#endif

523
ipl/sdram.c Executable file
View File

@ -0,0 +1,523 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "t210.h"
#include "mc.h"
#include "emc.h"
#include "pmc.h"
#include "util.h"
#include "fuse.h"
#include "max77620.h"
#include "sdram_param_t210.h"
#define CONFIG_SDRAM_COMPRESS_CFG
#ifdef CONFIG_SDRAM_COMPRESS_CFG
#include "lz.h"
#include "sdram_lz.inl"
#else
#include "sdram.inl"
#endif
static u32 _get_sdram_id()
{
return (fuse_read_odm(4) & 0x38) >> 3;
}
static void _sdram_config(const sdram_params_t *params)
{
PMC(0x45C) = (((4 * params->emc_pmc_scratch1 >> 2) + 0x80000000) ^ 0xFFFF) & 0xC000FFFF;
sleep(params->pmc_io_dpd3_req_wait);
u32 req = (4 * params->emc_pmc_scratch2 >> 2) + 0x80000000;
PMC(APBDEV_PMC_IO_DPD4_REQ) = (req >> 16 << 16) ^ 0x3FFF0000;
sleep(params->pmc_io_dpd4_req_wait);
PMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0xFFFF) & 0xC000FFFF;
sleep(params->pmc_io_dpd4_req_wait);
PMC(APBDEV_PMC_WEAK_BIAS) = 0;
sleep(1);
CLOCK(0x98) = params->pllm_setup_control;
CLOCK(0x9C) = 0;
CLOCK(0x90) = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | 0x40000000 | ((params->pllm_post_divider & 0xFFFF) << 20);
u32 wait_end = TMR(0x10) + 300;
while (!(CLOCK(0x90) & 0x8000000))
{
if (TMR(0x10) >= wait_end)
goto break_nosleep;
}
sleep(10);
break_nosleep:
CLOCK(0x19C) = (params->mc_emem_arb_misc0 >> 11) & 0x10000 | params->emc_clock_source & 0xFFFEFFFF;
if (params->emc_clock_source_dll)
CLOCK(0x664) = params->emc_clock_source_dll;
if (params->clear_clock2_mc1)
CLOCK(0x44C) = 0x40000000;
CLOCK(0x328) = 0x2000001;
CLOCK(0x284) = 0x4000;
CLOCK(0x30C) = 0x2000001;
EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
EMC(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;
EMC(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;
EMC(EMC_TIMING_CONTROL) = 1;
sleep(1);
EMC(EMC_DBG) = (params->emc_dbg_write_mux << 1) | params->emc_dbg;
if (params->emc_bct_spare2)
*(vu32 *)params->emc_bct_spare2 = params->emc_bct_spare3;
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
EMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;
EMC(EMC_CMD_MAPPING_CMD1_0) = params->emc_cmd_mapping_cmd1_0;
EMC(EMC_CMD_MAPPING_CMD1_1) = params->emc_cmd_mapping_cmd1_1;
EMC(EMC_CMD_MAPPING_CMD1_2) = params->emc_cmd_mapping_cmd1_2;
EMC(EMC_CMD_MAPPING_CMD2_0) = params->emc_cmd_mapping_cmd2_0;
EMC(EMC_CMD_MAPPING_CMD2_1) = params->emc_cmd_mapping_cmd2_1;
EMC(EMC_CMD_MAPPING_CMD2_2) = params->emc_cmd_mapping_cmd2_2;
EMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
EMC(EMC_PMACRO_BRICK_MAPPING_1) = params->emc_pmacro_brick_mapping1;
EMC(EMC_PMACRO_BRICK_MAPPING_2) = params->emc_pmacro_brick_mapping2;
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1 & 0x1120112 | 0x1EED1EED;
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
EMC(EMC_SWIZZLE_RANK0_BYTE0) = params->emc_swizzle_rank0_byte0;
EMC(EMC_SWIZZLE_RANK0_BYTE1) = params->emc_swizzle_rank0_byte1;
EMC(EMC_SWIZZLE_RANK0_BYTE2) = params->emc_swizzle_rank0_byte2;
EMC(EMC_SWIZZLE_RANK0_BYTE3) = params->emc_swizzle_rank0_byte3;
EMC(EMC_SWIZZLE_RANK1_BYTE0) = params->emc_swizzle_rank1_byte0;
EMC(EMC_SWIZZLE_RANK1_BYTE1) = params->emc_swizzle_rank1_byte1;
EMC(EMC_SWIZZLE_RANK1_BYTE2) = params->emc_swizzle_rank1_byte2;
EMC(EMC_SWIZZLE_RANK1_BYTE3) = params->emc_swizzle_rank1_byte3;
if (params->emc_bct_spare6)
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
EMC(EMC_AUTO_CAL_CONFIG5) = params->emc_auto_cal_config5;
EMC(EMC_AUTO_CAL_CONFIG6) = params->emc_auto_cal_config6;
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
EMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1;
EMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0;
EMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1;
EMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2;
EMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3;
EMC(EMC_QUSE_BRLSHFT_0) = params->emc_quse_brlshft0;
EMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1;
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF | 0x1E401E40;
EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;
EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F;
EMC(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd;
EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = params->emc_pmacro_bg_bias_ctrl0;
EMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl;
EMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl;
EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl;
EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
EMC(EMC_CFG_3) = params->emc_cfg3;
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
EMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3;
EMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4;
EMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_0) = params->emc_pmacro_tx_sel_clk_src0;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_1) = params->emc_pmacro_tx_sel_clk_src1;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_2) = params->emc_pmacro_tx_sel_clk_src2;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_3) = params->emc_pmacro_tx_sel_clk_src3;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_4) = params->emc_pmacro_tx_sel_clk_src4;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_5) = params->emc_pmacro_tx_sel_clk_src5;
EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;
EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;
EMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1;
EMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2;
EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;
EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;
EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;
EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;
EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;
EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_3) = params->emc_pmacro_quse_ddll_rank0_3;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_4) = params->emc_pmacro_quse_ddll_rank0_4;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_5) = params->emc_pmacro_quse_ddll_rank0_5;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_0) = params->emc_pmacro_quse_ddll_rank1_0;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_1) = params->emc_pmacro_quse_ddll_rank1_1;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_2) = params->emc_pmacro_quse_ddll_rank1_2;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_3) = params->emc_pmacro_quse_ddll_rank1_3;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3) = params->emc_pmacro_ob_ddll_long_dq_rank0_3;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4) = params->emc_pmacro_ob_ddll_long_dq_rank0_4;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5) = params->emc_pmacro_ob_ddll_long_dq_rank0_5;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0) = params->emc_pmacro_ob_ddll_long_dq_rank1_0;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1) = params->emc_pmacro_ob_ddll_long_dq_rank1_1;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2) = params->emc_pmacro_ob_ddll_long_dq_rank1_2;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) = params->emc_pmacro_ob_ddll_long_dq_rank1_3;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4) = params->emc_pmacro_ob_ddll_long_dq_rank1_4;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5) = params->emc_pmacro_ob_ddll_long_dq_rank1_5;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ob_ddll_long_dqs_rank0_0;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ob_ddll_long_dqs_rank0_1;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ob_ddll_long_dqs_rank0_2;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3) = params->emc_pmacro_ob_ddll_long_dqs_rank0_3;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4) = params->emc_pmacro_ob_ddll_long_dqs_rank0_4;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5) = params->emc_pmacro_ob_ddll_long_dqs_rank0_5;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0) = params->emc_pmacro_ob_ddll_long_dqs_rank1_0;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ob_ddll_long_dqs_rank1_1;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ob_ddll_long_dqs_rank1_2;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ob_ddll_long_dqs_rank1_3;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4) = params->emc_pmacro_ob_ddll_long_dqs_rank1_4;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5) = params->emc_pmacro_ob_ddll_long_dqs_rank1_5;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ib_ddll_long_dqs_rank0_0;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ib_ddll_long_dqs_rank0_1;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ib_ddll_long_dqs_rank0_2;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3) = params->emc_pmacro_ib_ddll_long_dqs_rank0_3;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0) = params->emc_pmacro_ib_ddll_long_dqs_rank1_0;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ib_ddll_long_dqs_rank1_1;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
EMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3;
EMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2;
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl & 1 | 0xE;
if (params->emc_bct_spare4)
*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;
EMC(EMC_TIMING_CONTROL) = 1;
MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;
MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;
MC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override;
MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1;
MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;
MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;
MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;
MC(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask;
MC(MC_EMEM_ADR_CFG_BANK_MASK_0) = params->mc_emem_adr_cfg_bank_mask0;
MC(MC_EMEM_ADR_CFG_BANK_MASK_1) = params->mc_emem_adr_cfg_bank_mask1;
MC(MC_EMEM_ADR_CFG_BANK_MASK_2) = params->mc_emem_adr_cfg_bank_mask2;
MC(MC_EMEM_CFG) = params->mc_emem_cfg;
MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;
MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;
MC(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb;
MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;
MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;
MC(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb;
MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;
MC(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req;
MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;
MC(MC_EMEM_ARB_REFPB_BANK_CTRL) = params->emc_emem_arb_refpb_bank_ctrl;
MC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd;
MC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp;
MC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc;
MC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras;
MC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw;
MC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd;
MC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre;
MC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre;
MC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r;
MC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w;
MC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw;
MC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w;
MC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r;
MC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb;
MC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns;
MC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers;
MC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0;
MC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1;
MC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2;
MC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle;
MC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override;
MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;
MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
MC(MC_TIMING_CONTROL) = 1;
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
MC(MC_STAT_CONTROL) = params->mc_stat_control;
EMC(EMC_ADR_CFG) = params->emc_adr_cfg;
EMC(EMC_CLKEN_OVERRIDE) = params->emc_clken_override;
EMC(EMC_PMACRO_AUTOCAL_CFG_0) = params->emc_pmacro_auto_cal_cfg0;
EMC(EMC_PMACRO_AUTOCAL_CFG_1) = params->emc_pmacro_auto_cal_cfg1;
EMC(EMC_PMACRO_AUTOCAL_CFG_2) = params->emc_pmacro_auto_cal_cfg2;
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
sleep(params->emc_auto_cal_wait);
if (params->emc_bct_spare8)
*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;
EMC(EMC_CFG_2) = params->emc_cfg2;
EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe;
EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;
EMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2;
EMC(EMC_CMDQ) = params->emc_cmd_q;
EMC(EMC_MC2EMCQ) = params->emc_mc2emc_q;
EMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt;
EMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2;
EMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5;
EMC(EMC_RC) = params->emc_rc;
EMC(EMC_RFC) = params->emc_rfc;
EMC(EMC_RFCPB) = params->emc_rfc_pb;
EMC(EMC_REFCTRL2) = params->emc_ref_ctrl2;
EMC(EMC_RFC_SLR) = params->emc_rfc_slr;
EMC(EMC_RAS) = params->emc_ras;
EMC(EMC_RP) = params->emc_rp;
EMC(EMC_TPPD) = params->emc_tppd;
EMC(EMC_R2R) = params->emc_r2r;
EMC(EMC_W2W) = params->emc_w2w;
EMC(EMC_R2W) = params->emc_r2w;
EMC(EMC_W2R) = params->emc_w2r;
EMC(EMC_R2P) = params->emc_r2p;
EMC(EMC_W2P) = params->emc_w2p;
EMC(EMC_CCDMW) = params->emc_ccdmw;
EMC(EMC_RD_RCD) = params->emc_rd_rcd;
EMC(EMC_WR_RCD) = params->emc_wr_rcd;
EMC(EMC_RRD) = params->emc_rrd;
EMC(EMC_REXT) = params->emc_rext;
EMC(EMC_WEXT) = params->emc_wext;
EMC(EMC_WDV) = params->emc_wdv;
EMC(EMC_WDV_CHK) = params->emc_wdv_chk;
EMC(EMC_WSV) = params->emc_wsv;
EMC(EMC_WEV) = params->emc_wev;
EMC(EMC_WDV_MASK) = params->emc_wdv_mask;
EMC(EMC_WS_DURATION) = params->emc_ws_duration;
EMC(EMC_WE_DURATION) = params->emc_we_duration;
EMC(EMC_QUSE) = params->emc_quse;
EMC(EMC_QUSE_WIDTH) = params->emc_quse_width;
EMC(EMC_IBDLY) = params->emc_ibdly;
EMC(EMC_OBDLY) = params->emc_obdly;
EMC(EMC_EINPUT) = params->emc_einput;
EMC(EMC_EINPUT_DURATION) = params->emc_einput_duration;
EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;
EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
EMC(EMC_DBG) = params->emc_dbg;
EMC(EMC_QRST) = params->emc_qrst;
EMC(EMC_ISSUE_QRST) = 0;
EMC(EMC_QSAFE) = params->emc_qsafe;
EMC(EMC_RDV) = params->emc_rdv;
EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
EMC(EMC_RDV_EARLY) = params->emc_rdv_early;
EMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask;
EMC(EMC_QPOP) = params->emc_qpop;
EMC(EMC_REFRESH) = params->emc_refresh;
EMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num;
EMC(EMC_PRE_REFRESH_REQ_CNT) = params->emc_prerefresh_req_cnt;
EMC(EMC_PDEX2WR) = params->emc_pdex2wr;
EMC(EMC_PDEX2RD) = params->emc_pdex2rd;
EMC(EMC_PCHG2PDEN) = params->emc_pchg2pden;
EMC(EMC_ACT2PDEN) = params->emc_act2pden;
EMC(EMC_AR2PDEN) = params->emc_ar2pden;
EMC(EMC_RW2PDEN) = params->emc_rw2pden;
EMC(EMC_CKE2PDEN) = params->emc_cke2pden;
EMC(EMC_PDEX2CKE) = params->emc_pdex2che;
EMC(EMC_PDEX2MRR) = params->emc_pdex2mrr;
EMC(EMC_TXSR) = params->emc_txsr;
EMC(EMC_TXSRDLL) = params->emc_txsr_dll;
EMC(EMC_TCKE) = params->emc_tcke;
EMC(EMC_TCKESR) = params->emc_tckesr;
EMC(EMC_TPD) = params->emc_tpd;
EMC(EMC_TFAW) = params->emc_tfaw;
EMC(EMC_TRPAB) = params->emc_trpab;
EMC(EMC_TCLKSTABLE) = params->emc_tclkstable;
EMC(EMC_TCLKSTOP) = params->emc_tclkstop;
EMC(EMC_TREFBW) = params->emc_trefbw;
EMC(EMC_ODT_WRITE) = params->emc_odt_write;
EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;
EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;
EMC(EMC_CFG_RSV) = params->emc_cfg_rsv;
EMC(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1;
EMC(EMC_PMC_SCRATCH2) = params->emc_pmc_scratch2;
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
EMC(EMC_CFG) = params->emc_cfg & 0xE | 0x3C00000;
if (params->boot_rom_patch_control & 0x80000000)
{
*(vu32 *)(4 * (params->boot_rom_patch_control + 0x1C000000)) = params->boot_rom_patch_data;
MC(MC_TIMING_CONTROL) = 1;
}
PMC(0x45C) = ((4 * params->emc_pmc_scratch1 >> 2) + 0x40000000) & 0xCFFF0000;
sleep(params->pmc_io_dpd3_req_wait);
if (!params->emc_auto_cal_interval)
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config | 0x200;
EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2;
if (params->emc_zcal_warm_cold_boot_enables & 1)
{
if (params->memory_type == 2)
EMC(EMC_ZCAL_WAIT_CNT) = 8 * params->emc_zcal_wait_cnt;
if (params->memory_type == 3)
{
EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
}
}
EMC(EMC_TIMING_CONTROL) = 1;
sleep(params->emc_timing_control_wait);
PMC(0x4E4) &= 0xFFF8007F;
sleep(params->pmc_ddr_ctrl_wait);
if (params->memory_type == 2)
{
EMC(EMC_PIN) = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);
sleep(params->emc_pin_extra_wait + 200);
EMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256;
sleep(params->emc_pin_extra_wait + 500);
}
if (params->memory_type == 3)
{
EMC(EMC_PIN) = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);
sleep(params->emc_pin_extra_wait + 200);
EMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256;
sleep(params->emc_pin_extra_wait + 2000);
}
EMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 0x101;
sleep(params->emc_pin_program_wait);
if (params->memory_type != 3)
EMC(EMC_NOP) = (params->emc_dev_select << 30) + 1;
if (params->memory_type == 1)
sleep(params->emc_pin_extra_wait + 200);
if (params->memory_type == 3)
{
if (params->emc_bct_spare10)
*(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11;
EMC(EMC_MRW2) = params->emc_mrw2;
EMC(EMC_MRW) = params->emc_mrw1;
EMC(EMC_MRW3) = params->emc_mrw3;
EMC(EMC_MRW4) = params->emc_mrw4;
EMC(EMC_MRW6) = params->emc_mrw6;
EMC(EMC_MRW14) = params->emc_mrw14;
EMC(EMC_MRW8) = params->emc_mrw8;
EMC(EMC_MRW12) = params->emc_mrw12;
EMC(EMC_MRW9) = params->emc_mrw9;
EMC(EMC_MRW13) = params->emc_mrw13;
if (params->emc_zcal_warm_cold_boot_enables & 1)
{
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;
sleep(params->emc_zcal_init_wait);
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3;
if (!(params->emc_dev_select & 2))
{
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;
sleep(params->emc_zcal_init_wait);
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3;
}
}
}
PMC(0x1D0) = params->pmc_ddr_cfg;
if (params->memory_type - 1 <= 2)
{
EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;
EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
}
if (params->emc_bct_spare12)
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
EMC(EMC_TIMING_CONTROL) = 1;
if (params->emc_extra_refresh_num)
EMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 0xFD) | (params->emc_pin_gpio << 30);
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
EMC(EMC_CFG) = params->emc_cfg;
EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;
EMC(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd;
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
EMC(EMC_TIMING_CONTROL) = 1;
EMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
SYSREG(AHB_ARBITRATION_XBAR_CTRL) = SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF | ((params->ahb_arbitration_xbar_ctrl_meminit_done & 0xFFFF) << 16);
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;
MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1; //Disable write access to a bunch of MC registers.
}
const void *sdram_get_params()
{
//TODO: sdram_id should be in [0, 7].
#ifdef CONFIG_SDRAM_COMPRESS_CFG
u8 *buf = (u8 *)0x40030000;
LZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz));
return (const void *)&buf[sizeof(sdram_params_t) * _get_sdram_id()];
#else
return _dram_cfgs[_get_sdram_id()];
#endif
}
void sdram_init()
{
//TODO: sdram_id should be in [0,4].
const sdram_params_t *params = (const sdram_params_t *)sdram_get_params();
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_SD_CFG2, 0x05);
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_SD1, 40); //40 = (1000 * 1100 - 600000) / 12500 -> 1.1V
PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
sleep(params->pmc_vddp_sel_wait);
PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR);
PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;
PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
if (params->emc_bct_spare0)
*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
_sdram_config(params);
}

2
hwinit/sdram.h → ipl/sdram.h Normal file → Executable file
View File

@ -18,5 +18,7 @@
#define _SDRAM_H_
void sdram_init();
const void *sdram_get_params();
void sdram_lp0_save_params(const void *params);
#endif

328
hwinit/sdram.inl → ipl/sdram.inl Normal file → Executable file
View File

@ -819,10 +819,334 @@ static const u8 _dram_cfg_4[1896] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const u32 *_dram_cfgs[5] = {
static const u8 _dram_cfg_5[1896] = {
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00,
0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00,
0x2F, 0x00, 0x33, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00,
0x2F, 0x00, 0x33, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x15, 0x00, 0x15, 0x00,
0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00, 0x16, 0x00,
0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 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,
0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00,
0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const u8 _dram_cfg_6[1896] = {
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00,
0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00,
0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00,
0x2F, 0x00, 0x33, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00,
0x2F, 0x00, 0x33, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x15, 0x00, 0x15, 0x00,
0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00, 0x16, 0x00,
0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 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,
0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const u32 *_dram_cfgs[7] = {
(const u32 *)_dram_cfg_0,
(const u32 *)_dram_cfg_1,
(const u32 *)_dram_cfg_2,
(const u32 *)_dram_cfg_3,
(const u32 *)_dram_cfg_4
(const u32 *)_dram_cfg_4,
(const u32 *)_dram_cfg_5,
(const u32 *)_dram_cfg_6
};

1034
ipl/sdram_lp0.c Executable file

File diff suppressed because it is too large Load Diff

124
ipl/sdram_lz.inl Executable file
View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 u8 _dram_cfg_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
};

930
ipl/sdram_param_t210.h Executable file
View File

@ -0,0 +1,930 @@
/*
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
*
* 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/>.
*
* See file CREDITS for list of people who contributed to this
* project.
*/
/**
* Defines the SDRAM parameter structure.
*
* Note that PLLM is used by EMC.
*/
#ifndef _SDRAM_PARAM_T210_H_
#define _SDRAM_PARAM_T210_H_
#define MEMORY_TYPE_NONE 0
#define MEMORY_TYPE_DDR 0
#define MEMORY_TYPE_LPDDR 0
#define MEMORY_TYPE_DDR2 0
#define MEMORY_TYPE_LPDDR2 1
#define MEMORY_TYPE_DDR3 2
#define MEMORY_TYPE_LPDDR4 3
/**
* Defines the SDRAM parameter structure
*/
typedef struct _sdram_params {
/* Specifies the type of memory device */
u32 memory_type;
/* MC/EMC clock source configuration */
/* Specifies the M value for PllM */
u32 pllm_input_divider;
/* Specifies the N value for PllM */
u32 pllm_feedback_divider;
/* Specifies the time to wait for PLLM to lock (in microseconds) */
u32 pllm_stable_time;
/* Specifies misc. control bits */
u32 pllm_setup_control;
/* Specifies the P value for PLLM */
u32 pllm_post_divider;
/* Specifies value for Charge Pump Gain Control */
u32 pllm_kcp;
/* Specifies VCO gain */
u32 pllm_kvco;
/* Spare BCT param */
u32 emc_bct_spare0;
/* Spare BCT param */
u32 emc_bct_spare1;
/* Spare BCT param */
u32 emc_bct_spare2;
/* Spare BCT param */
u32 emc_bct_spare3;
/* Spare BCT param */
u32 emc_bct_spare4;
/* Spare BCT param */
u32 emc_bct_spare5;
/* Spare BCT param */
u32 emc_bct_spare6;
/* Spare BCT param */
u32 emc_bct_spare7;
/* Spare BCT param */
u32 emc_bct_spare8;
/* Spare BCT param */
u32 emc_bct_spare9;
/* Spare BCT param */
u32 emc_bct_spare10;
/* Spare BCT param */
u32 emc_bct_spare11;
/* Spare BCT param */
u32 emc_bct_spare12;
/* Spare BCT param */
u32 emc_bct_spare13;
/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
u32 emc_clock_source;
u32 emc_clock_source_dll;
/* Defines possible override for PLLLM_MISC2 */
u32 clk_rst_pllm_misc20_override;
/* enables override for PLLLM_MISC2 */
u32 clk_rst_pllm_misc20_override_enable;
/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
u32 clear_clock2_mc1;
/* Auto-calibration of EMC pads */
/* Specifies the value for EMC_AUTO_CAL_INTERVAL */
u32 emc_auto_cal_interval;
/*
* Specifies the value for EMC_AUTO_CAL_CONFIG
* Note: Trigger bits are set by the SDRAM code.
*/
u32 emc_auto_cal_config;
/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
u32 emc_auto_cal_config2;
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
u32 emc_auto_cal_config3;
u32 emc_auto_cal_config4;
u32 emc_auto_cal_config5;
u32 emc_auto_cal_config6;
u32 emc_auto_cal_config7;
u32 emc_auto_cal_config8;
/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
u32 emc_auto_cal_vref_sel0;
u32 emc_auto_cal_vref_sel1;
/* Specifies the value for EMC_AUTO_CAL_CHANNEL */
u32 emc_auto_cal_channel;
/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
u32 emc_pmacro_auto_cal_cfg0;
u32 emc_pmacro_auto_cal_cfg1;
u32 emc_pmacro_auto_cal_cfg2;
u32 emc_pmacro_rx_term;
u32 emc_pmacro_dq_tx_drive;
u32 emc_pmacro_ca_tx_drive;
u32 emc_pmacro_cmd_tx_drive;
u32 emc_pmacro_auto_cal_common;
u32 emc_pmacro_zcrtl;
/*
* Specifies the time for the calibration
* to stabilize (in microseconds)
*/
u32 emc_auto_cal_wait;
u32 emc_xm2_comp_pad_ctrl;
u32 emc_xm2_comp_pad_ctrl2;
u32 emc_xm2_comp_pad_ctrl3;
/*
* DRAM size information
* Specifies the value for EMC_ADR_CFG
*/
u32 emc_adr_cfg;
/*
* Specifies the time to wait after asserting pin
* CKE (in microseconds)
*/
u32 emc_pin_program_wait;
/* Specifies the extra delay before/after pin RESET/CKE command */
u32 emc_pin_extra_wait;
u32 emc_pin_gpio_enable;
u32 emc_pin_gpio;
/*
* Specifies the extra delay after the first writing
* of EMC_TIMING_CONTROL
*/
u32 emc_timing_control_wait;
/* Timing parameters required for the SDRAM */
/* Specifies the value for EMC_RC */
u32 emc_rc;
/* Specifies the value for EMC_RFC */
u32 emc_rfc;
u32 emc_rfc_pb;
u32 emc_ref_ctrl2;
/* Specifies the value for EMC_RFC_SLR */
u32 emc_rfc_slr;
/* Specifies the value for EMC_RAS */
u32 emc_ras;
/* Specifies the value for EMC_RP */
u32 emc_rp;
/* Specifies the value for EMC_R2R */
u32 emc_r2r;
/* Specifies the value for EMC_W2W */
u32 emc_w2w;
/* Specifies the value for EMC_R2W */
u32 emc_r2w;
/* Specifies the value for EMC_W2R */
u32 emc_w2r;
/* Specifies the value for EMC_R2P */
u32 emc_r2p;
/* Specifies the value for EMC_W2P */
u32 emc_w2p;
/* Specifies the value for EMC_RD_RCD */
u32 emc_tppd;
u32 emc_ccdmw;
u32 emc_rd_rcd;
/* Specifies the value for EMC_WR_RCD */
u32 emc_wr_rcd;
/* Specifies the value for EMC_RRD */
u32 emc_rrd;
/* Specifies the value for EMC_REXT */
u32 emc_rext;
/* Specifies the value for EMC_WEXT */
u32 emc_wext;
/* Specifies the value for EMC_WDV */
u32 emc_wdv;
u32 emc_wdv_chk;
u32 emc_wsv;
u32 emc_wev;
/* Specifies the value for EMC_WDV_MASK */
u32 emc_wdv_mask;
u32 emc_ws_duration;
u32 emc_we_duration;
/* Specifies the value for EMC_QUSE */
u32 emc_quse;
/* Specifies the value for EMC_QUSE_WIDTH */
u32 emc_quse_width;
/* Specifies the value for EMC_IBDLY */
u32 emc_ibdly;
u32 emc_obdly;
/* Specifies the value for EMC_EINPUT */
u32 emc_einput;
/* Specifies the value for EMC_EINPUT_DURATION */
u32 emc_einput_duration;
/* Specifies the value for EMC_PUTERM_EXTRA */
u32 emc_puterm_extra;
/* Specifies the value for EMC_PUTERM_WIDTH */
u32 emc_puterm_width;
u32 emc_qrst;
u32 emc_qsafe;
u32 emc_rdv;
u32 emc_rdv_mask;
u32 emc_rdv_early;
u32 emc_rdv_early_mask;
/* Specifies the value for EMC_QPOP */
u32 emc_qpop;
/* Specifies the value for EMC_REFRESH */
u32 emc_refresh;
/* Specifies the value for EMC_BURST_REFRESH_NUM */
u32 emc_burst_refresh_num;
/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
u32 emc_prerefresh_req_cnt;
/* Specifies the value for EMC_PDEX2WR */
u32 emc_pdex2wr;
/* Specifies the value for EMC_PDEX2RD */
u32 emc_pdex2rd;
/* Specifies the value for EMC_PCHG2PDEN */
u32 emc_pchg2pden;
/* Specifies the value for EMC_ACT2PDEN */
u32 emc_act2pden;
/* Specifies the value for EMC_AR2PDEN */
u32 emc_ar2pden;
/* Specifies the value for EMC_RW2PDEN */
u32 emc_rw2pden;
u32 emc_cke2pden;
u32 emc_pdex2che;
u32 emc_pdex2mrr;
/* Specifies the value for EMC_TXSR */
u32 emc_txsr;
/* Specifies the value for EMC_TXSRDLL */
u32 emc_txsr_dll;
/* Specifies the value for EMC_TCKE */
u32 emc_tcke;
/* Specifies the value for EMC_TCKESR */
u32 emc_tckesr;
/* Specifies the value for EMC_TPD */
u32 emc_tpd;
/* Specifies the value for EMC_TFAW */
u32 emc_tfaw;
/* Specifies the value for EMC_TRPAB */
u32 emc_trpab;
/* Specifies the value for EMC_TCLKSTABLE */
u32 emc_tclkstable;
/* Specifies the value for EMC_TCLKSTOP */
u32 emc_tclkstop;
/* Specifies the value for EMC_TREFBW */
u32 emc_trefbw;
/* FBIO configuration values */
/* Specifies the value for EMC_FBIO_CFG5 */
u32 emc_fbio_cfg5;
/* Specifies the value for EMC_FBIO_CFG7 */
u32 emc_fbio_cfg7;
u32 emc_fbio_cfg8;
/* Command mapping for CMD brick 0 */
u32 emc_cmd_mapping_cmd0_0;
u32 emc_cmd_mapping_cmd0_1;
u32 emc_cmd_mapping_cmd0_2;
u32 emc_cmd_mapping_cmd1_0;
u32 emc_cmd_mapping_cmd1_1;
u32 emc_cmd_mapping_cmd1_2;
u32 emc_cmd_mapping_cmd2_0;
u32 emc_cmd_mapping_cmd2_1;
u32 emc_cmd_mapping_cmd2_2;
u32 emc_cmd_mapping_cmd3_0;
u32 emc_cmd_mapping_cmd3_1;
u32 emc_cmd_mapping_cmd3_2;
u32 emc_cmd_mapping_byte;
/* Specifies the value for EMC_FBIO_SPARE */
u32 emc_fbio_spare;
/* Specifies the value for EMC_CFG_RSV */
u32 emc_cfg_rsv;
/* MRS command values */
/* Specifies the value for EMC_MRS */
u32 emc_mrs;
/* Specifies the MP0 command to initialize mode registers */
u32 emc_emrs;
/* Specifies the MP2 command to initialize mode registers */
u32 emc_emrs2;
/* Specifies the MP3 command to initialize mode registers */
u32 emc_emrs3;
/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
u32 emc_mrw1;
/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
u32 emc_mrw2;
/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
u32 emc_mrw3;
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
u32 emc_mrw4;
/* Specifies the programming to LPDDR4 Mode Register 3 at cold boot */
u32 emc_mrw6;
/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
u32 emc_mrw8;
/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
u32 emc_mrw9;
/* Specifies the programming to LPDDR4 Mode Register 12 at cold boot */
u32 emc_mrw10;
/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
u32 emc_mrw12;
/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
u32 emc_mrw13;
/* Specifies the programming to LPDDR4 Mode Register 22 at cold boot */
u32 emc_mrw14;
/*
* Specifies the programming to extra LPDDR2 Mode Register
* at cold boot
*/
u32 emc_mrw_extra;
/*
* Specifies the programming to extra LPDDR2 Mode Register
* at warm boot
*/
u32 emc_warm_boot_mrw_extra;
/*
* Specify the enable of extra Mode Register programming at
* warm boot
*/
u32 emc_warm_boot_extramode_reg_write_enable;
/*
* Specify the enable of extra Mode Register programming at
* cold boot
*/
u32 emc_extramode_reg_write_enable;
/* Specifies the EMC_MRW reset command value */
u32 emc_mrw_reset_command;
/* Specifies the EMC Reset wait time (in microseconds) */
u32 emc_mrw_reset_ninit_wait;
/* Specifies the value for EMC_MRS_WAIT_CNT */
u32 emc_mrs_wait_cnt;
/* Specifies the value for EMC_MRS_WAIT_CNT2 */
u32 emc_mrs_wait_cnt2;
/* EMC miscellaneous configurations */
/* Specifies the value for EMC_CFG */
u32 emc_cfg;
/* Specifies the value for EMC_CFG_2 */
u32 emc_cfg2;
/* Specifies the pipe bypass controls */
u32 emc_cfg_pipe;
u32 emc_cfg_pipe_clk;
u32 emc_fdpd_ctrl_cmd_no_ramp;
u32 emc_cfg_update;
/* Specifies the value for EMC_DBG */
u32 emc_dbg;
u32 emc_dbg_write_mux;
/* Specifies the value for EMC_CMDQ */
u32 emc_cmd_q;
/* Specifies the value for EMC_MC2EMCQ */
u32 emc_mc2emc_q;
/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
u32 emc_dyn_self_ref_control;
/* Specifies the value for MEM_INIT_DONE */
u32 ahb_arbitration_xbar_ctrl_meminit_done;
/* Specifies the value for EMC_CFG_DIG_DLL */
u32 emc_cfg_dig_dll;
u32 emc_cfg_dig_dll_1;
/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
u32 emc_cfg_dig_dll_period;
/* Specifies the value of *DEV_SELECTN of various EMC registers */
u32 emc_dev_select;
/* Specifies the value for EMC_SEL_DPD_CTRL */
u32 emc_sel_dpd_ctrl;
/* Pads trimmer delays */
u32 emc_fdpd_ctrl_dq;
u32 emc_fdpd_ctrl_cmd;
u32 emc_pmacro_ib_vref_dq_0;
u32 emc_pmacro_ib_vref_dq_1;
u32 emc_pmacro_ib_vref_dqs_0;
u32 emc_pmacro_ib_vref_dqs_1;
u32 emc_pmacro_ib_rxrt;
u32 emc_cfg_pipe1;
u32 emc_cfg_pipe2;
/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
u32 emc_pmacro_quse_ddll_rank0_0;
u32 emc_pmacro_quse_ddll_rank0_1;
u32 emc_pmacro_quse_ddll_rank0_2;
u32 emc_pmacro_quse_ddll_rank0_3;
u32 emc_pmacro_quse_ddll_rank0_4;
u32 emc_pmacro_quse_ddll_rank0_5;
u32 emc_pmacro_quse_ddll_rank1_0;
u32 emc_pmacro_quse_ddll_rank1_1;
u32 emc_pmacro_quse_ddll_rank1_2;
u32 emc_pmacro_quse_ddll_rank1_3;
u32 emc_pmacro_quse_ddll_rank1_4;
u32 emc_pmacro_quse_ddll_rank1_5;
u32 emc_pmacro_ob_ddll_long_dq_rank0_0;
u32 emc_pmacro_ob_ddll_long_dq_rank0_1;
u32 emc_pmacro_ob_ddll_long_dq_rank0_2;
u32 emc_pmacro_ob_ddll_long_dq_rank0_3;
u32 emc_pmacro_ob_ddll_long_dq_rank0_4;
u32 emc_pmacro_ob_ddll_long_dq_rank0_5;
u32 emc_pmacro_ob_ddll_long_dq_rank1_0;
u32 emc_pmacro_ob_ddll_long_dq_rank1_1;
u32 emc_pmacro_ob_ddll_long_dq_rank1_2;
u32 emc_pmacro_ob_ddll_long_dq_rank1_3;
u32 emc_pmacro_ob_ddll_long_dq_rank1_4;
u32 emc_pmacro_ob_ddll_long_dq_rank1_5;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_0;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_1;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_2;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_3;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_4;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_5;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_0;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_1;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_2;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_3;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_4;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_5;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_0;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_1;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_2;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_3;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_0;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_1;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_2;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_3;
u32 emc_pmacro_ddll_long_cmd_0;
u32 emc_pmacro_ddll_long_cmd_1;
u32 emc_pmacro_ddll_long_cmd_2;
u32 emc_pmacro_ddll_long_cmd_3;
u32 emc_pmacro_ddll_long_cmd_4;
u32 emc_pmacro_ddll_short_cmd_0;
u32 emc_pmacro_ddll_short_cmd_1;
u32 emc_pmacro_ddll_short_cmd_2;
/*
* Specifies the delay after asserting CKE pin during a WarmBoot0
* sequence (in microseconds)
*/
u32 warm_boot_wait;
/* Specifies the value for EMC_ODT_WRITE */
u32 emc_odt_write;
/* Periodic ZQ calibration */
/*
* Specifies the value for EMC_ZCAL_INTERVAL
* Value 0 disables ZQ calibration
*/
u32 emc_zcal_interval;
/* Specifies the value for EMC_ZCAL_WAIT_CNT */
u32 emc_zcal_wait_cnt;
/* Specifies the value for EMC_ZCAL_MRW_CMD */
u32 emc_zcal_mrw_cmd;
/* DRAM initialization sequence flow control */
/* Specifies the MRS command value for resetting DLL */
u32 emc_mrs_reset_dll;
/* Specifies the command for ZQ initialization of device 0 */
u32 emc_zcal_init_dev0;
/* Specifies the command for ZQ initialization of device 1 */
u32 emc_zcal_init_dev1;
/*
* Specifies the wait time after programming a ZQ initialization
* command (in microseconds)
*/
u32 emc_zcal_init_wait;
/*
* Specifies the enable for ZQ calibration at cold boot [bit 0]
* and warm boot [bit 1]
*/
u32 emc_zcal_warm_cold_boot_enables;
/*
* Specifies the MRW command to LPDDR2 for ZQ calibration
* on warmboot
*/
/* Is issued to both devices separately */
u32 emc_mrw_lpddr2zcal_warm_boot;
/*
* Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
* Is issued to both devices separately
*/
u32 emc_zqcal_ddr3_warm_boot;
u32 emc_zqcal_lpddr4_warm_boot;
/*
* Specifies the wait time for ZQ calibration on warmboot
* (in microseconds)
*/
u32 emc_zcal_warm_boot_wait;
/*
* Specifies the enable for DRAM Mode Register programming
* at warm boot
*/
u32 emc_mrs_warm_boot_enable;
/*
* Specifies the wait time after sending an MRS DLL reset command
* in microseconds)
*/
u32 emc_mrs_reset_dll_wait;
/* Specifies the extra MRS command to initialize mode registers */
u32 emc_mrs_extra;
/* Specifies the extra MRS command at warm boot */
u32 emc_warm_boot_mrs_extra;
/* Specifies the EMRS command to enable the DDR2 DLL */
u32 emc_emrs_ddr2_dll_enable;
/* Specifies the MRS command to reset the DDR2 DLL */
u32 emc_mrs_ddr2_dll_reset;
/* Specifies the EMRS command to set OCD calibration */
u32 emc_emrs_ddr2_ocd_calib;
/*
* Specifies the wait between initializing DDR and setting OCD
* calibration (in microseconds)
*/
u32 emc_ddr2_wait;
/* Specifies the value for EMC_CLKEN_OVERRIDE */
u32 emc_clken_override;
/*
* Specifies LOG2 of the extra refresh numbers after booting
* Program 0 to disable
*/
u32 emc_extra_refresh_num;
/* Specifies the master override for all EMC clocks */
u32 emc_clken_override_allwarm_boot;
/* Specifies the master override for all MC clocks */
u32 mc_clken_override_allwarm_boot;
/* Specifies digital dll period, choosing between 4 to 64 ms */
u32 emc_cfg_dig_dll_period_warm_boot;
/* Pad controls */
/* Specifies the value for PMC_VDDP_SEL */
u32 pmc_vddp_sel;
/* Specifies the wait time after programming PMC_VDDP_SEL */
u32 pmc_vddp_sel_wait;
/* Specifies the value for PMC_DDR_PWR */
u32 pmc_ddr_pwr;
/* Specifies the value for PMC_DDR_CFG */
u32 pmc_ddr_cfg;
/* Specifies the value for PMC_IO_DPD3_REQ */
u32 pmc_io_dpd3_req;
/* Specifies the wait time after programming PMC_IO_DPD3_REQ */
u32 pmc_io_dpd3_req_wait;
u32 pmc_io_dpd4_req_wait;
/* Specifies the value for PMC_REG_SHORT */
u32 pmc_reg_short;
/* Specifies the value for PMC_NO_IOPOWER */
u32 pmc_no_io_power;
u32 pmc_ddr_ctrl_wait;
u32 pmc_ddr_ctrl;
/* Specifies the value for EMC_ACPD_CONTROL */
u32 emc_acpd_control;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
u32 emc_swizzle_rank0_byte0;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
u32 emc_swizzle_rank0_byte1;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
u32 emc_swizzle_rank0_byte2;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
u32 emc_swizzle_rank0_byte3;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
u32 emc_swizzle_rank1_byte0;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
u32 emc_swizzle_rank1_byte1;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
u32 emc_swizzle_rank1_byte2;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
u32 emc_swizzle_rank1_byte3;
/* Specifies the value for EMC_TXDSRVTTGEN */
u32 emc_txdsrvttgen;
/* Specifies the value for EMC_DATA_BRLSHFT_0 */
u32 emc_data_brlshft0;
u32 emc_data_brlshft1;
u32 emc_dqs_brlshft0;
u32 emc_dqs_brlshft1;
u32 emc_cmd_brlshft0;
u32 emc_cmd_brlshft1;
u32 emc_cmd_brlshft2;
u32 emc_cmd_brlshft3;
u32 emc_quse_brlshft0;
u32 emc_quse_brlshft1;
u32 emc_quse_brlshft2;
u32 emc_quse_brlshft3;
u32 emc_dll_cfg0;
u32 emc_dll_cfg1;
u32 emc_pmc_scratch1;
u32 emc_pmc_scratch2;
u32 emc_pmc_scratch3;
u32 emc_pmacro_pad_cfg_ctrl;
u32 emc_pmacro_vttgen_ctrl0;
u32 emc_pmacro_vttgen_ctrl1;
u32 emc_pmacro_vttgen_ctrl2;
u32 emc_pmacro_brick_ctrl_rfu1;
u32 emc_pmacro_cmd_brick_ctrl_fdpd;
u32 emc_pmacro_brick_ctrl_rfu2;
u32 emc_pmacro_data_brick_ctrl_fdpd;
u32 emc_pmacro_bg_bias_ctrl0;
u32 emc_pmacro_data_pad_rx_ctrl;
u32 emc_pmacro_cmd_pad_rx_ctrl;
u32 emc_pmacro_data_rx_term_mode;
u32 emc_pmacro_cmd_rx_term_mode;
u32 emc_pmacro_data_pad_tx_ctrl;
u32 emc_pmacro_common_pad_tx_ctrl;
u32 emc_pmacro_cmd_pad_tx_ctrl;
u32 emc_cfg3;
u32 emc_pmacro_tx_pwrd0;
u32 emc_pmacro_tx_pwrd1;
u32 emc_pmacro_tx_pwrd2;
u32 emc_pmacro_tx_pwrd3;
u32 emc_pmacro_tx_pwrd4;
u32 emc_pmacro_tx_pwrd5;
u32 emc_config_sample_delay;
u32 emc_pmacro_brick_mapping0;
u32 emc_pmacro_brick_mapping1;
u32 emc_pmacro_brick_mapping2;
u32 emc_pmacro_tx_sel_clk_src0;
u32 emc_pmacro_tx_sel_clk_src1;
u32 emc_pmacro_tx_sel_clk_src2;
u32 emc_pmacro_tx_sel_clk_src3;
u32 emc_pmacro_tx_sel_clk_src4;
u32 emc_pmacro_tx_sel_clk_src5;
u32 emc_pmacro_ddll_bypass;
u32 emc_pmacro_ddll_pwrd0;
u32 emc_pmacro_ddll_pwrd1;
u32 emc_pmacro_ddll_pwrd2;
u32 emc_pmacro_cmd_ctrl0;
u32 emc_pmacro_cmd_ctrl1;
u32 emc_pmacro_cmd_ctrl2;
/* DRAM size information */
/* Specifies the value for MC_EMEM_ADR_CFG */
u32 mc_emem_adr_cfg;
/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
u32 mc_emem_adr_cfg_dev0;
/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
u32 mc_emem_adr_cfg_dev1;
u32 mc_emem_adr_cfg_channel_mask;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG0 */
u32 mc_emem_adr_cfg_bank_mask0;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
u32 mc_emem_adr_cfg_bank_mask1;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
u32 mc_emem_adr_cfg_bank_mask2;
/*
* Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes)
*/
u32 mc_emem_cfg;
/* MC arbitration configuration */
/* Specifies the value for MC_EMEM_ARB_CFG */
u32 mc_emem_arb_cfg;
/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
u32 mc_emem_arb_outstanding_req;
u32 emc_emem_arb_refpb_hp_ctrl;
u32 emc_emem_arb_refpb_bank_ctrl;
/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
u32 mc_emem_arb_timing_rcd;
/* Specifies the value for MC_EMEM_ARB_TIMING_RP */
u32 mc_emem_arb_timing_rp;
/* Specifies the value for MC_EMEM_ARB_TIMING_RC */
u32 mc_emem_arb_timing_rc;
/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
u32 mc_emem_arb_timing_ras;
/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
u32 mc_emem_arb_timing_faw;
/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
u32 mc_emem_arb_timing_rrd;
/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
u32 mc_emem_arb_timing_rap2pre;
/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
u32 mc_emem_arb_timing_wap2pre;
/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
u32 mc_emem_arb_timing_r2r;
/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
u32 mc_emem_arb_timing_w2w;
/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
u32 mc_emem_arb_timing_r2w;
/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
u32 mc_emem_arb_timing_w2r;
u32 mc_emem_arb_timing_rfcpb;
/* Specifies the value for MC_EMEM_ARB_DA_TURNS */
u32 mc_emem_arb_da_turns;
/* Specifies the value for MC_EMEM_ARB_DA_COVERS */
u32 mc_emem_arb_da_covers;
/* Specifies the value for MC_EMEM_ARB_MISC0 */
u32 mc_emem_arb_misc0;
/* Specifies the value for MC_EMEM_ARB_MISC1 */
u32 mc_emem_arb_misc1;
u32 mc_emem_arb_misc2;
/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
u32 mc_emem_arb_ring1_throttle;
/* Specifies the value for MC_EMEM_ARB_OVERRIDE */
u32 mc_emem_arb_override;
/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
u32 mc_emem_arb_override1;
/* Specifies the value for MC_EMEM_ARB_RSV */
u32 mc_emem_arb_rsv;
u32 mc_da_cfg0;
u32 mc_emem_arb_timing_ccdmw;
/* Specifies the value for MC_CLKEN_OVERRIDE */
u32 mc_clken_override;
/* Specifies the value for MC_STAT_CONTROL */
u32 mc_stat_control;
/* Specifies the value for MC_VIDEO_PROTECT_BOM */
u32 mc_video_protect_bom;
/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
u32 mc_video_protect_bom_adr_hi;
/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
u32 mc_video_protect_size_mb;
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
u32 mc_video_protect_vpr_override;
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
u32 mc_video_protect_vpr_override1;
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
u32 mc_video_protect_gpu_override0;
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
u32 mc_video_protect_gpu_override1;
/* Specifies the value for MC_SEC_CARVEOUT_BOM */
u32 mc_sec_carveout_bom;
/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
u32 mc_sec_carveout_adr_hi;
/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
u32 mc_sec_carveout_size_mb;
/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.VIDEO_PROTECT_WRITE_ACCESS */
u32 mc_video_protect_write_access;
/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.SEC_CARVEOUT_WRITE_ACCESS */
u32 mc_sec_carveout_protect_write_access;
u32 mc_generalized_carveout1_bom;
u32 mc_generalized_carveout1_bom_hi;
u32 mc_generalized_carveout1_size_128kb;
u32 mc_generalized_carveout1_access0;
u32 mc_generalized_carveout1_access1;
u32 mc_generalized_carveout1_access2;
u32 mc_generalized_carveout1_access3;
u32 mc_generalized_carveout1_access4;
u32 mc_generalized_carveout1_force_internal_access0;
u32 mc_generalized_carveout1_force_internal_access1;
u32 mc_generalized_carveout1_force_internal_access2;
u32 mc_generalized_carveout1_force_internal_access3;
u32 mc_generalized_carveout1_force_internal_access4;
u32 mc_generalized_carveout1_cfg0;
u32 mc_generalized_carveout2_bom;
u32 mc_generalized_carveout2_bom_hi;
u32 mc_generalized_carveout2_size_128kb;
u32 mc_generalized_carveout2_access0;
u32 mc_generalized_carveout2_access1;
u32 mc_generalized_carveout2_access2;
u32 mc_generalized_carveout2_access3;
u32 mc_generalized_carveout2_access4;
u32 mc_generalized_carveout2_force_internal_access0;
u32 mc_generalized_carveout2_force_internal_access1;
u32 mc_generalized_carveout2_force_internal_access2;
u32 mc_generalized_carveout2_force_internal_access3;
u32 mc_generalized_carveout2_force_internal_access4;
u32 mc_generalized_carveout2_cfg0;
u32 mc_generalized_carveout3_bom;
u32 mc_generalized_carveout3_bom_hi;
u32 mc_generalized_carveout3_size_128kb;
u32 mc_generalized_carveout3_access0;
u32 mc_generalized_carveout3_access1;
u32 mc_generalized_carveout3_access2;
u32 mc_generalized_carveout3_access3;
u32 mc_generalized_carveout3_access4;
u32 mc_generalized_carveout3_force_internal_access0;
u32 mc_generalized_carveout3_force_internal_access1;
u32 mc_generalized_carveout3_force_internal_access2;
u32 mc_generalized_carveout3_force_internal_access3;
u32 mc_generalized_carveout3_force_internal_access4;
u32 mc_generalized_carveout3_cfg0;
u32 mc_generalized_carveout4_bom;
u32 mc_generalized_carveout4_bom_hi;
u32 mc_generalized_carveout4_size_128kb;
u32 mc_generalized_carveout4_access0;
u32 mc_generalized_carveout4_access1;
u32 mc_generalized_carveout4_access2;
u32 mc_generalized_carveout4_access3;
u32 mc_generalized_carveout4_access4;
u32 mc_generalized_carveout4_force_internal_access0;
u32 mc_generalized_carveout4_force_internal_access1;
u32 mc_generalized_carveout4_force_internal_access2;
u32 mc_generalized_carveout4_force_internal_access3;
u32 mc_generalized_carveout4_force_internal_access4;
u32 mc_generalized_carveout4_cfg0;
u32 mc_generalized_carveout5_bom;
u32 mc_generalized_carveout5_bom_hi;
u32 mc_generalized_carveout5_size_128kb;
u32 mc_generalized_carveout5_access0;
u32 mc_generalized_carveout5_access1;
u32 mc_generalized_carveout5_access2;
u32 mc_generalized_carveout5_access3;
u32 mc_generalized_carveout5_access4;
u32 mc_generalized_carveout5_force_internal_access0;
u32 mc_generalized_carveout5_force_internal_access1;
u32 mc_generalized_carveout5_force_internal_access2;
u32 mc_generalized_carveout5_force_internal_access3;
u32 mc_generalized_carveout5_force_internal_access4;
u32 mc_generalized_carveout5_cfg0;
/* Specifies enable for CA training */
u32 emc_ca_training_enable;
/* Set if bit 6 select is greater than bit 7 select; uses aremc.spec packet SWIZZLE_BIT6_GT_BIT7 */
u32 swizzle_rank_byte_encode;
/* Specifies enable and offset for patched boot rom write */
u32 boot_rom_patch_control;
/* Specifies data for patched boot rom write */
u32 boot_rom_patch_data;
/* Specifies the value for MC_MTS_CARVEOUT_BOM */
u32 mc_mts_carveout_bom;
/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
u32 mc_mts_carveout_adr_hi;
/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
u32 mc_mts_carveout_size_mb;
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
u32 mc_mts_carveout_reg_ctrl;
} sdram_params_t;
#endif

961
ipl/sdram_param_t210_lp0.h Executable file
View File

@ -0,0 +1,961 @@
/*
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
* Copyright 2014 Google Inc.
*
* 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.
*/
/**
* Defines the SDRAM parameter structure.
*
* Note that PLLM is used by EMC. The field names are in camel case to ease
* directly converting BCT config files (*.cfg) into C structure.
*/
#ifndef __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__
#define __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__
#include "types.h"
enum {
/* Specifies the memory type to be undefined */
NvBootMemoryType_None = 0,
/* Specifies the memory type to be DDR SDRAM */
NvBootMemoryType_Ddr = 0,
/* Specifies the memory type to be LPDDR SDRAM */
NvBootMemoryType_LpDdr = 0,
/* Specifies the memory type to be DDR2 SDRAM */
NvBootMemoryType_Ddr2 = 0,
/* Specifies the memory type to be LPDDR2 SDRAM */
NvBootMemoryType_LpDdr2,
/* Specifies the memory type to be DDR3 SDRAM */
NvBootMemoryType_Ddr3,
/* Specifies the memory type to be LPDDR4 SDRAM */
NvBootMemoryType_LpDdr4,
NvBootMemoryType_Num,
/* Specifies an entry in the ram_code table that's not in use */
NvBootMemoryType_Unused = 0X7FFFFFF,
};
/**
* Defines the SDRAM parameter structure
*/
struct sdram_params {
/* Specifies the type of memory device */
u32 MemoryType;
/* MC/EMC clock source configuration */
/* Specifies the M value for PllM */
u32 PllMInputDivider;
/* Specifies the N value for PllM */
u32 PllMFeedbackDivider;
/* Specifies the time to wait for PLLM to lock (in microseconds) */
u32 PllMStableTime;
/* Specifies misc. control bits */
u32 PllMSetupControl;
/* Specifies the P value for PLLM */
u32 PllMPostDivider;
/* Specifies value for Charge Pump Gain Control */
u32 PllMKCP;
/* Specifies VCO gain */
u32 PllMKVCO;
/* Spare BCT param */
u32 EmcBctSpare0;
/* Spare BCT param */
u32 EmcBctSpare1;
/* Spare BCT param */
u32 EmcBctSpare2;
/* Spare BCT param */
u32 EmcBctSpare3;
/* Spare BCT param */
u32 EmcBctSpare4;
/* Spare BCT param */
u32 EmcBctSpare5;
/* Spare BCT param */
u32 EmcBctSpare6;
/* Spare BCT param */
u32 EmcBctSpare7;
/* Spare BCT param */
u32 EmcBctSpare8;
/* Spare BCT param */
u32 EmcBctSpare9;
/* Spare BCT param */
u32 EmcBctSpare10;
/* Spare BCT param */
u32 EmcBctSpare11;
/* Spare BCT param */
u32 EmcBctSpare12;
/* Spare BCT param */
u32 EmcBctSpare13;
/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
u32 EmcClockSource;
u32 EmcClockSourceDll;
/* Defines possible override for PLLLM_MISC2 */
u32 ClkRstControllerPllmMisc2Override;
/* enables override for PLLLM_MISC2 */
u32 ClkRstControllerPllmMisc2OverrideEnable;
/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
u32 ClearClk2Mc1;
/* Auto-calibration of EMC pads */
/* Specifies the value for EMC_AUTO_CAL_INTERVAL */
u32 EmcAutoCalInterval;
/*
* Specifies the value for EMC_AUTO_CAL_CONFIG
* Note: Trigger bits are set by the SDRAM code.
*/
u32 EmcAutoCalConfig;
/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
u32 EmcAutoCalConfig2;
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
u32 EmcAutoCalConfig3;
/* Specifies the values for EMC_AUTO_CAL_CONFIG4-8 */
u32 EmcAutoCalConfig4;
u32 EmcAutoCalConfig5;
u32 EmcAutoCalConfig6;
u32 EmcAutoCalConfig7;
u32 EmcAutoCalConfig8;
/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
u32 EmcAutoCalVrefSel0;
u32 EmcAutoCalVrefSel1;
/* Specifies the value for EMC_AUTO_CAL_CHANNEL */
u32 EmcAutoCalChannel;
/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
u32 EmcPmacroAutocalCfg0;
u32 EmcPmacroAutocalCfg1;
u32 EmcPmacroAutocalCfg2;
u32 EmcPmacroRxTerm;
u32 EmcPmacroDqTxDrv;
u32 EmcPmacroCaTxDrv;
u32 EmcPmacroCmdTxDrv;
u32 EmcPmacroAutocalCfgCommon;
u32 EmcPmacroZctrl;
/*
* Specifies the time for the calibration
* to stabilize (in microseconds)
*/
u32 EmcAutoCalWait;
u32 EmcXm2CompPadCtrl;
u32 EmcXm2CompPadCtrl2;
u32 EmcXm2CompPadCtrl3;
/*
* DRAM size information
* Specifies the value for EMC_ADR_CFG
*/
u32 EmcAdrCfg;
/*
* Specifies the time to wait after asserting pin
* CKE (in microseconds)
*/
u32 EmcPinProgramWait;
/* Specifies the extra delay before/after pin RESET/CKE command */
u32 EmcPinExtraWait;
u32 EmcPinGpioEn;
u32 EmcPinGpio;
/*
* Specifies the extra delay after the first writing
* of EMC_TIMING_CONTROL
*/
u32 EmcTimingControlWait;
/* Timing parameters required for the SDRAM */
/* Specifies the value for EMC_RC */
u32 EmcRc;
/* Specifies the value for EMC_RFC */
u32 EmcRfc;
/* Specifies the value for EMC_RFC_PB */
u32 EmcRfcPb;
/* Specifies the value for EMC_RFC_CTRL2 */
u32 EmcRefctrl2;
/* Specifies the value for EMC_RFC_SLR */
u32 EmcRfcSlr;
/* Specifies the value for EMC_RAS */
u32 EmcRas;
/* Specifies the value for EMC_RP */
u32 EmcRp;
/* Specifies the value for EMC_R2R */
u32 EmcR2r;
/* Specifies the value for EMC_W2W */
u32 EmcW2w;
/* Specifies the value for EMC_R2W */
u32 EmcR2w;
/* Specifies the value for EMC_W2R */
u32 EmcW2r;
/* Specifies the value for EMC_R2P */
u32 EmcR2p;
/* Specifies the value for EMC_W2P */
u32 EmcW2p;
u32 EmcTppd;
u32 EmcCcdmw;
/* Specifies the value for EMC_RD_RCD */
u32 EmcRdRcd;
/* Specifies the value for EMC_WR_RCD */
u32 EmcWrRcd;
/* Specifies the value for EMC_RRD */
u32 EmcRrd;
/* Specifies the value for EMC_REXT */
u32 EmcRext;
/* Specifies the value for EMC_WEXT */
u32 EmcWext;
/* Specifies the value for EMC_WDV */
u32 EmcWdv;
u32 EmcWdvChk;
u32 EmcWsv;
u32 EmcWev;
/* Specifies the value for EMC_WDV_MASK */
u32 EmcWdvMask;
u32 EmcWsDuration;
u32 EmcWeDuration;
/* Specifies the value for EMC_QUSE */
u32 EmcQUse;
/* Specifies the value for EMC_QUSE_WIDTH */
u32 EmcQuseWidth;
/* Specifies the value for EMC_IBDLY */
u32 EmcIbdly;
/* Specifies the value for EMC_OBDLY */
u32 EmcObdly;
/* Specifies the value for EMC_EINPUT */
u32 EmcEInput;
/* Specifies the value for EMC_EINPUT_DURATION */
u32 EmcEInputDuration;
/* Specifies the value for EMC_PUTERM_EXTRA */
u32 EmcPutermExtra;
/* Specifies the value for EMC_PUTERM_WIDTH */
u32 EmcPutermWidth;
/* Specifies the value for EMC_PUTERM_ADJ */
u32 EmcPutermAdj;
/* Specifies the value for EMC_QRST */
u32 EmcQRst;
/* Specifies the value for EMC_QSAFE */
u32 EmcQSafe;
/* Specifies the value for EMC_RDV */
u32 EmcRdv;
/* Specifies the value for EMC_RDV_MASK */
u32 EmcRdvMask;
/* Specifies the value for EMC_RDV_EARLY */
u32 EmcRdvEarly;
/* Specifies the value for EMC_RDV_EARLY_MASK */
u32 EmcRdvEarlyMask;
/* Specifies the value for EMC_QPOP */
u32 EmcQpop;
/* Specifies the value for EMC_REFRESH */
u32 EmcRefresh;
/* Specifies the value for EMC_BURST_REFRESH_NUM */
u32 EmcBurstRefreshNum;
/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
u32 EmcPreRefreshReqCnt;
/* Specifies the value for EMC_PDEX2WR */
u32 EmcPdEx2Wr;
/* Specifies the value for EMC_PDEX2RD */
u32 EmcPdEx2Rd;
/* Specifies the value for EMC_PCHG2PDEN */
u32 EmcPChg2Pden;
/* Specifies the value for EMC_ACT2PDEN */
u32 EmcAct2Pden;
/* Specifies the value for EMC_AR2PDEN */
u32 EmcAr2Pden;
/* Specifies the value for EMC_RW2PDEN */
u32 EmcRw2Pden;
/* Specifies the value for EMC_CKE2PDEN */
u32 EmcCke2Pden;
/* Specifies the value for EMC_PDEX2CKE */
u32 EmcPdex2Cke;
/* Specifies the value for EMC_PDEX2MRR */
u32 EmcPdex2Mrr;
/* Specifies the value for EMC_TXSR */
u32 EmcTxsr;
/* Specifies the value for EMC_TXSRDLL */
u32 EmcTxsrDll;
/* Specifies the value for EMC_TCKE */
u32 EmcTcke;
/* Specifies the value for EMC_TCKESR */
u32 EmcTckesr;
/* Specifies the value for EMC_TPD */
u32 EmcTpd;
/* Specifies the value for EMC_TFAW */
u32 EmcTfaw;
/* Specifies the value for EMC_TRPAB */
u32 EmcTrpab;
/* Specifies the value for EMC_TCLKSTABLE */
u32 EmcTClkStable;
/* Specifies the value for EMC_TCLKSTOP */
u32 EmcTClkStop;
/* Specifies the value for EMC_TREFBW */
u32 EmcTRefBw;
/* FBIO configuration values */
/* Specifies the value for EMC_FBIO_CFG5 */
u32 EmcFbioCfg5;
/* Specifies the value for EMC_FBIO_CFG7 */
u32 EmcFbioCfg7;
/* Specifies the value for EMC_FBIO_CFG8 */
u32 EmcFbioCfg8;
/* Command mapping for CMD brick 0 */
u32 EmcCmdMappingCmd0_0;
u32 EmcCmdMappingCmd0_1;
u32 EmcCmdMappingCmd0_2;
u32 EmcCmdMappingCmd1_0;
u32 EmcCmdMappingCmd1_1;
u32 EmcCmdMappingCmd1_2;
u32 EmcCmdMappingCmd2_0;
u32 EmcCmdMappingCmd2_1;
u32 EmcCmdMappingCmd2_2;
u32 EmcCmdMappingCmd3_0;
u32 EmcCmdMappingCmd3_1;
u32 EmcCmdMappingCmd3_2;
u32 EmcCmdMappingByte;
/* Specifies the value for EMC_FBIO_SPARE */
u32 EmcFbioSpare;
/* Specifies the value for EMC_CFG_RSV */
u32 EmcCfgRsv;
/* MRS command values */
/* Specifies the value for EMC_MRS */
u32 EmcMrs;
/* Specifies the MP0 command to initialize mode registers */
u32 EmcEmrs;
/* Specifies the MP2 command to initialize mode registers */
u32 EmcEmrs2;
/* Specifies the MP3 command to initialize mode registers */
u32 EmcEmrs3;
/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
u32 EmcMrw1;
/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
u32 EmcMrw2;
/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
u32 EmcMrw3;
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
u32 EmcMrw4;
/* Specifies the programming to LPDDR2 Mode Register 3? at cold boot */
u32 EmcMrw6;
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
u32 EmcMrw8;
/* Specifies the programming to LPDDR2 Mode Register 11? at cold boot */
u32 EmcMrw9;
/* Specifies the programming to LPDDR2 Mode Register 12 at cold boot */
u32 EmcMrw10;
/* Specifies the programming to LPDDR2 Mode Register 14 at cold boot */
u32 EmcMrw12;
/* Specifies the programming to LPDDR2 Mode Register 14? at cold boot */
u32 EmcMrw13;
/* Specifies the programming to LPDDR2 Mode Register 22 at cold boot */
u32 EmcMrw14;
/*
* Specifies the programming to extra LPDDR2 Mode Register
* at cold boot
*/
u32 EmcMrwExtra;
/*
* Specifies the programming to extra LPDDR2 Mode Register
* at warm boot
*/
u32 EmcWarmBootMrwExtra;
/*
* Specify the enable of extra Mode Register programming at
* warm boot
*/
u32 EmcWarmBootExtraModeRegWriteEnable;
/*
* Specify the enable of extra Mode Register programming at
* cold boot
*/
u32 EmcExtraModeRegWriteEnable;
/* Specifies the EMC_MRW reset command value */
u32 EmcMrwResetCommand;
/* Specifies the EMC Reset wait time (in microseconds) */
u32 EmcMrwResetNInitWait;
/* Specifies the value for EMC_MRS_WAIT_CNT */
u32 EmcMrsWaitCnt;
/* Specifies the value for EMC_MRS_WAIT_CNT2 */
u32 EmcMrsWaitCnt2;
/* EMC miscellaneous configurations */
/* Specifies the value for EMC_CFG */
u32 EmcCfg;
/* Specifies the value for EMC_CFG_2 */
u32 EmcCfg2;
/* Specifies the pipe bypass controls */
u32 EmcCfgPipe;
u32 EmcCfgPipeClk;
u32 EmcFdpdCtrlCmdNoRamp;
u32 EmcCfgUpdate;
/* Specifies the value for EMC_DBG */
u32 EmcDbg;
u32 EmcDbgWriteMux;
/* Specifies the value for EMC_CMDQ */
u32 EmcCmdQ;
/* Specifies the value for EMC_MC2EMCQ */
u32 EmcMc2EmcQ;
/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
u32 EmcDynSelfRefControl;
/* Specifies the value for MEM_INIT_DONE */
u32 AhbArbitrationXbarCtrlMemInitDone;
/* Specifies the value for EMC_CFG_DIG_DLL */
u32 EmcCfgDigDll;
u32 EmcCfgDigDll_1;
/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
u32 EmcCfgDigDllPeriod;
/* Specifies the value of *DEV_SELECTN of various EMC registers */
u32 EmcDevSelect;
/* Specifies the value for EMC_SEL_DPD_CTRL */
u32 EmcSelDpdCtrl;
/* Pads trimmer delays */
u32 EmcFdpdCtrlDq;
u32 EmcFdpdCtrlCmd;
u32 EmcPmacroIbVrefDq_0;
u32 EmcPmacroIbVrefDq_1;
u32 EmcPmacroIbVrefDqs_0;
u32 EmcPmacroIbVrefDqs_1;
u32 EmcPmacroIbRxrt;
u32 EmcCfgPipe1;
u32 EmcCfgPipe2;
/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
u32 EmcPmacroQuseDdllRank0_0;
u32 EmcPmacroQuseDdllRank0_1;
u32 EmcPmacroQuseDdllRank0_2;
u32 EmcPmacroQuseDdllRank0_3;
u32 EmcPmacroQuseDdllRank0_4;
u32 EmcPmacroQuseDdllRank0_5;
u32 EmcPmacroQuseDdllRank1_0;
u32 EmcPmacroQuseDdllRank1_1;
u32 EmcPmacroQuseDdllRank1_2;
u32 EmcPmacroQuseDdllRank1_3;
u32 EmcPmacroQuseDdllRank1_4;
u32 EmcPmacroQuseDdllRank1_5;
u32 EmcPmacroObDdllLongDqRank0_0;
u32 EmcPmacroObDdllLongDqRank0_1;
u32 EmcPmacroObDdllLongDqRank0_2;
u32 EmcPmacroObDdllLongDqRank0_3;
u32 EmcPmacroObDdllLongDqRank0_4;
u32 EmcPmacroObDdllLongDqRank0_5;
u32 EmcPmacroObDdllLongDqRank1_0;
u32 EmcPmacroObDdllLongDqRank1_1;
u32 EmcPmacroObDdllLongDqRank1_2;
u32 EmcPmacroObDdllLongDqRank1_3;
u32 EmcPmacroObDdllLongDqRank1_4;
u32 EmcPmacroObDdllLongDqRank1_5;
u32 EmcPmacroObDdllLongDqsRank0_0;
u32 EmcPmacroObDdllLongDqsRank0_1;
u32 EmcPmacroObDdllLongDqsRank0_2;
u32 EmcPmacroObDdllLongDqsRank0_3;
u32 EmcPmacroObDdllLongDqsRank0_4;
u32 EmcPmacroObDdllLongDqsRank0_5;
u32 EmcPmacroObDdllLongDqsRank1_0;
u32 EmcPmacroObDdllLongDqsRank1_1;
u32 EmcPmacroObDdllLongDqsRank1_2;
u32 EmcPmacroObDdllLongDqsRank1_3;
u32 EmcPmacroObDdllLongDqsRank1_4;
u32 EmcPmacroObDdllLongDqsRank1_5;
u32 EmcPmacroIbDdllLongDqsRank0_0;
u32 EmcPmacroIbDdllLongDqsRank0_1;
u32 EmcPmacroIbDdllLongDqsRank0_2;
u32 EmcPmacroIbDdllLongDqsRank0_3;
u32 EmcPmacroIbDdllLongDqsRank1_0;
u32 EmcPmacroIbDdllLongDqsRank1_1;
u32 EmcPmacroIbDdllLongDqsRank1_2;
u32 EmcPmacroIbDdllLongDqsRank1_3;
u32 EmcPmacroDdllLongCmd_0;
u32 EmcPmacroDdllLongCmd_1;
u32 EmcPmacroDdllLongCmd_2;
u32 EmcPmacroDdllLongCmd_3;
u32 EmcPmacroDdllLongCmd_4;
u32 EmcPmacroDdllShortCmd_0;
u32 EmcPmacroDdllShortCmd_1;
u32 EmcPmacroDdllShortCmd_2;
/*
* Specifies the delay after asserting CKE pin during a WarmBoot0
* sequence (in microseconds)
*/
u32 WarmBootWait;
/* Specifies the value for EMC_ODT_WRITE */
u32 EmcOdtWrite;
/* Periodic ZQ calibration */
/*
* Specifies the value for EMC_ZCAL_INTERVAL
* Value 0 disables ZQ calibration
*/
u32 EmcZcalInterval;
/* Specifies the value for EMC_ZCAL_WAIT_CNT */
u32 EmcZcalWaitCnt;
/* Specifies the value for EMC_ZCAL_MRW_CMD */
u32 EmcZcalMrwCmd;
/* DRAM initialization sequence flow control */
/* Specifies the MRS command value for resetting DLL */
u32 EmcMrsResetDll;
/* Specifies the command for ZQ initialization of device 0 */
u32 EmcZcalInitDev0;
/* Specifies the command for ZQ initialization of device 1 */
u32 EmcZcalInitDev1;
/*
* Specifies the wait time after programming a ZQ initialization
* command (in microseconds)
*/
u32 EmcZcalInitWait;
/*
* Specifies the enable for ZQ calibration at cold boot [bit 0]
* and warm boot [bit 1]
*/
u32 EmcZcalWarmColdBootEnables;
/*
* Specifies the MRW command to LPDDR2 for ZQ calibration
* on warmboot
*/
/* Is issued to both devices separately */
u32 EmcMrwLpddr2ZcalWarmBoot;
/*
* Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
* Is issued to both devices separately
*/
u32 EmcZqCalDdr3WarmBoot;
u32 EmcZqCalLpDdr4WarmBoot;
/*
* Specifies the wait time for ZQ calibration on warmboot
* (in microseconds)
*/
u32 EmcZcalWarmBootWait;
/*
* Specifies the enable for DRAM Mode Register programming
* at warm boot
*/
u32 EmcMrsWarmBootEnable;
/*
* Specifies the wait time after sending an MRS DLL reset command
* in microseconds)
*/
u32 EmcMrsResetDllWait;
/* Specifies the extra MRS command to initialize mode registers */
u32 EmcMrsExtra;
/* Specifies the extra MRS command at warm boot */
u32 EmcWarmBootMrsExtra;
/* Specifies the EMRS command to enable the DDR2 DLL */
u32 EmcEmrsDdr2DllEnable;
/* Specifies the MRS command to reset the DDR2 DLL */
u32 EmcMrsDdr2DllReset;
/* Specifies the EMRS command to set OCD calibration */
u32 EmcEmrsDdr2OcdCalib;
/*
* Specifies the wait between initializing DDR and setting OCD
* calibration (in microseconds)
*/
u32 EmcDdr2Wait;
/* Specifies the value for EMC_CLKEN_OVERRIDE */
u32 EmcClkenOverride;
/*
* Specifies LOG2 of the extra refresh numbers after booting
* Program 0 to disable
*/
u32 EmcExtraRefreshNum;
/* Specifies the master override for all EMC clocks */
u32 EmcClkenOverrideAllWarmBoot;
/* Specifies the master override for all MC clocks */
u32 McClkenOverrideAllWarmBoot;
/* Specifies digital dll period, choosing between 4 to 64 ms */
u32 EmcCfgDigDllPeriodWarmBoot;
/* Pad controls */
/* Specifies the value for PMC_VDDP_SEL */
u32 PmcVddpSel;
/* Specifies the wait time after programming PMC_VDDP_SEL */
u32 PmcVddpSelWait;
/* Specifies the value for PMC_DDR_PWR */
u32 PmcDdrPwr;
/* Specifies the value for PMC_DDR_CFG */
u32 PmcDdrCfg;
/* Specifies the value for PMC_IO_DPD3_REQ */
u32 PmcIoDpd3Req;
/* Specifies the wait time after programming PMC_IO_DPD3_REQ */
u32 PmcIoDpd3ReqWait;
u32 PmcIoDpd4ReqWait;
/* Specifies the value for PMC_REG_SHORT */
u32 PmcRegShort;
/* Specifies the value for PMC_NO_IOPOWER */
u32 PmcNoIoPower;
u32 PmcDdrCntrlWait;
u32 PmcDdrCntrl;
/* Specifies the value for EMC_ACPD_CONTROL */
u32 EmcAcpdControl;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE_CFG */
u32 EmcSwizzleRank0ByteCfg;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
u32 EmcSwizzleRank0Byte0;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
u32 EmcSwizzleRank0Byte1;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
u32 EmcSwizzleRank0Byte2;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
u32 EmcSwizzleRank0Byte3;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE_CFG */
u32 EmcSwizzleRank1ByteCfg;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
u32 EmcSwizzleRank1Byte0;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
u32 EmcSwizzleRank1Byte1;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
u32 EmcSwizzleRank1Byte2;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
u32 EmcSwizzleRank1Byte3;
/* Specifies the value for EMC_TXDSRVTTGEN */
u32 EmcTxdsrvttgen;
/* Specifies the value for EMC_DATA_BRLSHFT_0 */
u32 EmcDataBrlshft0;
u32 EmcDataBrlshft1;
u32 EmcDqsBrlshft0;
u32 EmcDqsBrlshft1;
u32 EmcCmdBrlshft0;
u32 EmcCmdBrlshft1;
u32 EmcCmdBrlshft2;
u32 EmcCmdBrlshft3;
u32 EmcQuseBrlshft0;
u32 EmcQuseBrlshft1;
u32 EmcQuseBrlshft2;
u32 EmcQuseBrlshft3;
u32 EmcDllCfg0;
u32 EmcDllCfg1;
u32 EmcPmcScratch1;
u32 EmcPmcScratch2;
u32 EmcPmcScratch3;
u32 EmcPmacroPadCfgCtrl;
u32 EmcPmacroVttgenCtrl0;
u32 EmcPmacroVttgenCtrl1;
u32 EmcPmacroVttgenCtrl2;
u32 EmcPmacroBrickCtrlRfu1;
u32 EmcPmacroCmdBrickCtrlFdpd;
u32 EmcPmacroBrickCtrlRfu2;
u32 EmcPmacroDataBrickCtrlFdpd;
u32 EmcPmacroBgBiasCtrl0;
u32 EmcPmacroDataPadRxCtrl;
u32 EmcPmacroCmdPadRxCtrl;
u32 EmcPmacroDataRxTermMode;
u32 EmcPmacroCmdRxTermMode;
u32 EmcPmacroDataPadTxCtrl;
u32 EmcPmacroCommonPadTxCtrl;
u32 EmcPmacroCmdPadTxCtrl;
u32 EmcCfg3;
u32 EmcPmacroTxPwrd0;
u32 EmcPmacroTxPwrd1;
u32 EmcPmacroTxPwrd2;
u32 EmcPmacroTxPwrd3;
u32 EmcPmacroTxPwrd4;
u32 EmcPmacroTxPwrd5;
u32 EmcConfigSampleDelay;
u32 EmcPmacroBrickMapping0;
u32 EmcPmacroBrickMapping1;
u32 EmcPmacroBrickMapping2;
u32 EmcPmacroTxSelClkSrc0;
u32 EmcPmacroTxSelClkSrc1;
u32 EmcPmacroTxSelClkSrc2;
u32 EmcPmacroTxSelClkSrc3;
u32 EmcPmacroTxSelClkSrc4;
u32 EmcPmacroTxSelClkSrc5;
u32 EmcPmacroDdllBypass;
u32 EmcPmacroDdllPwrd0;
u32 EmcPmacroDdllPwrd1;
u32 EmcPmacroDdllPwrd2;
u32 EmcPmacroCmdCtrl0;
u32 EmcPmacroCmdCtrl1;
u32 EmcPmacroCmdCtrl2;
/* DRAM size information */
/* Specifies the value for MC_EMEM_ADR_CFG */
u32 McEmemAdrCfg;
/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
u32 McEmemAdrCfgDev0;
/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
u32 McEmemAdrCfgDev1;
u32 McEmemAdrCfgChannelMask;
/* Specifies the value for MC_EMEM_BANK_SWIZZLECfg0 */
u32 McEmemAdrCfgBankMask0;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
u32 McEmemAdrCfgBankMask1;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
u32 McEmemAdrCfgBankMask2;
/*
* Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes)
*/
u32 McEmemCfg;
/* MC arbitration configuration */
/* Specifies the value for MC_EMEM_ARB_CFG */
u32 McEmemArbCfg;
/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
u32 McEmemArbOutstandingReq;
u32 McEmemArbRefpbHpCtrl;
u32 McEmemArbRefpbBankCtrl;
/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
u32 McEmemArbTimingRcd;
/* Specifies the value for MC_EMEM_ARB_TIMING_RP */
u32 McEmemArbTimingRp;
/* Specifies the value for MC_EMEM_ARB_TIMING_RC */
u32 McEmemArbTimingRc;
/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
u32 McEmemArbTimingRas;
/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
u32 McEmemArbTimingFaw;
/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
u32 McEmemArbTimingRrd;
/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
u32 McEmemArbTimingRap2Pre;
/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
u32 McEmemArbTimingWap2Pre;
/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
u32 McEmemArbTimingR2R;
/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
u32 McEmemArbTimingW2W;
/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
u32 McEmemArbTimingR2W;
/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
u32 McEmemArbTimingW2R;
u32 McEmemArbTimingRFCPB;
/* Specifies the value for MC_EMEM_ARB_DA_TURNS */
u32 McEmemArbDaTurns;
/* Specifies the value for MC_EMEM_ARB_DA_COVERS */
u32 McEmemArbDaCovers;
/* Specifies the value for MC_EMEM_ARB_MISC0 */
u32 McEmemArbMisc0;
/* Specifies the value for MC_EMEM_ARB_MISC1 */
u32 McEmemArbMisc1;
u32 McEmemArbMisc2;
/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
u32 McEmemArbRing1Throttle;
/* Specifies the value for MC_EMEM_ARB_OVERRIDE */
u32 McEmemArbOverride;
/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
u32 McEmemArbOverride1;
/* Specifies the value for MC_EMEM_ARB_RSV */
u32 McEmemArbRsv;
u32 McDaCfg0;
u32 McEmemArbTimingCcdmw;
/* Specifies the value for MC_CLKEN_OVERRIDE */
u32 McClkenOverride;
/* Specifies the value for MC_STAT_CONTROL */
u32 McStatControl;
/* Specifies the value for MC_VIDEO_PROTECT_BOM */
u32 McVideoProtectBom;
/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
u32 McVideoProtectBomAdrHi;
/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
u32 McVideoProtectSizeMb;
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
u32 McVideoProtectVprOverride;
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
u32 McVideoProtectVprOverride1;
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
u32 McVideoProtectGpuOverride0;
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
u32 McVideoProtectGpuOverride1;
/* Specifies the value for MC_SEC_CARVEOUT_BOM */
u32 McSecCarveoutBom;
/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
u32 McSecCarveoutAdrHi;
/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
u32 McSecCarveoutSizeMb;
/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.
VIDEO_PROTECT_WRITEAccess */
u32 McVideoProtectWriteAccess;
/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.
SEC_CARVEOUT_WRITEAccess */
u32 McSecCarveoutProtectWriteAccess;
/* Write-Protect Regions (WPR) */
u32 McGeneralizedCarveout1Bom;
u32 McGeneralizedCarveout1BomHi;
u32 McGeneralizedCarveout1Size128kb;
u32 McGeneralizedCarveout1Access0;
u32 McGeneralizedCarveout1Access1;
u32 McGeneralizedCarveout1Access2;
u32 McGeneralizedCarveout1Access3;
u32 McGeneralizedCarveout1Access4;
u32 McGeneralizedCarveout1ForceInternalAccess0;
u32 McGeneralizedCarveout1ForceInternalAccess1;
u32 McGeneralizedCarveout1ForceInternalAccess2;
u32 McGeneralizedCarveout1ForceInternalAccess3;
u32 McGeneralizedCarveout1ForceInternalAccess4;
u32 McGeneralizedCarveout1Cfg0;
u32 McGeneralizedCarveout2Bom;
u32 McGeneralizedCarveout2BomHi;
u32 McGeneralizedCarveout2Size128kb;
u32 McGeneralizedCarveout2Access0;
u32 McGeneralizedCarveout2Access1;
u32 McGeneralizedCarveout2Access2;
u32 McGeneralizedCarveout2Access3;
u32 McGeneralizedCarveout2Access4;
u32 McGeneralizedCarveout2ForceInternalAccess0;
u32 McGeneralizedCarveout2ForceInternalAccess1;
u32 McGeneralizedCarveout2ForceInternalAccess2;
u32 McGeneralizedCarveout2ForceInternalAccess3;
u32 McGeneralizedCarveout2ForceInternalAccess4;
u32 McGeneralizedCarveout2Cfg0;
u32 McGeneralizedCarveout3Bom;
u32 McGeneralizedCarveout3BomHi;
u32 McGeneralizedCarveout3Size128kb;
u32 McGeneralizedCarveout3Access0;
u32 McGeneralizedCarveout3Access1;
u32 McGeneralizedCarveout3Access2;
u32 McGeneralizedCarveout3Access3;
u32 McGeneralizedCarveout3Access4;
u32 McGeneralizedCarveout3ForceInternalAccess0;
u32 McGeneralizedCarveout3ForceInternalAccess1;
u32 McGeneralizedCarveout3ForceInternalAccess2;
u32 McGeneralizedCarveout3ForceInternalAccess3;
u32 McGeneralizedCarveout3ForceInternalAccess4;
u32 McGeneralizedCarveout3Cfg0;
u32 McGeneralizedCarveout4Bom;
u32 McGeneralizedCarveout4BomHi;
u32 McGeneralizedCarveout4Size128kb;
u32 McGeneralizedCarveout4Access0;
u32 McGeneralizedCarveout4Access1;
u32 McGeneralizedCarveout4Access2;
u32 McGeneralizedCarveout4Access3;
u32 McGeneralizedCarveout4Access4;
u32 McGeneralizedCarveout4ForceInternalAccess0;
u32 McGeneralizedCarveout4ForceInternalAccess1;
u32 McGeneralizedCarveout4ForceInternalAccess2;
u32 McGeneralizedCarveout4ForceInternalAccess3;
u32 McGeneralizedCarveout4ForceInternalAccess4;
u32 McGeneralizedCarveout4Cfg0;
u32 McGeneralizedCarveout5Bom;
u32 McGeneralizedCarveout5BomHi;
u32 McGeneralizedCarveout5Size128kb;
u32 McGeneralizedCarveout5Access0;
u32 McGeneralizedCarveout5Access1;
u32 McGeneralizedCarveout5Access2;
u32 McGeneralizedCarveout5Access3;
u32 McGeneralizedCarveout5Access4;
u32 McGeneralizedCarveout5ForceInternalAccess0;
u32 McGeneralizedCarveout5ForceInternalAccess1;
u32 McGeneralizedCarveout5ForceInternalAccess2;
u32 McGeneralizedCarveout5ForceInternalAccess3;
u32 McGeneralizedCarveout5ForceInternalAccess4;
u32 McGeneralizedCarveout5Cfg0;
/* Specifies enable for CA training */
u32 EmcCaTrainingEnable;
/* Set if bit 6 select is greater than bit 7 select; uses aremc.
spec packet SWIZZLE_BIT6_GT_BIT7 */
u32 SwizzleRankByteEncode;
/* Specifies enable and offset for patched boot ROM write */
u32 BootRomPatchControl;
/* Specifies data for patched boot ROM write */
u32 BootRomPatchData;
/* Specifies the value for MC_MTS_CARVEOUT_BOM */
u32 McMtsCarveoutBom;
/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
u32 McMtsCarveoutAdrHi;
/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
u32 McMtsCarveoutSizeMb;
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
u32 McMtsCarveoutRegCtrl;
/* End */
};
#endif /* __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__ */

256
ipl/se.c Executable file
View File

@ -0,0 +1,256 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 "se.h"
#include "heap.h"
#include "t210.h"
#include "se_t210.h"
typedef struct _se_ll_t
{
vu32 num;
vu32 addr;
vu32 size;
} se_ll_t;
static void _gf256_mul_x(void *block)
{
u8 *pdata = (u8 *)block;
u32 carry = 0;
for (u32 i = 0xF; i >= 0; i--)
{
u8 b = pdata[i];
pdata[i] = (b << 1) | carry;
carry = b >> 7;
}
if (carry)
pdata[0xF] ^= 0x87;
}
static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size)
{
ll->num = 0;
ll->addr = addr;
ll->size = size;
}
static void _se_ll_set(se_ll_t *dst, se_ll_t *src)
{
SE(SE_IN_LL_ADDR_REG_OFFSET) = (u32)src;
SE(SE_OUT_LL_ADDR_REG_OFFSET) = (u32)dst;
}
static int _se_wait()
{
while (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET)))
;
if (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) ||
SE(SE_STATUS_0) & 3 ||
SE(SE_ERR_STATUS_0) != 0)
return 0;
return 1;
}
static int _se_execute(u32 op, void *dst, u32 dst_size, void *src, u32 src_size)
{
se_ll_t *ll_dst = NULL, *ll_src = NULL;
if (dst)
{
ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));
_se_ll_init(ll_dst, (u32)dst, dst_size);
}
if (src)
{
ll_src = (se_ll_t *)malloc(sizeof(se_ll_t));
_se_ll_init(ll_src, (u32)src, src_size);
}
_se_ll_set(ll_dst, ll_src);
SE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0);
SE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET);
SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op);
int res = _se_wait();
if (src)
free(ll_src);
if (dst)
free(ll_dst);
return res;
}
static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, void *src, u32 src_size)
{
u8 *block = (u8 *)malloc(0x10);
memset(block, 0, 0x10);
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
memcpy(block, src, src_size);
int res = _se_execute(op, block, 0x10, block, 0x10);
memcpy(dst, block, dst_size);
free(block);
return res;
}
static void _se_aes_ctr_set(void *ctr)
{
u32 *data = (u32 *)ctr;
for (u32 i = 0; i < 4; i++)
SE(SE_CRYPTO_CTR_REG_OFFSET + 4 * i) = data[i];
}
void se_rsa_acc_ctrl(u32 rs, u32 flags)
{
if (flags & 0x7F)
SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = ((flags >> 4) & 4 | flags & 3) ^ 7;
if (flags & 0x80)
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs);
}
void se_key_acc_ctrl(u32 ks, u32 flags)
{
if (flags & 0x7F)
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags;
if (flags & 0x80)
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks);
}
void se_aes_key_set(u32 ks, void *key, u32 size)
{
u32 *data = (u32 *)key;
for (u32 i = 0; i < size / 4; i++)
{
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
}
}
void se_aes_key_clear(u32 ks)
{
for (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++)
{
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
}
}
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, void *input)
{
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTAB);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst);
return _se_execute(OP_START, NULL, 0, input, 0x10);
}
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, void *src)
{
if (enc)
{
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
}
else
{
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
}
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
return _se_execute(OP_START, dst, 0x10, src, 0x10);
}
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, void *src, u32 src_size, void *ctr)
{
SE(SE_SPARE_0_REG_OFFSET) = 1;
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_VAL(1);
_se_aes_ctr_set(ctr);
u32 src_size_aligned = src_size & 0xFFFFFFF0;
u32 src_size_delta = src_size & 0xF;
if (src_size_aligned)
{
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
if (!_se_execute(OP_START, dst, dst_size, src, src_size_aligned))
return 0;
}
if (src_size - src_size_aligned && src_size_aligned < dst_size)
return _se_execute_one_block(OP_START, dst + src_size_aligned,
MIN(src_size_delta, dst_size - src_size_aligned),
src + src_size_aligned, src_size_delta);
return 1;
}
int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
{
int res = 0;
u8 *tweak = (u8 *)malloc(0x10);
u8 *pdst = (u8 *)dst;
u8 *psrc = (u8 *)src;
//Generate tweak.
for (int i = 0xF; i >= 0; i--)
{
tweak[i] = sec & 0xFF;
sec >>= 8;
}
if (!se_aes_crypt_block_ecb(ks1, 1, tweak, tweak))
goto out;
//We are assuming a 0x10-aligned sector size in this implementation.
for (u32 i = 0; i < secsize / 0x10; i++)
{
for (u32 j = 0; j < 0x10; j++)
pdst[j] = psrc[j] ^ tweak[j];
if (!se_aes_crypt_block_ecb(ks2, enc, pdst, pdst))
goto out;
for (u32 j = 0; j < 0x10; j++)
pdst[j] = pdst[j] ^ tweak[j];
_gf256_mul_x(tweak);
psrc += 0x10;
pdst += 0x10;
}
res = 1;
out:;
free(tweak);
return res;
}
int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)
{
u8 *pdst = (u8 *)dst;
u8 *psrc = (u8 *)src;
for (u32 i = 0; i < num_secs; i++)
if (!se_aes_xts_crypt_sec(ks1, ks2, enc, sec + i, pdst + secsize * i, psrc + secsize * i, secsize))
return 0;
return 1;
}

30
ipl/se.h Executable file
View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _SE_H_
#define _SE_H_
#include "types.h"
void se_rsa_acc_ctrl(u32 rs, u32 flags);
void se_key_acc_ctrl(u32 ks, u32 flags);
void se_aes_key_set(u32 ks, void *key, u32 size);
void se_aes_key_clear(u32 ks);
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, void *input);
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, void *src);
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, void *src, u32 src_size, void *ctr);
#endif

357
ipl/se_t210.h Executable file
View File

@ -0,0 +1,357 @@
/*
* Driver for Tegra Security Engine
*
* Copyright (c) 2011-2013, NVIDIA Corporation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _CRYPTO_TEGRA_SE_H
#define _CRYPTO_TEGRA_SE_H
#include "types.h"
#define TEGRA_SE_CRA_PRIORITY 300
#define TEGRA_SE_COMPOSITE_PRIORITY 400
#define TEGRA_SE_CRYPTO_QUEUE_LENGTH 50
#define SE_MAX_SRC_SG_COUNT 50
#define SE_MAX_DST_SG_COUNT 50
#define TEGRA_SE_KEYSLOT_COUNT 16
#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF
/* SE register definitions */
#define SE_SECURITY_0 0x000
#define SE_KEY_SCHED_READ_SHIFT 3
#define SE_CONFIG_REG_OFFSET 0x014
#define SE_CONFIG_ENC_ALG_SHIFT 12
#define SE_CONFIG_DEC_ALG_SHIFT 8
#define ALG_AES_ENC 1
#define ALG_RNG 2
#define ALG_SHA 3
#define ALG_RSA 4
#define ALG_NOP 0
#define ALG_AES_DEC 1
#define SE_CONFIG_ENC_ALG(x) (x << SE_CONFIG_ENC_ALG_SHIFT)
#define SE_CONFIG_DEC_ALG(x) (x << SE_CONFIG_DEC_ALG_SHIFT)
#define SE_CONFIG_DST_SHIFT 2
#define DST_MEMORY 0
#define DST_HASHREG 1
#define DST_KEYTAB 2
#define DST_SRK 3
#define DST_RSAREG 4
#define SE_CONFIG_DST(x) (x << SE_CONFIG_DST_SHIFT)
#define SE_CONFIG_ENC_MODE_SHIFT 24
#define SE_CONFIG_DEC_MODE_SHIFT 16
#define MODE_KEY128 0
#define MODE_KEY192 1
#define MODE_KEY256 2
#define MODE_SHA1 0
#define MODE_SHA224 4
#define MODE_SHA256 5
#define MODE_SHA384 6
#define MODE_SHA512 7
#define SE_CONFIG_ENC_MODE(x) (x << SE_CONFIG_ENC_MODE_SHIFT)
#define SE_CONFIG_DEC_MODE(x) (x << SE_CONFIG_DEC_MODE_SHIFT)
#define SE_RNG_CONFIG_REG_OFFSET 0x340
#define DRBG_MODE_SHIFT 0
#define DRBG_MODE_NORMAL 0
#define DRBG_MODE_FORCE_INSTANTION 1
#define DRBG_MODE_FORCE_RESEED 2
#define SE_RNG_CONFIG_MODE(x) (x << DRBG_MODE_SHIFT)
#define SE_RNG_SRC_CONFIG_REG_OFFSET 0x344
#define DRBG_RO_ENT_SRC_SHIFT 1
#define DRBG_RO_ENT_SRC_ENABLE 1
#define DRBG_RO_ENT_SRC_DISABLE 0
#define SE_RNG_SRC_CONFIG_RO_ENT_SRC(x) (x << DRBG_RO_ENT_SRC_SHIFT)
#define DRBG_RO_ENT_SRC_LOCK_SHIFT 0
#define DRBG_RO_ENT_SRC_LOCK_ENABLE 1
#define DRBG_RO_ENT_SRC_LOCK_DISABLE 0
#define SE_RNG_SRC_CONFIG_RO_ENT_SRC_LOCK(x) (x << DRBG_RO_ENT_SRC_LOCK_SHIFT)
#define DRBG_SRC_SHIFT 2
#define DRBG_SRC_NONE 0
#define DRBG_SRC_ENTROPY 1
#define DRBG_SRC_LFSR 2
#define SE_RNG_CONFIG_SRC(x) (x << DRBG_SRC_SHIFT)
#define SE_RNG_RESEED_INTERVAL_REG_OFFSET 0x348
#define SE_KEYTABLE_REG_OFFSET 0x31c
#define SE_KEYTABLE_SLOT_SHIFT 4
#define SE_KEYTABLE_SLOT(x) (x << SE_KEYTABLE_SLOT_SHIFT)
#define SE_KEYTABLE_QUAD_SHIFT 2
#define QUAD_KEYS_128 0
#define QUAD_KEYS_192 1
#define QUAD_KEYS_256 1
#define QUAD_ORG_IV 2
#define QUAD_UPDTD_IV 3
#define SE_KEYTABLE_QUAD(x) (x << SE_KEYTABLE_QUAD_SHIFT)
#define SE_KEYTABLE_OP_TYPE_SHIFT 9
#define OP_READ 0
#define OP_WRITE 1
#define SE_KEYTABLE_OP_TYPE(x) (x << SE_KEYTABLE_OP_TYPE_SHIFT)
#define SE_KEYTABLE_TABLE_SEL_SHIFT 8
#define TABLE_KEYIV 0
#define TABLE_SCHEDULE 1
#define SE_KEYTABLE_TABLE_SEL(x) (x << SE_KEYTABLE_TABLE_SEL_SHIFT)
#define SE_KEYTABLE_PKT_SHIFT 0
#define SE_KEYTABLE_PKT(x) (x << SE_KEYTABLE_PKT_SHIFT)
#define SE_OP_DONE_SHIFT 4
#define OP_DONE 1
#define SE_OP_DONE(x, y) ((x) && (y << SE_OP_DONE_SHIFT))
#define SE_CRYPTO_REG_OFFSET 0x304
#define SE_CRYPTO_HASH_SHIFT 0
#define HASH_DISABLE 0
#define HASH_ENABLE 1
#define SE_CRYPTO_HASH(x) (x << SE_CRYPTO_HASH_SHIFT)
#define SE_CRYPTO_XOR_POS_SHIFT 1
#define XOR_BYPASS 0
#define XOR_TOP 2
#define XOR_BOTTOM 3
#define SE_CRYPTO_XOR_POS(x) (x << SE_CRYPTO_XOR_POS_SHIFT)
#define SE_CRYPTO_INPUT_SEL_SHIFT 3
#define INPUT_AHB 0
#define INPUT_RANDOM 1
#define INPUT_AESOUT 2
#define INPUT_LNR_CTR 3
#define SE_CRYPTO_INPUT_SEL(x) (x << SE_CRYPTO_INPUT_SEL_SHIFT)
#define SE_CRYPTO_VCTRAM_SEL_SHIFT 5
#define VCTRAM_AHB 0
#define VCTRAM_AESOUT 2
#define VCTRAM_PREVAHB 3
#define SE_CRYPTO_VCTRAM_SEL(x) (x << SE_CRYPTO_VCTRAM_SEL_SHIFT)
#define SE_CRYPTO_IV_SEL_SHIFT 7
#define IV_ORIGINAL 0
#define IV_UPDATED 1
#define SE_CRYPTO_IV_SEL(x) (x << SE_CRYPTO_IV_SEL_SHIFT)
#define SE_CRYPTO_CORE_SEL_SHIFT 8
#define CORE_DECRYPT 0
#define CORE_ENCRYPT 1
#define SE_CRYPTO_CORE_SEL(x) (x << SE_CRYPTO_CORE_SEL_SHIFT)
#define SE_CRYPTO_CTR_VAL_SHIFT 11
#define SE_CRYPTO_CTR_VAL(x) (x << SE_CRYPTO_CTR_VAL_SHIFT)
#define SE_CRYPTO_KEY_INDEX_SHIFT 24
#define SE_CRYPTO_KEY_INDEX(x) (x << SE_CRYPTO_KEY_INDEX_SHIFT)
#define SE_CRYPTO_CTR_CNTN_SHIFT 11
#define SE_CRYPTO_CTR_CNTN(x) (x << SE_CRYPTO_CTR_CNTN_SHIFT)
#define SE_CRYPTO_CTR_REG_COUNT 4
#define SE_CRYPTO_CTR_REG_OFFSET 0x308
#define SE_OPERATION_REG_OFFSET 0x008
#define SE_OPERATION_SHIFT 0
#define OP_ABORT 0
#define OP_START 1
#define OP_RESTART 2
#define OP_CTX_SAVE 3
#define OP_RESTART_IN 4
#define SE_OPERATION(x) (x << SE_OPERATION_SHIFT)
#define SE_CONTEXT_SAVE_CONFIG_REG_OFFSET 0x070
#define SE_CONTEXT_SAVE_WORD_QUAD_SHIFT 0
#define KEYS_0_3 0
#define KEYS_4_7 1
#define ORIG_IV 2
#define UPD_IV 3
#define SE_CONTEXT_SAVE_WORD_QUAD(x) (x << SE_CONTEXT_SAVE_WORD_QUAD_SHIFT)
#define SE_CONTEXT_SAVE_KEY_INDEX_SHIFT 8
#define SE_CONTEXT_SAVE_KEY_INDEX(x) (x << SE_CONTEXT_SAVE_KEY_INDEX_SHIFT)
#define SE_CONTEXT_SAVAE_STICKY_WORD_QUAD_SHIFT 24
#define STICKY_0_3 0
#define STICKY_4_7 1
#define SE_CONTEXT_SAVE_STICKY_WORD_QUAD(x) \
(x << SE_CONTEXT_SAVAE_STICKY_WORD_QUAD_SHIFT)
#define SE_CONTEXT_SAVE_SRC_SHIFT 29
#define STICKY_BITS 0
#define KEYTABLE 2
#define MEM 4
#define SRK 6
#define RSA_KEYTABLE 1
#define SE_CONTEXT_SAVE_SRC(x) (x << SE_CONTEXT_SAVE_SRC_SHIFT)
#define SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT 16
#define SE_CONTEXT_SAVE_RSA_KEY_INDEX(x) \
(x << SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT)
#define SE_CONTEXT_RSA_WORD_QUAD_SHIFT 12
#define SE_CONTEXT_RSA_WORD_QUAD(x) \
(x << SE_CONTEXT_RSA_WORD_QUAD_SHIFT)
#define SE_INT_ENABLE_REG_OFFSET 0x00c
#define SE_INT_STATUS_REG_OFFSET 0x010
#define INT_DISABLE 0
#define INT_ENABLE 1
#define INT_UNSET 0
#define INT_SET 1
#define SE_INT_OP_DONE_SHIFT 4
#define SE_INT_OP_DONE(x) (x << SE_INT_OP_DONE_SHIFT)
#define SE_INT_ERROR_SHIFT 16
#define SE_INT_ERROR(x) (x << SE_INT_ERROR_SHIFT)
#define SE_STATUS_0 0x800
#define SE_ERR_STATUS_0 0x804
#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330
#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0
#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x) \
(x << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT)
#define SE_KEY_INDEX_SHIFT 8
#define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x) (x << SE_KEY_INDEX_SHIFT)
#define SE_IN_LL_ADDR_REG_OFFSET 0x018
#define SE_OUT_LL_ADDR_REG_OFFSET 0x024
#define SE_KEYTABLE_DATA0_REG_OFFSET 0x320
#define SE_KEYTABLE_REG_MAX_DATA 16
#define SE_BLOCK_COUNT_REG_OFFSET 0x318
#define SE_SPARE_0_REG_OFFSET 0x80c
#define SE_SHA_CONFIG_REG_OFFSET 0x200
#define SHA_DISABLE 0
#define SHA_ENABLE 1
#define SE_SHA_MSG_LENGTH_REG_OFFSET 0x204
#define SE_SHA_MSG_LEFT_REG_OFFSET 0x214
#define SE_HASH_RESULT_REG_COUNT 16
#define SE_HASH_RESULT_REG_OFFSET 0x030
#define TEGRA_SE_KEY_256_SIZE 32
#define TEGRA_SE_KEY_192_SIZE 24
#define TEGRA_SE_KEY_128_SIZE 16
#define TEGRA_SE_AES_BLOCK_SIZE 16
#define TEGRA_SE_AES_MIN_KEY_SIZE 16
#define TEGRA_SE_AES_MAX_KEY_SIZE 32
#define TEGRA_SE_AES_IV_SIZE 16
#define TEGRA_SE_RNG_IV_SIZE 16
#define TEGRA_SE_RNG_DT_SIZE 16
#define TEGRA_SE_RNG_KEY_SIZE 16
#define TEGRA_SE_RNG_SEED_SIZE (TEGRA_SE_RNG_IV_SIZE + \
TEGRA_SE_RNG_KEY_SIZE + \
TEGRA_SE_RNG_DT_SIZE)
#define TEGRA_SE_AES_CMAC_DIGEST_SIZE 16
#define TEGRA_SE_RSA512_DIGEST_SIZE 64
#define TEGRA_SE_RSA1024_DIGEST_SIZE 128
#define TEGRA_SE_RSA1536_DIGEST_SIZE 192
#define TEGRA_SE_RSA2048_DIGEST_SIZE 256
#define SE_KEY_TABLE_ACCESS_LOCK_OFFSET 0x280
#define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284
#define SE_KEY_READ_DISABLE_SHIFT 0
#define SE_KEY_UPDATE_DISABLE_SHIFT 1
#define SE_CONTEXT_BUFER_SIZE 1072
#define SE_CONTEXT_DRBG_BUFER_SIZE 2112
#define SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET 0
#define SE_CONTEXT_SAVE_RANDOM_DATA_SIZE 16
#define SE_CONTEXT_SAVE_STICKY_BITS_OFFSET \
(SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET + SE_CONTEXT_SAVE_RANDOM_DATA_SIZE)
#define SE_CONTEXT_SAVE_STICKY_BITS_SIZE 16
#define SE_CONTEXT_SAVE_KEYS_OFFSET (SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \
SE_CONTEXT_SAVE_STICKY_BITS_SIZE)
#define SE11_CONTEXT_SAVE_KEYS_OFFSET (SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \
SE_CONTEXT_SAVE_STICKY_BITS_SIZE + \
SE_CONTEXT_SAVE_STICKY_BITS_SIZE)
#define SE_CONTEXT_SAVE_KEY_LENGTH 512
#define SE_CONTEXT_ORIGINAL_IV_OFFSET (SE_CONTEXT_SAVE_KEYS_OFFSET + \
SE_CONTEXT_SAVE_KEY_LENGTH)
#define SE11_CONTEXT_ORIGINAL_IV_OFFSET (SE11_CONTEXT_SAVE_KEYS_OFFSET + \
SE_CONTEXT_SAVE_KEY_LENGTH)
#define SE_CONTEXT_ORIGINAL_IV_LENGTH 256
#define SE_CONTEXT_UPDATED_IV_OFFSET (SE_CONTEXT_ORIGINAL_IV_OFFSET + \
SE_CONTEXT_ORIGINAL_IV_LENGTH)
#define SE11_CONTEXT_UPDATED_IV_OFFSET (SE11_CONTEXT_ORIGINAL_IV_OFFSET + \
SE_CONTEXT_ORIGINAL_IV_LENGTH)
#define SE_CONTEXT_UPDATED_IV_LENGTH 256
#define SE_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET (SE_CONTEXT_UPDATED_IV_OFFSET + \
SE_CONTEXT_UPDATED_IV_LENGTH)
#define SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET \
(SE11_CONTEXT_UPDATED_IV_OFFSET + \
SE_CONTEXT_UPDATED_IV_LENGTH)
#define SE_CONTEXT_SAVE_RSA_KEYS_OFFSET SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET
#define SE_CONTEXT_SAVE_RSA_KEY_LENGTH 1024
#define SE_CONTEXT_SAVE_RSA_KNOWN_PATTERN_OFFSET \
(SE_CONTEXT_SAVE_RSA_KEYS_OFFSET + SE_CONTEXT_SAVE_RSA_KEY_LENGTH)
#define SE_CONTEXT_KNOWN_PATTERN_SIZE 16
#define TEGRA_SE_RSA_KEYSLOT_COUNT 2
#define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET 0x40C
#define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410
#define SE_RSA_KEYTABLE_ADDR 0x420
#define SE_RSA_KEYTABLE_DATA 0x424
#define SE_RSA_OUTPUT 0x428
#define RSA_KEY_READ 0
#define RSA_KEY_WRITE 1
#define SE_RSA_KEY_OP_SHIFT 10
#define SE_RSA_KEY_OP(x) (x << SE_RSA_KEY_OP_SHIFT)
#define RSA_KEY_INPUT_MODE_REG 0
#define RSA_KEY_INPUT_MODE_DMA 1
#define RSA_KEY_INPUT_MODE_SHIFT 8
#define RSA_KEY_INPUT_MODE(x) (x << RSA_KEY_INPUT_MODE_SHIFT)
#define RSA_KEY_SLOT_ONE 0
#define RSA_KEY_SLOT_TW0 1
#define RSA_KEY_NUM_SHIFT 7
#define RSA_KEY_NUM(x) (x << RSA_KEY_NUM_SHIFT)
#define RSA_KEY_TYPE_EXP 0
#define RSA_KEY_TYPE_MOD 1
#define RSA_KEY_TYPE_SHIFT 6
#define RSA_KEY_TYPE(x) (x << RSA_KEY_TYPE_SHIFT)
#define SE_RSA_KEY_SIZE_REG_OFFSET 0x404
#define SE_RSA_EXP_SIZE_REG_OFFSET 0x408
#define RSA_KEY_SLOT_SHIFT 24
#define RSA_KEY_SLOT(x) (x << RSA_KEY_SLOT_SHIFT)
#define SE_RSA_CONFIG 0x400
#define RSA_KEY_PKT_WORD_ADDR_SHIFT 0
#define RSA_KEY_PKT_WORD_ADDR(x) (x << RSA_KEY_PKT_WORD_ADDR_SHIFT)
#define RSA_KEY_WORD_ADDR_SHIFT 0
#define RSA_KEY_WORD_ADDR(x) (x << RSA_KEY_WORD_ADDR_SHIFT)
#define SE_RSA_KEYTABLE_PKT_SHIFT 0
#define SE_RSA_KEYTABLE_PKT(x) (x << SE_RSA_KEYTABLE_PKT_SHIFT)
#endif /* _CRYPTO_TEGRA_SE_H */

77
ipl/start.S Executable file
View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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/>.
*/
.section .text._start
.arm
.extern _reloc_ipl
.type _reloc_ipl, %function
.extern memset
.type memset, %function
.extern ipl_main
.type ipl_main, %function
.globl _start
.type _start, %function
_start:
ADR R0, _start
LDR R1, =__ipl_start
CMP R0, R1
BEQ _real_start
/* If we are not in the right location already, copy a relocator to upper IRAM. */
ADR R2, _reloc_ipl
LDR R3, =0x4003FF00
MOV R4, #(_real_start - _reloc_ipl)
_copy_loop:
LDMIA R2!, {R5}
STMIA R3!, {R5}
SUBS R4, #4
BNE _copy_loop
/* Use the relocator to copy ourselves into the right place. */
LDR R2, =__ipl_end
SUB R2, R2, R1
LDR R3, =_real_start
LDR R4, =0x4003FF00
BX R4
_reloc_ipl:
LDMIA R0!, {R4-R7}
STMIA R1!, {R4-R7}
SUBS R2, #0x10
BNE _reloc_ipl
/* Jump to the relocated entry. */
BX R3
_real_start:
/* Initially, we place our stack in IRAM but will move it to SDRAM later. */
LDR SP, =0x4003FF00
LDR R0, =__bss_start
EOR R1, R1, R1
LDR R2, =__bss_end
SUB R2, R2, R0
BL memset
BL ipl_main
B .
.globl pivot_stack
.type pivot_stack, %function
pivot_stack:
MOV SP, R0
BX LR

17
hwinit/t210.h → ipl/t210.h Normal file → Executable file
View File

@ -34,13 +34,20 @@
#define GPIO_1_BASE (GPIO_BASE)
#define GPIO_2_BASE (GPIO_BASE + 0x100)
#define GPIO_3_BASE (GPIO_BASE + 0x200)
#define GPIO_4_BASE (GPIO_BASE + 0x300)
#define GPIO_5_BASE (GPIO_BASE + 0x400)
#define GPIO_6_BASE (GPIO_BASE + 0x500)
#define GPIO_7_BASE (GPIO_BASE + 0x600)
#define GPIO_8_BASE (GPIO_BASE + 0x700)
#define EXCP_VEC_BASE 0x6000F000
#define APB_MISC_BASE 0x70000000
#define PINMUX_AUX_BASE 0x70003000
#define UART_BASE 0x70006000
#define PMC_BASE 0x7000E400
#define SYSCTR0_BASE 0x7000F000
#define FUSE_BASE 0x7000F800
#define KFUSE_BASE 0x7000FC00
#define SE_BASE 0x70012000
#define MC_BASE 0x70019000
#define EMC_BASE 0x7001B000
#define MIPI_CAL_BASE 0x700E3000
@ -59,15 +66,23 @@
#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off)
#define SYSREG(off) _REG(SYSREG_BASE, off)
#define SB(off) _REG(SB_BASE, off)
#define GPIO(off) _REG(GPIO_BASE, off)
#define GPIO_1(off) _REG(GPIO_1_BASE, off)
#define GPIO_2(off) _REG(GPIO_2_BASE, off)
#define GPIO_3(off) _REG(GPIO_3_BASE, off)
#define GPIO_4(off) _REG(GPIO_4_BASE, off)
#define GPIO_5(off) _REG(GPIO_5_BASE, off)
#define GPIO_6(off) _REG(GPIO_6_BASE, off)
#define GPIO_7(off) _REG(GPIO_7_BASE, off)
#define GPIO_8(off) _REG(GPIO_8_BASE, off)
#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off)
#define APB_MISC(off) _REG(APB_MISC_BASE, off)
#define PINMUX_AUX(off) _REG(PINMUX_AUX_BASE, off)
#define PMC(off) _REG(PMC_BASE, off)
#define SYSCTR0(off) _REG(SYSCTR0_BASE, off)
#define FUSE(off) _REG(FUSE_BASE, off)
#define KFUSE(off) _REG(KFUSE_BASE, off)
#define SE(off) _REG(SE_BASE, off)
#define MC(off) _REG(MC_BASE, off)
#define EMC(off) _REG(EMC_BASE, off)
#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off)
@ -77,7 +92,7 @@
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
/*! Secure boot registers. */
#define SB_CSR_0 0x0
#define SB_CSR 0x0
#define SB_AA64_RESET_LOW 0x30
#define SB_AA64_RESET_HIGH 0x34

24
hwinit/tsec.c → ipl/tsec.c Normal file → Executable file
View File

@ -18,10 +18,7 @@
#include "tsec.h"
#include "clock.h"
#include "t210.h"
static const u8 _tsec_fw[3840] __attribute__((aligned(0x100))) = {
/* ... */
};
#include "heap.h"
static int _tsec_dma_wait_idle()
{
@ -50,7 +47,7 @@ static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offse
return _tsec_dma_wait_idle();
}
int tsec_query(u32 carveout, u8 *dst, u32 rev)
int tsec_query(u8 *dst, u32 rev, void *fw)
{
int res = 0;
@ -74,13 +71,15 @@ int tsec_query(u32 carveout, u8 *dst, u32 rev)
}
//Load firmware.
memcpy((void *)carveout, _tsec_fw, 0xF00);
TSEC(0x1110) = carveout >> 8;// tsec_dmatrfbase_r
u8 *fwbuf = (u8 *)malloc(0x2000);
u8 *fwbuf_aligned = (u8 *)ALIGN((u32)fwbuf + 0x1000, 0x100);
memcpy(fwbuf_aligned, fw, 0xF00);
TSEC(0x1110) = (u32)fwbuf_aligned >> 8;// tsec_dmatrfbase_r
for (u32 addr = 0; addr < 0xF00; addr += 0x100)
if (!_tsec_dma_pa_to_internal_100(0, addr, addr))
{
res = -2;
goto out;
goto out_free;
}
//Execute firmware.
@ -92,19 +91,19 @@ int tsec_query(u32 carveout, u8 *dst, u32 rev)
if (!_tsec_dma_wait_idle())
{
res = -3;
goto out;
goto out_free;
}
u32 timeout = TMR(0x10) + 2000000;
while (!TSEC(0x1044))
if (TMR(0x10) > timeout)
{
res = -4;
goto out;
goto out_free;
}
if (TSEC(0x1044) != 0xB0B0B0B0)
{
res = -5;
goto out;
goto out_free;
}
//Fetch result.
@ -120,6 +119,9 @@ int tsec_query(u32 carveout, u8 *dst, u32 rev)
SOR1(0x20C) = 0;
memcpy(dst, &buf, 0x10);
out_free:;
free(fwbuf);
out:;
//Disable clocks.

2
hwinit/tsec.h → ipl/tsec.h Normal file → Executable file
View File

@ -19,6 +19,6 @@
#include "types.h"
int tsec_query(u32 carveout, u8 *dst, u32 rev);
int tsec_query(u8 *dst, u32 rev, void *fw);
#endif

98
ipl/tui.c Executable file
View File

@ -0,0 +1,98 @@
/*{
* Copyright (c) 2018 naehrwert
*
* 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 "tui.h"
#include "btn.h"
void tui_pbar(gfx_con_t *con, int x, int y, u32 val)
{
u32 cx, cy;
gfx_con_getpos(con, &cx, &cy);
gfx_con_setpos(con, x, y);
gfx_printf(con, "[%3d%%]", val);
x += 7 * 8;
for (int i = 0; i < 6; i++)
{
gfx_line(con->gfx_ctxt, x, y + i + 1, x + 3 * val, y + i + 1, 0xFFFFFFFF);
gfx_line(con->gfx_ctxt, x + 3 * val, y + i + 1, x + 3 * 100, y + i + 1, 0xFF888888);
}
gfx_con_setpos(con, cx, cy);
}
void *tui_do_menu(gfx_con_t *con, menu_t *menu)
{
int idx = 0, cnt;
gfx_clear(con->gfx_ctxt, 0xFF000000);
while (1)
{
gfx_con_setcol(con, 0xFFFFFFFF, 1, 0xFF000000);
gfx_con_setpos(con, menu->x, menu->y);
gfx_printf(con, "[%s]\n\n", menu->caption);
for (cnt = 0; menu->ents[cnt].type != MENT_END; cnt++)
{
if (cnt == idx)
gfx_con_setcol(con, 0xFF000000, 1, 0xFFCCCCCC);
else
gfx_con_setcol(con, 0xFFFFFFFF, 1, 0xFF000000);
con->x += 8;
gfx_printf(con, "%s", menu->ents[cnt].caption);
if(menu->ents[cnt].type == MENT_MENU)
gfx_printf(con, "%k...", 0xFFEE9900);
gfx_putc(con, '\n');
}
gfx_con_setcol(con, 0xFFFFFFFF, 1, 0xFF000000);
gfx_putc(con, '\n');
u32 btn = btn_wait();
if (btn & BTN_VOL_DOWN && idx < cnt - 1)
idx++;
if (btn & BTN_VOL_UP && idx > 0)
idx--;
if (btn & BTN_POWER)
{
ment_t *ent = &menu->ents[idx];
switch (ent->type)
{
case MENT_HANDLER:
ent->handler(ent->data);
break;
case MENT_MENU:
return tui_do_menu(con, ent->menu);
break;
case MENT_CHOICE:
return ent->data;
break;
case MENT_BACK:
return NULL;
break;
}
gfx_clear(con->gfx_ctxt, 0xFF000000);
}
}
return NULL;
}

58
ipl/tui.h Executable file
View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _TUI_H_
#define _TUI_H_
#include "types.h"
#include "gfx.h"
#define MENT_END 0
#define MENT_HANDLER 1
#define MENT_MENU 2
#define MENT_CHOICE 3
#define MENT_BACK 4
typedef struct _ment_t
{
u32 type;
const char *caption;
void *data;
union
{
void(*handler)(void *);
struct _menu_t *menu;
};
} ment_t;
typedef struct _menu_t
{
ment_t *ents;
const char *caption;
u32 x;
u32 y;
} menu_t;
#define MDEF_END() {MENT_END}
#define MDEF_HANDLER(caption, _handler) { MENT_HANDLER, caption, NULL, { .handler = _handler } }
#define MDEF_HANDLER_EX(caption, data, _handler) { MENT_HANDLER, caption, data, { .handler = _handler } }
#define MDEF_MENU(caption, _menu) { MENT_MENU, caption, NULL, { .menu = _menu } }
#define MDEF_BACK() { MENT_BACK, "Back" }
void tui_pbar(gfx_con_t *con, int x, int y, u32 val);
void *tui_do_menu(gfx_con_t *con, menu_t *menu);
#endif

37
ipl/types.h Executable file
View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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 _TYPES_H_
#define _TYPES_H_
#define NULL ((void *)0)
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define OFFSET_OF(t, m) ((u32)&((t *)NULL)->m)
#define CONTAINER_OF(mp, t, mn) ((t *)((u32)mp - OFFSET_OF(t, mn)))
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long int u64;
typedef volatile unsigned char vu8;
typedef volatile unsigned short vu16;
typedef volatile unsigned int vu32;
#endif

0
hwinit/uart.c → ipl/uart.c Normal file → Executable file
View File

0
hwinit/uart.h → ipl/uart.h Normal file → Executable file
View File

5
hwinit/util.c → ipl/util.c Normal file → Executable file
View File

@ -17,6 +17,11 @@
#include "util.h"
#include "t210.h"
u32 get_tmr()
{
return TMR(0x10);
}
void sleep(u32 ticks)
{
u32 start = TMR(0x10);

1
hwinit/util.h → ipl/util.h Normal file → Executable file
View File

@ -25,6 +25,7 @@ typedef struct _cfg_op_t
u32 val;
} cfg_op_t;
u32 get_tmr();
void sleep(u32 ticks);
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);

641
tools/emc.def Executable file
View File

@ -0,0 +1,641 @@
EMC_DBG 8
EMC_CFG C
EMC_CONFIG_SAMPLE_DELAY 5f0
EMC_CFG_UPDATE 5f4
EMC_ADR_CFG 10
EMC_REFCTRL 20
EMC_PIN 24
EMC_TIMING_CONTROL 28
EMC_RC 2c
EMC_RFC 30
EMC_RFCPB 590
EMC_RAS 34
EMC_RP 38
EMC_R2W 3c
EMC_W2R 40
EMC_R2P 44
EMC_W2P 48
EMC_CCDMW 5c0
EMC_RD_RCD 4c
EMC_WR_RCD 50
EMC_RRD 54
EMC_REXT 58
EMC_WDV 5c
EMC_QUSE 60
EMC_QRST 64
EMC_ISSUE_QRST 428
EMC_QSAFE 68
EMC_RDV 6c
EMC_REFRESH 70
EMC_BURST_REFRESH_NUM 74
EMC_PDEX2WR 78
EMC_PDEX2RD 7c
EMC_PDEX2CKE 118
EMC_PCHG2PDEN 80
EMC_ACT2PDEN 84
EMC_AR2PDEN 88
EMC_RW2PDEN 8c
EMC_CKE2PDEN 11c
EMC_TXSR 90
EMC_TCKE 94
EMC_TFAW 98
EMC_TRPAB 9c
EMC_TCLKSTABLE a0
EMC_TCLKSTOP a4
EMC_TREFBW a8
EMC_TPPD ac
EMC_PDEX2MRR b4
EMC_ODT_WRITE b0
EMC_WEXT b8
EMC_RFC_SLR c0
EMC_MRS_WAIT_CNT2 c4
EMC_MRS_WAIT_CNT c8
EMC_MRS cc
EMC_EMRS d0
EMC_REF d4
EMC_PRE d8
EMC_NOP dc
EMC_SELF_REF e0
EMC_DPD e4
EMC_MRW e8
EMC_MRR ec
EMC_CMDQ f0
EMC_MC2EMCQ f4
EMC_FBIO_SPARE 100
EMC_FBIO_CFG5 104
EMC_CFG_RSV 120
EMC_ACPD_CONTROL 124
EMC_MPC 128
EMC_EMRS2 12c
EMC_EMRS3 130
EMC_MRW2 134
EMC_MRW3 138
EMC_MRW4 13c
EMC_MRW5 4a0
EMC_MRW6 4a4
EMC_MRW7 4a8
EMC_MRW8 4ac
EMC_MRW9 4b0
EMC_MRW10 4b4
EMC_MRW11 4b8
EMC_MRW12 4bc
EMC_MRW13 4c0
EMC_MRW14 4c4
EMC_MRW15 4d0
EMC_CFG_SYNC 4d4
EMC_CLKEN_OVERRIDE 140
EMC_R2R 144
EMC_W2W 148
EMC_EINPUT 14c
EMC_EINPUT_DURATION 150
EMC_PUTERM_EXTRA 154
EMC_TCKESR 158
EMC_TPD 15c
EMC_STAT_CONTROL 160
EMC_STAT_STATUS 164
EMC_STAT_DRAM_CLOCK_LIMIT_LO 19c
EMC_STAT_DRAM_CLOCK_LIMIT_HI 1a0
EMC_STAT_DRAM_CLOCKS_LO 1a4
EMC_STAT_DRAM_CLOCKS_HI 1a8
EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_LO 1ac
EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_HI 1b0
EMC_STAT_DRAM_DEV0_READ_CNT_LO 1b4
EMC_STAT_DRAM_DEV0_READ_CNT_HI 1b8
EMC_STAT_DRAM_DEV0_READ8_CNT_LO 1bc
EMC_STAT_DRAM_DEV0_READ8_CNT_HI 1c0
EMC_STAT_DRAM_DEV0_WRITE_CNT_LO 1c4
EMC_STAT_DRAM_DEV0_WRITE_CNT_HI 1c8
EMC_STAT_DRAM_DEV0_WRITE8_CNT_LO 1cc
EMC_STAT_DRAM_DEV0_WRITE8_CNT_HI 1d0
EMC_STAT_DRAM_DEV0_REF_CNT_LO 1d4
EMC_STAT_DRAM_DEV0_REF_CNT_HI 1d8
EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 1dc
EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 1e0
EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 1e4
EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 1e8
EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 1ec
EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 1f0
EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 1f4
EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 1f8
EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 1fc
EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 200
EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 204
EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 208
EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 20c
EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 210
EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 214
EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 218
EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_LO 21c
EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_HI 220
EMC_STAT_DRAM_DEV0_DSR 224
EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_LO 228
EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_HI 22c
EMC_STAT_DRAM_DEV1_READ_CNT_LO 230
EMC_STAT_DRAM_DEV1_READ_CNT_HI 234
EMC_STAT_DRAM_DEV1_READ8_CNT_LO 238
EMC_STAT_DRAM_DEV1_READ8_CNT_HI 23c
EMC_STAT_DRAM_DEV1_WRITE_CNT_LO 240
EMC_STAT_DRAM_DEV1_WRITE_CNT_HI 244
EMC_STAT_DRAM_DEV1_WRITE8_CNT_LO 248
EMC_STAT_DRAM_DEV1_WRITE8_CNT_HI 24c
EMC_STAT_DRAM_DEV1_REF_CNT_LO 250
EMC_STAT_DRAM_DEV1_REF_CNT_HI 254
EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 258
EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 25c
EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 260
EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 264
EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 268
EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 26c
EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 270
EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 274
EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 278
EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 27c
EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 280
EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 284
EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 288
EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 28c
EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 290
EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 294
EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_LO 298
EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_HI 29c
EMC_STAT_DRAM_DEV1_DSR 2a0
EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO c8c
EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI c90
EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO c94
EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI c98
EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO c9c
EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI ca0
EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO ca4
EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI ca8
EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO cac
EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI cb0
EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO cb4
EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI cb8
EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO cbc
EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI cc0
EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO cc4
EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI cc8
EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_LO ccc
EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_HI cd0
EMC_STAT_DRAM_IO_DSR cd4
EMC_AUTO_CAL_CONFIG 2a4
EMC_AUTO_CAL_CONFIG2 458
EMC_AUTO_CAL_CONFIG3 45c
EMC_AUTO_CAL_CONFIG4 5b0
EMC_AUTO_CAL_CONFIG5 5b4
EMC_AUTO_CAL_CONFIG6 5cc
EMC_AUTO_CAL_CONFIG7 574
EMC_AUTO_CAL_CONFIG8 2dc
EMC_AUTO_CAL_VREF_SEL_0 2f8
EMC_AUTO_CAL_VREF_SEL_1 300
EMC_AUTO_CAL_INTERVAL 2a8
EMC_AUTO_CAL_STATUS 2ac
EMC_AUTO_CAL_STATUS2 3d4
EMC_AUTO_CAL_CHANNEL 464
EMC_PMACRO_RX_TERM c48
EMC_PMACRO_DQ_TX_DRV c70
EMC_PMACRO_CA_TX_DRV c74
EMC_PMACRO_CMD_TX_DRV c4c
EMC_PMACRO_AUTOCAL_CFG_0 700
EMC_PMACRO_AUTOCAL_CFG_1 704
EMC_PMACRO_AUTOCAL_CFG_2 708
EMC_PMACRO_AUTOCAL_CFG_COMMON c78
EMC_PMACRO_ZCTRL c44
EMC_XM2COMPPADCTRL 30c
EMC_XM2COMPPADCTRL2 578
EMC_XM2COMPPADCTRL3 2f4
EMC_COMP_PAD_SW_CTRL 57c
EMC_REQ_CTRL 2b0
EMC_EMC_STATUS 2b4
EMC_CFG_2 2b8
EMC_CFG_DIG_DLL 2bc
EMC_CFG_DIG_DLL_PERIOD 2c0
EMC_DIG_DLL_STATUS 2c4
EMC_CFG_DIG_DLL_1 2c8
EMC_RDV_MASK 2cc
EMC_WDV_MASK 2d0
EMC_RDV_EARLY_MASK 2d4
EMC_RDV_EARLY 2d8
EMC_WDV_CHK 4e0
EMC_ZCAL_INTERVAL 2e0
EMC_ZCAL_WAIT_CNT 2e4
EMC_ZCAL_MRW_CMD 2e8
EMC_ZQ_CAL 2ec
EMC_SCRATCH0 324
EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE 3c8
EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 3cc
EMC_UNSTALL_RW_AFTER_CLKCHANGE 3d0
EMC_FDPD_CTRL_CMD_NO_RAMP 4d8
EMC_SEL_DPD_CTRL 3d8
EMC_FDPD_CTRL_DQ 310
EMC_FDPD_CTRL_CMD 314
EMC_PRE_REFRESH_REQ_CNT 3dc
EMC_REFCTRL2 580
EMC_FBIO_CFG7 584
EMC_DATA_BRLSHFT_0 588
EMC_DATA_BRLSHFT_1 58c
EMC_DQS_BRLSHFT_0 594
EMC_DQS_BRLSHFT_1 598
EMC_CMD_BRLSHFT_0 59c
EMC_CMD_BRLSHFT_1 5a0
EMC_CMD_BRLSHFT_2 5a4
EMC_CMD_BRLSHFT_3 5a8
EMC_QUSE_BRLSHFT_0 5ac
EMC_QUSE_BRLSHFT_1 5b8
EMC_QUSE_BRLSHFT_2 5bc
EMC_QUSE_BRLSHFT_3 5c4
EMC_FBIO_CFG8 5c8
EMC_CMD_MAPPING_CMD0_0 380
EMC_CMD_MAPPING_CMD0_1 384
EMC_CMD_MAPPING_CMD0_2 388
EMC_CMD_MAPPING_CMD1_0 38c
EMC_CMD_MAPPING_CMD1_1 390
EMC_CMD_MAPPING_CMD1_2 394
EMC_CMD_MAPPING_CMD2_0 398
EMC_CMD_MAPPING_CMD2_1 39c
EMC_CMD_MAPPING_CMD2_2 3a0
EMC_CMD_MAPPING_CMD3_0 3a4
EMC_CMD_MAPPING_CMD3_1 3a8
EMC_CMD_MAPPING_CMD3_2 3ac
EMC_CMD_MAPPING_BYTE 3b0
EMC_DYN_SELF_REF_CONTROL 3e0
EMC_TXSRDLL 3e4
EMC_CCFIFO_ADDR 3e8
EMC_CCFIFO_DATA 3ec
EMC_CCFIFO_STATUS 3f0
EMC_SWIZZLE_RANK0_BYTE0 404
EMC_SWIZZLE_RANK0_BYTE1 408
EMC_SWIZZLE_RANK0_BYTE2 40c
EMC_SWIZZLE_RANK0_BYTE3 410
EMC_SWIZZLE_RANK1_BYTE0 418
EMC_SWIZZLE_RANK1_BYTE1 41c
EMC_SWIZZLE_RANK1_BYTE2 420
EMC_SWIZZLE_RANK1_BYTE3 424
EMC_TR_TIMING_0 3b4
EMC_TR_CTRL_0 3b8
EMC_TR_CTRL_1 3bc
EMC_TR_DVFS 460
EMC_SWITCH_BACK_CTRL 3c0
EMC_TR_RDV 3c4
EMC_TR_QPOP 3f4
EMC_TR_RDV_MASK 3f8
EMC_TR_QSAFE 3fc
EMC_TR_QRST 400
EMC_IBDLY 468
EMC_OBDLY 46c
EMC_TXDSRVTTGEN 480
EMC_WE_DURATION 48c
EMC_WS_DURATION 490
EMC_WEV 494
EMC_WSV 498
EMC_CFG_3 49c
EMC_CFG_PIPE_2 554
EMC_CFG_PIPE_CLK 558
EMC_CFG_PIPE_1 55c
EMC_CFG_PIPE 560
EMC_QPOP 564
EMC_QUSE_WIDTH 568
EMC_PUTERM_WIDTH 56c
EMC_PROTOBIST_CONFIG_ADR_1 5d0
EMC_PROTOBIST_CONFIG_ADR_2 5d4
EMC_PROTOBIST_MISC 5d8
EMC_PROTOBIST_WDATA_LOWER 5dc
EMC_PROTOBIST_WDATA_UPPER 5e0
EMC_PROTOBIST_RDATA 5ec
EMC_DLL_CFG_0 5e4
EMC_DLL_CFG_1 5e8
EMC_TRAINING_CMD e00
EMC_TRAINING_CTRL e04
EMC_TRAINING_STATUS e08
EMC_TRAINING_QUSE_CORS_CTRL e0c
EMC_TRAINING_QUSE_FINE_CTRL e10
EMC_TRAINING_QUSE_CTRL_MISC e14
EMC_TRAINING_WRITE_FINE_CTRL e18
EMC_TRAINING_WRITE_CTRL_MISC e1c
EMC_TRAINING_WRITE_VREF_CTRL e20
EMC_TRAINING_READ_FINE_CTRL e24
EMC_TRAINING_READ_CTRL_MISC e28
EMC_TRAINING_READ_VREF_CTRL e2c
EMC_TRAINING_CA_FINE_CTRL e30
EMC_TRAINING_CA_CTRL_MISC e34
EMC_TRAINING_CA_CTRL_MISC1 e38
EMC_TRAINING_CA_VREF_CTRL e3c
EMC_TRAINING_CA_TADR_CTRL e40
EMC_TRAINING_SETTLE e44
EMC_TRAINING_DEBUG_CTRL e48
EMC_TRAINING_DEBUG_DQ0 e4c
EMC_TRAINING_DEBUG_DQ1 e50
EMC_TRAINING_DEBUG_DQ2 e54
EMC_TRAINING_DEBUG_DQ3 e58
EMC_TRAINING_MPC e5c
EMC_TRAINING_PATRAM_CTRL e60
EMC_TRAINING_PATRAM_DQ e64
EMC_TRAINING_PATRAM_DMI e68
EMC_TRAINING_VREF_SETTLE e6c
EMC_TRAINING_RW_EYE_CENTER_IB_BYTE0 e70
EMC_TRAINING_RW_EYE_CENTER_IB_BYTE1 e74
EMC_TRAINING_RW_EYE_CENTER_IB_BYTE2 e78
EMC_TRAINING_RW_EYE_CENTER_IB_BYTE3 e7c
EMC_TRAINING_RW_EYE_CENTER_IB_MISC e80
EMC_TRAINING_RW_EYE_CENTER_OB_BYTE0 e84
EMC_TRAINING_RW_EYE_CENTER_OB_BYTE1 e88
EMC_TRAINING_RW_EYE_CENTER_OB_BYTE2 e8c
EMC_TRAINING_RW_EYE_CENTER_OB_BYTE3 e90
EMC_TRAINING_RW_EYE_CENTER_OB_MISC e94
EMC_TRAINING_RW_OFFSET_IB_BYTE0 e98
EMC_TRAINING_RW_OFFSET_IB_BYTE1 e9c
EMC_TRAINING_RW_OFFSET_IB_BYTE2 ea0
EMC_TRAINING_RW_OFFSET_IB_BYTE3 ea4
EMC_TRAINING_RW_OFFSET_IB_MISC ea8
EMC_TRAINING_RW_OFFSET_OB_BYTE0 eac
EMC_TRAINING_RW_OFFSET_OB_BYTE1 eb0
EMC_TRAINING_RW_OFFSET_OB_BYTE2 eb4
EMC_TRAINING_RW_OFFSET_OB_BYTE3 eb8
EMC_TRAINING_RW_OFFSET_OB_MISC ebc
EMC_TRAINING_OPT_CA_VREF ec0
EMC_TRAINING_OPT_DQ_OB_VREF ec4
EMC_TRAINING_OPT_DQ_IB_VREF_RANK0 ec8
EMC_TRAINING_OPT_DQ_IB_VREF_RANK1 ecc
EMC_TRAINING_QUSE_VREF_CTRL ed0
EMC_TRAINING_OPT_DQS_IB_VREF_RANK0 ed4
EMC_TRAINING_OPT_DQS_IB_VREF_RANK1 ed8
EMC_TRAINING_DRAMC_TIMING edc
EMC_PMACRO_QUSE_DDLL_RANK0_0 600
EMC_PMACRO_QUSE_DDLL_RANK0_1 604
EMC_PMACRO_QUSE_DDLL_RANK0_2 608
EMC_PMACRO_QUSE_DDLL_RANK0_3 60c
EMC_PMACRO_QUSE_DDLL_RANK0_4 610
EMC_PMACRO_QUSE_DDLL_RANK0_5 614
EMC_PMACRO_QUSE_DDLL_RANK1_0 620
EMC_PMACRO_QUSE_DDLL_RANK1_1 624
EMC_PMACRO_QUSE_DDLL_RANK1_2 628
EMC_PMACRO_QUSE_DDLL_RANK1_3 62c
EMC_PMACRO_QUSE_DDLL_RANK1_4 630
EMC_PMACRO_QUSE_DDLL_RANK1_5 634
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0 640
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1 644
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2 648
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3 64c
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4 650
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5 654
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0 660
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1 664
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2 668
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3 66c
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4 670
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5 674
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0 680
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1 684
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2 688
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3 68c
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4 690
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5 694
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0 6a0
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1 6a4
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2 6a8
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3 6ac
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4 6b0
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5 6b4
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0 6c0
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1 6c4
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2 6c8
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3 6cc
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_4 6d0
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_5 6d4
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0 6e0
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1 6e4
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2 6e8
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3 6ec
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_4 6f0
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_5 6f4
EMC_PMACRO_TX_PWRD_0 720
EMC_PMACRO_TX_PWRD_1 724
EMC_PMACRO_TX_PWRD_2 728
EMC_PMACRO_TX_PWRD_3 72c
EMC_PMACRO_TX_PWRD_4 730
EMC_PMACRO_TX_PWRD_5 734
EMC_PMACRO_TX_SEL_CLK_SRC_0 740
EMC_PMACRO_TX_SEL_CLK_SRC_1 744
EMC_PMACRO_TX_SEL_CLK_SRC_3 74c
EMC_PMACRO_TX_SEL_CLK_SRC_2 748
EMC_PMACRO_TX_SEL_CLK_SRC_4 750
EMC_PMACRO_TX_SEL_CLK_SRC_5 754
EMC_PMACRO_DDLL_BYPASS 760
EMC_PMACRO_DDLL_PWRD_0 770
EMC_PMACRO_DDLL_PWRD_1 774
EMC_PMACRO_DDLL_PWRD_2 778
EMC_PMACRO_CMD_CTRL_0 780
EMC_PMACRO_CMD_CTRL_1 784
EMC_PMACRO_CMD_CTRL_2 788
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0 800
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1 804
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2 808
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3 80c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0 810
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1 814
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2 818
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3 81c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0 820
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1 824
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2 828
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3 82c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0 830
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1 834
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2 838
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3 83c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0 840
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1 844
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2 848
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3 84c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0 850
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1 854
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2 858
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3 85c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0 860
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1 864
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2 868
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3 86c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0 870
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1 874
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2 878
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3 87c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0 880
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1 884
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2 888
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3 88c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0 890
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1 894
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2 898
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3 89c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0 8a0
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1 8a4
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2 8a8
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3 8ac
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0 8b0
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1 8b4
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2 8b8
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3 8bc
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0 900
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1 904
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2 908
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3 90c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0 910
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1 914
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2 918
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3 91c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0 920
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1 924
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2 928
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3 92c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0 930
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1 934
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2 938
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3 93c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0 940
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1 944
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2 948
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3 94c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0 950
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1 954
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2 958
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3 95c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0 960
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1 964
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2 968
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3 96c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0 970
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1 974
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2 978
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3 97c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0 980
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1 984
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2 988
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3 98c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0 990
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1 994
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2 998
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3 99c
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0 9a0
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1 9a4
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2 9a8
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3 9ac
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0 9b0
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1 9b4
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2 9b8
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3 9bc
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0 a00
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1 a04
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2 a08
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0 a10
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1 a14
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2 a18
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0 a20
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1 a24
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2 a28
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0 a30
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1 a34
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2 a38
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0 a40
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1 a44
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2 a48
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0 a50
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1 a54
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2 a58
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0 a60
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1 a64
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2 a68
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0 a70
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1 a74
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2 a78
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_0 a80
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_1 a84
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_2 a88
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_0 a90
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_1 a94
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_2 a98
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_0 aa0
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_1 aa4
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_2 aa8
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_0 ab0
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_1 ab4
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_2 ab8
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0 b00
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1 b04
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2 b08
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0 b10
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1 b14
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2 b18
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0 b20
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1 b24
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2 b28
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0 b30
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1 b34
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2 b38
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0 b40
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1 b44
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2 b48
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0 b50
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1 b54
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2 b58
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0 b60
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1 b64
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2 b68
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0 b70
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1 b74
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2 b78
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_0 b80
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_1 b84
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_2 b88
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_0 b90
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_1 b94
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_2 b98
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_0 ba0
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_1 ba4
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_2 ba8
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_0 bb0
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_1 bb4
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_2 bb8
EMC_PMACRO_IB_VREF_DQ_0 be0
EMC_PMACRO_IB_VREF_DQ_1 be4
EMC_PMACRO_IB_VREF_DQ_2 be8
EMC_PMACRO_IB_VREF_DQS_0 bf0
EMC_PMACRO_IB_VREF_DQS_1 bf4
EMC_PMACRO_IB_VREF_DQS_2 bf8
EMC_PMACRO_IB_RXRT cf4
EMC_PMACRO_DDLL_LONG_CMD_0 c00
EMC_PMACRO_DDLL_LONG_CMD_1 c04
EMC_PMACRO_DDLL_LONG_CMD_2 c08
EMC_PMACRO_DDLL_LONG_CMD_3 c0c
EMC_PMACRO_DDLL_LONG_CMD_4 c10
EMC_PMACRO_DDLL_LONG_CMD_5 c14
EMC_PMACRO_DDLL_SHORT_CMD_0 c20
EMC_PMACRO_DDLL_SHORT_CMD_1 c24
EMC_PMACRO_DDLL_SHORT_CMD_2 c28
EMC_PMACRO_CFG_PM_GLOBAL_0 c30
EMC_PMACRO_VTTGEN_CTRL_0 c34
EMC_PMACRO_VTTGEN_CTRL_1 c38
EMC_PMACRO_VTTGEN_CTRL_2 cf0
EMC_PMACRO_BG_BIAS_CTRL_0 c3c
EMC_PMACRO_PAD_CFG_CTRL c40
EMC_PMACRO_CMD_PAD_RX_CTRL c50
EMC_PMACRO_DATA_PAD_RX_CTRL c54
EMC_PMACRO_CMD_RX_TERM_MODE c58
EMC_PMACRO_DATA_RX_TERM_MODE c5c
EMC_PMACRO_CMD_PAD_TX_CTRL c60
EMC_PMACRO_DATA_PAD_TX_CTRL c64
EMC_PMACRO_COMMON_PAD_TX_CTRL c68
EMC_PMACRO_BRICK_MAPPING_0 c80
EMC_PMACRO_BRICK_MAPPING_1 c84
EMC_PMACRO_BRICK_MAPPING_2 c88
EMC_PMACRO_DDLLCAL_CAL ce0
EMC_PMACRO_DDLL_OFFSET ce4
EMC_PMACRO_DDLL_PERIODIC_OFFSET ce8
EMC_PMACRO_BRICK_CTRL_RFU1 330
EMC_PMACRO_BRICK_CTRL_RFU2 334
EMC_PMACRO_CMD_BRICK_CTRL_FDPD 318
EMC_PMACRO_DATA_BRICK_CTRL_FDPD 31c
EMC_PMACRO_TRAINING_CTRL_0 cf8
EMC_PMACRO_TRAINING_CTRL_1 cfc
EMC_PMC_SCRATCH1 440
EMC_PMC_SCRATCH2 444
EMC_PMC_SCRATCH3 448

35
tools/fix_regs.py Executable file
View File

@ -0,0 +1,35 @@
import re
def parse_defs(fname):
f = open(fname, "r")
lines = f.readlines()
f.close()
res = {}
for l in lines:
p = [str(_.strip()) for _ in l.strip().split(" ", 1)]
res[int(p[1], 16)] = p[0]
return res
mc = parse_defs("mc.def")
emc = parse_defs("emc.def")
f = open(sys.argv[1], "r")
buf = f.read()
f.close()
def fix(m):
what = m.groups()[0]
off = int(m.groups()[1], 16)
if what == "MC":
if off in mc:
return "MC({0})".format(mc[off])
elif what == "EMC":
if off in emc:
return "EMC({0})".format(emc[off])
return "{0}(0x{1:X})".format(what, off)
buf = re.sub(r'([A-Z]+)\(0x([0-9a-fA-F]+)\)', fix, buf)
f = open(sys.argv[2], "w")
f.write(buf)
f.close()

448
tools/mc.def Executable file
View File

@ -0,0 +1,448 @@
MC_INTSTATUS 0
MC_INTMASK 4
MC_ERR_STATUS 8
MC_ERR_ADR c
MC_PCFIFO_CLIENT_CONFIG0 dd0
MC_PCFIFO_CLIENT_CONFIG1 dd4
MC_PCFIFO_CLIENT_CONFIG2 dd8
MC_PCFIFO_CLIENT_CONFIG3 ddc
MC_PCFIFO_CLIENT_CONFIG4 de0
MC_EMEM_CFG 50
MC_EMEM_ADR_CFG 54
MC_EMEM_ADR_CFG_DEV0 58
MC_EMEM_ADR_CFG_DEV1 5c
MC_EMEM_ADR_CFG_CHANNEL_MASK 60
MC_EMEM_ADR_CFG_BANK_MASK_0 64
MC_EMEM_ADR_CFG_BANK_MASK_1 68
MC_EMEM_ADR_CFG_BANK_MASK_2 6c
MC_SECURITY_CFG0 70
MC_SECURITY_CFG1 74
MC_SECURITY_CFG3 9bc
MC_SECURITY_RSV 7c
MC_EMEM_ARB_CFG 90
MC_EMEM_ARB_OUTSTANDING_REQ 94
MC_EMEM_ARB_TIMING_RCD 98
MC_EMEM_ARB_TIMING_RP 9c
MC_EMEM_ARB_TIMING_RC a0
MC_EMEM_ARB_TIMING_RAS a4
MC_EMEM_ARB_TIMING_FAW a8
MC_EMEM_ARB_TIMING_RRD ac
MC_EMEM_ARB_TIMING_RAP2PRE b0
MC_EMEM_ARB_TIMING_WAP2PRE b4
MC_EMEM_ARB_TIMING_R2R b8
MC_EMEM_ARB_TIMING_W2W bc
MC_EMEM_ARB_TIMING_R2W c0
MC_EMEM_ARB_TIMING_W2R c4
MC_EMEM_ARB_TIMING_RFCPB 6c0
MC_EMEM_ARB_TIMING_CCDMW 6c4
MC_EMEM_ARB_REFPB_HP_CTRL 6f0
MC_EMEM_ARB_REFPB_BANK_CTRL 6f4
MC_EMEM_ARB_DA_TURNS d0
MC_EMEM_ARB_DA_COVERS d4
MC_EMEM_ARB_MISC0 d8
MC_EMEM_ARB_MISC1 dc
MC_EMEM_ARB_MISC2 c8
MC_EMEM_ARB_RING1_THROTTLE e0
MC_EMEM_ARB_RING3_THROTTLE e4
MC_EMEM_ARB_NISO_THROTTLE 6b0
MC_EMEM_ARB_OVERRIDE e8
MC_EMEM_ARB_RSV ec
MC_CLKEN_OVERRIDE f4
MC_TIMING_CONTROL_DBG f8
MC_TIMING_CONTROL fc
MC_STAT_CONTROL 100
MC_STAT_STATUS 104
MC_STAT_EMC_CLOCK_LIMIT 108
MC_STAT_EMC_CLOCK_LIMIT_MSBS 10c
MC_STAT_EMC_CLOCKS 110
MC_STAT_EMC_CLOCKS_MSBS 114
MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 118
MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 158
MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 11c
MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 15c
MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER a20
MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER a24
MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 198
MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 1a8
MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 19c
MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 1ac
MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER a28
MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER a2c
MC_STAT_EMC_FILTER_SET0_ASID 1a0
MC_STAT_EMC_FILTER_SET1_ASID 1b0
MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 120
MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 160
MC_STAT_EMC_FILTER_SET0_CLIENT_0 128
MC_STAT_EMC_FILTER_SET1_CLIENT_0 168
MC_STAT_EMC_FILTER_SET0_CLIENT_1 12c
MC_STAT_EMC_FILTER_SET1_CLIENT_1 16c
MC_STAT_EMC_FILTER_SET0_CLIENT_2 130
MC_STAT_EMC_FILTER_SET1_CLIENT_2 170
MC_STAT_EMC_FILTER_SET0_CLIENT_3 134
MC_STAT_EMC_FILTER_SET0_CLIENT_4 b88
MC_STAT_EMC_FILTER_SET1_CLIENT_3 174
MC_STAT_EMC_FILTER_SET1_CLIENT_4 b8c
MC_STAT_EMC_SET0_COUNT 138
MC_STAT_EMC_SET0_COUNT_MSBS 13c
MC_STAT_EMC_SET1_COUNT 178
MC_STAT_EMC_SET1_COUNT_MSBS 17c
MC_STAT_EMC_SET0_SLACK_ACCUM 140
MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 144
MC_STAT_EMC_SET1_SLACK_ACCUM 180
MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 184
MC_STAT_EMC_SET0_HISTO_COUNT 148
MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 14c
MC_STAT_EMC_SET1_HISTO_COUNT 188
MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 18c
MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 150
MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 190
MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 1b8
MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 1bc
MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 1c8
MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 1cc
MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 1c0
MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 1d0
MC_CLIENT_HOTRESET_CTRL 200
MC_CLIENT_HOTRESET_CTRL_1 970
MC_CLIENT_HOTRESET_STATUS 204
MC_CLIENT_HOTRESET_STATUS_1 974
MC_EMEM_ARB_ISOCHRONOUS_0 208
MC_EMEM_ARB_ISOCHRONOUS_1 20c
MC_EMEM_ARB_ISOCHRONOUS_2 210
MC_EMEM_ARB_ISOCHRONOUS_3 214
MC_EMEM_ARB_ISOCHRONOUS_4 b94
MC_EMEM_ARB_HYSTERESIS_0 218
MC_EMEM_ARB_HYSTERESIS_1 21c
MC_EMEM_ARB_HYSTERESIS_2 220
MC_EMEM_ARB_HYSTERESIS_3 224
MC_EMEM_ARB_HYSTERESIS_4 b84
MC_EMEM_ARB_DHYSTERESIS_0 bb0
MC_EMEM_ARB_DHYSTERESIS_1 bb4
MC_EMEM_ARB_DHYSTERESIS_2 bb8
MC_EMEM_ARB_DHYSTERESIS_3 bbc
MC_EMEM_ARB_DHYSTERESIS_4 bc0
MC_EMEM_ARB_DHYST_CTRL bcc
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 bd0
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 bd4
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 bd8
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 bdc
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 be0
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 be4
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 be8
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 bec
MC_RESERVED_RSV 3fc
MC_DISB_EXTRA_SNAP_LEVELS 408
MC_APB_EXTRA_SNAP_LEVELS 2a4
MC_AHB_EXTRA_SNAP_LEVELS 2a0
MC_USBD_EXTRA_SNAP_LEVELS a18
MC_ISP_EXTRA_SNAP_LEVELS a08
MC_AUD_EXTRA_SNAP_LEVELS a10
MC_MSE_EXTRA_SNAP_LEVELS 40c
MC_GK2_EXTRA_SNAP_LEVELS a40
MC_A9AVPPC_EXTRA_SNAP_LEVELS 414
MC_FTOP_EXTRA_SNAP_LEVELS 2bc
MC_JPG_EXTRA_SNAP_LEVELS a3c
MC_HOST_EXTRA_SNAP_LEVELS a14
MC_SAX_EXTRA_SNAP_LEVELS 2c0
MC_DIS_EXTRA_SNAP_LEVELS 2ac
MC_VICPC_EXTRA_SNAP_LEVELS a1c
MC_HDAPC_EXTRA_SNAP_LEVELS a48
MC_AVP_EXTRA_SNAP_LEVELS 2a8
MC_USBX_EXTRA_SNAP_LEVELS 404
MC_PCX_EXTRA_SNAP_LEVELS 2b8
MC_SD_EXTRA_SNAP_LEVELS a04
MC_DFD_EXTRA_SNAP_LEVELS a4c
MC_VE_EXTRA_SNAP_LEVELS 2d8
MC_GK_EXTRA_SNAP_LEVELS a00
MC_VE2_EXTRA_SNAP_LEVELS 410
MC_SDM_EXTRA_SNAP_LEVELS a44
MC_VIDEO_PROTECT_BOM 648
MC_VIDEO_PROTECT_SIZE_MB 64c
MC_VIDEO_PROTECT_BOM_ADR_HI 978
MC_VIDEO_PROTECT_REG_CTRL 650
MC_ERR_VPR_STATUS 654
MC_ERR_VPR_ADR 658
MC_VIDEO_PROTECT_VPR_OVERRIDE 418
MC_VIDEO_PROTECT_VPR_OVERRIDE1 590
MC_IRAM_BOM 65c
MC_IRAM_TOM 660
MC_IRAM_ADR_HI 980
MC_IRAM_REG_CTRL 964
MC_EMEM_CFG_ACCESS_CTRL 664
MC_TZ_SECURITY_CTRL 668
MC_EMEM_ARB_OUTSTANDING_REQ_RING3 66c
MC_EMEM_ARB_OUTSTANDING_REQ_NISO 6b4
MC_EMEM_ARB_RING0_THROTTLE_MASK 6bc
MC_EMEM_ARB_NISO_THROTTLE_MASK 6b8
MC_EMEM_ARB_NISO_THROTTLE_MASK_1 b80
MC_SEC_CARVEOUT_BOM 670
MC_SEC_CARVEOUT_SIZE_MB 674
MC_SEC_CARVEOUT_ADR_HI 9d4
MC_SEC_CARVEOUT_REG_CTRL 678
MC_ERR_SEC_STATUS 67c
MC_ERR_SEC_ADR 680
MC_PC_IDLE_CLOCK_GATE_CONFIG 684
MC_STUTTER_CONTROL 688
MC_RESERVED_RSV_1 958
MC_DVFS_PIPE_SELECT 95c
MC_AHB_PTSA_MIN 4e0
MC_AUD_PTSA_MIN 54c
MC_MLL_MPCORER_PTSA_RATE 44c
MC_RING2_PTSA_RATE 440
MC_USBD_PTSA_RATE 530
MC_USBX_PTSA_MIN 528
MC_USBD_PTSA_MIN 534
MC_APB_PTSA_MAX 4f0
MC_JPG_PTSA_RATE 584
MC_DIS_PTSA_MIN 420
MC_AVP_PTSA_MAX 4fc
MC_AVP_PTSA_RATE 4f4
MC_RING1_PTSA_MIN 480
MC_DIS_PTSA_MAX 424
MC_SD_PTSA_MAX 4d8
MC_MSE_PTSA_RATE 4c4
MC_VICPC_PTSA_MIN 558
MC_PCX_PTSA_MAX 4b4
MC_ISP_PTSA_RATE 4a0
MC_A9AVPPC_PTSA_MIN 48c
MC_RING2_PTSA_MAX 448
MC_AUD_PTSA_RATE 548
MC_HOST_PTSA_MIN 51c
MC_MLL_MPCORER_PTSA_MAX 454
MC_SD_PTSA_MIN 4d4
MC_RING1_PTSA_RATE 47c
MC_JPG_PTSA_MIN 588
MC_HDAPC_PTSA_MIN 62c
MC_AVP_PTSA_MIN 4f8
MC_JPG_PTSA_MAX 58c
MC_VE_PTSA_MAX 43c
MC_DFD_PTSA_MAX 63c
MC_VICPC_PTSA_RATE 554
MC_GK_PTSA_MAX 544
MC_VICPC_PTSA_MAX 55c
MC_SDM_PTSA_MAX 624
MC_SAX_PTSA_RATE 4b8
MC_PCX_PTSA_MIN 4b0
MC_APB_PTSA_MIN 4ec
MC_GK2_PTSA_MIN 614
MC_PCX_PTSA_RATE 4ac
MC_RING1_PTSA_MAX 484
MC_HDAPC_PTSA_RATE 628
MC_MLL_MPCORER_PTSA_MIN 450
MC_GK2_PTSA_MAX 618
MC_AUD_PTSA_MAX 550
MC_GK2_PTSA_RATE 610
MC_ISP_PTSA_MAX 4a8
MC_DISB_PTSA_RATE 428
MC_VE2_PTSA_MAX 49c
MC_DFD_PTSA_MIN 638
MC_FTOP_PTSA_RATE 50c
MC_A9AVPPC_PTSA_RATE 488
MC_VE2_PTSA_MIN 498
MC_USBX_PTSA_MAX 52c
MC_DIS_PTSA_RATE 41c
MC_USBD_PTSA_MAX 538
MC_A9AVPPC_PTSA_MAX 490
MC_USBX_PTSA_RATE 524
MC_FTOP_PTSA_MAX 514
MC_HDAPC_PTSA_MAX 630
MC_SD_PTSA_RATE 4d0
MC_DFD_PTSA_RATE 634
MC_FTOP_PTSA_MIN 510
MC_SDM_PTSA_RATE 61c
MC_AHB_PTSA_RATE 4dc
MC_SMMU_SMMU_PTSA_MAX 460
MC_RING2_PTSA_MIN 444
MC_SDM_PTSA_MIN 620
MC_APB_PTSA_RATE 4e8
MC_MSE_PTSA_MIN 4c8
MC_HOST_PTSA_RATE 518
MC_VE_PTSA_RATE 434
MC_AHB_PTSA_MAX 4e4
MC_SAX_PTSA_MIN 4bc
MC_SMMU_SMMU_PTSA_MIN 45c
MC_ISP_PTSA_MIN 4a4
MC_HOST_PTSA_MAX 520
MC_SAX_PTSA_MAX 4c0
MC_VE_PTSA_MIN 438
MC_GK_PTSA_MIN 540
MC_MSE_PTSA_MAX 4cc
MC_DISB_PTSA_MAX 430
MC_DISB_PTSA_MIN 42c
MC_SMMU_SMMU_PTSA_RATE 458
MC_VE2_PTSA_RATE 494
MC_GK_PTSA_RATE 53c
MC_PTSA_GRANT_DECREMENT 960
MC_LATENCY_ALLOWANCE_AVPC_0 2e4
MC_LATENCY_ALLOWANCE_AXIAP_0 3a0
MC_LATENCY_ALLOWANCE_XUSB_1 380
MC_LATENCY_ALLOWANCE_ISP2B_0 384
MC_LATENCY_ALLOWANCE_SDMMCAA_0 3bc
MC_LATENCY_ALLOWANCE_SDMMCA_0 3b8
MC_LATENCY_ALLOWANCE_ISP2_0 370
MC_LATENCY_ALLOWANCE_SE_0 3e0
MC_LATENCY_ALLOWANCE_ISP2_1 374
MC_LATENCY_ALLOWANCE_DC_0 2e8
MC_LATENCY_ALLOWANCE_VIC_0 394
MC_LATENCY_ALLOWANCE_DCB_1 2f8
MC_LATENCY_ALLOWANCE_NVDEC_0 3d8
MC_LATENCY_ALLOWANCE_DCB_2 2fc
MC_LATENCY_ALLOWANCE_TSEC_0 390
MC_LATENCY_ALLOWANCE_DC_2 2f0
MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 694
MC_LATENCY_ALLOWANCE_PPCS_1 348
MC_LATENCY_ALLOWANCE_XUSB_0 37c
MC_LATENCY_ALLOWANCE_PPCS_0 344
MC_LATENCY_ALLOWANCE_TSECB_0 3f0
MC_LATENCY_ALLOWANCE_AFI_0 2e0
MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 698
MC_LATENCY_ALLOWANCE_DC_1 2ec
MC_LATENCY_ALLOWANCE_APE_0 3dc
MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 6a0
MC_LATENCY_ALLOWANCE_A9AVP_0 3a4
MC_LATENCY_ALLOWANCE_GPU2_0 3e8
MC_LATENCY_ALLOWANCE_DCB_0 2f4
MC_LATENCY_ALLOWANCE_HC_1 314
MC_LATENCY_ALLOWANCE_SDMMC_0 3c0
MC_LATENCY_ALLOWANCE_NVJPG_0 3e4
MC_LATENCY_ALLOWANCE_PTC_0 34c
MC_LATENCY_ALLOWANCE_ETR_0 3ec
MC_LATENCY_ALLOWANCE_MPCORE_0 320
MC_LATENCY_ALLOWANCE_VI2_0 398
MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 69c
MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 6a4
MC_LATENCY_ALLOWANCE_SATA_0 350
MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 690
MC_LATENCY_ALLOWANCE_HC_0 310
MC_LATENCY_ALLOWANCE_DC_3 3c8
MC_LATENCY_ALLOWANCE_GPU_0 3ac
MC_LATENCY_ALLOWANCE_SDMMCAB_0 3c4
MC_LATENCY_ALLOWANCE_ISP2B_1 388
MC_LATENCY_ALLOWANCE_NVENC_0 328
MC_LATENCY_ALLOWANCE_HDA_0 318
MC_MIN_LENGTH_APE_0 b34
MC_MIN_LENGTH_DCB_2 8a8
MC_MIN_LENGTH_A9AVP_0 950
MC_MIN_LENGTH_TSEC_0 93c
MC_MIN_LENGTH_DC_1 898
MC_MIN_LENGTH_AXIAP_0 94c
MC_MIN_LENGTH_ISP2B_0 930
MC_MIN_LENGTH_VI2_0 944
MC_MIN_LENGTH_DCB_0 8a0
MC_MIN_LENGTH_DCB_1 8a4
MC_MIN_LENGTH_PPCS_1 8f4
MC_MIN_LENGTH_NVJPG_0 b3c
MC_MIN_LENGTH_HDA_0 8c4
MC_MIN_LENGTH_NVENC_0 8d4
MC_MIN_LENGTH_SDMMC_0 b18
MC_MIN_LENGTH_ISP2B_1 934
MC_MIN_LENGTH_HC_1 8c0
MC_MIN_LENGTH_DC_3 b20
MC_MIN_LENGTH_AVPC_0 890
MC_MIN_LENGTH_VIC_0 940
MC_MIN_LENGTH_ISP2_0 91c
MC_MIN_LENGTH_HC_0 8bc
MC_MIN_LENGTH_SE_0 b38
MC_MIN_LENGTH_NVDEC_0 b30
MC_MIN_LENGTH_SATA_0 8fc
MC_MIN_LENGTH_DC_0 894
MC_MIN_LENGTH_XUSB_1 92c
MC_MIN_LENGTH_DC_2 89c
MC_MIN_LENGTH_SDMMCAA_0 b14
MC_MIN_LENGTH_GPU_0 b04
MC_MIN_LENGTH_ETR_0 b44
MC_MIN_LENGTH_AFI_0 88c
MC_MIN_LENGTH_PPCS_0 8f0
MC_MIN_LENGTH_ISP2_1 920
MC_MIN_LENGTH_XUSB_0 928
MC_MIN_LENGTH_MPCORE_0 8cc
MC_MIN_LENGTH_TSECB_0 b48
MC_MIN_LENGTH_SDMMCA_0 b10
MC_MIN_LENGTH_GPU2_0 b40
MC_MIN_LENGTH_SDMMCAB_0 b1c
MC_MIN_LENGTH_PTC_0 8f8
MC_EMEM_ARB_OVERRIDE_1 968
MC_VIDEO_PROTECT_GPU_OVERRIDE_0 984
MC_VIDEO_PROTECT_GPU_OVERRIDE_1 988
MC_EMEM_ARB_STATS_0 990
MC_EMEM_ARB_STATS_1 994
MC_MTS_CARVEOUT_BOM 9a0
MC_MTS_CARVEOUT_SIZE_MB 9a4
MC_MTS_CARVEOUT_ADR_HI 9a8
MC_MTS_CARVEOUT_REG_CTRL 9ac
MC_ERR_MTS_STATUS 9b0
MC_ERR_MTS_ADR 9b4
MC_ERR_GENERALIZED_CARVEOUT_STATUS c00
MC_ERR_GENERALIZED_CARVEOUT_ADR c04
MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 d74
MC_SECURITY_CARVEOUT4_CFG0 cf8
MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 d10
MC_SECURITY_CARVEOUT4_SIZE_128KB d04
MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 c28
MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 c30
MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 c8c
MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 d1c
MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 d70
MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 c2c
MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 d7c
MC_SECURITY_CARVEOUT3_SIZE_128KB cb4
MC_SECURITY_CARVEOUT2_CFG0 c58
MC_SECURITY_CARVEOUT1_CFG0 c08
MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 c84
MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 c68
MC_SECURITY_CARVEOUT3_BOM cac
MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 c70
MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 d78
MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 c7c
MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 d18
MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 cbc
MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 c38
MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 c34
MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 cc0
MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 d60
MC_SECURITY_CARVEOUT3_CFG0 ca8
MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 cb8
MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 c88
MC_SECURITY_CARVEOUT2_SIZE_128KB c64
MC_SECURITY_CARVEOUT5_BOM_HI d50
MC_SECURITY_CARVEOUT1_SIZE_128KB c14
MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 d14
MC_SECURITY_CARVEOUT1_BOM c0c
MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 d2c
MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 d68
MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 cc8
MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 d58
MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 d24
MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 cc4
MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 c78
MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 c1c
MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 c18
MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 d28
MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 d5c
MC_SECURITY_CARVEOUT3_BOM_HI cb0
MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 cd8
MC_SECURITY_CARVEOUT2_BOM_HI c60
MC_SECURITY_CARVEOUT4_BOM_HI d00
MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 d64
MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 cdc
MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 c80
MC_SECURITY_CARVEOUT5_SIZE_128KB d54
MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 d20
MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 cd4
MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 d0c
MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 c74
MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 ccc
MC_SECURITY_CARVEOUT4_BOM cfc
MC_SECURITY_CARVEOUT5_CFG0 d48
MC_SECURITY_CARVEOUT2_BOM c5c
MC_SECURITY_CARVEOUT5_BOM d4c
MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 c24
MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 d6c
MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 cd0
MC_SECURITY_CARVEOUT1_BOM_HI c10
MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 c20
MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 c3c
MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 c6c
MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 d08
MC_ERR_APB_ASID_UPDATE_STATUS 9d0
MC_DA_CONFIG0 9dc