Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a6608dff4 | ||
|
|
8f222fd0bd | ||
|
|
1f5b371608 | ||
|
|
ce156ab4e7 | ||
|
|
94235dd005 | ||
|
|
cb471162d2 | ||
|
|
9d1c0ce308 | ||
|
|
27b1f0e843 | ||
|
|
dae7be8ec4 | ||
|
|
2f5b52223c | ||
|
|
bf222290b8 | ||
|
|
d825be5eb2 | ||
|
|
9da0e0358b | ||
|
|
216d97aada | ||
|
|
e3421fd44e | ||
|
|
85d43147ee | ||
|
|
e3e5dab0fc | ||
|
|
8b837dd81b | ||
|
|
8f7bdd45b1 | ||
|
|
0142ac1697 | ||
|
|
e8fb6624c0 | ||
|
|
bdb21ce3fd | ||
|
|
2ca4fb6d8f | ||
|
|
e7900b11b4 | ||
|
|
d71f6d0b99 | ||
|
|
926bd5d2fb | ||
|
|
461d14c39a | ||
|
|
6714cae498 | ||
|
|
b20a0e74c2 | ||
|
|
9686eaf3f1 | ||
|
|
7b03a24196 | ||
|
|
98555b24f8 | ||
|
|
3d05b58856 | ||
|
|
15b46ddb27 | ||
|
|
78c4e6510d | ||
|
|
cd76d5ac09 | ||
|
|
9c2a064817 | ||
|
|
db2da89f69 | ||
|
|
0652d6b3f1 | ||
|
|
1111125aab | ||
|
|
4fc420616d | ||
|
|
fb7c83a66c | ||
|
|
f021665089 | ||
|
|
6c887c15be | ||
|
|
2b7722da7d | ||
|
|
4f65697522 | ||
|
|
5140992a7b | ||
|
|
af0cd34f92 | ||
|
|
b8ca88ee0a | ||
|
|
fac1884a43 | ||
|
|
46fa330bdd | ||
|
|
adfa7c0780 | ||
|
|
11df6030f9 | ||
|
|
45ca2938f5 | ||
|
|
88fa4fa861 | ||
|
|
100d6cc4a5 | ||
|
|
32e58d2bb3 | ||
|
|
638a3909c5 | ||
|
|
82da1aaf2a | ||
|
|
3c2d86ef7b | ||
|
|
f559017aeb | ||
|
|
e158d9bc00 | ||
|
|
3ddd1c26ad | ||
|
|
ab5b59e10d | ||
|
|
1f67251331 | ||
|
|
4eecdfa553 | ||
|
|
80dd0f1580 | ||
|
|
4e0c70a402 | ||
|
|
ffd5a198f9 | ||
|
|
ddc89c9f49 | ||
|
|
9673d5524a | ||
|
|
3214fc2f93 | ||
|
|
3b0925b912 | ||
|
|
c5f032fcb2 |
18
Makefile
18
Makefile
@@ -19,7 +19,7 @@ SOURCEDIR = bootloader
|
||||
BDKDIR := bdk
|
||||
BDKINC := -I./$(BDKDIR)
|
||||
VPATH = $(dir ./$(SOURCEDIR)/) $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
|
||||
VPATH += $(dir $(wildcard ./$(BDKDIR)/*/)) $(dir $(wildcard ./$(BDKDIR)/*/*/))
|
||||
VPATH += $(dir $(wildcard ./$(BDKDIR)/)) $(dir $(wildcard ./$(BDKDIR)/*/)) $(dir $(wildcard ./$(BDKDIR)/*/*/))
|
||||
|
||||
# Main and graphics.
|
||||
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
@@ -32,7 +32,7 @@ OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
# Hardware.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
bpmp.o ccplex.o clock.o di.o gpio.o i2c.o irq.o mc.o sdram.o \
|
||||
pinmux.o se.o smmu.o tsec.o uart.o \
|
||||
pinmux.o pmc.o se.o smmu.o tsec.o uart.o \
|
||||
fuse.o kfuse.o minerva.o \
|
||||
sdmmc.o sdmmc_driver.o emummc.o nx_emmc.o nx_sd.o \
|
||||
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
||||
@@ -84,11 +84,14 @@ NYXDIR := $(wildcard nyx)
|
||||
.PHONY: all clean $(MODULEDIRS) $(NYXDIR)
|
||||
|
||||
all: $(TARGET).bin
|
||||
@echo -n "Payload size is "
|
||||
@printf ICTC49 >> $(OUTPUTDIR)/$(TARGET).bin
|
||||
@echo "--------------------------------------"
|
||||
@echo -n "Payload size: "
|
||||
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET).bin))
|
||||
@echo $(BIN_SIZE)
|
||||
@echo "Max size is 126296 Bytes."
|
||||
@echo $(BIN_SIZE)" Bytes"
|
||||
@echo "Payload Max: 126296 Bytes"
|
||||
@if [ ${BIN_SIZE} -gt 126296 ]; then echo "\e[1;33mPayload size exceeds limit!\e[0m"; fi
|
||||
@echo "--------------------------------------"
|
||||
|
||||
clean:
|
||||
@rm -rf $(OBJS)
|
||||
@@ -96,14 +99,13 @@ clean:
|
||||
@rm -rf $(OUTPUTDIR)
|
||||
|
||||
$(MODULEDIRS):
|
||||
@$(MAKE) -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(NYXDIR):
|
||||
@$(MAKE) -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) $(NYXDIR)
|
||||
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||
@printf ICTC49 >> $(OUTPUTDIR)/$@
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||
@$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||
|
||||
10
README.md
10
README.md
@@ -55,6 +55,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. |
|
||||
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
|
||||
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
|
||||
| bootprotect=0 | 0: Disable, 1: Protect bootloader folder from being corrupted by disallowing reading or editing in HOS. |
|
||||
| updater2p=0 | 0: Disable, 1: Force updates (if needed) the reboot2payload binary to be hekate. |
|
||||
| backlight=100 | Screen backlight level. 0-255. |
|
||||
|
||||
@@ -67,7 +68,8 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
| timeoff=100 | Sets time offset in HEX. Must be in HOS epoch format |
|
||||
| homescreen=0 | Sets home screen. 0: Home menu, 1: All configs (merges Launch and More configs), 2: Launch, 3: More Configs. |
|
||||
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| umsemmcrw=1 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
|
||||
| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
|
||||
| jcdisable=0 | 1: Disables Joycon driver completely. |
|
||||
|
||||
|
||||
### Boot entry key/value combinations:
|
||||
@@ -120,12 +122,12 @@ hekate has a boot storage in the binary that helps it configure it outside of BP
|
||||
|
||||
| Offset / Name | Description |
|
||||
| ----------------------- | ----------------------------------------------------------------- |
|
||||
| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: `Boot from ID`, bit3: `Boot to emuMMC`, bit6: `Boot to UMS`, bit7: `sept run`. |
|
||||
| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: `Boot from ID`, bit3: `Boot to emuMMC`, bit7: `sept run`. |
|
||||
| '0x95' autoboot | If `Force AutoBoot`: 0: Force go to menu, else boot that entry. |
|
||||
| '0x96' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
|
||||
| '0x97' extra_cfg | bit7: Force Nyx to run `Dump pkg1/2`. |
|
||||
| '0x97' extra_cfg | When menu is forced: bit5: `Run UMS`, bit7: `Run Dump pkg1/2`. |
|
||||
| '0x98' xt_str[128] | Depends on the set cfg bits. |
|
||||
| '0x98' ums[1] | When `Boot to UMS` is set, it will launch the selected UMS. 0: SD, 1: eMMC BOOT0, 2: eMMC BOOT1, 3: eMMC GPP, 4: emuMMC BOOT0, 5: emuMMC BOOT1, 6: emuMMC GPP, |
|
||||
| '0x98' ums[1] | When `Run UMS` is set, it will launch the selected UMS. 0: SD, 1: eMMC BOOT0, 2: eMMC BOOT1, 3: eMMC GPP, 4: emuMMC BOOT0, 5: emuMMC BOOT1, 6: emuMMC GPP, |
|
||||
| '0x98' id[8] | When `Boot from ID` is set, it will search all inis automatically and find the boot entry with that id and boot it. Must be NULL terminated. |
|
||||
| '0xA0' emummc_path[120] | When `Boot to emuMMC` is set, it will override the current emuMMC (boot entry or emummc.ini). Must be NULL terminated. |
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# IPL Version.
|
||||
BLVERSION_MAJOR := 5
|
||||
BLVERSION_MINOR := 3
|
||||
BLVERSION_HOTFX := 0
|
||||
BLVERSION_HOTFX := 4
|
||||
BLVERSION_RSVD := 0
|
||||
|
||||
# Nyx Version.
|
||||
NYXVERSION_MAJOR := 0
|
||||
NYXVERSION_MINOR := 9
|
||||
NYXVERSION_HOTFX := 2
|
||||
NYXVERSION_HOTFX := 5
|
||||
NYXVERSION_RSVD := 0
|
||||
|
||||
47
bdk/gfx/di.c
47
bdk/gfx/di.c
@@ -56,7 +56,7 @@ static void _display_dsi_send_cmd(u8 cmd, u32 param, u32 wait)
|
||||
void display_init()
|
||||
{
|
||||
// Check if display is already initialized.
|
||||
if (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) & 0x18000000)
|
||||
if (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) & (BIT(CLK_L_DISP1) | BIT(CLK_L_HOST1X)))
|
||||
display_end();
|
||||
|
||||
// Power on.
|
||||
@@ -64,28 +64,28 @@ void display_init()
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7, MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DRV_PUSHPULL);
|
||||
|
||||
// Enable Display Interface specific clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x1010000; // Clear reset DSI, MIPI_CAL.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x1010000; // Set enable clock DSI, MIPI_CAL.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000; // Clear reset DISP1, HOST1X.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = 0x18000000; // Set enable clock DISP1, HOST1X.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x20000; // Set enable clock UART_FST_MIPI_CAL.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz).
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = 0x80000; // Set enable clock DSIA_LP.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz).
|
||||
|
||||
// Disable deep power down.
|
||||
PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000;
|
||||
PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000;
|
||||
PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000;
|
||||
|
||||
// Config LCD and Backlight pins.
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE; // PULL_DOWN | 1
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
|
||||
// Set Backlight +-5V pins mode and direction
|
||||
gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
@@ -170,8 +170,8 @@ void display_init()
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
break;
|
||||
case PANEL_INL_P062CCA_AZ2:
|
||||
case PANEL_AUO_A062TAN02:
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
case PANEL_AUO_A055TAN01:
|
||||
default: // Allow spare part displays to work.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 120000);
|
||||
break;
|
||||
@@ -180,14 +180,15 @@ void display_init()
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
|
||||
|
||||
// Configure PLLD for DISP1.
|
||||
plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 460.8 MHz.
|
||||
plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 230.4 MHz.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // Use new PLLD_SDM_DIN.
|
||||
|
||||
// Finalize DSI configuration.
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_packet_config, 21);
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4; // PCD1 | div3.
|
||||
// Set pixel clock dividers: 230.4 / 3 / 1 = 76.8 MHz. 60 Hz.
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3.
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_mode_config, 10);
|
||||
usleep(10000);
|
||||
|
||||
@@ -269,15 +270,15 @@ void display_end()
|
||||
case PANEL_AUO_A062TAN01:
|
||||
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_auo, 37);
|
||||
break;
|
||||
case PANEL_INL_P062CCA_AZ2:
|
||||
case PANEL_AUO_A062TAN02:
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
case PANEL_AUO_A055TAN01:
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // Enable extension cmd. (Pass: FF 83 94).
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
// Set Power.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0xB39; // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
|
||||
if (_display_id == PANEL_INL_P062CCA_AZ2)
|
||||
if (_display_id == PANEL_INL_2J055IA_27A)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // Set Power control. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
|
||||
else
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // Set Power control. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
|
||||
@@ -305,10 +306,10 @@ void display_end()
|
||||
usleep(10000);
|
||||
|
||||
// Disable Display Interface specific clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x1010000; // Set reset clock DSI, MIPI_CAL.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = 0x1010000; // Clear enable clock DSI, MIPI_CAL.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000; // Set reset DISP1, HOST1X.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = 0x18000000; // Clear enable DISP1, HOST1X.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
|
||||
// Power down pads.
|
||||
DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
|
||||
|
||||
14
bdk/gfx/di.h
14
bdk/gfx/di.h
@@ -496,12 +496,18 @@
|
||||
#define MIPI_DCS_SET_DISPLAY_ON 0x29
|
||||
|
||||
/* Switch Panels:
|
||||
*
|
||||
* 6.2 panels":
|
||||
* [10] 81 [26]: JDI LPM062M326A
|
||||
* [10] 96 [09]: JDI LAM062M109A
|
||||
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
|
||||
* [20] XX [10]: InnoLux P062CCA-AZ2 [UNCONFIRMED ID]
|
||||
* [20] 95 [0F]: InnoLux P062CCA-AZ2
|
||||
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
|
||||
* [30] XX [10]: AUO A062TAN02 (59.06A33.002) [UNCONFIRMED ID]
|
||||
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
|
||||
*
|
||||
* 5.5" panels:
|
||||
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1)
|
||||
* [30] XX [10]: AUO A055TAN01 (59.05A30.001) [UNCONFIRMED ID]
|
||||
*/
|
||||
|
||||
enum
|
||||
@@ -511,8 +517,8 @@ enum
|
||||
PANEL_JDI_LPM062M326A = 0x2610,
|
||||
PANEL_INL_P062CCA_AZ1 = 0x0F20,
|
||||
PANEL_AUO_A062TAN01 = 0x0F30,
|
||||
PANEL_INL_P062CCA_AZ2 = 0x1020,
|
||||
PANEL_AUO_A062TAN02 = 0x1030
|
||||
PANEL_INL_2J055IA_27A = 0x1020,
|
||||
PANEL_AUO_A055TAN01 = 0x1030
|
||||
};
|
||||
|
||||
void display_init();
|
||||
|
||||
@@ -96,7 +96,7 @@ static const cfg_op_t _display_dc_setup_win_config[94] = {
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{0x4E4, 0},
|
||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
@@ -253,7 +253,7 @@ static const cfg_op_t _display_dsi_packet_config[21] = {
|
||||
{DSI_PKT_LEN_2_3, 0x87001A2},
|
||||
{DSI_PKT_LEN_4_5, 0x190},
|
||||
{DSI_PKT_LEN_6_7, 0x190},
|
||||
{DSI_HOST_CONTROL, 0},
|
||||
{DSI_HOST_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI mode config.
|
||||
@@ -372,16 +372,16 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{0x4E4, 0},
|
||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
@@ -394,14 +394,37 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
/* Set Display timings */
|
||||
|
||||
/* Set Display timings
|
||||
*
|
||||
* DC_DISP_REF_TO_SYNC:
|
||||
* V_REF_TO_SYNC - 1
|
||||
* H_REF_TO_SYNC - 0
|
||||
*
|
||||
* DC_DISP_SYNC_WIDTH:
|
||||
* V_SYNC_WIDTH - 1
|
||||
* H_SYNC_WIDTH - 72
|
||||
*
|
||||
* DC_DISP_BACK_PORCH:
|
||||
* V_BACK_PORCH - 9
|
||||
* H_BACK_PORCH - 72
|
||||
*
|
||||
* DC_DISP_ACTIVE:
|
||||
* V_DISP_ACTIVE - 1280
|
||||
* H_DISP_ACTIVE - 720
|
||||
*
|
||||
* DC_DISP_FRONT_PORCH:
|
||||
* V_FRONT_PORCH - 10
|
||||
* H_FRONT_PORCH - 136
|
||||
*/
|
||||
{DC_DISP_DISP_TIMING_OPTIONS, 0},
|
||||
{DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.
|
||||
{DC_DISP_REF_TO_SYNC, 0x10000},
|
||||
{DC_DISP_SYNC_WIDTH, 0x10048},
|
||||
{DC_DISP_BACK_PORCH, 0x90048},
|
||||
{DC_DISP_ACTIVE, 0x50002D0},
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should happen before DC_DISP_ACTIVE cmd.
|
||||
/* End of Display timings */
|
||||
|
||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
|
||||
|
||||
@@ -102,7 +102,8 @@ u8 als_init(als_table_t *als_val)
|
||||
i2c_init(I2C_2);
|
||||
|
||||
max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2, 0xD8 | MAX77620_LDO_CFG2_ADE_MASK);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
|
||||
(MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT | (3 << 3) | MAX77620_LDO_CFG2_ADE_ENABLE));
|
||||
|
||||
u8 id = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(0x12));
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_SPEC(BH1730_SPECCMD_RESET), 0);
|
||||
|
||||
@@ -206,7 +206,7 @@ static u16 jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u
|
||||
out->uart_hdr.magic[1] = 0x01;
|
||||
out->uart_hdr.magic[2] = 0x3;
|
||||
|
||||
out->uart_hdr.total_size_lsb = 7;
|
||||
out->uart_hdr.total_size_lsb = sizeof(jc_wired_hdr_t) - sizeof(jc_uart_hdr_t);
|
||||
out->uart_hdr.total_size_msb = 0;
|
||||
out->cmd = wired_cmd;
|
||||
|
||||
@@ -523,6 +523,9 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos)
|
||||
u8 retries;
|
||||
jc_bt_conn_t *bt_conn;
|
||||
|
||||
if (!jc_init_done)
|
||||
return NULL;
|
||||
|
||||
bt_conn = &jc_gamepad.bt_conn_l;
|
||||
memset(bt_conn->host_mac, 0, 6);
|
||||
memset(bt_conn->ltk, 0, 16);
|
||||
@@ -812,7 +815,7 @@ void jc_init_hw()
|
||||
jc_l.uart = UART_C;
|
||||
jc_r.uart = UART_B;
|
||||
|
||||
#if (LV_LOG_PRINTF != 1)
|
||||
#ifndef DEBUG_UART_PORT
|
||||
jc_power_supply(UART_C, true);
|
||||
jc_power_supply(UART_B, true);
|
||||
|
||||
|
||||
@@ -361,7 +361,7 @@ int touch_power_on()
|
||||
// Enables LDO6 for touchscreen VDD/AVDD supply
|
||||
max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
|
||||
MAX77620_LDO_CFG2_ADE_ENABLE | (3 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT));
|
||||
(MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT | (3 << 3) | MAX77620_LDO_CFG2_ADE_ENABLE));
|
||||
|
||||
// Configure touchscreen GPIO.
|
||||
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
||||
|
||||
@@ -125,7 +125,7 @@ static int _LZ_ReadVarSize( unsigned int * x, const unsigned char * buf )
|
||||
* insize - Number of input bytes.
|
||||
*************************************************************************/
|
||||
|
||||
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int insize )
|
||||
{
|
||||
unsigned char marker, symbol;
|
||||
@@ -134,7 +134,7 @@ void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
/* Do we have anything to uncompress? */
|
||||
if( insize < 1 )
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get marker symbol from input stream */
|
||||
@@ -176,4 +176,6 @@ void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
}
|
||||
}
|
||||
while( inpos < insize );
|
||||
|
||||
return outpos;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ extern "C" {
|
||||
* Function prototypes
|
||||
*************************************************************************/
|
||||
|
||||
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int insize );
|
||||
|
||||
|
||||
|
||||
@@ -155,7 +155,11 @@
|
||||
|
||||
|
||||
/*Log settings*/
|
||||
#define USE_LV_LOG 0 /*Enable/disable the log module*/
|
||||
#ifdef DEBUG_UART_PORT
|
||||
# define USE_LV_LOG 1 /*Enable/disable the log module*/
|
||||
#else
|
||||
# define USE_LV_LOG 0 /*Enable/disable the log module*/
|
||||
#endif
|
||||
#if USE_LV_LOG
|
||||
/* How important log should be added:
|
||||
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
|
||||
@@ -67,7 +67,7 @@ void lv_log_add(lv_log_level_t level, const char * file, int line, const char *
|
||||
static const char * lvl_prefix[] = {"Trace", "Info", "Warn", "Error"};
|
||||
char *log = (char *)malloc(0x1000);
|
||||
s_printf(log, "%s: %s \t(%s #%d)\r\n", lvl_prefix[level], dsc, file, line);
|
||||
uart_send(UART_B, (u8 *)log, strlen(log) + 1);
|
||||
uart_send(DEBUG_UART_PORT, (u8 *)log, strlen(log) + 1);
|
||||
//gfx_printf("%s: %s \t(%s #%d)\n", lvl_prefix[level], dsc, file, line);
|
||||
#else
|
||||
if(print_cb) print_cb(level, file, line, dsc);
|
||||
|
||||
13
bdk/mem/mc.c
13
bdk/mem/mc.c
@@ -144,13 +144,12 @@ void mc_disable_ahb_redirect()
|
||||
void mc_enable()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000;
|
||||
// Enable EMC 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_CLR) = 0x2000001; //Clear EMC and MC reset.
|
||||
// Enable memory clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & ~BIT(CLK_H_EMC)) | BIT(CLK_H_EMC);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & ~BIT(CLK_H_MEM)) | BIT(CLK_H_MEM);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & ~BIT(CLK_X_EMC_DLL)) | BIT(CLK_X_EMC_DLL);
|
||||
// Clear clock resets for memory.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||
usleep(5);
|
||||
|
||||
//#ifdef CONFIG_ENABLE_AHB_REDIRECT
|
||||
|
||||
@@ -143,9 +143,10 @@ break_nosleep:
|
||||
if (params->clear_clock2_mc1)
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000; // Clear Reset to MC1.
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001; // Enable EMC and MEM clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000; // Enable EMC_DLL clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001; // Clear EMC and MEM resets.
|
||||
// Enable and clear reset for memory clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||
|
||||
// Set pad macros.
|
||||
EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
|
||||
|
||||
@@ -41,8 +41,12 @@
|
||||
/* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */
|
||||
|
||||
// Virtual disk / Chainloader buffers.
|
||||
#define RAM_DISK_ADDR 0xA4000000
|
||||
#define RAM_DISK_SZ 0x41000000 // 1040MB.
|
||||
#define RAM_DISK_ADDR 0xA4000000
|
||||
#define RAM_DISK_SZ 0x41000000 // 1040MB.
|
||||
|
||||
// L4T Kernel Panic Storage (PSTORE).
|
||||
#define PSTORE_ADDR 0xB0000000
|
||||
#define PSTORE_SZ 0x200000 // 2MB.
|
||||
|
||||
//#define DRAM_LIB_ADDR 0xE0000000
|
||||
/* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading.
|
||||
|
||||
99
bdk/power/bm92t36.c
Normal file
99
bdk/power/bm92t36.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* USB-PD driver for Nintendo Switch's TI BM92T36
|
||||
*
|
||||
* Copyright (c) 2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bm92t36.h"
|
||||
#include <soc/i2c.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define ALERT_STATUS_REG 0x2
|
||||
#define STATUS1_REG 0x3
|
||||
#define STATUS2_REG 0x4
|
||||
#define COMMAND_REG 0x5
|
||||
#define CONFIG1_REG 0x6
|
||||
#define DEV_CAPS_REG 0x7
|
||||
#define READ_PDOS_SRC_REG 0x8
|
||||
#define CONFIG2_REG 0x17
|
||||
#define DP_STATUS_REG 0x18
|
||||
#define DP_ALERT_EN_REG 0x19
|
||||
#define VENDOR_CONFIG_REG 0x1A
|
||||
#define AUTO_NGT_FIXED_REG 0x20
|
||||
#define AUTO_NGT_BATT_REG 0x23
|
||||
#define SYS_CONFIG1_REG 0x26
|
||||
#define SYS_CONFIG2_REG 0x27
|
||||
#define CURRENT_PDO_REG 0x28
|
||||
#define CURRENT_RDO_REG 0x2B
|
||||
#define ALERT_ENABLE_REG 0x2E
|
||||
#define SYS_CONFIG3_REG 0x2F
|
||||
#define SET_RDO_REG 0x30
|
||||
#define PDOS_SNK_REG 0x33
|
||||
#define PDOS_SRC_PROV_REG 0x3C
|
||||
#define FW_TYPE_REG 0x4B
|
||||
#define FW_REVISION_REG 0x4C
|
||||
#define MAN_ID_REG 0x4D
|
||||
#define DEV_ID_REG 0x4E
|
||||
#define REV_ID_REG 0x4F
|
||||
#define INCOMING_VDM_REG 0x50
|
||||
#define OUTGOING_VDM_REG 0x60
|
||||
|
||||
#define STATUS1_INSERT BIT(7) // Cable inserted.
|
||||
|
||||
typedef struct _pd_object_t {
|
||||
unsigned int amp:10;
|
||||
unsigned int volt:10;
|
||||
unsigned int info:10;
|
||||
unsigned int type:2;
|
||||
} __attribute__((packed)) pd_object_t;
|
||||
|
||||
static int _bm92t36_read_reg(u8 *buf, u32 size, u32 reg)
|
||||
{
|
||||
return i2c_recv_buf_big(buf, size, I2C_1, BM92T36_I2C_ADDR, reg);
|
||||
}
|
||||
|
||||
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
||||
{
|
||||
u8 buf[32];
|
||||
pd_object_t pdos[7];
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
_bm92t36_read_reg(buf, 2, STATUS1_REG);
|
||||
*inserted = buf[0] & STATUS1_INSERT ? true : false;
|
||||
}
|
||||
|
||||
if (usb_pd)
|
||||
{
|
||||
_bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG);
|
||||
memcpy(pdos, &buf[1], 28);
|
||||
|
||||
memset(usb_pd, 0, sizeof(usb_pd_objects_t));
|
||||
usb_pd->pdo_no = buf[0] / sizeof(pd_object_t);
|
||||
|
||||
for (u32 i = 0; i < usb_pd->pdo_no; i++)
|
||||
{
|
||||
usb_pd->pdos[i].amperage = pdos[i].amp * 10;
|
||||
usb_pd->pdos[i].voltage = (pdos[i].volt * 50) / 1000;
|
||||
}
|
||||
|
||||
_bm92t36_read_reg(buf, 5, CURRENT_PDO_REG);
|
||||
memcpy(pdos, &buf[1], 4);
|
||||
usb_pd->selected_pdo.amperage = pdos[0].amp * 10;
|
||||
usb_pd->selected_pdo.voltage = (pdos[0].volt * 50) / 1000;
|
||||
}
|
||||
}
|
||||
41
bdk/power/bm92t36.h
Normal file
41
bdk/power/bm92t36.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* USB-PD driver for Nintendo Switch's TI BM92T36
|
||||
*
|
||||
* Copyright (c) 2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __BM92T36_H_
|
||||
#define __BM92T36_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define BM92T36_I2C_ADDR 0x18
|
||||
|
||||
typedef struct _usb_pd_object_t
|
||||
{
|
||||
u32 amperage;
|
||||
u32 voltage;
|
||||
} usb_pd_object_t;
|
||||
|
||||
typedef struct _usb_pd_objects_t
|
||||
{
|
||||
u32 pdo_no;
|
||||
usb_pd_object_t pdos[7];
|
||||
usb_pd_object_t selected_pdo;
|
||||
} usb_pd_objects_t;
|
||||
|
||||
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd);
|
||||
|
||||
#endif
|
||||
@@ -108,11 +108,11 @@
|
||||
#define MAX77620_LDO_VOLT_MASK 0x3F
|
||||
#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_SD0_CFG 0x1D // SD CNFG1.
|
||||
#define MAX77620_REG_SD1_CFG 0x1E // SD CNFG1.
|
||||
#define MAX77620_REG_SD2_CFG 0x1F // SD CNFG1.
|
||||
#define MAX77620_REG_SD3_CFG 0x20 // SD CNFG1.
|
||||
#define MAX77620_REG_SD4_CFG 0x21 // SD CNFG1.
|
||||
#define MAX77620_REG_SD_CFG2 0x22
|
||||
#define MAX77620_REG_LDO0_CFG 0x23
|
||||
#define MAX77620_REG_LDO0_CFG2 0x24
|
||||
|
||||
32
bdk/sec/se.c
32
bdk/sec/se.c
@@ -198,6 +198,27 @@ void se_aes_key_set(u32 ks, void *key, u32 size)
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_iv_set(u32 ks, void *iv)
|
||||
{
|
||||
u32 *data = (u32 *)iv;
|
||||
|
||||
for (u32 i = 0; i < TEGRA_SE_AES_MIN_KEY_SIZE / 4; i++)
|
||||
{
|
||||
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i;
|
||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_key_get(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;
|
||||
data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_key_clear(u32 ks)
|
||||
{
|
||||
for (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++)
|
||||
@@ -207,6 +228,16 @@ void se_aes_key_clear(u32 ks)
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_iv_clear(u32 ks)
|
||||
{
|
||||
for (u32 i = 0; i < TEGRA_SE_AES_MIN_KEY_SIZE / 4; i++)
|
||||
{
|
||||
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i;
|
||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
|
||||
{
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTAB);
|
||||
@@ -336,6 +367,7 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
|
||||
int res;
|
||||
u32 *hash32 = (u32 *)hash;
|
||||
|
||||
//! TODO: src_size must be 512 bit aligned if continuing and not last block for SHA256.
|
||||
if (src_size > 0xFFFFFF || (u32)hash % 4 || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -24,8 +24,12 @@ void se_key_acc_ctrl(u32 ks, u32 flags);
|
||||
u32 se_key_acc_ctrl_get(u32 ks);
|
||||
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize);
|
||||
void se_aes_key_set(u32 ks, void *key, u32 size);
|
||||
void se_aes_iv_set(u32 ks, void *iv);
|
||||
void se_aes_key_get(u32 ks, void *key, u32 size);
|
||||
void se_aes_key_clear(u32 ks);
|
||||
void se_aes_iv_clear(u32 ks);
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
|
||||
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
|
||||
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
#include <soc/ccplex.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/clock.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <power/max77620.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
void _ccplex_enable_power()
|
||||
{
|
||||
@@ -40,39 +40,6 @@ void _ccplex_enable_power()
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_0_95V);
|
||||
}
|
||||
|
||||
int _ccplex_pmc_enable_partition(u32 part, int enable)
|
||||
{
|
||||
u32 part_mask = 1 << part;
|
||||
u32 desired_state = enable << part;
|
||||
|
||||
// Check if the partition has the state we want.
|
||||
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
|
||||
return 1;
|
||||
|
||||
u32 i = 5001;
|
||||
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
|
||||
{
|
||||
usleep(1);
|
||||
i--;
|
||||
if (i < 1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Toggle power gating.
|
||||
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = part | 0x100;
|
||||
|
||||
i = 5001;
|
||||
while (i > 0)
|
||||
{
|
||||
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
|
||||
break;
|
||||
usleep(1);
|
||||
i--;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ccplex_boot_cpu0(u32 entry)
|
||||
{
|
||||
// Set ACTIVE_CLUSER to FAST.
|
||||
@@ -94,12 +61,12 @@ void ccplex_boot_cpu0(u32 entry)
|
||||
|
||||
// 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;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) & ~BIT(CLK_V_MSELECT)) | BIT(CLK_V_MSELECT);
|
||||
|
||||
// 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(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
|
||||
|
||||
clock_enable_coresight();
|
||||
|
||||
@@ -107,11 +74,11 @@ void ccplex_boot_cpu0(u32 entry)
|
||||
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
|
||||
|
||||
// Enable CPU rail.
|
||||
_ccplex_pmc_enable_partition(0, 1);
|
||||
// Enable cluster 0 non-CPU.
|
||||
_ccplex_pmc_enable_partition(15, 1);
|
||||
// Enable CE0.
|
||||
_ccplex_pmc_enable_partition(14, 1);
|
||||
pmc_enable_partition(0, 1);
|
||||
// Enable cluster 0 non-CPU rail.
|
||||
pmc_enable_partition(15, 1);
|
||||
// Enable CE0 rail.
|
||||
pmc_enable_partition(14, 1);
|
||||
|
||||
// Request and wait for RAM repair.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;
|
||||
@@ -131,7 +98,7 @@ void ccplex_boot_cpu0(u32 entry)
|
||||
// MC(MC_TZ_SECURITY_CTRL) = 1;
|
||||
|
||||
// Clear MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= ~BIT(CLK_V_MSELECT);
|
||||
// Clear NONCPU reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
|
||||
// Clear CPU0 reset.
|
||||
|
||||
136
bdk/soc/clock.c
136
bdk/soc/clock.c
@@ -34,63 +34,63 @@
|
||||
/* clock_t: reset, enable, source, index, clk_src, clk_div */
|
||||
|
||||
static const clock_t _clock_uart[] = {
|
||||
/* UART A */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, 6, 0, 2 },
|
||||
/* UART B */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, 7, 0, 2 },
|
||||
/* UART C */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, 23, 0, 2 },
|
||||
/* UART D */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, 1, 0, 2 },
|
||||
/* UART E */ { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, 20, 0, 2 }
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, 2 }
|
||||
};
|
||||
|
||||
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
|
||||
static const clock_t _clock_i2c[] = {
|
||||
/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 12, 0, 19 }, //20.4MHz -> 100KHz
|
||||
/* I2C2 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, 22, 0, 4 }, //81.6MHz -> 400KHz
|
||||
/* I2C3 */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, 3, 0, 4 }, //81.6MHz -> 400KHz
|
||||
/* I2C4 */ { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, 7, 0, 19 }, //20.4MHz -> 100KHz
|
||||
/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 15, 0, 4 }, //81.6MHz -> 400KHz
|
||||
/* I2C6 */ { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, 6, 0, 19 } //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, 19 }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, 19 }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz
|
||||
};
|
||||
|
||||
static clock_t _clock_se = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, 31, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_tzram = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, 30, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_host1x = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, 28, 4, 3
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3
|
||||
};
|
||||
static clock_t _clock_tsec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, 19, 0, 2
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2
|
||||
};
|
||||
static clock_t _clock_sor_safe = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, 30, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0
|
||||
};
|
||||
static clock_t _clock_sor0 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NO_SOURCE, 22, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NO_SOURCE, CLK_X_SOR0, 0, 0
|
||||
};
|
||||
static clock_t _clock_sor1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, 23, 0, 2
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2
|
||||
};
|
||||
static clock_t _clock_kfuse = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, 8, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_cl_dvfs = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, 27, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0
|
||||
};
|
||||
static clock_t _clock_coresight = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, 9, 0, 4
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4
|
||||
};
|
||||
|
||||
static clock_t _clock_pwm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, 17, 6, 4 // Fref: 6.2MHz.
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, 4 // Fref: 6.2MHz.
|
||||
};
|
||||
|
||||
static clock_t _clock_sdmmc_legacy_tm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, 1, 4, 66
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, 66
|
||||
};
|
||||
|
||||
void clock_enable(const clock_t *clk)
|
||||
@@ -223,12 +223,12 @@ void clock_disable_sor1()
|
||||
|
||||
void clock_enable_kfuse()
|
||||
{
|
||||
//clock_enable(&_clock_kfuse);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) = (CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) & 0xFFFFFEFF) | 0x100;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) &= 0xFFFFFEFF;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) & 0xFFFFFEFF) | 0x100;
|
||||
u32 kfuse_clk_unmask = ~BIT(CLK_H_KFUSE);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) = (CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) & kfuse_clk_unmask) | BIT(CLK_H_KFUSE);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) &= kfuse_clk_unmask;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) & kfuse_clk_unmask) | BIT(CLK_H_KFUSE);
|
||||
usleep(10);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) &= 0xFFFFFEFF;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) &= kfuse_clk_unmask;
|
||||
usleep(20);
|
||||
}
|
||||
|
||||
@@ -362,48 +362,18 @@ static void _clock_disable_pllc4(u32 mask)
|
||||
pllc4_enabled = 0;
|
||||
}
|
||||
|
||||
#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;
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC1);
|
||||
case SDMMC_2:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC2_RST;
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC2);
|
||||
case SDMMC_3:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & U_SWR_SDMMC3_RST;
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & BIT(CLK_U_SDMMC3);
|
||||
case SDMMC_4:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC4_RST;
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -413,16 +383,16 @@ 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;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC2_RST;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = U_SET_SDMMC3_RST;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC4_RST;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -432,16 +402,16 @@ 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;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC2_RST;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = U_CLR_SDMMC3_RST;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC4_RST;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -451,13 +421,13 @@ 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;
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC1);
|
||||
case SDMMC_2:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC2;
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC2);
|
||||
case SDMMC_3:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & U_CLK_ENB_SDMMC3;
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & BIT(CLK_U_SDMMC3);
|
||||
case SDMMC_4:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC4;
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -467,16 +437,16 @@ static void _clock_sdmmc_set_enable(u32 id)
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC1;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC2;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = U_SET_CLK_ENB_SDMMC3;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC4;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -486,16 +456,16 @@ static void _clock_sdmmc_clear_enable(u32 id)
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC1;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC2;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = U_CLR_CLK_ENB_SDMMC3;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC4;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -680,7 +650,7 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
|
||||
*pclock = 40800;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case SDHCI_TIMING_MMC_DDR52: // Actual IO Freq: 49.92 MHz.
|
||||
case SDHCI_TIMING_MMC_HS102: // Actual IO Freq: 99.84 MHz.
|
||||
*pclock = 200000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
|
||||
263
bdk/soc/clock.h
263
bdk/soc/clock.h
@@ -171,6 +171,269 @@
|
||||
#define PLLC4_OUT3_CLKEN (1 << 1)
|
||||
#define PLLC4_OUT3_RSTN_CLR (1 << 0)
|
||||
|
||||
/*
|
||||
* CLOCK Peripherals:
|
||||
* L 0 - 31
|
||||
* H 32 - 63
|
||||
* U 64 - 95
|
||||
* V 96 - 127
|
||||
* W 128 - 159
|
||||
* X 160 - 191
|
||||
* Y 192 - 223
|
||||
*/
|
||||
|
||||
enum CLK_L_DEV
|
||||
{
|
||||
CLK_L_CPU = 0, // Only reset. Deprecated.
|
||||
CLK_L_BPMP = 1, // Only reset.
|
||||
CLK_L_SYS = 2, // Only reset.
|
||||
CLK_L_ISPB = 3,
|
||||
CLK_L_RTC = 4,
|
||||
CLK_L_TMR = 5,
|
||||
CLK_L_UARTA = 6,
|
||||
CLK_L_UARTB = 7,
|
||||
CLK_L_GPIO = 8,
|
||||
CLK_L_SDMMC2 = 9,
|
||||
CLK_L_SPDIF = 10,
|
||||
CLK_L_I2S2 = 11, // I2S1
|
||||
CLK_L_I2C1 = 12,
|
||||
CLK_L_NDFLASH = 13, // HIDDEN.
|
||||
CLK_L_SDMMC1 = 14,
|
||||
CLK_L_SDMMC4 = 15,
|
||||
CLK_L_TWC = 16, // HIDDEN.
|
||||
CLK_L_PWM = 17,
|
||||
CLK_L_I2S3 = 18,
|
||||
CLK_L_EPP = 19, // HIDDEN.
|
||||
CLK_L_VI = 20,
|
||||
CLK_L_2D = 21, // HIDDEN.
|
||||
CLK_L_USBD = 22,
|
||||
CLK_L_ISP = 23,
|
||||
CLK_L_3D = 24, // HIDDEN.
|
||||
//CLK_L_ = 25,
|
||||
CLK_L_DISP2 = 26,
|
||||
CLK_L_DISP1 = 27,
|
||||
CLK_L_HOST1X = 28,
|
||||
CLK_L_VCP = 29, // HIDDEN.
|
||||
CLK_L_I2S1 = 30, // I2S0
|
||||
CLK_L_BPMP_CACHE_CTRL = 31, // CONTROLLER
|
||||
};
|
||||
|
||||
enum CLK_H_DEV
|
||||
{
|
||||
CLK_H_MEM = 0, // MC.
|
||||
CLK_H_AHBDMA = 1,
|
||||
CLK_H_APBDMA = 2,
|
||||
//CLK_H_ = 3,
|
||||
CLK_H_KBC = 4, // HIDDEN.
|
||||
CLK_H_STAT_MON = 5,
|
||||
CLK_H_PMC = 6,
|
||||
CLK_H_FUSE = 7,
|
||||
CLK_H_KFUSE = 8,
|
||||
CLK_H_SPI1 = 9,
|
||||
CLK_H_SNOR = 10, // HIDDEN.
|
||||
CLK_H_JTAG2TBC = 11,
|
||||
CLK_H_SPI2 = 12,
|
||||
CLK_H_XIO = 13, // HIDDEN.
|
||||
CLK_H_SPI3 = 14,
|
||||
CLK_H_I2C5 = 15,
|
||||
CLK_H_DSI = 16,
|
||||
//CLK_H_ = 17,
|
||||
CLK_H_HSI = 18, // HIDDEN.
|
||||
CLK_H_HDMI = 19, // HIDDEN.
|
||||
CLK_H_CSI = 20,
|
||||
//CLK_H_ = 21,
|
||||
CLK_H_I2C2 = 22,
|
||||
CLK_H_UARTC = 23,
|
||||
CLK_H_MIPI_CAL = 24,
|
||||
CLK_H_EMC = 25,
|
||||
CLK_H_USB2 = 26,
|
||||
CLK_H_USB3 = 27, // HIDDEN.
|
||||
CLK_H_MPE = 28, // HIDDEN.
|
||||
CLK_H_VDE = 29, // HIDDEN.
|
||||
CLK_H_BSEA = 30, // HIDDEN.
|
||||
CLK_H_BSEV = 31,
|
||||
};
|
||||
|
||||
enum CLK_U_DEV
|
||||
{
|
||||
//CLK_U_ = 0,
|
||||
CLK_U_UARTD = 1,
|
||||
CLK_U_UARTE = 2, // HIDDEN.
|
||||
CLK_U_I2C3 = 3,
|
||||
CLK_U_SPI4 = 4,
|
||||
CLK_U_SDMMC3 = 5,
|
||||
CLK_U_PCIE = 6,
|
||||
CLK_U_UNUSED = 7, // RESERVED
|
||||
CLK_U_AFI = 8,
|
||||
CLK_U_CSITE = 9,
|
||||
CLK_U_PCIEXCLK = 10, // Only reset.
|
||||
CLK_U_BPMPUCQ = 11, // HIDDEN.
|
||||
CLK_U_LA = 12,
|
||||
CLK_U_TRACECLKIN = 13, // HIDDEN.
|
||||
CLK_U_SOC_THERM = 14,
|
||||
CLK_U_DTV = 15,
|
||||
CLK_U_NAND_SPEED = 16, // HIDDEN.
|
||||
CLK_U_I2C_SLOW = 17,
|
||||
CLK_U_DSIB = 18,
|
||||
CLK_U_TSEC = 19,
|
||||
CLK_U_IRAMA = 20,
|
||||
CLK_U_IRAMB = 21,
|
||||
CLK_U_IRAMC = 22,
|
||||
CLK_U_IRAMD = 23, // EMUCIF ON RESET
|
||||
CLK_U_BPMP_CACHE_RAM = 24,
|
||||
CLK_U_XUSB_HOST = 25,
|
||||
CLK_U_CLK_M_DOUBLER = 26,
|
||||
CLK_U_MSENC = 27, // HIDDEN.
|
||||
CLK_U_SUS_OUT = 28,
|
||||
CLK_U_DEV2_OUT = 29,
|
||||
CLK_U_DEV1_OUT = 30,
|
||||
CLK_U_XUSB_DEV = 31,
|
||||
};
|
||||
|
||||
enum CLK_V_DEV
|
||||
{
|
||||
CLK_V_CPUG = 0,
|
||||
CLK_V_CPULP = 1, // Reserved.
|
||||
CLK_V_3D2 = 2, // HIDDEN.
|
||||
CLK_V_MSELECT = 3,
|
||||
CLK_V_TSENSOR = 4,
|
||||
CLK_V_I2S4 = 5,
|
||||
CLK_V_I2S5 = 6,
|
||||
CLK_V_I2C4 = 7,
|
||||
CLK_V_SPI5 = 8, // HIDDEN.
|
||||
CLK_V_SPI6 = 9, // HIDDEN.
|
||||
CLK_V_AHUB = 10, // AUDIO.
|
||||
CLK_V_APB2APE = 11, // APBIF.
|
||||
CLK_V_DAM0 = 12, // HIDDEN.
|
||||
CLK_V_DAM1 = 13, // HIDDEN.
|
||||
CLK_V_DAM2 = 14, // HIDDEN.
|
||||
CLK_V_HDA2CODEC_2X = 15,
|
||||
CLK_V_ATOMICS = 16,
|
||||
//CLK_V_ = 17,
|
||||
//CLK_V_ = 18,
|
||||
//CLK_V_ = 19,
|
||||
//CLK_V_ = 20,
|
||||
//CLK_V_ = 21,
|
||||
CLK_V_SPDIF_DOUBLER = 22,
|
||||
CLK_V_ACTMON = 23,
|
||||
CLK_V_EXTPERIPH1 = 24,
|
||||
CLK_V_EXTPERIPH2 = 25,
|
||||
CLK_V_EXTPERIPH3 = 26,
|
||||
CLK_V_SATA_OOB = 27,
|
||||
CLK_V_SATA = 28,
|
||||
CLK_V_HDA = 29,
|
||||
CLK_V_TZRAM = 30, // HIDDEN.
|
||||
CLK_V_SE = 31, // HIDDEN.
|
||||
};
|
||||
|
||||
enum CLK_W_DEV
|
||||
{
|
||||
CLK_W_HDA2HDMICODEC = 0,
|
||||
CLK_W_RESERVED0 = 1, //satacoldrstn
|
||||
CLK_W_PCIERX0 = 2,
|
||||
CLK_W_PCIERX1 = 3,
|
||||
CLK_W_PCIERX2 = 4,
|
||||
CLK_W_PCIERX3 = 5,
|
||||
CLK_W_PCIERX4 = 6,
|
||||
CLK_W_PCIERX5 = 7,
|
||||
CLK_W_CEC = 8,
|
||||
CLK_W_PCIE2_IOBIST = 9,
|
||||
CLK_W_EMC_IOBIST = 10,
|
||||
CLK_W_HDMI_IOBIST = 11, // HIDDEN.
|
||||
CLK_W_SATA_IOBIST = 12,
|
||||
CLK_W_MIPI_IOBIST = 13,
|
||||
CLK_W_XUSB_PADCTL = 14, // Only reset.
|
||||
CLK_W_XUSB = 15,
|
||||
CLK_W_CILAB = 16,
|
||||
CLK_W_CILCD = 17,
|
||||
CLK_W_CILEF = 18,
|
||||
CLK_W_DSIA_LP = 19,
|
||||
CLK_W_DSIB_LP = 20,
|
||||
CLK_W_ENTROPY = 21,
|
||||
CLK_W_DDS = 22, // HIDDEN.
|
||||
//CLK_W_ = 23,
|
||||
CLK_W_DP2 = 24, // HIDDEN.
|
||||
CLK_W_AMX0 = 25, // HIDDEN.
|
||||
CLK_W_ADX0 = 26, // HIDDEN.
|
||||
CLK_W_DVFS = 27,
|
||||
CLK_W_XUSB_SS = 28,
|
||||
CLK_W_EMC_LATENCY = 29,
|
||||
CLK_W_MC1 = 30,
|
||||
//CLK_W_ = 31,
|
||||
};
|
||||
|
||||
enum CLK_X_DEV
|
||||
{
|
||||
CLK_X_SPARE = 0,
|
||||
CLK_X_DMIC1 = 1,
|
||||
CLK_X_DMIC2 = 2,
|
||||
CLK_X_ETR = 3,
|
||||
CLK_X_CAM_MCLK = 4,
|
||||
CLK_X_CAM_MCLK2 = 5,
|
||||
CLK_X_I2C6 = 6,
|
||||
CLK_X_MC_CAPA = 7, // MC DAISY CHAIN1
|
||||
CLK_X_MC_CBPA = 8, // MC DAISY CHAIN2
|
||||
CLK_X_MC_CPU = 9,
|
||||
CLK_X_MC_BBC = 10,
|
||||
CLK_X_VIM2_CLK = 11,
|
||||
//CLK_X_ = 12,
|
||||
CLK_X_MIPIBIF = 13, //RESERVED
|
||||
CLK_X_EMC_DLL = 14,
|
||||
//CLK_X_ = 15,
|
||||
CLK_X_HDMI_AUDIO = 16, // HIDDEN.
|
||||
CLK_X_UART_FST_MIPI_CAL = 17,
|
||||
CLK_X_VIC = 18,
|
||||
//CLK_X_ = 19,
|
||||
CLK_X_ADX1 = 20, // HIDDEN.
|
||||
CLK_X_DPAUX = 21,
|
||||
CLK_X_SOR0 = 22,
|
||||
CLK_X_SOR1 = 23,
|
||||
CLK_X_GPU = 24,
|
||||
CLK_X_DBGAPB = 25,
|
||||
CLK_X_HPLL_ADSP = 26,
|
||||
CLK_X_PLLP_ADSP = 27,
|
||||
CLK_X_PLLA_ADSP = 28,
|
||||
CLK_X_PLLG_REF = 29,
|
||||
//CLK_X_ = 30,
|
||||
//CLK_X_ = 31,
|
||||
};
|
||||
|
||||
enum CLK_Y_DEV
|
||||
{
|
||||
CLK_Y_SPARE1 = 0,
|
||||
CLK_Y_SDMMC_LEGACY_TM = 1,
|
||||
CLK_Y_NVDEC = 2,
|
||||
CLK_Y_NVJPG = 3,
|
||||
CLK_Y_AXIAP = 4,
|
||||
CLK_Y_DMIC3 = 5,
|
||||
CLK_Y_APE = 6,
|
||||
CLK_Y_ADSP = 7,
|
||||
CLK_Y_MC_CDPA = 8, // MC DAISY CHAIN4
|
||||
CLK_Y_MC_CCPA = 9, // MC DAISY CHAIN3
|
||||
CLK_Y_MAUD = 10,
|
||||
//CLK_Y_ = 11,
|
||||
CLK_Y_SATA_USB_UPHY = 12, // Only reset.
|
||||
CLK_Y_PEX_USB_UPHY = 13, // Only reset.
|
||||
CLK_Y_TSECB = 14,
|
||||
CLK_Y_DPAUX1 = 15,
|
||||
CLK_Y_VI_I2C = 16,
|
||||
CLK_Y_HSIC_TRK = 17,
|
||||
CLK_Y_USB2_TRK = 18,
|
||||
CLK_Y_QSPI = 19,
|
||||
CLK_Y_UARTAPE = 20,
|
||||
CLK_Y_ADSPINTF = 21, // Only reset.
|
||||
CLK_Y_ADSPPERIPH = 22, // Only reset.
|
||||
CLK_Y_ADSPDBG = 23, // Only reset.
|
||||
CLK_Y_ADSPWDT = 24, // Only reset.
|
||||
CLK_Y_ADSPSCU = 25, // Only reset.
|
||||
CLK_Y_ADSPNEON = 26,
|
||||
CLK_Y_NVENC = 27,
|
||||
CLK_Y_IQC2 = 28,
|
||||
CLK_Y_IQC1 = 29,
|
||||
CLK_Y_SOR_SAFE = 30,
|
||||
CLK_Y_PLLP_OUT_CPU = 31,
|
||||
};
|
||||
|
||||
/*! Generic clock descriptor. */
|
||||
typedef struct _clock_t
|
||||
{
|
||||
|
||||
@@ -68,6 +68,18 @@ u32 fuse_read_odm_keygen_rev()
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 fuse_count_burnt(u32 val)
|
||||
{
|
||||
u8 burnt_fuses = 0;
|
||||
for (u32 i = 0; i < 32; i++)
|
||||
{
|
||||
if ((val >> i) & 1)
|
||||
burnt_fuses++;
|
||||
}
|
||||
|
||||
return burnt_fuses;
|
||||
}
|
||||
|
||||
void fuse_wait_idle()
|
||||
{
|
||||
u32 ctrl;
|
||||
|
||||
@@ -76,11 +76,12 @@
|
||||
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
|
||||
|
||||
void fuse_disable_program();
|
||||
u32 fuse_read_odm(u32 idx);
|
||||
u32 fuse_read_odm_keygen_rev();
|
||||
u32 fuse_read_odm(u32 idx);
|
||||
u32 fuse_read_odm_keygen_rev();
|
||||
u8 fuse_count_burnt(u32 val);
|
||||
void fuse_wait_idle();
|
||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
||||
void fuse_read_array(u32 *words);
|
||||
bool fuse_check_patched_rcm();
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ extern volatile nyx_storage_t *nyx_str;
|
||||
* PCLK - 68MHz init (-> 136MHz -> OC/4).
|
||||
*/
|
||||
|
||||
void _config_oscillators()
|
||||
static void _config_oscillators()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2.
|
||||
SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
|
||||
@@ -73,14 +73,17 @@ void _config_oscillators()
|
||||
|
||||
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set SCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set clk source to Run and PLLP_OUT2 (204MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
|
||||
}
|
||||
|
||||
void _config_gpios()
|
||||
static void _config_gpios()
|
||||
{
|
||||
// Clamp inputs when tristated.
|
||||
APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0;
|
||||
|
||||
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
|
||||
|
||||
@@ -120,27 +123,28 @@ void _config_gpios()
|
||||
// gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
}
|
||||
|
||||
void _config_pmc_scratch()
|
||||
static void _config_pmc_scratch()
|
||||
{
|
||||
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option.
|
||||
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option.
|
||||
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset DATA_DQ_E_IVREF EMC_PMACRO_DATA_PAD_TX_CTRL
|
||||
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
|
||||
}
|
||||
|
||||
void _mbist_workaround()
|
||||
static void _mbist_workaround()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= (1 << 6); // Enable APE clock.
|
||||
// Make sure Audio clocks are enabled before accessing I2S.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
|
||||
// Set mux output to SOR1 clock switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF;
|
||||
// Enabled PLLD and set csi to PLLD for test pattern generation.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000;
|
||||
|
||||
// Clear per-clock resets.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = 0x40; // Clear reset APE.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_CLR) = 0x40000; // Clear reset VIC.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000; // Clear reset DISP1, HOST1X.
|
||||
// Clear per-clock resets for APE/VIC/HOST1X/DISP1.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = BIT(CLK_Y_APE);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_CLR) = BIT(CLK_X_VIC);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
usleep(2);
|
||||
|
||||
// I2S channels to master and disable SLCG.
|
||||
@@ -159,20 +163,59 @@ void _mbist_workaround()
|
||||
VIC(0x8C) = 0xFFFFFFFF;
|
||||
usleep(2);
|
||||
|
||||
// Set per-clock reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = 0x40; // Set reset APE.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000; // Set reset DISP1, HOST1x.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = 0x40000; // Set reset VIC.
|
||||
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = BIT(CLK_Y_APE);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = BIT(CLK_X_VIC);
|
||||
|
||||
// Enable specific clocks and disable all others.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = 0xC0; // Enable clock PMC, FUSE.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80000130; // Enable clock RTC, TMR, GPIO, BPMP_CACHE.
|
||||
//CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80400130; // Keep USBD ON.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = 0x1F00200; // Enable clock CSITE, IRAMA, IRAMB, IRAMC, IRAMD, BPMP_CACHE_RAM.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = 0x80400808; // Enable clock MSELECT, APB2APE, SPDIF_DOUBLER, SE.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = 0x402000FC; // Enable clock PCIERX0, PCIERX1, PCIERX2, PCIERX3, PCIERX4, PCIERX5, ENTROPY, MC1.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = 0x23000780; // Enable clock MC_CAPA, MC_CAPB, MC_CPU, MC_BBC, DBGAPB, HPLL_ADSP, PLLG_REF.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = 0x300; // Enable clock MC_CDPA, MC_CCPA.
|
||||
// CLK L Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) =
|
||||
BIT(CLK_H_PMC) |
|
||||
BIT(CLK_H_FUSE);
|
||||
// CLK H Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) =
|
||||
BIT(CLK_L_RTC) |
|
||||
BIT(CLK_L_TMR) |
|
||||
BIT(CLK_L_GPIO) |
|
||||
BIT(CLK_L_BPMP_CACHE_CTRL);
|
||||
// CLK U Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) =
|
||||
BIT(CLK_U_CSITE) |
|
||||
BIT(CLK_U_IRAMA) |
|
||||
BIT(CLK_U_IRAMB) |
|
||||
BIT(CLK_U_IRAMC) |
|
||||
BIT(CLK_U_IRAMD) |
|
||||
BIT(CLK_U_BPMP_CACHE_RAM);
|
||||
// CLK V Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) =
|
||||
BIT(CLK_V_MSELECT) |
|
||||
BIT(CLK_V_APB2APE) |
|
||||
BIT(CLK_V_SPDIF_DOUBLER) |
|
||||
BIT(CLK_V_SE);
|
||||
// CLK W Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) =
|
||||
BIT(CLK_W_PCIERX0) |
|
||||
BIT(CLK_W_PCIERX1) |
|
||||
BIT(CLK_W_PCIERX2) |
|
||||
BIT(CLK_W_PCIERX3) |
|
||||
BIT(CLK_W_PCIERX4) |
|
||||
BIT(CLK_W_PCIERX5) |
|
||||
BIT(CLK_W_ENTROPY) |
|
||||
BIT(CLK_W_MC1);
|
||||
// CLK X Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) =
|
||||
BIT(CLK_X_MC_CAPA) |
|
||||
BIT(CLK_X_MC_CBPA) |
|
||||
BIT(CLK_X_MC_CPU) |
|
||||
BIT(CLK_X_MC_BBC) |
|
||||
BIT(CLK_X_GPU) |
|
||||
BIT(CLK_X_DBGAPB) |
|
||||
BIT(CLK_X_PLLG_REF);
|
||||
// CLK Y Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) =
|
||||
BIT(CLK_Y_MC_CDPA) |
|
||||
BIT(CLK_Y_MC_CCPA);
|
||||
|
||||
// Disable clock gate overrides.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;
|
||||
@@ -182,20 +225,21 @@ void _mbist_workaround()
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE) = 0;
|
||||
|
||||
// Set child clock sources.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
}
|
||||
|
||||
void _config_se_brom()
|
||||
static void _config_se_brom()
|
||||
{
|
||||
// Enable fuse clock.
|
||||
clock_enable_fuse(true);
|
||||
|
||||
// Skip SBK/SSK if sept was run.
|
||||
if (!(b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN))
|
||||
bool sbk_skip = b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN || FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF;
|
||||
if (!sbk_skip)
|
||||
{
|
||||
// Bootrom part we skipped.
|
||||
u32 sbk[4] = {
|
||||
@@ -225,7 +269,7 @@ void _config_se_brom()
|
||||
APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
|
||||
}
|
||||
|
||||
void _config_regulators()
|
||||
static void _config_regulators()
|
||||
{
|
||||
// Disable low battery shutdown monitor.
|
||||
max77620_low_battery_monitor_config(false);
|
||||
@@ -277,7 +321,7 @@ void _config_regulators()
|
||||
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
|
||||
}
|
||||
|
||||
void config_hw()
|
||||
void hw_init()
|
||||
{
|
||||
// Bootrom stuff we skipped by going through rcm.
|
||||
_config_se_brom();
|
||||
@@ -285,19 +329,25 @@ void config_hw()
|
||||
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F; // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
|
||||
PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC;
|
||||
|
||||
// Perform Memory Built-In Self Test WAR if T210.
|
||||
_mbist_workaround();
|
||||
|
||||
// Enable Security Engine clock.
|
||||
clock_enable_se();
|
||||
|
||||
// Enable fuse clock.
|
||||
// Enable Fuse clock.
|
||||
clock_enable_fuse(true);
|
||||
|
||||
// Disable fuse programming.
|
||||
// Disable Fuse programming.
|
||||
fuse_disable_program();
|
||||
|
||||
// Enable clocks to Memory controllers and disable AHB redirect.
|
||||
mc_enable();
|
||||
|
||||
// Initialize counters, CLKM, BPMP and other clocks based on 38.4MHz oscillator.
|
||||
_config_oscillators();
|
||||
APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0;
|
||||
|
||||
// Initialize pin configuration.
|
||||
_config_gpios();
|
||||
|
||||
#ifdef DEBUG_UART_PORT
|
||||
@@ -305,34 +355,39 @@ void config_hw()
|
||||
uart_init(DEBUG_UART_PORT, 115200);
|
||||
#endif
|
||||
|
||||
// Enable Dynamic Voltage and Frequency Scaling device clock.
|
||||
clock_enable_cl_dvfs();
|
||||
|
||||
// Enable clocks to I2C1 and I2CPWR.
|
||||
clock_enable_i2c(I2C_1);
|
||||
clock_enable_i2c(I2C_5);
|
||||
|
||||
// Enable clock to TZRAM.
|
||||
clock_enable_tzram();
|
||||
|
||||
// Initialize I2C5, mandatory for PMIC comms.
|
||||
i2c_init(I2C_1);
|
||||
i2c_init(I2C_5);
|
||||
|
||||
// Enable charger in case it's disabled.
|
||||
bq24193_enable_charger();
|
||||
|
||||
// Initialize various regulators based on Erista/Mariko platform.
|
||||
_config_regulators();
|
||||
|
||||
_config_pmc_scratch(); // Missing from 4.x+
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // Set SCLK to PLLP_OUT (408MHz).
|
||||
// Set BPMP/SCLK to PLLP_OUT (408MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
|
||||
|
||||
|
||||
// Initialize External memory controller and configure DRAM parameters.
|
||||
sdram_init();
|
||||
|
||||
bpmp_mmu_enable();
|
||||
|
||||
// Clear flags from PMC_SCRATCH0
|
||||
PMC(APBDEV_PMC_SCRATCH0) &= ~PMC_SCRATCH0_MODE_PAYLOAD;
|
||||
}
|
||||
|
||||
void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
|
||||
void hw_reinit_workaround(bool extra_reconfig, u32 magic)
|
||||
{
|
||||
// Disable BPMP max clock.
|
||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
@@ -353,8 +408,8 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
|
||||
nyx_str->mtc_cfg.init_done = 0;
|
||||
|
||||
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= (1 << 6); // Enable APE clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
|
||||
if (extra_reconfig)
|
||||
{
|
||||
@@ -376,7 +431,7 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
|
||||
// Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits.
|
||||
if (magic == 0xBAADF00D)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) |= (1 << 22);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD);
|
||||
sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, 0);
|
||||
clock_disable_cl_dvfs();
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
void config_hw();
|
||||
void reconfig_hw_workaround(bool extra_reconfig, u32 magic);
|
||||
void hw_init();
|
||||
void hw_reinit_workaround(bool extra_reconfig, u32 magic);
|
||||
|
||||
#endif
|
||||
|
||||
342
bdk/soc/i2c.c
342
bdk/soc/i2c.c
@@ -20,31 +20,98 @@
|
||||
#include <soc/i2c.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define I2C_PACKET_PROT_I2C (1 << 4)
|
||||
#define I2C_HEADER_CONT_XFER (1 << 15)
|
||||
#define I2C_HEADER_REP_START (1 << 16)
|
||||
#define I2C_HEADER_IE_ENABLE (1 << 17)
|
||||
#define I2C_HEADER_READ (1 << 19)
|
||||
|
||||
#define I2C_CNFG (0x00 / 4)
|
||||
#define CMD1_WRITE (0 << 6)
|
||||
#define CMD1_READ (1 << 6)
|
||||
#define NORMAL_MODE_GO (1 << 9)
|
||||
#define PACKET_MODE_GO (1 << 10)
|
||||
#define NEW_MASTER_FSM (1 << 11)
|
||||
#define DEBOUNCE_CNT_4T (2 << 12)
|
||||
|
||||
#define I2C_CMD_ADDR0 (0x04 / 4)
|
||||
#define ADDR0_WRITE 0
|
||||
#define ADDR0_READ 1
|
||||
|
||||
#define I2C_CMD_DATA1 (0x0C / 4)
|
||||
#define I2C_CMD_DATA2 (0x10 / 4)
|
||||
|
||||
#define I2C_STATUS (0x1C / 4)
|
||||
#define I2C_STATUS_NOACK (0xF << 0)
|
||||
#define I2C_STATUS_BUSY (1 << 8)
|
||||
|
||||
#define I2C_TX_FIFO (0x50 / 4)
|
||||
#define I2C_RX_FIFO (0x54 / 4)
|
||||
|
||||
#define I2C_FIFO_CONTROL (0x5C / 4)
|
||||
#define RX_FIFO_FLUSH (1 << 0)
|
||||
#define TX_FIFO_FLUSH (1 << 1)
|
||||
|
||||
#define I2C_FIFO_STATUS (0x60 / 4)
|
||||
#define RX_FIFO_FULL_CNT (0xF << 0)
|
||||
#define TX_FIFO_EMPTY_CNT (0xF << 4)
|
||||
|
||||
#define I2C_INT_EN (0x64 / 4)
|
||||
#define I2C_INT_STATUS (0x68 / 4)
|
||||
#define I2C_INT_SOURCE (0x70 / 4)
|
||||
#define RX_FIFO_DATA_REQ (1 << 0)
|
||||
#define TX_FIFO_DATA_REQ (1 << 1)
|
||||
#define ARB_LOST (1 << 2)
|
||||
#define NO_ACK (1 << 3)
|
||||
#define RX_FIFO_UNDER (1 << 4)
|
||||
#define TX_FIFO_OVER (1 << 5)
|
||||
#define ALL_PACKETS_COMPLETE (1 << 6)
|
||||
#define PACKET_COMPLETE (1 << 7)
|
||||
#define BUS_CLEAR_DONE (1 << 11)
|
||||
|
||||
#define I2C_CLK_DIVISOR (0x6C / 4)
|
||||
|
||||
#define I2C_BUS_CLEAR_CONFIG (0x84 / 4)
|
||||
#define BC_ENABLE (1 << 0)
|
||||
#define BC_TERMINATE (1 << 1)
|
||||
|
||||
#define I2C_BUS_CLEAR_STATUS (0x88 / 4)
|
||||
|
||||
#define I2C_CONFIG_LOAD (0x8C / 4)
|
||||
#define MSTR_CONFIG_LOAD (1 << 0)
|
||||
#define TIMEOUT_CONFIG_LOAD (1 << 2)
|
||||
|
||||
static const u32 i2c_addrs[] = {
|
||||
0x7000C000, 0x7000C400, 0x7000C500,
|
||||
0x7000C700, 0x7000D000, 0x7000D100
|
||||
0x7000C000, // I2C_1.
|
||||
0x7000C400, // I2C_2.
|
||||
0x7000C500, // I2C_3.
|
||||
0x7000C700, // I2C_4.
|
||||
0x7000D000, // I2C_5.
|
||||
0x7000D100 // I2C_6.
|
||||
};
|
||||
|
||||
static void _i2c_wait(vu32 *base)
|
||||
static void _i2c_load_cfg_wait(vu32 *base)
|
||||
{
|
||||
base[I2C_CONFIG_LOAD] = 0x25;
|
||||
base[I2C_CONFIG_LOAD] = (1 << 5) | TIMEOUT_CONFIG_LOAD | MSTR_CONFIG_LOAD;
|
||||
for (u32 i = 0; i < 20; i++)
|
||||
{
|
||||
usleep(1);
|
||||
if (!(base[I2C_CONFIG_LOAD] & 1))
|
||||
if (!(base[I2C_CONFIG_LOAD] & MSTR_CONFIG_LOAD))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
|
||||
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
|
||||
{
|
||||
if (size > 8)
|
||||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
||||
base[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).
|
||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||
|
||||
// Set device address and send mode.
|
||||
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
|
||||
|
||||
if (size > 4)
|
||||
{
|
||||
@@ -60,44 +127,55 @@ static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
|
||||
base[I2C_CMD_DATA1] = tmp; //Set value.
|
||||
}
|
||||
|
||||
base[I2C_CNFG] = ((size - 1) << 1) | 0x2800; //Set size and send mode.
|
||||
_i2c_wait(base); //Kick transaction.
|
||||
// Set size and send mode.
|
||||
base[I2C_CNFG] = ((size - 1) << 1) | DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
|
||||
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
|
||||
// Load configuration.
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
u32 timeout = get_tmr_ms() + 1500;
|
||||
while (base[I2C_STATUS] & 0x100)
|
||||
// Initiate transaction on normal mode.
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | NORMAL_MODE_GO;
|
||||
|
||||
u32 timeout = get_tmr_ms() + 100; // Actual for max 8 bytes at 100KHz is 0.74ms.
|
||||
while (base[I2C_STATUS] & I2C_STATUS_BUSY)
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (base[I2C_STATUS] << 28)
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
|
||||
static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
{
|
||||
if (size > 8)
|
||||
return 0;
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
||||
base[I2C_CMD_ADDR0] = (x << 1) | 1; // Set x (recv mode).
|
||||
base[I2C_CNFG] = ((size - 1) << 1) | 0x2840; // Set size and recv mode.
|
||||
_i2c_wait(base); // Kick transaction.
|
||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
|
||||
// Set device address and recv mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
||||
|
||||
u32 timeout = get_tmr_ms() + 1500;
|
||||
while (base[I2C_STATUS] & 0x100)
|
||||
// Set size and recv mode.
|
||||
base[I2C_CNFG] = ((size - 1) << 1) | DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_READ;
|
||||
|
||||
// Load configuration.
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
// Initiate transaction on normal mode.
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | NORMAL_MODE_GO;
|
||||
|
||||
u32 timeout = get_tmr_ms() + 100; // Actual for max 8 bytes at 100KHz is 0.74ms.
|
||||
while (base[I2C_STATUS] & I2C_STATUS_BUSY)
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (base[I2C_STATUS] << 28)
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
|
||||
return 0;
|
||||
|
||||
u32 tmp = base[I2C_CMD_DATA1]; // Get LS value.
|
||||
@@ -113,60 +191,234 @@ static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void i2c_init(u32 idx)
|
||||
static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
{
|
||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
||||
if (size > 32)
|
||||
return 0;
|
||||
|
||||
base[I2C_CLK_DIVISOR_REGISTER] = 0x50001;
|
||||
base[I2C_BUS_CLEAR_CONFIG] = 0x90003;
|
||||
_i2c_wait(base);
|
||||
int res = 0;
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||
|
||||
// Enable interrupts.
|
||||
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
|
||||
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | TX_FIFO_DATA_REQ;
|
||||
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
|
||||
|
||||
// Set device address and recv mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
||||
|
||||
// Set recv mode.
|
||||
base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
|
||||
|
||||
// Set and flush FIFO.
|
||||
base[I2C_FIFO_CONTROL] = RX_FIFO_FLUSH | TX_FIFO_FLUSH;
|
||||
|
||||
// Load configuration.
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
// Initiate transaction on packet mode.
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | PACKET_MODE_GO;
|
||||
|
||||
u32 hdr[3];
|
||||
hdr[0] = I2C_PACKET_PROT_I2C;
|
||||
hdr[1] = size - 1;
|
||||
hdr[2] = I2C_HEADER_IE_ENABLE | I2C_HEADER_CONT_XFER | (dev_addr << 1);
|
||||
|
||||
// Send header with request.
|
||||
base[I2C_TX_FIFO] = hdr[0];
|
||||
base[I2C_TX_FIFO] = hdr[1];
|
||||
base[I2C_TX_FIFO] = hdr[2];
|
||||
|
||||
u32 timeout = get_tmr_ms() + 400;
|
||||
while (size)
|
||||
{
|
||||
if (base[I2C_FIFO_STATUS] & TX_FIFO_EMPTY_CNT)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
u32 snd_size = MIN(size, 4);
|
||||
memcpy(&tmp, buf, snd_size);
|
||||
base[I2C_TX_FIFO] = tmp;
|
||||
buf += snd_size;
|
||||
size -= snd_size;
|
||||
}
|
||||
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK || base[I2C_INT_STATUS] & NO_ACK)
|
||||
res = 1;
|
||||
|
||||
// Disable packet mode.
|
||||
usleep(20);
|
||||
base[I2C_CNFG] &= 0xFFFFF9FF;
|
||||
|
||||
// Disable interrupts.
|
||||
base[I2C_INT_EN] = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
|
||||
{
|
||||
if (size > 32)
|
||||
return 0;
|
||||
|
||||
int res = 0;
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||
|
||||
// Enable interrupts.
|
||||
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
|
||||
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | RX_FIFO_DATA_REQ;
|
||||
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
|
||||
|
||||
// Set device address and recv mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
||||
|
||||
// Set recv mode.
|
||||
base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_READ;
|
||||
|
||||
// Set and flush FIFO.
|
||||
base[I2C_FIFO_CONTROL] = RX_FIFO_FLUSH | TX_FIFO_FLUSH;
|
||||
|
||||
// Load configuration.
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
// Initiate transaction on packet mode.
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | PACKET_MODE_GO;
|
||||
|
||||
// Send reg request.
|
||||
u32 hdr[3];
|
||||
hdr[0] = I2C_PACKET_PROT_I2C;
|
||||
hdr[1] = 1 - 1;
|
||||
hdr[2] = I2C_HEADER_REP_START | (dev_addr << 1);
|
||||
|
||||
// Send header with reg request.
|
||||
base[I2C_TX_FIFO] = hdr[0];
|
||||
base[I2C_TX_FIFO] = hdr[1];
|
||||
base[I2C_TX_FIFO] = hdr[2];
|
||||
base[I2C_TX_FIFO] = reg;
|
||||
|
||||
u32 timeout = get_tmr_ms() + 400;
|
||||
while (!(base[I2C_FIFO_STATUS] & TX_FIFO_EMPTY_CNT))
|
||||
if (get_tmr_ms() > timeout)
|
||||
break;
|
||||
|
||||
// Send read request.
|
||||
hdr[1] = size - 1;
|
||||
hdr[2] = I2C_HEADER_READ | (dev_addr << 1);
|
||||
|
||||
// Send header with read request.
|
||||
base[I2C_TX_FIFO] = hdr[0];
|
||||
base[I2C_TX_FIFO] = hdr[1];
|
||||
base[I2C_TX_FIFO] = hdr[2];
|
||||
|
||||
timeout = get_tmr_ms() + 400;
|
||||
while (size)
|
||||
{
|
||||
if (base[I2C_FIFO_STATUS] & RX_FIFO_FULL_CNT)
|
||||
{
|
||||
u32 rcv_size = MIN(size, 4);
|
||||
u32 tmp = base[I2C_RX_FIFO];
|
||||
memcpy(buf, &tmp, rcv_size);
|
||||
buf += rcv_size;
|
||||
size -= rcv_size;
|
||||
}
|
||||
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK || base[I2C_INT_STATUS] & NO_ACK)
|
||||
res = 1;
|
||||
|
||||
// Disable packet mode.
|
||||
usleep(20);
|
||||
base[I2C_CNFG] &= 0xFFFFF9FF;
|
||||
|
||||
// Disable interrupts.
|
||||
base[I2C_INT_EN] = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void i2c_init(u32 i2c_idx)
|
||||
{
|
||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||
|
||||
base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2.
|
||||
base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE;
|
||||
|
||||
// Load configuration.
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
for (u32 i = 0; i < 10; i++)
|
||||
{
|
||||
usleep(20000);
|
||||
if (base[INTERRUPT_STATUS_REGISTER] & 0x800)
|
||||
if (base[I2C_INT_STATUS] & BUS_CLEAR_DONE)
|
||||
break;
|
||||
}
|
||||
|
||||
(vu32)base[I2C_BUS_CLEAR_STATUS];
|
||||
base[INTERRUPT_STATUS_REGISTER] = base[INTERRUPT_STATUS_REGISTER];
|
||||
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
|
||||
}
|
||||
|
||||
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
|
||||
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr)
|
||||
{
|
||||
return _i2c_recv_single(i2c_idx, buf, size, dev_addr);
|
||||
}
|
||||
|
||||
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
|
||||
{
|
||||
if (size > 32)
|
||||
return 0;
|
||||
|
||||
return _i2c_send_pkt(i2c_idx, buf, size, dev_addr);
|
||||
}
|
||||
|
||||
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
|
||||
{
|
||||
return _i2c_recv_pkt(i2c_idx, buf, size, dev_addr, reg);
|
||||
}
|
||||
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size)
|
||||
{
|
||||
u8 tmp[4];
|
||||
|
||||
if (size > 7)
|
||||
return 0;
|
||||
|
||||
tmp[0] = y;
|
||||
tmp[0] = reg;
|
||||
memcpy(tmp + 1, buf, size);
|
||||
|
||||
return _i2c_send_pkt(idx, x, tmp, size + 1);
|
||||
return _i2c_send_single(i2c_idx, dev_addr, tmp, size + 1);
|
||||
}
|
||||
|
||||
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x)
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
|
||||
{
|
||||
return _i2c_recv_pkt(idx, buf, size, x);
|
||||
}
|
||||
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
|
||||
{
|
||||
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);
|
||||
int res = _i2c_send_single(i2c_idx, dev_addr, (u8 *)®, 1);
|
||||
if (res)
|
||||
res = _i2c_recv_pkt(idx, buf, size, x);
|
||||
res = _i2c_recv_single(i2c_idx, buf, size, dev_addr);
|
||||
return res;
|
||||
}
|
||||
|
||||
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)
|
||||
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val)
|
||||
{
|
||||
return i2c_send_buf_small(idx, x, y, &b, 1);
|
||||
return i2c_send_buf_small(i2c_idx, dev_addr, reg, &val, 1);
|
||||
}
|
||||
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y)
|
||||
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg)
|
||||
{
|
||||
u8 tmp = 0;
|
||||
i2c_recv_buf_small(&tmp, 1, idx, x, y);
|
||||
i2c_recv_buf_small(&tmp, 1, i2c_idx, dev_addr, reg);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,22 +27,13 @@
|
||||
#define I2C_5 4
|
||||
#define I2C_6 5
|
||||
|
||||
#define I2C_CNFG 0x00
|
||||
#define I2C_CMD_ADDR0 0x01
|
||||
#define I2C_CMD_DATA1 0x03
|
||||
#define I2C_CMD_DATA2 0x04
|
||||
#define I2C_STATUS 0x07
|
||||
#define INTERRUPT_STATUS_REGISTER 0x1A
|
||||
#define I2C_CLK_DIVISOR_REGISTER 0x1B
|
||||
#define I2C_BUS_CLEAR_CONFIG 0x21
|
||||
#define I2C_BUS_CLEAR_STATUS 0x22
|
||||
#define I2C_CONFIG_LOAD 0x23
|
||||
|
||||
void i2c_init(u32 idx);
|
||||
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
|
||||
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x);
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
|
||||
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
|
||||
void i2c_init(u32 i2c_idx);
|
||||
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr);
|
||||
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size);
|
||||
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size);
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val);
|
||||
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||
|
||||
#endif
|
||||
|
||||
52
bdk/soc/pmc.c
Normal file
52
bdk/soc/pmc.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
int pmc_enable_partition(u32 part, int enable)
|
||||
{
|
||||
u32 part_mask = 1 << part;
|
||||
u32 desired_state = enable << part;
|
||||
|
||||
// Check if the partition has the state we want.
|
||||
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
|
||||
return 1;
|
||||
|
||||
u32 i = 5001;
|
||||
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
|
||||
{
|
||||
usleep(1);
|
||||
i--;
|
||||
if (i < 1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Toggle power gating.
|
||||
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = part | 0x100;
|
||||
|
||||
i = 5001;
|
||||
while (i > 0)
|
||||
{
|
||||
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
|
||||
break;
|
||||
usleep(1);
|
||||
i--;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -18,6 +19,8 @@
|
||||
#ifndef _PMC_H_
|
||||
#define _PMC_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
/*! PMC registers. */
|
||||
#define APBDEV_PMC_CNTRL 0x0
|
||||
#define PMC_CNTRL_MAIN_RST (1 << 4)
|
||||
@@ -34,6 +37,7 @@
|
||||
#define PMC_SCRATCH0_MODE_PAYLOAD (1 << 29)
|
||||
#define PMC_SCRATCH0_MODE_RCM (1 << 1)
|
||||
#define PMC_SCRATCH0_MODE_WARMBOOT (1 << 0)
|
||||
#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | PMC_SCRATCH0_MODE_FASTBOOT | PMC_SCRATCH0_MODE_PAYLOAD)
|
||||
#define APBDEV_PMC_SCRATCH1 0x54
|
||||
#define APBDEV_PMC_SCRATCH20 0xA0
|
||||
#define APBDEV_PMC_PWR_DET_VAL 0xE4
|
||||
@@ -46,6 +50,8 @@
|
||||
#define PMC_CRYPTO_OP_SE_ENABLE 0
|
||||
#define PMC_CRYPTO_OP_SE_DISABLE 1
|
||||
#define APBDEV_PMC_SCRATCH33 0x120
|
||||
#define APBDEV_PMC_SCRATCH37 0x130
|
||||
#define PMC_SCRATCH37_KERNEL_PANIC_FLAG (1 << 24)
|
||||
#define APBDEV_PMC_SCRATCH40 0x13C
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||
#define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER 0x400000
|
||||
@@ -84,4 +90,6 @@
|
||||
#define APBDEV_PMC_SCRATCH190 0x818
|
||||
#define APBDEV_PMC_SCRATCH200 0x840
|
||||
|
||||
int pmc_enable_partition(u32 part, int enable);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -169,14 +169,23 @@ int sdmmc_storage_end(sdmmc_storage_t *storage)
|
||||
|
||||
sdmmc_end(storage->sdmmc);
|
||||
|
||||
storage->initialized = 0;
|
||||
|
||||
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;
|
||||
bool first_reinit = false;
|
||||
while (num_sectors)
|
||||
u32 sct_off = sector;
|
||||
u32 sct_total = num_sectors;
|
||||
bool first_reinit = true;
|
||||
|
||||
// Exit if not initialized.
|
||||
if (!storage->initialized)
|
||||
return 0;
|
||||
|
||||
while (sct_total)
|
||||
{
|
||||
u32 blkcnt = 0;
|
||||
// Retry 5 times if failed.
|
||||
@@ -184,7 +193,7 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu
|
||||
do
|
||||
{
|
||||
reinit_try:
|
||||
if (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sector, MIN(num_sectors, 0xFFFF), bbuf, is_write))
|
||||
if (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sct_off, MIN(sct_total, 0xFFFF), bbuf, is_write))
|
||||
goto out;
|
||||
else
|
||||
retries--;
|
||||
@@ -201,7 +210,7 @@ reinit_try:
|
||||
|
||||
sd_error_count_increment(SD_ERROR_RW_FAIL);
|
||||
|
||||
if (!first_reinit)
|
||||
if (first_reinit)
|
||||
res = sd_initialize(true);
|
||||
else
|
||||
{
|
||||
@@ -210,19 +219,29 @@ reinit_try:
|
||||
sd_error_count_increment(SD_ERROR_INIT_FAIL);
|
||||
}
|
||||
|
||||
// Reset values for a retry.
|
||||
blkcnt = 0;
|
||||
retries = 3;
|
||||
first_reinit = true;
|
||||
first_reinit = false;
|
||||
|
||||
// If succesful reinit, restart xfer.
|
||||
if (res)
|
||||
{
|
||||
bbuf = (u8 *)buf;
|
||||
sct_off = sector;
|
||||
sct_total = num_sectors;
|
||||
|
||||
goto reinit_try;
|
||||
}
|
||||
}
|
||||
|
||||
// Failed.
|
||||
return 0;
|
||||
|
||||
out:
|
||||
DPRINTF("readwrite: %08X\n", blkcnt);
|
||||
sector += blkcnt;
|
||||
num_sectors -= blkcnt;
|
||||
sct_off += blkcnt;
|
||||
sct_total -= blkcnt;
|
||||
bbuf += 512 * blkcnt;
|
||||
}
|
||||
|
||||
@@ -387,6 +406,10 @@ static void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf)
|
||||
storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN];
|
||||
storage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS];
|
||||
|
||||
storage->ext_csd.pre_eol_info = buf[EXT_CSD_PRE_EOL_INFO];
|
||||
storage->ext_csd.dev_life_est_a = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A];
|
||||
storage->ext_csd.dev_life_est_b = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B];
|
||||
|
||||
storage->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT];
|
||||
}
|
||||
|
||||
@@ -616,6 +639,8 @@ DPRINTF("[MMC] succesfully switched to HS mode\n");
|
||||
|
||||
sdmmc_card_clock_ctrl(storage->sdmmc, SDMMC_AUTO_CAL_ENABLE);
|
||||
|
||||
storage->initialized = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -628,6 +653,7 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition)
|
||||
return 0;
|
||||
|
||||
storage->partition = partition;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1030,6 +1056,8 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage)
|
||||
raw_ssr2[0] = *(u32 *)&storage->raw_ssr[16];
|
||||
|
||||
storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1;
|
||||
storage->ssr.protected_size = unstuff_bits(raw_ssr1, 448 - 384, 32);
|
||||
|
||||
switch(unstuff_bits(raw_ssr1, 440 - 384, 8))
|
||||
{
|
||||
case 0:
|
||||
@@ -1289,6 +1317,8 @@ DPRINTF("[SD] enabled HS\n");
|
||||
DPRINTF("[SD] got sd status\n");
|
||||
}
|
||||
|
||||
storage->initialized = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1328,17 +1358,19 @@ 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, SDHCI_TIMING_MMC_DDR52, SDMMC_AUTO_CAL_DISABLE))
|
||||
if (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS102, SDMMC_AUTO_CAL_DISABLE))
|
||||
return 0;
|
||||
DPRINTF("[gc] after init\n");
|
||||
|
||||
usleep(1000 + (10000 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
|
||||
if (!sdmmc_tuning_execute(storage->sdmmc, SDHCI_TIMING_MMC_DDR52, MMC_SEND_TUNING_BLOCK_HS200))
|
||||
if (!sdmmc_tuning_execute(storage->sdmmc, SDHCI_TIMING_MMC_HS102, MMC_SEND_TUNING_BLOCK_HS200))
|
||||
return 0;
|
||||
DPRINTF("[gc] after tuning\n");
|
||||
|
||||
sdmmc_card_clock_ctrl(sdmmc, SDMMC_AUTO_CAL_ENABLE);
|
||||
|
||||
storage->initialized = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -65,16 +65,19 @@ typedef struct _mmc_csd
|
||||
|
||||
typedef struct _mmc_ext_csd
|
||||
{
|
||||
u8 rev;
|
||||
u32 sectors;
|
||||
int bkops; /* background support bit */
|
||||
int bkops_en; /* manual bkops enable bit */
|
||||
u8 rev;
|
||||
u8 ext_struct; /* 194 */
|
||||
u8 card_type; /* 196 */
|
||||
u8 bkops_status; /* 246 */
|
||||
u16 dev_version;
|
||||
u8 pre_eol_info;
|
||||
u8 dev_life_est_a;
|
||||
u8 dev_life_est_b;
|
||||
u8 boot_mult;
|
||||
u8 rpmb_mult;
|
||||
u16 dev_version;
|
||||
} mmc_ext_csd_t;
|
||||
|
||||
typedef struct _sd_scr
|
||||
@@ -92,6 +95,7 @@ typedef struct _sd_ssr
|
||||
u8 uhs_grade;
|
||||
u8 video_class;
|
||||
u8 app_class;
|
||||
u32 protected_size;
|
||||
} sd_ssr_t;
|
||||
|
||||
/*! SDMMC storage context. */
|
||||
@@ -112,6 +116,7 @@ typedef struct _sdmmc_storage_t
|
||||
mmc_ext_csd_t ext_csd;
|
||||
sd_scr_t scr;
|
||||
sd_ssr_t ssr;
|
||||
int initialized;
|
||||
} sdmmc_storage_t;
|
||||
|
||||
int sdmmc_storage_end(sdmmc_storage_t *storage);
|
||||
|
||||
@@ -241,8 +241,9 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
|
||||
}
|
||||
|
||||
#ifdef SDMMC_EMMC_OC
|
||||
// Add -4 TX_DLY_CODE_OFFSET if HS533.
|
||||
if (sdmmc->id == SDMMC_4 && overclock)
|
||||
sdmmc->regs->vendllcalcfg = sdmmc->regs->vendllcalcfg &= 0xFFFFC07F | (0x7C << 7); // Add -4 TX_DLY_CODE_OFFSET if HS533.
|
||||
sdmmc->regs->vendllcalcfg = sdmmc->regs->vendllcalcfg &= 0xFFFFC07F | (0x7C << 7);
|
||||
#endif
|
||||
|
||||
sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE;
|
||||
@@ -316,7 +317,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
||||
case SDHCI_TIMING_UHS_SDR104:
|
||||
case SDHCI_TIMING_UHS_SDR82:
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
case SDHCI_TIMING_MMC_DDR52:
|
||||
case SDHCI_TIMING_MMC_HS102:
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
@@ -399,9 +400,8 @@ void sdmmc_card_clock_ctrl(sdmmc_t *sdmmc, int auto_cal_enable)
|
||||
sdmmc->auto_cal_enabled = auto_cal_enable;
|
||||
if (auto_cal_enable)
|
||||
{
|
||||
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN))
|
||||
return;
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
if (sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN)
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -653,7 +653,7 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
|
||||
break;
|
||||
case SDHCI_TIMING_UHS_SDR50:
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
case SDHCI_TIMING_MMC_DDR52:
|
||||
case SDHCI_TIMING_MMC_HS102:
|
||||
max = 256;
|
||||
flag = (4 << 13); // 256 iterations.
|
||||
break;
|
||||
@@ -725,7 +725,6 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)
|
||||
off_pu = 5;
|
||||
break;
|
||||
case SDMMC_1:
|
||||
case SDMMC_3:
|
||||
if (power == SDMMC_POWER_1_8)
|
||||
{
|
||||
off_pd = 123;
|
||||
@@ -764,7 +763,7 @@ static int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
||||
u16 norintsts = sdmmc->regs->norintsts;
|
||||
u16 errintsts = sdmmc->regs->errintsts;
|
||||
|
||||
DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts);
|
||||
DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
||||
|
||||
if (pout)
|
||||
*pout = norintsts;
|
||||
@@ -772,6 +771,9 @@ DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts);
|
||||
// Check for error interrupt.
|
||||
if (norintsts & SDHCI_INT_ERROR)
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTFARGS("SDMMC: norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
||||
#endif
|
||||
sdmmc->regs->errintsts = errintsts;
|
||||
return SDMMC_MASKINT_ERROR;
|
||||
}
|
||||
@@ -963,8 +965,6 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
|
||||
is_data_present = true;
|
||||
}
|
||||
else
|
||||
is_data_present = false;
|
||||
|
||||
_sdmmc_enable_interrupts(sdmmc);
|
||||
|
||||
@@ -983,7 +983,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
EPRINTF("SDMMC: Transfer timeout!");
|
||||
#endif
|
||||
}
|
||||
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
||||
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
||||
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
|
||||
if (result)
|
||||
{
|
||||
@@ -994,7 +994,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
if (!result)
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTFARGS("SDMMC: Unknown response %08X!", sdmmc->rsp[0]);
|
||||
EPRINTF("SDMMC: Unknown response type!");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1004,7 +1004,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
if (!result)
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTF("SDMMC: DMA Update failed!");
|
||||
EPRINTFARGS("SDMMC: DMA Update failed (%08X)!", result);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1116,10 +1116,7 @@ static void _sdmmc_config_emmc(u32 id)
|
||||
case SDMMC_4:
|
||||
// Unset park for pads.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) &= 0xF8003FFF;
|
||||
// Set default pad cfg.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) | 0x1040;
|
||||
|
||||
// Enabled schmitt trigger.
|
||||
// Enable schmitt trigger.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) |= 1; // Enable Schmitt trigger.
|
||||
break;
|
||||
}
|
||||
@@ -1129,7 +1126,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int a
|
||||
{
|
||||
const u32 trim_values[] = { 2, 8, 3, 8 };
|
||||
|
||||
if (id > SDMMC_4)
|
||||
if (id > SDMMC_4 || id == SDMMC_3)
|
||||
return 0;
|
||||
|
||||
memset(sdmmc, 0, sizeof(sdmmc_t));
|
||||
@@ -1294,7 +1291,7 @@ int sdmmc_enable_low_voltage(sdmmc_t *sdmmc)
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
usleep(1000);
|
||||
if ((sdmmc->regs->prnsts & 0xF00000) == 0xF00000)
|
||||
if ((sdmmc->regs->prnsts & SDHCI_DATA_LVL_MASK) == SDHCI_DATA_LVL_MASK)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
#define SDHCI_TIMING_UHS_SDR104 11
|
||||
#define SDHCI_TIMING_UHS_SDR82 12 // SDR104 with a 163.2MHz -> 81.6MHz clock.
|
||||
#define SDHCI_TIMING_UHS_DDR50 13
|
||||
#define SDHCI_TIMING_MMC_DDR52 14
|
||||
#define SDHCI_TIMING_MMC_HS102 14
|
||||
|
||||
#define SDHCI_CAN_64BIT 0x10000000
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ void set_fan_duty(u32 duty)
|
||||
gpio_config(GPIO_PORT_S, GPIO_PIN_7, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_S, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
|
||||
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (1 << 24); // Max PWM to disable fan.
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (0x100 << 16); // Max PWM to disable fan.
|
||||
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = 1; // Set source to PWM1.
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_4, GPIO_MODE_SPIO); // Fan power mode.
|
||||
@@ -55,7 +55,7 @@ void set_fan_duty(u32 duty)
|
||||
// If disabled send a 0 duty.
|
||||
if (inv_duty == 236)
|
||||
{
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (1 << 24); // Bit 24 is absolute 0%.
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (0x100 << 16); // Bit 24 is absolute 0%.
|
||||
regulator_disable_5v(REGULATOR_5V_FAN);
|
||||
|
||||
// Disable fan.
|
||||
|
||||
@@ -75,7 +75,7 @@ typedef struct _usb_dev_descr_t
|
||||
u8 bNumConfigs; // Number of possible configuration.
|
||||
} __attribute__((packed)) usb_dev_descr_t;
|
||||
|
||||
/* Device Qualigier descriptor structure */
|
||||
/* Device Qualifier descriptor structure */
|
||||
typedef struct _usb_dev_qual_descr_t
|
||||
{
|
||||
u8 bLength; // Size of this descriptor in bytes.
|
||||
@@ -369,7 +369,7 @@ usb_dev_bot_t usb_device_binary_object_descriptor =
|
||||
.wU2DevExitLat = 0
|
||||
};
|
||||
|
||||
u8 usb_vendor_string_descriptor_ums[32] =
|
||||
u8 usb_vendor_string_descriptor_ums[32] =
|
||||
{
|
||||
26, 0x03,
|
||||
'N', 0, 'y', 0, 'x', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0,
|
||||
|
||||
@@ -1523,7 +1523,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
DPRINTF("USB: EP timeout\n");
|
||||
// In case we disconnected, exit UMS.
|
||||
// Raise timeout if removable and didn't got a unit ready command inside 4s.
|
||||
if (bulk_ctxt->bulk_out_status == 28 ||
|
||||
if (bulk_ctxt->bulk_out_status == 28 ||
|
||||
(bulk_ctxt->bulk_out_status == 3 && ums->lun.removable && !ums->lun.prevent_medium_removal))
|
||||
{
|
||||
if (bulk_ctxt->bulk_out_status == 3)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* USB driver for Tegra X1
|
||||
* Enhanced USB (EHCI) device driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* USB Device driver for Tegra X1
|
||||
* Enhanced USB (EHCI) Device driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
@@ -312,7 +312,7 @@ static void _usb_charger_detect()
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_3, GPIO_MODE_GPIO);
|
||||
|
||||
// Configure charger pin.
|
||||
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) &=
|
||||
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN1) &=
|
||||
~(PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_MASK);
|
||||
gpio_config(GPIO_PORT_CC, GPIO_PIN_5, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_5, GPIO_OUTPUT_ENABLE);
|
||||
@@ -335,10 +335,10 @@ int usb_device_init()
|
||||
return 0;
|
||||
|
||||
// Configure PLLU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) = CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) | 0x20000000; // Disable reference clock.
|
||||
u32 pllu_cfg = (((((CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) >> 8 << 8) | 2) & 0xFFFF00FF) | ((0x19 << 8) & 0xFFFF)) & 0xFFE0FFFF) | (1<< 16) | 0x1000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) |= (1 << 29); // Disable reference clock.
|
||||
u32 pllu_cfg = (((((CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) >> 8 << 8) | 2) & 0xFFFF00FF) | ((0x19 << 8) & 0xFFFF)) & 0xFFE0FFFF) | (1 << 16) | (1 << 24);
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | 0x40000000; // Enable.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | (1 << 30); // Enable.
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
u32 timeout = (u32)TMR(TIMERUS_CNTR_1US) + 1300;
|
||||
@@ -348,18 +348,18 @@ int usb_device_init()
|
||||
usleep(10);
|
||||
|
||||
// Enable PLLU USB/HSIC/ICUSB/48M.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) | 0x2600000 | 0x800000;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) |= 0x2E00000;
|
||||
|
||||
// Enable USBD clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = (1 << 22);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD);
|
||||
usleep(2);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = (1 << 22);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_USBD);
|
||||
usleep(2);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = (1 << 22);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_USBD);
|
||||
usleep(2);
|
||||
|
||||
// Clear XUSB_PADCTL reset
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_CLR) = (1 << 14);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_CLR) = BIT(CLK_W_XUSB_PADCTL);
|
||||
|
||||
// Enable USB PHY and reset for programming.
|
||||
u32 usb_susp_ctrl = USB(USB1_IF_USB_SUSP_CTRL);
|
||||
@@ -419,7 +419,7 @@ int usb_device_init()
|
||||
// Enable crystal clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) |= 0x40000000;
|
||||
// Enable USB2 tracking.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= 0x40000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_USB2_TRK);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK) & 0xFFFFFF00) | 6; // Set trank divisor to 4.
|
||||
|
||||
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFFC03F07) | 0x78000 | 0x50; // Set delays.
|
||||
@@ -442,7 +442,7 @@ int usb_device_init()
|
||||
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFF7FFFFF) | 1;
|
||||
|
||||
// Disable USB2_TRK clock and configure UTMIP misc.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) &= 0xFFFBFFFF;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_CLR) = BIT(CLK_Y_USB2_TRK);
|
||||
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) = (CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) & 0xFEFFFFEA) | 0x2000000 | 0x28 | 2;
|
||||
usleep(1);
|
||||
|
||||
@@ -535,10 +535,10 @@ static void _usb_device_power_down()
|
||||
CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) |= 2;
|
||||
|
||||
// Set XUSB_PADCTL reset
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = (1 << 14);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_PADCTL);
|
||||
|
||||
// Disable USBD clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = (1 << 22);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_USBD);
|
||||
|
||||
// Completely disable PLLU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M.
|
||||
@@ -930,10 +930,10 @@ out:
|
||||
_usbd_mark_ep_complete(endpoint);
|
||||
else if (_usbd_get_ep_status(endpoint) != USB_EP_STATUS_IDLE)
|
||||
res = 26;
|
||||
}
|
||||
|
||||
if (direction == USB_XFER_DIR_OUT)
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
if (direction == USB_XFER_DIR_OUT)
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1175,17 +1175,17 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
|
||||
switch (_bmRequestType)
|
||||
{
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_RECIPIENT_DEVICE | USB_SETUP_TYPE_STANDARD):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
|
||||
ret = _usbd_handle_set_request(&ep_stall);
|
||||
break;
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_RECIPIENT_INTERFACE | USB_SETUP_TYPE_STANDARD):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
ret = _usbd_ep_ack(USB_EP_CTRL_IN);
|
||||
if (!ret)
|
||||
usbd_otg->interface = _wValue;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_RECIPIENT_ENDPOINT | USB_SETUP_TYPE_STANDARD):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_CLEAR_FEATURE:
|
||||
@@ -1227,10 +1227,12 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_RECIPIENT_INTERFACE | USB_SETUP_TYPE_CLASS):
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
_usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall);
|
||||
break;
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_DEVICE | USB_SETUP_TYPE_STANDARD):
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_GET_STATUS:
|
||||
@@ -1253,7 +1255,7 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
}
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_INTERFACE | USB_SETUP_TYPE_STANDARD):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
if (_bRequest == USB_REQUEST_GET_INTERFACE)
|
||||
{
|
||||
descriptor = (void *)&usbd_otg->interface;
|
||||
@@ -1287,7 +1289,7 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
transmit_data = 1;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_ENDPOINT | USB_SETUP_TYPE_STANDARD):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
if (_bRequest == USB_REQUEST_GET_STATUS)
|
||||
{
|
||||
int ep_req;
|
||||
@@ -1324,14 +1326,15 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_INTERFACE | USB_SETUP_TYPE_CLASS):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
memset(descriptor, 0, _wLength);
|
||||
|
||||
_usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall);
|
||||
size = _wLength;
|
||||
break;
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_INTERFACE | USB_SETUP_TYPE_VENDOR):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_DEVICE | USB_SETUP_TYPE_VENDOR):
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE):
|
||||
if (_bRequest == USB_REQUEST_GET_MS_DESCRIPTOR)
|
||||
{
|
||||
switch (_wIndex)
|
||||
@@ -1565,6 +1568,8 @@ int usb_device_ep1_out_reading_finish(u32 *pending_bytes)
|
||||
|
||||
*pending_bytes = _usbd_get_ep1_out_bytes_read();
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
if (ep_status == USB_EP_STATUS_IDLE)
|
||||
return 0;
|
||||
else if (ep_status == USB_EP_STATUS_DISABLED)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* USB Device driver for Tegra X1
|
||||
* Enhanced USB (EHCI) Device driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
|
||||
@@ -65,11 +65,6 @@ static void _s_putn(u32 v, int base, char fill, int fcnt)
|
||||
_s_puts(p);
|
||||
}
|
||||
|
||||
static void _s_putp(u32 *v, int base, char fill, int fcnt)
|
||||
{
|
||||
_s_putn(*v, base, fill, fcnt);
|
||||
}
|
||||
|
||||
void s_printf(char *out_buf, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@@ -114,8 +109,6 @@ void s_printf(char *out_buf, const char *fmt, ...)
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
_s_putp(va_arg(ap, u32*), 16, fill, fcnt);
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
_s_putn(va_arg(ap, u32), 16, fill, fcnt);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
||||
#define ALIGN_DOWN(x, a) (((x) - ((a) - 1)) & ~((a) - 1))
|
||||
#define BIT(n) (1U << (n))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ void panic(u32 val)
|
||||
void reboot_normal()
|
||||
{
|
||||
sd_end();
|
||||
reconfig_hw_workaround(false, 0);
|
||||
hw_reinit_workaround(false, 0);
|
||||
|
||||
panic(0x21); // Bypass fuse programming in package1.
|
||||
}
|
||||
@@ -143,7 +143,7 @@ void reboot_normal()
|
||||
void reboot_rcm()
|
||||
{
|
||||
sd_end();
|
||||
reconfig_hw_workaround(false, 0);
|
||||
hw_reinit_workaround(false, 0);
|
||||
|
||||
PMC(APBDEV_PMC_SCRATCH0) = PMC_SCRATCH0_MODE_RCM;
|
||||
PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST;
|
||||
@@ -155,7 +155,7 @@ void reboot_rcm()
|
||||
void power_off()
|
||||
{
|
||||
sd_end();
|
||||
reconfig_hw_workaround(false, 0);
|
||||
hw_reinit_workaround(false, 0);
|
||||
|
||||
// Stop the alarm, in case we injected and powered off too fast.
|
||||
max77620_rtc_stop_alarm();
|
||||
|
||||
@@ -32,8 +32,10 @@ typedef enum
|
||||
{
|
||||
ERR_LIBSYS_LP0 = (1 << 0),
|
||||
ERR_SYSOLD_NYX = (1 << 1),
|
||||
ERR_SYSOLD_MTC = (1 << 2),
|
||||
ERR_EXCEPT_ENB = (1 << 31),
|
||||
ERR_LIBSYS_MTC = (1 << 2),
|
||||
ERR_SD_BOOT_EN = (1 << 3),
|
||||
ERR_L4T_KERNEL = (1 << 24),
|
||||
ERR_EXCEPTION = (1 << 31),
|
||||
} hekate_errors_t;
|
||||
|
||||
#define byte_swap_32(num) (((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
||||
|
||||
@@ -42,8 +42,7 @@ void set_default_configuration()
|
||||
h_cfg.autohosoff = 0;
|
||||
h_cfg.autonogc = 1;
|
||||
h_cfg.updater2p = 0;
|
||||
h_cfg.brand = NULL;
|
||||
h_cfg.tagline = NULL;
|
||||
h_cfg.bootprotect = 0;
|
||||
h_cfg.errors = 0;
|
||||
h_cfg.eks = NULL;
|
||||
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
||||
@@ -107,16 +106,9 @@ int create_config_entry()
|
||||
f_puts("\nupdater2p=", &fp);
|
||||
itoa(h_cfg.updater2p, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
if (h_cfg.brand)
|
||||
{
|
||||
f_puts("\nbrand=", &fp);
|
||||
f_puts(h_cfg.brand, &fp);
|
||||
}
|
||||
if (h_cfg.tagline)
|
||||
{
|
||||
f_puts("\ntagline=", &fp);
|
||||
f_puts(h_cfg.tagline, &fp);
|
||||
}
|
||||
f_puts("\nbootprotect=", &fp);
|
||||
itoa(h_cfg.bootprotect, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\n", &fp);
|
||||
|
||||
if (mainIniFound)
|
||||
|
||||
@@ -30,8 +30,7 @@ typedef struct _hekate_config
|
||||
u32 autohosoff;
|
||||
u32 autonogc;
|
||||
u32 updater2p;
|
||||
char *brand;
|
||||
char *tagline;
|
||||
u32 bootprotect;
|
||||
// Global temporary config.
|
||||
bool se_keygen_done;
|
||||
bool sept_run;
|
||||
|
||||
@@ -270,7 +270,7 @@ void print_sdcard_info()
|
||||
gfx_clear_partial_grey(0x1B, 0, 1256);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
if (sd_mount())
|
||||
if (sd_initialize(true))
|
||||
{
|
||||
gfx_printf("%kCard IDentification:%k\n", 0xFF00DDFF, 0xFFCCCCCC);
|
||||
gfx_printf(
|
||||
@@ -287,6 +287,7 @@ void print_sdcard_info()
|
||||
sd_storage.cid.hwrev, sd_storage.cid.fwrev, sd_storage.cid.serial,
|
||||
sd_storage.cid.month, sd_storage.cid.year);
|
||||
|
||||
u16 *sd_errors = sd_get_error_count();
|
||||
gfx_printf("%kCard-Specific Data V%d.0:%k\n", 0xFF00DDFF, sd_storage.csd.structure + 1, 0xFFCCCCCC);
|
||||
gfx_printf(
|
||||
" Cmd Classes: %02X\n"
|
||||
@@ -297,18 +298,39 @@ void print_sdcard_info()
|
||||
" UHS Grade: U%d\n"
|
||||
" Video Class: V%d\n"
|
||||
" App perf class: A%d\n"
|
||||
" Write Protect: %d\n\n",
|
||||
" Write Protect: %d\n"
|
||||
" SDMMC Errors: %d %d %d\n\n",
|
||||
sd_storage.csd.cmdclass, sd_storage.sec_cnt >> 11,
|
||||
sd_storage.ssr.bus_width, sd_storage.csd.busspeed, sd_storage.csd.busspeed * 2,
|
||||
sd_storage.ssr.speed_class, sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class,
|
||||
sd_storage.ssr.app_class, sd_storage.csd.write_protect);
|
||||
sd_storage.ssr.app_class, sd_storage.csd.write_protect,
|
||||
sd_errors[0], sd_errors[1], sd_errors[2]); // SD_ERROR_INIT_FAIL, SD_ERROR_RW_FAIL, SD_ERROR_RW_RETRY.
|
||||
|
||||
gfx_puts("Acquiring FAT volume info...\n\n");
|
||||
f_getfree("", &sd_fs.free_clst, NULL);
|
||||
gfx_printf("%kFound %s volume:%k\n Free: %d MiB\n Cluster: %d KiB\n",
|
||||
0xFF00DDFF, sd_fs.fs_type == FS_EXFAT ? "exFAT" : "FAT32", 0xFFCCCCCC,
|
||||
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF, (sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512);
|
||||
sd_end();
|
||||
int res = f_mount(&sd_fs, "", 1);
|
||||
if (!res)
|
||||
{
|
||||
gfx_puts("Acquiring FAT volume info...\n\n");
|
||||
f_getfree("", &sd_fs.free_clst, NULL);
|
||||
gfx_printf("%kFound %s volume:%k\n Free: %d MiB\n Cluster: %d KiB\n",
|
||||
0xFF00DDFF, sd_fs.fs_type == FS_EXFAT ? "exFAT" : "FAT32", 0xFFCCCCCC,
|
||||
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF, (sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512);
|
||||
f_mount(NULL, "", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
EPRINTFARGS("Failed to mount SD card (FatFS Error %d).\n"
|
||||
"Make sure that a FAT partition exists..", res);
|
||||
}
|
||||
|
||||
sdmmc_storage_end(&sd_storage);
|
||||
}
|
||||
else
|
||||
{
|
||||
EPRINTF("Failed to init SD card.");
|
||||
if (!sdmmc_get_sd_inserted())
|
||||
EPRINTF("Make sure that it is inserted.");
|
||||
else
|
||||
EPRINTF("SD Card Reader is not properly seated!");
|
||||
}
|
||||
|
||||
btn_wait();
|
||||
|
||||
@@ -88,7 +88,6 @@ void dump_packages12()
|
||||
|
||||
goto out_free;
|
||||
}
|
||||
const pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + pkg1_id->pkg11_off + 0x20);
|
||||
|
||||
kb = pkg1_id->kb;
|
||||
|
||||
@@ -130,16 +129,30 @@ void dump_packages12()
|
||||
|
||||
if (kb <= KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1);
|
||||
const u8 *sec_map = pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1);
|
||||
|
||||
pk11_hdr_t *hdr_pk11 = (pk11_hdr_t *)(pkg1 + pkg1_id->pkg11_off + 0x20);
|
||||
|
||||
// Use correct sizes.
|
||||
u32 sec_size[3] = { hdr_pk11->wb_size, hdr_pk11->ldr_size, hdr_pk11->sm_size };
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (sec_map[i] == PK11_SECTION_WB)
|
||||
hdr_pk11->wb_size = sec_size[i];
|
||||
else if (sec_map[i] == PK11_SECTION_LD)
|
||||
hdr_pk11->ldr_size = sec_size[i];
|
||||
else if (sec_map[i] == PK11_SECTION_SM)
|
||||
hdr_pk11->sm_size = sec_size[i];
|
||||
}
|
||||
|
||||
// Display info.
|
||||
gfx_printf("%kNX Bootloader size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->ldr_size);
|
||||
gfx_printf("%kNX Bootloader size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr_pk11->ldr_size);
|
||||
|
||||
gfx_printf("%kSecure monitor addr: %k0x%05X\n", 0xFFC7EA46, 0xFFCCCCCC, pkg1_id->secmon_base);
|
||||
gfx_printf("%kSecure monitor size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->sm_size);
|
||||
gfx_printf("%kSecure monitor size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr_pk11->sm_size);
|
||||
|
||||
gfx_printf("%kWarmboot addr: %k0x%05X\n", 0xFFC7EA46, 0xFFCCCCCC, pkg1_id->warmboot_base);
|
||||
gfx_printf("%kWarmboot size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->wb_size);
|
||||
gfx_printf("%kWarmboot size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr_pk11->wb_size);
|
||||
|
||||
// Dump package1.1.
|
||||
emmcsn_path_impl(path, "/pkg1", "pkg1_decr.bin", &storage);
|
||||
@@ -149,19 +162,19 @@ void dump_packages12()
|
||||
|
||||
// Dump nxbootloader.
|
||||
emmcsn_path_impl(path, "/pkg1", "nxloader.bin", &storage);
|
||||
if (sd_save_to_file(loader, hdr->ldr_size, path))
|
||||
if (sd_save_to_file(loader, hdr_pk11->ldr_size, path))
|
||||
goto out_free;
|
||||
gfx_puts("NX Bootloader dumped to nxloader.bin\n");
|
||||
|
||||
// Dump secmon.
|
||||
emmcsn_path_impl(path, "/pkg1", "secmon.bin", &storage);
|
||||
if (sd_save_to_file(secmon, hdr->sm_size, path))
|
||||
if (sd_save_to_file(secmon, hdr_pk11->sm_size, path))
|
||||
goto out_free;
|
||||
gfx_puts("Secure Monitor dumped to secmon.bin\n");
|
||||
|
||||
// Dump warmboot.
|
||||
emmcsn_path_impl(path, "/pkg1", "warmboot.bin", &storage);
|
||||
if (sd_save_to_file(warmboot, hdr->wb_size, path))
|
||||
if (sd_save_to_file(warmboot, hdr_pk11->wb_size, path))
|
||||
goto out_free;
|
||||
gfx_puts("Warmboot dumped to warmboot.bin\n\n\n");
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
|
||||
bool stock = false;
|
||||
int sept_used = 0;
|
||||
|
||||
// Skip if stock and Exosphere and warmboot are not needed.
|
||||
if (!sept_ctxt)
|
||||
{
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link)
|
||||
@@ -120,7 +121,8 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
|
||||
stock = true;
|
||||
}
|
||||
|
||||
if (stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable))
|
||||
bool emummc_disabled = !emu_cfg.enabled || h_cfg.emummc_force_disable;
|
||||
if (stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && emummc_disabled)
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -163,7 +165,7 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
|
||||
continue;
|
||||
|
||||
// If content is experimental and experimental flag is not enabled, skip it.
|
||||
if ((curr_fss_cnt[i].flags0 & CNT_FLAG0_EXPERIMENTAL) && !ctxt->fss0_enable_experimental)
|
||||
if ((curr_fss_cnt[i].flags0 & CNT_FLAG0_EXPERIMENTAL) && !ctxt->fss0_experimental)
|
||||
continue;
|
||||
|
||||
// Parse content.
|
||||
@@ -188,6 +190,10 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
|
||||
ctxt->warmboot_size = curr_fss_cnt[i].size;
|
||||
ctxt->warmboot = content;
|
||||
break;
|
||||
case CNT_TYPE_KRN:
|
||||
ctxt->kernel_size = curr_fss_cnt[i].size;
|
||||
ctxt->kernel = content;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,9 @@ extern hekate_config h_cfg;
|
||||
|
||||
#define PKG2_LOAD_ADDR 0xA9800000
|
||||
|
||||
#define SECMON_BCT_CFG_ADDR 0x4003D000
|
||||
#define SECMON6_BCT_CFG_ADDR 0x4003F800
|
||||
|
||||
// Secmon mailbox.
|
||||
#define SECMON_MAILBOX_ADDR 0x40002E00
|
||||
#define SECMON7_MAILBOX_ADDR 0x40000000
|
||||
@@ -87,21 +90,21 @@ static const u8 cmac_keyseed[0x10] =
|
||||
static const u8 master_keyseed_retail[0x10] =
|
||||
{ 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C };
|
||||
|
||||
static const u8 console_keyseed[0x10] =
|
||||
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
||||
|
||||
const u8 package2_keyseed[0x10] =
|
||||
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
|
||||
|
||||
static const u8 master_keyseed_4xx_5xx_610[0x10] =
|
||||
{ 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 };
|
||||
|
||||
static const u8 master_keyseed_620[0x10] =
|
||||
{ 0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A };
|
||||
|
||||
static const u8 console_keyseed[0x10] =
|
||||
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
||||
|
||||
static const u8 console_keyseed_4xx_5xx[0x10] =
|
||||
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
|
||||
|
||||
const u8 package2_keyseed[0x10] =
|
||||
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
|
||||
|
||||
static void _hos_crit_error(const char *text)
|
||||
{
|
||||
gfx_con.mute = false;
|
||||
@@ -214,7 +217,7 @@ void hos_eks_get()
|
||||
goto out;
|
||||
|
||||
// Decrypt EKS blob.
|
||||
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x60);
|
||||
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x80);
|
||||
se_aes_crypt_ecb(14, 0, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Check if valid and for this unit.
|
||||
@@ -266,6 +269,10 @@ void hos_eks_save(u32 kb)
|
||||
u8 *keys = (u8 *)calloc(0x1000, 1);
|
||||
se_get_aes_keys(keys + 0x800, keys, 0x10);
|
||||
|
||||
// Set SBK back.
|
||||
if (FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF)
|
||||
se_aes_key_set(14, keys + 14 * 0x10, 0x10);
|
||||
|
||||
// Set magic and personalized info.
|
||||
h_cfg.eks->magic = HOS_EKS_MAGIC;
|
||||
h_cfg.eks->enabled[key_idx] = kb;
|
||||
@@ -292,7 +299,7 @@ void hos_eks_save(u32 kb)
|
||||
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x60, eks, sizeof(hos_eks_mbr_t));
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
|
||||
@@ -329,7 +336,7 @@ void hos_eks_clear(u32 kb)
|
||||
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x60, eks, sizeof(hos_eks_mbr_t));
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
EMC(EMC_SCRATCH0) &= ~EMC_SEPT_RUN;
|
||||
@@ -540,23 +547,41 @@ int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_c
|
||||
|
||||
static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
|
||||
{
|
||||
static const u32 BOOTLOADER_SIZE = 0x40000;
|
||||
static const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
|
||||
static const u32 BOOTLOADER_BACKUP_OFFSET = 0x140000;
|
||||
static const u32 HOS_KEYBLOBS_OFFSET = 0x180000;
|
||||
|
||||
u32 bootloader_offset = BOOTLOADER_MAIN_OFFSET;
|
||||
ctxt->pkg1 = (void *)malloc(BOOTLOADER_SIZE);
|
||||
|
||||
try_load:
|
||||
// Read package1.
|
||||
ctxt->pkg1 = (void *)malloc(0x40000);
|
||||
emummc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0);
|
||||
emummc_storage_read(&emmc_storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, ctxt->pkg1);
|
||||
emummc_storage_read(&emmc_storage, bootloader_offset / NX_EMMC_BLOCKSIZE, BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, ctxt->pkg1);
|
||||
|
||||
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1);
|
||||
if (!ctxt->pkg1_id)
|
||||
{
|
||||
_hos_crit_error("Unknown pkg1 version.");
|
||||
EHPRINTFARGS("HOS version not supported!%s",
|
||||
EPRINTFARGS("HOS version not supported!%s",
|
||||
(emu_cfg.enabled && !h_cfg.emummc_force_disable) ? "\nOr emuMMC corrupt!" : "");
|
||||
|
||||
// Try backup bootloader.
|
||||
if (bootloader_offset != BOOTLOADER_BACKUP_OFFSET)
|
||||
{
|
||||
EPRINTF("Trying backup bootloader...");
|
||||
bootloader_offset = BOOTLOADER_BACKUP_OFFSET;
|
||||
goto try_load;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
gfx_printf("Identified pkg1 and Keyblob %d\n\n", ctxt->pkg1_id->kb);
|
||||
gfx_printf("Identified pkg1 and mkey %d\n\n", ctxt->pkg1_id->kb);
|
||||
|
||||
// Read the correct keyblob.
|
||||
ctxt->keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
|
||||
emummc_storage_read(&emmc_storage, 0x180000 / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
|
||||
emummc_storage_read(&emmc_storage, HOS_KEYBLOBS_OFFSET / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -630,20 +655,26 @@ static bool _get_fs_exfat_compatible(link_t *info, bool *fs_is_510)
|
||||
pkg2_get_ids(&kip_ids, &fs_ids_cnt);
|
||||
|
||||
for (fs_idx = 0; fs_idx < fs_ids_cnt; fs_idx++)
|
||||
{
|
||||
if (!memcmp(sha_buf, kip_ids[fs_idx].hash, 8))
|
||||
{
|
||||
// Check if it's 5.1.0.
|
||||
if ((fs_idx & ~1) == 16)
|
||||
*fs_is_510 = true;
|
||||
|
||||
// Check if FAT32-only.
|
||||
if (fs_ids_cnt <= fs_idx && !(fs_idx & 1))
|
||||
return false;
|
||||
|
||||
// FS is FAT32 + exFAT.
|
||||
break;
|
||||
|
||||
// Check if it's 5.1.0.
|
||||
if ((fs_idx & ~1) == 16)
|
||||
*fs_is_510 = true;
|
||||
|
||||
// Return false if FAT32 only.
|
||||
if (fs_ids_cnt <= fs_idx && !(fs_idx & 1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Hash didn't match or FAT32 + exFAT.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -695,8 +726,10 @@ int hos_launch(ini_sec_t *cfg)
|
||||
goto error;
|
||||
}
|
||||
|
||||
bool emummc_enabled = emu_cfg.enabled && !h_cfg.emummc_force_disable;
|
||||
|
||||
// Enable emummc patching.
|
||||
if (emu_cfg.enabled && !h_cfg.emummc_force_disable)
|
||||
if (emummc_enabled)
|
||||
{
|
||||
if (ctxt.stock)
|
||||
{
|
||||
@@ -721,7 +754,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
if ((h_cfg.autonogc &&
|
||||
((!(fuses & ~0xF) && (kb >= KB_FIRMWARE_VERSION_400)) || // LAFW v2.
|
||||
(!(fuses & ~0x3FF) && (kb >= KB_FIRMWARE_VERSION_900)))) // LAFW v3.
|
||||
|| ((emu_cfg.enabled && !h_cfg.emummc_force_disable) &&
|
||||
|| ((emummc_enabled) &&
|
||||
((fuses & 0x400) && (kb <= KB_FIRMWARE_VERSION_810))))
|
||||
config_kip1patch(&ctxt, "nogc");
|
||||
}
|
||||
@@ -763,7 +796,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
if (kb <= KB_FIRMWARE_VERSION_600)
|
||||
pkg1_decrypt(ctxt.pkg1_id, ctxt.pkg1);
|
||||
|
||||
if (kb <= KB_FIRMWARE_VERSION_620 && !(emu_cfg.enabled && !h_cfg.emummc_force_disable))
|
||||
if (kb <= KB_FIRMWARE_VERSION_620 && !emummc_enabled)
|
||||
{
|
||||
pkg1_unpack((void *)ctxt.pkg1_id->warmboot_base, (void *)ctxt.pkg1_id->secmon_base, NULL, ctxt.pkg1_id, ctxt.pkg1);
|
||||
gfx_puts("Decrypted & unpacked pkg1\n");
|
||||
@@ -780,6 +813,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
memcpy((void *)warmboot_base, ctxt.warmboot, ctxt.warmboot_size);
|
||||
else
|
||||
{
|
||||
// Patch warmboot on T210 to allow downgrading.
|
||||
if (kb >= KB_FIRMWARE_VERSION_700)
|
||||
{
|
||||
_hos_crit_error("No warmboot provided!");
|
||||
@@ -792,10 +826,10 @@ int hos_launch(ini_sec_t *cfg)
|
||||
*(vu32 *)(ctxt.pkg1_id->warmboot_base + warmboot_patchset[i].off) = warmboot_patchset[i].val;
|
||||
}
|
||||
// Set warmboot address in PMC if required.
|
||||
if (ctxt.pkg1_id->set_warmboot)
|
||||
if (kb <= KB_FIRMWARE_VERSION_301)
|
||||
PMC(APBDEV_PMC_SCRATCH1) = warmboot_base;
|
||||
|
||||
// Replace 'SecureMonitor' if requested.
|
||||
// Replace 'SecureMonitor' if requested or patch Pkg2 checks if needed.
|
||||
if (ctxt.secmon)
|
||||
memcpy((void *)secmon_base, ctxt.secmon, ctxt.secmon_size);
|
||||
else if (ctxt.pkg1_id->secmon_patchset)
|
||||
@@ -824,13 +858,11 @@ int hos_launch(ini_sec_t *cfg)
|
||||
if (!pkg2_hdr)
|
||||
{
|
||||
_hos_crit_error("Pkg2 decryption failed!");
|
||||
if (kb >= KB_FIRMWARE_VERSION_700)
|
||||
{
|
||||
EPRINTF("Is Sept updated?");
|
||||
EPRINTFARGS("Is hekate%s updated?", kb >= KB_FIRMWARE_VERSION_700 ? " or Sept" : "");
|
||||
|
||||
// Clear EKS slot, in case something went wrong with sept keygen.
|
||||
// Clear EKS slot, in case something went wrong with sept keygen.
|
||||
if (kb >= KB_FIRMWARE_VERSION_700)
|
||||
hos_eks_clear(kb);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
else if (kb >= KB_FIRMWARE_VERSION_700)
|
||||
@@ -853,8 +885,8 @@ int hos_launch(ini_sec_t *cfg)
|
||||
|
||||
if (!ctxt.stock && (ctxt.svcperm || ctxt.debugmode || ctxt.atmosphere))
|
||||
{
|
||||
u8 kernel_hash[0x20];
|
||||
// Hash only Kernel when it embeds INI1.
|
||||
u8 kernel_hash[0x20];
|
||||
if (!ctxt.new_pkg2)
|
||||
se_calc_sha256_oneshot(kernel_hash, ctxt.kernel, ctxt.kernel_size);
|
||||
else
|
||||
@@ -919,11 +951,14 @@ int hos_launch(ini_sec_t *cfg)
|
||||
{
|
||||
EHPRINTFARGS("Failed to apply '%s'!", unappliedPatch);
|
||||
|
||||
gfx_puts("\nPress POWER to continue.\nPress VOL to go to the menu.\n");
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
bool emmc_patch_failed = !strcmp(unappliedPatch, "emummc");
|
||||
if (!emmc_patch_failed)
|
||||
{
|
||||
gfx_puts("\nPress POWER to continue.\nPress VOL to go to the menu.\n");
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
}
|
||||
|
||||
u32 btn = btn_wait();
|
||||
if (!(btn & BTN_POWER))
|
||||
if (emmc_patch_failed || !(btn_wait() & BTN_POWER))
|
||||
{
|
||||
_free_launch_components(&ctxt);
|
||||
goto error; // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated!
|
||||
@@ -931,16 +966,12 @@ int hos_launch(ini_sec_t *cfg)
|
||||
}
|
||||
|
||||
// Rebuild and encrypt package2.
|
||||
pkg2_build_encrypt((void *)PKG2_LOAD_ADDR, ctxt.kernel, ctxt.kernel_size, &kip1_info, ctxt.new_pkg2, kb);
|
||||
pkg2_build_encrypt((void *)PKG2_LOAD_ADDR, &ctxt, &kip1_info);
|
||||
|
||||
gfx_puts("Rebuilt & loaded pkg2\n");
|
||||
|
||||
gfx_printf("\n%kBooting...%k\n", 0xFF96FF00, 0xFFCCCCCC);
|
||||
|
||||
// Clear pkg1/pkg2 keys.
|
||||
se_aes_key_clear(8);
|
||||
se_aes_key_clear(11);
|
||||
|
||||
// Set initial mailbox values.
|
||||
int bootStateDramPkg2 = 0;
|
||||
int bootStatePkg2Continue = 0;
|
||||
@@ -951,6 +982,10 @@ int hos_launch(ini_sec_t *cfg)
|
||||
else if (kb == KB_FIRMWARE_VERSION_301)
|
||||
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; // Warmboot 3.0.1/.2 PA address id.
|
||||
|
||||
// Clear pkg1/pkg2 keys.
|
||||
se_aes_key_clear(8);
|
||||
se_aes_key_clear(11);
|
||||
|
||||
// Finalize per firmware key access. Skip access control if new exosphere.
|
||||
switch (kb | (exo_new << 7))
|
||||
{
|
||||
@@ -976,15 +1011,15 @@ int hos_launch(ini_sec_t *cfg)
|
||||
// Clear BCT area for retail units and copy it over if dev unit.
|
||||
if (kb <= KB_FIRMWARE_VERSION_500 && !exo_new)
|
||||
{
|
||||
memset((void *)0x4003D000, 0, 0x3000);
|
||||
memset((void *)SECMON_BCT_CFG_ADDR, 0, 0x3000);
|
||||
if ((fuse_read_odm(4) & 3) == 3)
|
||||
memcpy((void *)0x4003D000, bootConfigBuf, 0x1000);
|
||||
memcpy((void *)SECMON_BCT_CFG_ADDR, bootConfigBuf, 0x1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset((void *)0x4003F800, 0, 0x800);
|
||||
memset((void *)SECMON6_BCT_CFG_ADDR, 0, 0x800);
|
||||
if ((fuse_read_odm(4) & 3) == 3)
|
||||
memcpy((void *)0x4003F800, bootConfigBuf, 0x800);
|
||||
memcpy((void *)SECMON6_BCT_CFG_ADDR, bootConfigBuf, 0x800);
|
||||
}
|
||||
free(bootConfigBuf);
|
||||
|
||||
@@ -997,7 +1032,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
sdmmc_storage_end(&emmc_storage);
|
||||
|
||||
// Finalize MC carveout.
|
||||
if (kb <= KB_FIRMWARE_VERSION_301)
|
||||
if (kb <= KB_FIRMWARE_VERSION_301 && !exo_new)
|
||||
mc_config_carveout();
|
||||
|
||||
// Lock SE before starting 'SecureMonitor' if < 6.2.0, otherwise lock bootrom and ipatches.
|
||||
@@ -1033,8 +1068,9 @@ int hos_launch(ini_sec_t *cfg)
|
||||
// Clear EMC_SCRATCH0.
|
||||
EMC(EMC_SCRATCH0) = 0;
|
||||
|
||||
// Hold USBD in reset for SoC state validation on sleep.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) |= 0x400000;
|
||||
// Hold USBD, USB2, AHBDMA and APBDMA in reset for SoC state validation on sleep.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_USBD);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_AHBDMA) | BIT(CLK_H_APBDMA) | BIT(CLK_H_USB2);
|
||||
|
||||
// Flush cache and disable MMU.
|
||||
bpmp_mmu_disable();
|
||||
@@ -1043,13 +1079,15 @@ int hos_launch(ini_sec_t *cfg)
|
||||
// emuMMC: Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
|
||||
sdmmc_storage_init_wait_sd();
|
||||
|
||||
// Wait for secmon to get ready.
|
||||
// Launch secmon.
|
||||
if (smmu_is_used())
|
||||
smmu_exit();
|
||||
else
|
||||
ccplex_boot_cpu0(secmon_base);
|
||||
|
||||
// Wait for secmon to get ready.
|
||||
while (!secmon_mailbox->out)
|
||||
; // A usleep(1) only works when in IRAM or with a trained DRAM.
|
||||
;
|
||||
|
||||
// Signal pkg2 ready and continue boot.
|
||||
secmon_mailbox->in = bootStatePkg2Continue;
|
||||
|
||||
@@ -66,17 +66,17 @@ typedef struct _hos_eks_bis_keys_t
|
||||
typedef struct _hos_eks_mbr_t
|
||||
{
|
||||
u32 magic;
|
||||
u8 enabled[6];
|
||||
u8 enabled[5];
|
||||
u8 enabled_bis;
|
||||
u8 rsvd;
|
||||
u8 rsvd[2];
|
||||
u32 sbk_low;
|
||||
u8 dkg[0x10];
|
||||
u8 dkk[0x10];
|
||||
hos_eks_keys_t keys[6];
|
||||
hos_eks_keys_t keys[5];
|
||||
hos_eks_bis_keys_t bis_keys[3];
|
||||
} hos_eks_mbr_t;
|
||||
|
||||
static_assert(sizeof(hos_eks_mbr_t) == 336, "HOS EKS size is wrong!");
|
||||
static_assert(sizeof(hos_eks_mbr_t) == 304, "HOS EKS size is wrong!");
|
||||
|
||||
typedef struct _launch_ctxt_t
|
||||
{
|
||||
@@ -97,6 +97,7 @@ typedef struct _launch_ctxt_t
|
||||
|
||||
void *kernel;
|
||||
u32 kernel_size;
|
||||
|
||||
link_t kip1_list;
|
||||
char* kip1_patches;
|
||||
|
||||
@@ -105,7 +106,7 @@ typedef struct _launch_ctxt_t
|
||||
bool debugmode;
|
||||
bool stock;
|
||||
bool atmosphere;
|
||||
bool fss0_enable_experimental;
|
||||
bool fss0_experimental;
|
||||
bool emummc_forced;
|
||||
|
||||
exo_ctxt_t exo_ctx;
|
||||
|
||||
@@ -253,7 +253,7 @@ static int _config_fss(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (!strcmp("fss0experimental", kv->key))
|
||||
{
|
||||
ctxt->fss0_enable_experimental = *kv->val == '1';
|
||||
ctxt->fss0_experimental = *kv->val == '1';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,45 +19,45 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "hos.h"
|
||||
#include "pkg1.h"
|
||||
#include <gfx_utils.h>
|
||||
#include <mem/heap.h>
|
||||
#include <sec/se.h>
|
||||
#include <utils/aarch64_util.h>
|
||||
|
||||
#define _NOPv7() 0xE320F000
|
||||
|
||||
#define SM_100_ADR 0x4002B020
|
||||
// Secmon package2 signature/hash checks patches for Erista.
|
||||
#define SM_100_ADR 0x4002B020 // Original: 0x40014020.
|
||||
PATCHSET_DEF(_secmon_1_patchset,
|
||||
// Patch the relocator to be able to run from SM_100_ADR.
|
||||
{ 0x1E0, _ADRP(0, 0x7C013000 - _PAGEOFF(SM_100_ADR)) },
|
||||
//Patch package2 decryption and signature/hash checks.
|
||||
{ 0x9F0 + 0xADC, _NOP() } // Header signature.
|
||||
// Patch package2 signature/hash checks.
|
||||
{ 0x9F0 + 0xADC, _NOP() }
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_secmon_2_patchset,
|
||||
// Patch package2 decryption and signature/hash checks.
|
||||
{ 0xAC8 + 0xAAC, _NOP() } // Header signature.
|
||||
// Patch package2 signature/hash checks.
|
||||
{ 0xAC8 + 0xAAC, _NOP() }
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_secmon_3_patchset,
|
||||
// Patch package2 decryption and signature/hash checks.
|
||||
{ 0xAC8 + 0xA30, _NOP() } // Header signature.
|
||||
// Patch package2 signature/hash checks.
|
||||
{ 0xAC8 + 0xA30, _NOP() }
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_secmon_4_patchset,
|
||||
// Patch package2 decryption and signature/hash checks.
|
||||
{ 0x2300 + 0x5EFC, _NOP() } // Header signature.
|
||||
// Patch package2 signature/hash checks.
|
||||
{ 0x2300 + 0x5EFC, _NOP() }
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_secmon_5_patchset,
|
||||
// Patch package2 decryption and signature/hash checks.
|
||||
{ 0xDA8 + 0xC9C, _NOP() } // Header signature.
|
||||
// Patch package2 signature/hash checks.
|
||||
{ 0xDA8 + 0xC9C, _NOP() }
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_secmon_6_patchset,
|
||||
// Patch package2 decryption and signature/hash checks.
|
||||
{ 0xDC8 + 0xE90, _NOP() } // Header signature.
|
||||
// Patch package2 signature/hash checks.
|
||||
{ 0xDC8 + 0xE90, _NOP() }
|
||||
// Fix sleep mode for debug.
|
||||
// { 0x1A68 + 0x3854, 0x94000E45 }, //gpio_config_for_uart.
|
||||
// { 0x1A68 + 0x3858, 0x97FFFC0F }, //clkrst_reboot_uarta.
|
||||
@@ -69,8 +69,8 @@ PATCHSET_DEF(_secmon_6_patchset,
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_secmon_620_patchset,
|
||||
// Patch package2 decryption and signature/hash checks.
|
||||
{ 0xDC8 + 0xC74, _NOP() } // Header signature.
|
||||
// Patch package2 signature/hash checks.
|
||||
{ 0xDC8 + 0xC74, _NOP() }
|
||||
// Fix sleep mode for debug.
|
||||
// { 0x2AC8 + 0x3854, 0x94000F42 }, //gpio_config_for_uart.
|
||||
// { 0x2AC8 + 0x3858, 0x97FFFC0F }, //clkrst_reboot_uarta.
|
||||
@@ -81,6 +81,8 @@ PATCHSET_DEF(_secmon_620_patchset,
|
||||
// { 0x2AC8 + 0x3A6C, _NOP() } // warmboot UARTA cfg.
|
||||
);
|
||||
|
||||
// Erista fuse check warmboot patches.
|
||||
#define _NOPv7() 0xE320F000
|
||||
PATCHSET_DEF(_warmboot_1_patchset,
|
||||
{ 0x4DC, _NOPv7() } // Fuse check.
|
||||
);
|
||||
@@ -99,38 +101,35 @@ PATCHSET_DEF(_warmboot_4_patchset,
|
||||
{ 0x558, _NOPv7() } // Segment id check.
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* 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 }
|
||||
* 6.0: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 6.2: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 7.0: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 1.0: {sm, ldr, wb} { 2, 1, 0 }
|
||||
* 2.0+: {wb, ldr, sm} { 0, 1, 2 }
|
||||
* 4.0+: {ldr, sm, wb} { 1, 2, 0 }
|
||||
*/
|
||||
|
||||
static const u8 sec_map_100[3] = { PK11_SECTION_SM, PK11_SECTION_LD, PK11_SECTION_WB };
|
||||
static const u8 sec_map_2xx[3] = { PK11_SECTION_WB, PK11_SECTION_LD, PK11_SECTION_SM };
|
||||
static const u8 sec_map_4xx[3] = { PK11_SECTION_LD, PK11_SECTION_SM, PK11_SECTION_WB };
|
||||
|
||||
static const pkg1_id_t _pkg1_ids[] = {
|
||||
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, true, _secmon_1_patchset, _warmboot_1_patchset }, //1.0.0 (Patched relocator)
|
||||
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_2_patchset, _warmboot_2_patchset }, //2.0.0 - 2.3.0
|
||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.0
|
||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.1 - 3.0.2
|
||||
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_4_patchset, _warmboot_4_patchset }, //4.0.0 - 4.1.0
|
||||
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_5_patchset, _warmboot_4_patchset }, //5.0.0 - 5.1.0
|
||||
{ "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_6_patchset, _warmboot_4_patchset }, //6.0.0 - 6.1.0
|
||||
{ "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_620_patchset, _warmboot_4_patchset }, //6.2.0
|
||||
{ "20181218175730", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.0
|
||||
{ "20190208150037", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.1
|
||||
{ "20190314172056", 7, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.0.0 - 8.0.1
|
||||
{ "20190531152432", 8, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.1.0
|
||||
{ "20190809135709", 9, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //9.0.0 - 9.0.1
|
||||
{ "20191021113848", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //9.1.0
|
||||
{ "20200303104606", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //10.0.0
|
||||
{ NULL } //End.
|
||||
{ "20161121183008", 0, 0x1900, 0x3FE0, SM_100_ADR, 0x8000D000, _secmon_1_patchset, _warmboot_1_patchset }, // 1.0.0 (Patched relocator).
|
||||
{ "20170210155124", 0, 0x1900, 0x3FE0, 0x4002D000, 0x8000D000, _secmon_2_patchset, _warmboot_2_patchset }, // 2.0.0 - 2.3.0.
|
||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, 0x4002D000, 0x8000D000, _secmon_3_patchset, _warmboot_3_patchset }, // 3.0.0.
|
||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, 0x4002D000, 0x8000D000, _secmon_3_patchset, _warmboot_3_patchset }, // 3.0.1 - 3.0.2.
|
||||
{ "20170921172629", 3, 0x1800, 0x3FE0, 0x4002B000, 0x4003B000, _secmon_4_patchset, _warmboot_4_patchset }, // 4.0.0 - 4.1.0.
|
||||
{ "20180220163747", 4, 0x1900, 0x3FE0, 0x4002B000, 0x4003B000, _secmon_5_patchset, _warmboot_4_patchset }, // 5.0.0 - 5.1.0.
|
||||
{ "20180802162753", 5, 0x1900, 0x3FE0, 0x4002B000, 0x4003D800, _secmon_6_patchset, _warmboot_4_patchset }, // 6.0.0 - 6.1.0.
|
||||
{ "20181107105733", 6, 0x0E00, 0x6FE0, 0x4002B000, 0x4003D800, _secmon_620_patchset, _warmboot_4_patchset }, // 6.2.0.
|
||||
{ "20181218175730", 7, 0x0F00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 7.0.0.
|
||||
{ "20190208150037", 7, 0x0F00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 7.0.1.
|
||||
{ "20190314172056", 7, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 8.0.0 - 8.0.1.
|
||||
{ "20190531152432", 8, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 8.1.0.
|
||||
{ "20190809135709", 9, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 9.0.0 - 9.0.1.
|
||||
{ "20191021113848", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 9.1.0.
|
||||
{ "20200303104606", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 10.0.0.
|
||||
{ NULL } // End.
|
||||
};
|
||||
|
||||
const pkg1_id_t *pkg1_get_latest()
|
||||
@@ -159,22 +158,34 @@ void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1)
|
||||
se_aes_crypt_ctr(11, pkg11 + 0x20, pkg11_size, pkg11 + 0x20, pkg11_size, pkg11 + 0x10);
|
||||
}
|
||||
|
||||
void pkg1_unpack(void *warmboot_dst, void *secmon_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1)
|
||||
const u8 *pkg1_unpack(void *wm_dst, void *sm_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1)
|
||||
{
|
||||
pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + id->pkg11_off + 0x20);
|
||||
const u8 *sec_map;
|
||||
const 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 };
|
||||
|
||||
// Get correct header mapping.
|
||||
if (id->kb == KB_FIRMWARE_VERSION_100_200 && !strcmp(id->id, "20161121183008"))
|
||||
sec_map = sec_map_100;
|
||||
else if (id->kb >= KB_FIRMWARE_VERSION_100_200 && id->kb <= KB_FIRMWARE_VERSION_301)
|
||||
sec_map = sec_map_2xx;
|
||||
else
|
||||
sec_map = sec_map_4xx;
|
||||
|
||||
// Copy secmon, warmboot and nx bootloader payloads.
|
||||
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] == 1 && ldr_dst)
|
||||
memcpy(ldr_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]];
|
||||
if (sec_map[i] == PK11_SECTION_WB && wm_dst)
|
||||
memcpy(wm_dst, pdata, sec_size[sec_map[i]]);
|
||||
else if (sec_map[i] == PK11_SECTION_LD && ldr_dst)
|
||||
memcpy(ldr_dst, pdata, sec_size[sec_map[i]]);
|
||||
else if (sec_map[i] == PK11_SECTION_SM && sm_dst)
|
||||
memcpy(sm_dst, pdata, sec_size[sec_map[i]]);
|
||||
pdata += sec_size[sec_map[i]];
|
||||
}
|
||||
|
||||
return sec_map;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define PK11_SECTION_WB 0
|
||||
#define PK11_SECTION_LD 1
|
||||
#define PK11_SECTION_SM 2
|
||||
|
||||
typedef struct _patch_t
|
||||
{
|
||||
u32 off;
|
||||
@@ -37,10 +41,8 @@ typedef struct _pkg1_id_t
|
||||
u32 kb;
|
||||
u32 tsec_off;
|
||||
u32 pkg11_off;
|
||||
u32 sec_map[3];
|
||||
u32 secmon_base;
|
||||
u32 warmboot_base;
|
||||
bool set_warmboot;
|
||||
patch_t *secmon_patchset;
|
||||
patch_t *warmboot_patchset;
|
||||
} pkg1_id_t;
|
||||
@@ -60,6 +62,6 @@ typedef struct _pk11_hdr_t
|
||||
const pkg1_id_t *pkg1_get_latest();
|
||||
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, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1);
|
||||
const u8 *pkg1_unpack(void *wm_dst, void *sm_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -604,6 +604,20 @@ static kip1_patchset_t _fs_patches_1000[] =
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_1020[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x13C2F0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x14E268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1020[] =
|
||||
{
|
||||
{ "nogc", _fs_nogc_1020 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// SHA256 hashes.
|
||||
static kip1_id_t _kip_ids[] =
|
||||
{
|
||||
@@ -641,6 +655,8 @@ static kip1_id_t _kip_ids[] =
|
||||
{ "FS", "\xF1\x96\xD1\x44\xD0\x44\x45\xB6", _fs_patches_910 }, // FS 9.1.0 exfat
|
||||
{ "FS", "\x3E\xEB\xD9\xB7\xBC\xD1\xB5\xE0", _fs_patches_1000 }, // FS 10.0.0
|
||||
{ "FS", "\x81\x7E\xA2\xB0\xB7\x02\xC1\xF3", _fs_patches_1000 }, // FS 10.0.0 exfat
|
||||
{ "FS", "\xA9\x52\xB6\x57\xAD\xF9\xC2\xBA", _fs_patches_1020 }, // FS 10.2.0
|
||||
{ "FS", "\x16\x0D\x3E\x10\x4E\xAD\x61\x76", _fs_patches_1020 }, // FS 10.2.0 exfat
|
||||
};
|
||||
|
||||
static kip1_id_t *_kip_id_sets = _kip_ids;
|
||||
@@ -1273,11 +1289,12 @@ static bool _pkg2_key_unwrap_validate(pkg2_hdr_t *tmp_test, pkg2_hdr_t *hdr, u8
|
||||
return (tmp_test->magic == PKG2_MAGIC);
|
||||
}
|
||||
|
||||
u8 pkg2_keyslot;
|
||||
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb)
|
||||
{
|
||||
pkg2_hdr_t mkey_test;
|
||||
u8 *pdata = (u8 *)data;
|
||||
u8 keyslot = 8;
|
||||
pkg2_keyslot = 8;
|
||||
|
||||
// Skip signature.
|
||||
pdata += 0x100;
|
||||
@@ -1310,7 +1327,7 @@ pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb)
|
||||
|
||||
if (res)
|
||||
{
|
||||
keyslot = 9;
|
||||
pkg2_keyslot = 9;
|
||||
goto key_found;
|
||||
}
|
||||
else
|
||||
@@ -1340,7 +1357,7 @@ pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb)
|
||||
|
||||
key_found:
|
||||
// Decrypt header.
|
||||
se_aes_crypt_ctr(keyslot, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||
se_aes_crypt_ctr(pkg2_keyslot, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||
//gfx_hexdump((u32)hdr, hdr, 0x100);
|
||||
|
||||
if (hdr->magic != PKG2_MAGIC)
|
||||
@@ -1352,15 +1369,12 @@ DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]);
|
||||
if (!hdr->sec_size[i])
|
||||
continue;
|
||||
|
||||
se_aes_crypt_ctr(keyslot, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]);
|
||||
se_aes_crypt_ctr(pkg2_keyslot, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]);
|
||||
//gfx_hexdump((u32)pdata, pdata, 0x100);
|
||||
|
||||
pdata += hdr->sec_size[i];
|
||||
}
|
||||
|
||||
if (keyslot != 8)
|
||||
se_aes_key_clear(9);
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
@@ -1396,9 +1410,16 @@ DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->s
|
||||
return ini1_size;
|
||||
}
|
||||
|
||||
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info, bool new_pkg2, u8 kb)
|
||||
void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info)
|
||||
{
|
||||
u8 *pdst = (u8 *)dst;
|
||||
launch_ctxt_t * ctxt = (launch_ctxt_t *)hos_ctxt;
|
||||
u32 kernel_size = ctxt->kernel_size;
|
||||
bool is_meso = *(u32 *)(ctxt->kernel + 4) == ATM_MESOSPHERE;
|
||||
|
||||
// Force new Package2 if Mesosphere.
|
||||
if (is_meso)
|
||||
ctxt->new_pkg2 = true;
|
||||
|
||||
// Signature.
|
||||
memset(pdst, 0, 0x100);
|
||||
@@ -1413,34 +1434,36 @@ void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_i
|
||||
hdr->bl_ver = 0;
|
||||
hdr->pkg2_ver = 0xFF;
|
||||
|
||||
if (!new_pkg2)
|
||||
if (!ctxt->new_pkg2)
|
||||
hdr->base = 0x10000000;
|
||||
else
|
||||
hdr->base = 0x60000;
|
||||
DPRINTF("kernel @ %08X (%08X)\n", (u32)kernel, kernel_size);
|
||||
DPRINTF("%s @ %08X (%08X)\n", is_meso ? "Mesosphere": "kernel",(u32)ctxt->kernel, kernel_size);
|
||||
|
||||
pdst += sizeof(pkg2_hdr_t);
|
||||
|
||||
// Kernel.
|
||||
memcpy(pdst, kernel, kernel_size);
|
||||
if (!new_pkg2)
|
||||
memcpy(pdst, ctxt->kernel, kernel_size);
|
||||
if (!ctxt->new_pkg2)
|
||||
hdr->sec_off[PKG2_SEC_KERNEL] = 0x10000000;
|
||||
else
|
||||
{
|
||||
// Set new INI1 offset to kernel.
|
||||
*(u32 *)(pdst + pkg2_newkern_ini1_val) = kernel_size;
|
||||
kernel_size += _pkg2_ini1_build(pdst + kernel_size, hdr, kips_info, new_pkg2);
|
||||
*(u32 *)(pdst + (is_meso ? 8 : pkg2_newkern_ini1_val)) = kernel_size;
|
||||
|
||||
// Build INI1 for new Package2.
|
||||
kernel_size += _pkg2_ini1_build(pdst + kernel_size, hdr, kips_info, ctxt->new_pkg2);
|
||||
hdr->sec_off[PKG2_SEC_KERNEL] = 0x60000;
|
||||
}
|
||||
hdr->sec_size[PKG2_SEC_KERNEL] = kernel_size;
|
||||
se_aes_crypt_ctr(8, pdst, kernel_size, pdst, kernel_size, &hdr->sec_ctr[PKG2_SEC_KERNEL * 0x10]);
|
||||
se_aes_crypt_ctr(pkg2_keyslot, pdst, kernel_size, pdst, kernel_size, &hdr->sec_ctr[PKG2_SEC_KERNEL * 0x10]);
|
||||
pdst += kernel_size;
|
||||
DPRINTF("kernel encrypted\n");
|
||||
|
||||
// INI1.
|
||||
/// Build INI1 for old Package2.
|
||||
u32 ini1_size = 0;
|
||||
if (!new_pkg2)
|
||||
ini1_size = _pkg2_ini1_build(pdst, hdr, kips_info, new_pkg2);
|
||||
if (!ctxt->new_pkg2)
|
||||
ini1_size = _pkg2_ini1_build(pdst, hdr, kips_info, false);
|
||||
DPRINTF("INI1 encrypted\n");
|
||||
|
||||
// Calculate SHA256 over encrypted Kernel and INI1.
|
||||
@@ -1452,11 +1475,14 @@ DPRINTF("INI1 encrypted\n");
|
||||
(void *)pk2_hash_data, hdr->sec_size[PKG2_SEC_INI1]);
|
||||
|
||||
//Encrypt header.
|
||||
u8 key_ver = kb ? kb + 1 : 0;
|
||||
u8 key_ver = ctxt->pkg1_id->kb ? ctxt->pkg1_id->kb + 1 : 0;
|
||||
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
|
||||
hdr->ctr[4] = key_ver;
|
||||
se_aes_crypt_ctr(8, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||
se_aes_crypt_ctr(pkg2_keyslot, 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;
|
||||
hdr->ctr[4] = key_ver;
|
||||
|
||||
if (pkg2_keyslot != 8)
|
||||
se_aes_key_clear(9);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // Offset of OP + 12 is the INI1 offset.
|
||||
#define PKG2_NEWKERN_START 0x800
|
||||
|
||||
#define ATM_MESOSPHERE 0x3053534D
|
||||
|
||||
extern u32 pkg2_newkern_ini1_val;
|
||||
extern u32 pkg2_newkern_ini1_start;
|
||||
extern u32 pkg2_newkern_ini1_end;
|
||||
@@ -155,6 +157,6 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames);
|
||||
|
||||
const pkg2_kernel_id_t *pkg2_identify(u8 *hash);
|
||||
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb);
|
||||
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info, bool new_pkg2, u8 kb);
|
||||
void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -331,23 +331,27 @@ static const char *get_error_desc(u32 error_desc)
|
||||
switch (error_desc)
|
||||
{
|
||||
case 0x100:
|
||||
return "Instruction Abort";
|
||||
return "IABRT"; // Instruction Abort.
|
||||
case 0x101:
|
||||
return "Data Abort";
|
||||
return "DABRT"; // Data Abort.
|
||||
case 0x102:
|
||||
return "PC Misalignment";
|
||||
return "IUA"; // Instruction Unaligned Access.
|
||||
case 0x103:
|
||||
return "SP Misalignment";
|
||||
return "DUA"; // Data Unaligned Access.
|
||||
case 0x104:
|
||||
return "Trap";
|
||||
return "UDF"; // Undefined Instruction.
|
||||
case 0x106:
|
||||
return "SError";
|
||||
return "SYS"; // System Error.
|
||||
case 0x301:
|
||||
return "Bad SVC";
|
||||
return "SVC"; // Bad arguments or unimplemented SVC.
|
||||
case 0xF00:
|
||||
return "KRNL"; // Kernel panic.
|
||||
case 0xFFD:
|
||||
return "SO"; // Stack Overflow.
|
||||
case 0xFFE:
|
||||
return "std::abort()";
|
||||
return "std::abort";
|
||||
default:
|
||||
return "Unknown";
|
||||
return "UNK";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,8 +367,8 @@ void secmon_exo_check_panic()
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
WPRINTF("Panic occurred while running Atmosphere.\n\n");
|
||||
WPRINTFARGS("Title ID: %08X%08X", (u32)((u64)rpt->title_id >> 32), (u32)rpt->title_id);
|
||||
WPRINTFARGS("Error Desc: %s (0x%x)\n", get_error_desc(rpt->error_desc), rpt->error_desc);
|
||||
WPRINTFARGS("Title ID: %08X%08X", (u32)((u64)rpt->title_id >> 32), (u32)rpt->title_id);
|
||||
WPRINTFARGS("Error: %s (0x%x)\n", get_error_desc(rpt->error_desc), rpt->error_desc);
|
||||
|
||||
// Save context to the SD card.
|
||||
char filepath[0x40];
|
||||
@@ -374,23 +378,23 @@ void secmon_exo_check_panic()
|
||||
itoa((u32)(rpt->report_identifier), filepath + strlen(filepath), 16);
|
||||
strcat(filepath, ".bin");
|
||||
|
||||
sd_save_to_file((void *)rpt, sizeof(atm_fatal_error_ctx), filepath);
|
||||
|
||||
gfx_con.fntsz = 8;
|
||||
WPRINTFARGS("Report saved to %s\n", filepath);
|
||||
if (!sd_save_to_file((void *)rpt, sizeof(atm_fatal_error_ctx), filepath))
|
||||
{
|
||||
gfx_con.fntsz = 8;
|
||||
WPRINTFARGS("Report saved to %s\n", filepath);
|
||||
gfx_con.fntsz = 16;
|
||||
}
|
||||
|
||||
// Change magic to invalid, to prevent double-display of error/bootlooping.
|
||||
rpt->magic = 0x0;
|
||||
rpt->magic = 0;
|
||||
|
||||
gfx_con.fntsz = 16;
|
||||
gfx_printf("\n\nPress POWER to continue.\n");
|
||||
|
||||
display_backlight_brightness(100, 1000);
|
||||
msleep(1000);
|
||||
|
||||
u32 btn = btn_wait();
|
||||
while (!(btn & BTN_POWER))
|
||||
btn = btn_wait();
|
||||
while (!(btn_wait() & BTN_POWER))
|
||||
;
|
||||
|
||||
display_backlight_brightness(0, 1000);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
@@ -243,7 +243,7 @@ int reboot_to_sept(const u8 *tsec_fw, u32 kb, ini_sec_t *cfg_sec)
|
||||
PMC(APBDEV_PMC_SCRATCH33) = SEPT_PRI_ADDR;
|
||||
PMC(APBDEV_PMC_SCRATCH40) = 0x6000F208;
|
||||
|
||||
reconfig_hw_workaround(false, 0);
|
||||
hw_reinit_workaround(false, 0);
|
||||
|
||||
(*sept)();
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <soc/uart.h>
|
||||
#include "storage/emummc.h"
|
||||
@@ -255,12 +256,12 @@ int launch_payload(char *path, bool update)
|
||||
else
|
||||
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10));
|
||||
|
||||
reconfig_hw_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
|
||||
hw_reinit_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
|
||||
}
|
||||
else
|
||||
{
|
||||
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000);
|
||||
reconfig_hw_workaround(true, 0);
|
||||
hw_reinit_workaround(true, 0);
|
||||
}
|
||||
|
||||
// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
|
||||
@@ -292,8 +293,15 @@ void auto_launch_update()
|
||||
EMC(EMC_SCRATCH0) &= ~EMC_HEKA_UPD;
|
||||
else if (sd_mount())
|
||||
{
|
||||
// Check if update.bin exists and is newer and launch it. Otherwise create it.
|
||||
if (!f_stat("bootloader/update.bin", NULL))
|
||||
launch_payload("bootloader/update.bin", true);
|
||||
else
|
||||
{
|
||||
u8 *buf = calloc(0x200, 1);
|
||||
is_ipl_updated(buf, "bootloader/update.bin", true);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -692,7 +700,7 @@ void nyx_load_run()
|
||||
WPRINTF("\nUpdate your bootloader folder!\n\n");
|
||||
WPRINTF("Press any key...");
|
||||
|
||||
msleep(2000);
|
||||
msleep(1000);
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
@@ -766,6 +774,18 @@ static ini_sec_t *get_ini_sec_from_id(ini_sec_t *ini_sec, char **bootlogoCustomE
|
||||
return cfg_sec;
|
||||
}
|
||||
|
||||
static void _bootloader_corruption_protect()
|
||||
{
|
||||
FILINFO fno;
|
||||
if (!f_stat("bootloader", &fno))
|
||||
{
|
||||
if (!h_cfg.bootprotect && (fno.fattrib & AM_ARC))
|
||||
f_chmod("bootloader", 0, AM_ARC);
|
||||
else if (h_cfg.bootprotect && !(fno.fattrib & AM_ARC))
|
||||
f_chmod("bootloader", AM_ARC, AM_ARC);
|
||||
}
|
||||
}
|
||||
|
||||
static void _auto_launch_firmware()
|
||||
{
|
||||
if(b_cfg.extra_cfg & (EXTRA_CFG_NYX_DUMP | EXTRA_CFG_NYX_BIS))
|
||||
@@ -774,8 +794,6 @@ static void _auto_launch_firmware()
|
||||
EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD;
|
||||
check_sept(NULL);
|
||||
}
|
||||
else if (b_cfg.extra_cfg & EXTRA_CFG_NYX_UMS)
|
||||
EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD;
|
||||
|
||||
if (!h_cfg.sept_run)
|
||||
auto_launch_update();
|
||||
@@ -844,16 +862,8 @@ static void _auto_launch_firmware()
|
||||
h_cfg.autonogc = atoi(kv->val);
|
||||
else if (!strcmp("updater2p", kv->key))
|
||||
h_cfg.updater2p = atoi(kv->val);
|
||||
else if (!strcmp("brand", kv->key))
|
||||
{
|
||||
h_cfg.brand = malloc(strlen(kv->val) + 1);
|
||||
strcpy(h_cfg.brand, kv->val);
|
||||
}
|
||||
else if (!strcmp("tagline", kv->key))
|
||||
{
|
||||
h_cfg.tagline = malloc(strlen(kv->val) + 1);
|
||||
strcpy(h_cfg.tagline, kv->val);
|
||||
}
|
||||
else if (!strcmp("bootprotect", kv->key))
|
||||
h_cfg.bootprotect = atoi(kv->val);
|
||||
}
|
||||
boot_entry_id++;
|
||||
|
||||
@@ -869,6 +879,9 @@ static void _auto_launch_firmware()
|
||||
b_cfg.autoboot_list = h_cfg.autoboot_list;
|
||||
}
|
||||
|
||||
// Apply bootloader protection against corruption.
|
||||
_bootloader_corruption_protect();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1079,9 +1092,10 @@ out:
|
||||
b_cfg.boot_cfg &= BOOT_CFG_SEPT_RUN;
|
||||
h_cfg.emummc_force_disable = false;
|
||||
|
||||
nyx_load_run();
|
||||
// L4T: Clear custom boot mode flags from PMC_SCRATCH0.
|
||||
PMC(APBDEV_PMC_SCRATCH0) &= ~PMC_SCRATCH0_MODE_CUSTOM_ALL;
|
||||
|
||||
sd_end();
|
||||
nyx_load_run();
|
||||
}
|
||||
|
||||
static void _patched_rcm_protection()
|
||||
@@ -1127,10 +1141,10 @@ static void _patched_rcm_protection()
|
||||
}
|
||||
|
||||
#define EXCP_EN_ADDR 0x4003FFFC
|
||||
#define EXCP_MAGIC 0x30505645 // EVP0
|
||||
#define EXCP_MAGIC 0x30505645 // EVP0
|
||||
#define EXCP_TYPE_ADDR 0x4003FFF8
|
||||
#define EXCP_TYPE_RESET 0x545352 // RST
|
||||
#define EXCP_TYPE_UNDEF 0x464455 // UDF
|
||||
#define EXCP_TYPE_RESET 0x545352 // RST
|
||||
#define EXCP_TYPE_UNDEF 0x464455 // UDF
|
||||
#define EXCP_TYPE_PABRT 0x54424150 // PABT
|
||||
#define EXCP_TYPE_DABRT 0x54424144 // DABT
|
||||
#define EXCP_LR_ADDR 0x4003FFF4
|
||||
@@ -1142,7 +1156,15 @@ static void _show_errors()
|
||||
u32 *excp_lr = (u32 *)EXCP_LR_ADDR;
|
||||
|
||||
if (*excp_enabled == EXCP_MAGIC)
|
||||
h_cfg.errors |= ERR_EXCEPT_ENB;
|
||||
h_cfg.errors |= ERR_EXCEPTION;
|
||||
|
||||
//! FIXME: Find a better way to identify if that scratch has proper data.
|
||||
if (0 && PMC(APBDEV_PMC_SCRATCH37) & PMC_SCRATCH37_KERNEL_PANIC_FLAG)
|
||||
{
|
||||
// Set error and clear flag.
|
||||
h_cfg.errors |= ERR_L4T_KERNEL;
|
||||
PMC(APBDEV_PMC_SCRATCH37) &= ~PMC_SCRATCH37_KERNEL_PANIC_FLAG;
|
||||
}
|
||||
|
||||
if (h_cfg.errors)
|
||||
{
|
||||
@@ -1150,32 +1172,33 @@ static void _show_errors()
|
||||
gfx_con_setpos(0, 0);
|
||||
display_backlight_brightness(150, 1000);
|
||||
|
||||
if (h_cfg.errors & ERR_SD_BOOT_EN)
|
||||
WPRINTF("Failed to mount SD!\n");
|
||||
|
||||
if (h_cfg.errors & ERR_LIBSYS_LP0)
|
||||
WPRINTF("Missing LP0 (sleep mode) lib!\n");
|
||||
if (h_cfg.errors & ERR_SYSOLD_MTC)
|
||||
if (h_cfg.errors & ERR_LIBSYS_MTC)
|
||||
WPRINTF("Missing or old Minerva lib!\n");
|
||||
|
||||
if (h_cfg.errors & ~ERR_EXCEPT_ENB)
|
||||
{
|
||||
if (h_cfg.errors & (ERR_LIBSYS_LP0 | ERR_LIBSYS_MTC))
|
||||
WPRINTF("\nUpdate bootloader folder!\n\n");
|
||||
}
|
||||
|
||||
if (h_cfg.errors & ERR_EXCEPT_ENB)
|
||||
if (h_cfg.errors & ERR_EXCEPTION)
|
||||
{
|
||||
WPRINTFARGS("An exception occurred (LR %08X):\n", *excp_lr);
|
||||
switch (*excp_type)
|
||||
{
|
||||
case EXCP_TYPE_RESET:
|
||||
WPRINTF("Reset");
|
||||
WPRINTF("RESET");
|
||||
break;
|
||||
case EXCP_TYPE_UNDEF:
|
||||
WPRINTF("Undefined instruction");
|
||||
WPRINTF("UNDEF");
|
||||
break;
|
||||
case EXCP_TYPE_PABRT:
|
||||
WPRINTF("Prefetch abort");
|
||||
WPRINTF("PABRT");
|
||||
break;
|
||||
case EXCP_TYPE_DABRT:
|
||||
WPRINTF("Data abort");
|
||||
WPRINTF("DABRT");
|
||||
break;
|
||||
}
|
||||
WPRINTF("\n");
|
||||
@@ -1184,9 +1207,16 @@ static void _show_errors()
|
||||
*excp_enabled = 0;
|
||||
}
|
||||
|
||||
if (0 && h_cfg.errors & ERR_L4T_KERNEL)
|
||||
{
|
||||
WPRINTF("Panic occurred while running L4T.\n");
|
||||
if (!sd_save_to_file((void *)PSTORE_ADDR, PSTORE_SZ, "L4T_panic.bin"))
|
||||
WPRINTF("PSTORE saved to L4T_panic.bin\n");
|
||||
}
|
||||
|
||||
WPRINTF("Press any key...");
|
||||
|
||||
msleep(2000);
|
||||
msleep(1000);
|
||||
btn_wait();
|
||||
}
|
||||
}
|
||||
@@ -1301,6 +1331,15 @@ out:
|
||||
max77620_low_battery_monitor_config(true);
|
||||
}
|
||||
|
||||
void ipl_reload()
|
||||
{
|
||||
hw_reinit_workaround(false, 0);
|
||||
|
||||
// Reload hekate.
|
||||
void (*ipl_ptr)() = (void *)IPL_LOAD_ADDR;
|
||||
(*ipl_ptr)();
|
||||
}
|
||||
|
||||
static void _about()
|
||||
{
|
||||
static const char credits[] =
|
||||
@@ -1444,6 +1483,7 @@ ment_t ment_top[] = {
|
||||
MDEF_MENU("Tools", &menu_tools),
|
||||
MDEF_MENU("Console info", &menu_cinfo),
|
||||
MDEF_CAPTION("---------------", 0xFF444444),
|
||||
MDEF_HANDLER("Reload", ipl_reload),
|
||||
MDEF_HANDLER("Reboot (Normal)", reboot_normal),
|
||||
MDEF_HANDLER("Reboot (RCM)", reboot_rcm),
|
||||
MDEF_HANDLER("Power off", power_off),
|
||||
@@ -1452,14 +1492,14 @@ ment_t ment_top[] = {
|
||||
MDEF_END()
|
||||
};
|
||||
|
||||
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.3.0", 0, 0 };
|
||||
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.3.4", 0, 0 };
|
||||
|
||||
extern void pivot_stack(u32 stack_top);
|
||||
|
||||
void ipl_main()
|
||||
{
|
||||
// Do initial HW configuration. This is compatible with consecutive reruns without a reset.
|
||||
config_hw();
|
||||
hw_init();
|
||||
|
||||
// Pivot the stack so we have enough space.
|
||||
pivot_stack(IPL_STACK_TOP);
|
||||
@@ -1478,7 +1518,8 @@ void ipl_main()
|
||||
// Set bootloader's default configuration.
|
||||
set_default_configuration();
|
||||
|
||||
sd_mount();
|
||||
// Mount SD Card.
|
||||
h_cfg.errors |= !sd_mount() ? ERR_SD_BOOT_EN : 0;
|
||||
|
||||
// Save sdram lp0 config.
|
||||
if (!ianos_loader("bootloader/sys/libsys_lp0.bso", DRAM_LIB, (void *)sdram_get_params_patched()))
|
||||
@@ -1486,7 +1527,7 @@ void ipl_main()
|
||||
|
||||
// Train DRAM and switch to max frequency.
|
||||
if (minerva_init())
|
||||
h_cfg.errors |= ERR_SYSOLD_MTC;
|
||||
h_cfg.errors |= ERR_LIBSYS_MTC;
|
||||
|
||||
display_init();
|
||||
|
||||
@@ -1516,6 +1557,9 @@ void ipl_main()
|
||||
// Load saved configuration and auto boot if enabled.
|
||||
_auto_launch_firmware();
|
||||
|
||||
// Failed to launch Nyx, unmount SD Card.
|
||||
sd_end();
|
||||
|
||||
minerva_change_freq(FREQ_800);
|
||||
|
||||
while (true)
|
||||
|
||||
@@ -136,7 +136,7 @@ int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc)
|
||||
FILINFO fno;
|
||||
emu_cfg.active_part = 0;
|
||||
|
||||
// Always init eMMC even when in emuMMC. eMMC is needed from theh emuMMC driver anyway.
|
||||
// Always init eMMC even when in emuMMC. eMMC is needed from the emuMMC driver anyway.
|
||||
if (!sdmmc_storage_init_mmc(storage, sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400))
|
||||
return 2;
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ $(BUILD)/%.o: ./%.c
|
||||
|
||||
$(TARGET).bso: $(OBJS)
|
||||
@$(CC) $(LDFLAGS) -e _modInit $^ -o $(OUTPUT)/$(TARGET).bso
|
||||
$(STRIP) -g $(OUTPUT)/$(TARGET).bso
|
||||
@$(STRIP) -g $(OUTPUT)/$(TARGET).bso
|
||||
@echo "-------------\nBuilt module: "$(TARGET)".bso\n-------------"
|
||||
|
||||
clean:
|
||||
@rm -rf $(OUTPUT)/$(TARGET).bso
|
||||
|
||||
@@ -27,7 +27,8 @@ $(BUILD)/%.o: ./%.c
|
||||
|
||||
$(TARGET).bso: $(OBJS)
|
||||
@$(CC) $(LDFLAGS) -e _minerva_init $^ -o $(OUTPUT)/$(TARGET).bso
|
||||
$(STRIP) -g $(OUTPUT)/$(TARGET).bso
|
||||
@$(STRIP) -g $(OUTPUT)/$(TARGET).bso
|
||||
@echo "-------------\nBuilt module: "$(TARGET)".bso\n-------------"
|
||||
|
||||
clean:
|
||||
@rm -rf $(OUTPUT)/$(TARGET).bso
|
||||
|
||||
@@ -34,7 +34,8 @@ $(BUILD)/%.o: ./%.c
|
||||
|
||||
$(TARGET).bso: $(OBJS)
|
||||
@$(CC) $(LDFLAGS) -e _modInit $^ -o $(OUTPUT)/$(TARGET).bso
|
||||
$(STRIP) -g $(OUTPUT)/$(TARGET).bso
|
||||
@$(STRIP) -g $(OUTPUT)/$(TARGET).bso
|
||||
@echo "-------------\nBuilt module: "$(TARGET)".bso\n-------------"
|
||||
|
||||
clean:
|
||||
@rm -rf $(OUTPUT)/$(TARGET).bso
|
||||
|
||||
19
nyx/Makefile
19
nyx/Makefile
@@ -20,7 +20,7 @@ BDKDIR := bdk
|
||||
BDKINC := -I../$(BDKDIR)
|
||||
VPATH = $(dir $(wildcard ./$(SOURCEDIR)/)) $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
|
||||
VPATH += $(dir $(wildcard ./$(SOURCEDIR)/*/*/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/*/*/))
|
||||
VPATH += $(dir $(wildcard ../$(BDKDIR)/*/)) $(dir $(wildcard ../$(BDKDIR)/*/*/)) $(dir $(wildcard ../$(BDKDIR)/*/*/*/))
|
||||
VPATH += $(dir $(wildcard ../$(BDKDIR)/)) $(dir $(wildcard ../$(BDKDIR)/*/)) $(dir $(wildcard ../$(BDKDIR)/*/*/)) $(dir $(wildcard ../$(BDKDIR)/*/*/*/))
|
||||
|
||||
# Main and graphics.
|
||||
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
@@ -33,11 +33,11 @@ OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
|
||||
# Hardware.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
bpmp.o ccplex.o clock.o di.o gpio.o i2c.o irq.o pinmux.o se.o smmu.o tsec.o uart.o \
|
||||
bpmp.o ccplex.o clock.o di.o gpio.o i2c.o irq.o pinmux.o pmc.o se.o smmu.o tsec.o uart.o \
|
||||
fuse.o kfuse.o \
|
||||
mc.o sdram.o minerva.o ramdisk.o \
|
||||
sdmmc.o sdmmc_driver.o nx_emmc.o nx_emmc_bis.o nx_sd.o \
|
||||
bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
|
||||
bm92t36.o bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
|
||||
touch.o joycon.o tmp451.o fan.o \
|
||||
usbd.o usb_gadget_ums.o usb_gadget_hid.o \
|
||||
hw_init.o \
|
||||
@@ -80,14 +80,14 @@ CUSTOMDEFINES := -DNYX_LOAD_ADDR=$(NYX_LOAD_ADDR) -DNYX_MAGIC=$(NYX_MAGIC)
|
||||
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_RESERVED=$(NYXVERSION_RSVD)
|
||||
CUSTOMDEFINES += -DNYX -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
|
||||
|
||||
# 0: UART_A, 1: UART_B.
|
||||
# 0: UART_A, 1: UART_B, 2: UART_C.
|
||||
# Also enables LV LOG.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_PORT=1
|
||||
|
||||
#CUSTOMDEFINES += -DDEBUG
|
||||
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
|
||||
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 -Wall $(CUSTOMDEFINES)
|
||||
CFLAGS += -g
|
||||
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 -Wall $(CUSTOMDEFINES)
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=NYX_LOAD_ADDR=$(NYX_LOAD_ADDR)
|
||||
|
||||
################################################################################
|
||||
@@ -95,8 +95,11 @@ LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defs
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(TARGET).bin
|
||||
@echo -n "Nyx size is "
|
||||
@wc -c < $(OUTPUTDIR)/$(TARGET).bin
|
||||
@echo "--------------------------------------"
|
||||
@echo -n "Nyx size: "
|
||||
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET).bin))
|
||||
@echo $(BIN_SIZE)" Bytes"
|
||||
@echo "--------------------------------------"
|
||||
|
||||
clean:
|
||||
@rm -rf $(OBJS)
|
||||
|
||||
@@ -42,13 +42,13 @@ void set_default_configuration()
|
||||
h_cfg.autohosoff = 0;
|
||||
h_cfg.autonogc = 1;
|
||||
h_cfg.updater2p = 0;
|
||||
h_cfg.brand = NULL;
|
||||
h_cfg.tagline = NULL;
|
||||
h_cfg.bootprotect = 0;
|
||||
h_cfg.errors = 0;
|
||||
h_cfg.eks = NULL;
|
||||
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
||||
h_cfg.aes_slots_new = false;
|
||||
h_cfg.rcm_patched = fuse_check_patched_rcm();
|
||||
h_cfg.sbk_set = FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF;
|
||||
h_cfg.emummc_force_disable = false;
|
||||
|
||||
sd_power_cycle_time_start = 0;
|
||||
@@ -61,6 +61,7 @@ void set_nyx_default_configuration()
|
||||
n_cfg.home_screen = 0;
|
||||
n_cfg.verification = 1;
|
||||
n_cfg.ums_emmc_rw = 0;
|
||||
n_cfg.jc_disable = 0;
|
||||
}
|
||||
|
||||
int create_config_entry()
|
||||
@@ -118,16 +119,9 @@ int create_config_entry()
|
||||
f_puts("\nupdater2p=", &fp);
|
||||
itoa(h_cfg.updater2p, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
if (h_cfg.brand)
|
||||
{
|
||||
f_puts("\nbrand=", &fp);
|
||||
f_puts(h_cfg.brand, &fp);
|
||||
}
|
||||
if (h_cfg.tagline)
|
||||
{
|
||||
f_puts("\ntagline=", &fp);
|
||||
f_puts(h_cfg.tagline, &fp);
|
||||
}
|
||||
f_puts("\nbootprotect=", &fp);
|
||||
itoa(h_cfg.bootprotect, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\n", &fp);
|
||||
|
||||
if (mainIniFound)
|
||||
@@ -206,6 +200,9 @@ int create_nyx_config_entry()
|
||||
f_puts("\numsemmcrw=", &fp);
|
||||
itoa(n_cfg.ums_emmc_rw, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\njcdisable=", &fp);
|
||||
itoa(n_cfg.jc_disable, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\n", &fp);
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
@@ -30,14 +30,14 @@ typedef struct _hekate_config
|
||||
u32 autohosoff;
|
||||
u32 autonogc;
|
||||
u32 updater2p;
|
||||
char *brand;
|
||||
char *tagline;
|
||||
u32 bootprotect;
|
||||
// Global temporary config.
|
||||
bool se_keygen_done;
|
||||
bool sept_run;
|
||||
bool aes_slots_new;
|
||||
bool emummc_force_disable;
|
||||
bool rcm_patched;
|
||||
bool sbk_set;
|
||||
u32 errors;
|
||||
hos_eks_mbr_t *eks;
|
||||
} hekate_config;
|
||||
@@ -49,6 +49,7 @@ typedef struct _nyx_config
|
||||
u32 home_screen;
|
||||
u32 verification;
|
||||
u32 ums_emmc_rw;
|
||||
u32 jc_disable;
|
||||
} nyx_config;
|
||||
|
||||
void set_default_configuration();
|
||||
|
||||
@@ -61,7 +61,8 @@ static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_
|
||||
curr_part_size = mbr->partitions[i].size_sct;
|
||||
*sector_start = mbr->partitions[i].start_sct;
|
||||
u8 type = mbr->partitions[i].type;
|
||||
if ((curr_part_size >= *sector_size) && *sector_start && type != 0x83 && (!backup || type == 0xE0))
|
||||
u32 sector_size_safe = !backup ? (*sector_size) + 0x8000 : (*sector_size);
|
||||
if ((curr_part_size >= sector_size_safe) && *sector_start && type != 0x83 && (!backup || type == 0xE0))
|
||||
{
|
||||
if (backup)
|
||||
{
|
||||
|
||||
@@ -200,6 +200,11 @@ static void _save_log_to_bmp(char *fname)
|
||||
|
||||
static void _save_fb_to_bmp()
|
||||
{
|
||||
// Disallow screenshots if less than 2s passed.
|
||||
static u32 timer = 0;
|
||||
if (get_tmr_ms() < timer)
|
||||
return;
|
||||
|
||||
if (do_reload)
|
||||
return;
|
||||
|
||||
@@ -298,6 +303,9 @@ static void _save_fb_to_bmp()
|
||||
lv_mbox_set_text(mbox, SYMBOL_CAMERA" #96FF00 Screenshot saved!#");
|
||||
manual_system_maintenance(true);
|
||||
lv_mbox_start_auto_close(mbox, 4000);
|
||||
|
||||
// Set timer to 2s.
|
||||
timer = get_tmr_ms() + 2000;
|
||||
}
|
||||
|
||||
static void _disp_fb_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t *color_p)
|
||||
@@ -316,25 +324,22 @@ static void _disp_fb_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const
|
||||
}
|
||||
|
||||
static touch_event touchpad;
|
||||
static bool touch_enabled;
|
||||
static bool console_enabled = false;
|
||||
|
||||
static bool _fts_touch_read(lv_indev_data_t *data)
|
||||
{
|
||||
touch_poll(&touchpad);
|
||||
if (touch_enabled)
|
||||
touch_poll(&touchpad);
|
||||
else
|
||||
return false;
|
||||
|
||||
// Take a screenshot if 3 fingers.
|
||||
if (touchpad.fingers > 2)
|
||||
{
|
||||
// Disallow screenshots if less than 2s passed.
|
||||
static u32 timer = 0;
|
||||
if (get_tmr_ms() > timer)
|
||||
{
|
||||
_save_fb_to_bmp();
|
||||
timer = get_tmr_ms() + 2000;
|
||||
}
|
||||
_save_fb_to_bmp();
|
||||
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -394,7 +399,9 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
|
||||
if (jc_pad->cap)
|
||||
{
|
||||
_save_fb_to_bmp();
|
||||
msleep(1000);
|
||||
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calibrate left stick.
|
||||
@@ -844,7 +851,7 @@ static void _launch_hos(u8 autoboot, u8 autoboot_list)
|
||||
|
||||
sd_end();
|
||||
|
||||
reconfig_hw_workaround(false, 0);
|
||||
hw_reinit_workaround(false, 0);
|
||||
|
||||
// Mitigate L4T Joy-Con driver issue.
|
||||
if ((autoboot & 0x80) && h_cfg.bootwait < 2)
|
||||
@@ -864,7 +871,7 @@ void reload_nyx()
|
||||
|
||||
sd_end();
|
||||
|
||||
reconfig_hw_workaround(false, 0);
|
||||
hw_reinit_workaround(false, 0);
|
||||
|
||||
// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
|
||||
sdmmc_storage_init_wait_sd();
|
||||
@@ -892,6 +899,10 @@ static lv_res_t _removed_sd_action(lv_obj_t *btns, const char *txt)
|
||||
case 1:
|
||||
power_off();
|
||||
break;
|
||||
case 2:
|
||||
sd_end();
|
||||
do_reload = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return mbox_action(btns, txt);
|
||||
@@ -908,10 +919,10 @@ static void _check_sd_card_removed(void *params)
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
static const char * mbox_btn_map[] = { "\221Reboot (RCM)", "\221Power Off", "" };
|
||||
static const char * mbox_btn_map[] = { "\221Reboot (RCM)", "\221Power Off", "\221Do not reload", "" };
|
||||
lv_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
|
||||
lv_mbox_set_recolor_text(mbox, true);
|
||||
lv_obj_set_width(mbox, LV_HOR_RES * 4 / 9);
|
||||
lv_obj_set_width(mbox, LV_HOR_RES * 6 / 9);
|
||||
|
||||
lv_mbox_set_text(mbox, "\n#FF8000 SD card was removed!#\n\n#96FF00 Nyx will reload after inserting it.#\n");
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, _removed_sd_action);
|
||||
@@ -1227,18 +1238,18 @@ static void _update_status_bar(void *params)
|
||||
|
||||
u8 batt_level = (batt_percent >> 8) & 0xFF;
|
||||
if (batt_level > 80)
|
||||
s_printf(label + strlen(label), SYMBOL_BATTERY_FULL);
|
||||
strcat(label, SYMBOL_BATTERY_FULL);
|
||||
else if (batt_level > 60)
|
||||
s_printf(label + strlen(label), SYMBOL_BATTERY_3);
|
||||
strcat(label, SYMBOL_BATTERY_3);
|
||||
else if (batt_level > 40)
|
||||
s_printf(label + strlen(label), SYMBOL_BATTERY_2);
|
||||
strcat(label, SYMBOL_BATTERY_2);
|
||||
else if (batt_level > 15)
|
||||
s_printf(label + strlen(label), SYMBOL_BATTERY_1);
|
||||
strcat(label, SYMBOL_BATTERY_1);
|
||||
else
|
||||
s_printf(label + strlen(label), "#FF3C28 "SYMBOL_BATTERY_EMPTY"#");
|
||||
strcat(label, "#FF3C28 "SYMBOL_BATTERY_EMPTY"#");
|
||||
|
||||
if (charge_status)
|
||||
s_printf(label + strlen(label), " #FFDD00 "SYMBOL_CHARGE"#");
|
||||
strcat(label, " #FFDD00 "SYMBOL_CHARGE"#");
|
||||
|
||||
lv_label_set_text(status_bar.battery, label);
|
||||
lv_obj_realign(status_bar.battery);
|
||||
@@ -1361,6 +1372,8 @@ static lv_res_t _win_launch_close_action(lv_obj_t * btn)
|
||||
launch_bg_done = true;
|
||||
}
|
||||
|
||||
close_btn = NULL;
|
||||
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
@@ -2221,8 +2234,11 @@ void nyx_load_and_run()
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
// Initialize Joy-Con.
|
||||
lv_task_t *task_jc_init_hw = lv_task_create(jc_init_hw, LV_TASK_ONESHOT, LV_TASK_PRIO_LOWEST, NULL);
|
||||
lv_task_once(task_jc_init_hw);
|
||||
if (!n_cfg.jc_disable)
|
||||
{
|
||||
lv_task_t *task_jc_init_hw = lv_task_create(jc_init_hw, LV_TASK_ONESHOT, LV_TASK_PRIO_LOWEST, NULL);
|
||||
lv_task_once(task_jc_init_hw);
|
||||
}
|
||||
lv_indev_drv_t indev_drv_jc;
|
||||
lv_indev_drv_init(&indev_drv_jc);
|
||||
indev_drv_jc.type = LV_INDEV_TYPE_POINTER;
|
||||
@@ -2232,7 +2248,7 @@ void nyx_load_and_run()
|
||||
close_btn = NULL;
|
||||
|
||||
// Initialize touch.
|
||||
touch_power_on();
|
||||
touch_enabled = touch_power_on();
|
||||
lv_indev_drv_t indev_drv_touch;
|
||||
lv_indev_drv_init(&indev_drv_touch);
|
||||
indev_drv_touch.type = LV_INDEV_TYPE_POINTER;
|
||||
|
||||
@@ -271,7 +271,7 @@ static void _create_mbox_emummc_raw()
|
||||
mbr->partitions[3].type, mbr->partitions[3].start_sct, mbr->partitions[3].size_sct);
|
||||
|
||||
if (!mbr_ctx.available)
|
||||
s_printf(txt_buf + strlen(txt_buf),
|
||||
strcat(txt_buf,
|
||||
"\n#FF8000 Do you want to partition your SD card?#\n"
|
||||
"#FF8000 (You will be asked on how to proceed)#");
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <mem/heap.h>
|
||||
#include <mem/sdram.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <power/bm92t36.h>
|
||||
#include <power/bq24193.h>
|
||||
#include <power/max17050.h>
|
||||
#include <sec/se.h>
|
||||
@@ -81,6 +82,32 @@ static lv_res_t _create_window_dump_done(int error, char *dump_filenames)
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
static lv_res_t _cal0_dump_window_action(lv_obj_t *btns, const char * txt)
|
||||
{
|
||||
int btn_idx = lv_btnm_get_pressed(btns);
|
||||
|
||||
mbox_action(btns, txt);
|
||||
|
||||
if (btn_idx == 1)
|
||||
{
|
||||
int error = !sd_mount();
|
||||
|
||||
if (!error)
|
||||
{
|
||||
char path[64];
|
||||
emmcsn_path_impl(path, "/dumps", "cal0.bin", NULL);
|
||||
error = sd_save_to_file((u8 *)cal0_buf, 0x8000, path);
|
||||
|
||||
sd_unmount();
|
||||
}
|
||||
|
||||
_create_window_dump_done(error, "cal0.bin");
|
||||
}
|
||||
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
|
||||
static lv_res_t _battery_dump_window_action(lv_obj_t * btn)
|
||||
{
|
||||
int error = !sd_mount();
|
||||
@@ -230,7 +257,7 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
static const char * mbox_btn_map[] = { "\211", "\222OK", "\211", "" };
|
||||
static const char * mbox_btn_map[] = { "\211", "\222Dump", "\222Close", "\211", "" };
|
||||
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
|
||||
lv_mbox_set_recolor_text(mbox, true);
|
||||
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5);
|
||||
@@ -238,6 +265,7 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
|
||||
lv_mbox_set_text(mbox, "#C7EA46 CAL0 Info#");
|
||||
|
||||
char *txt_buf = (char *)malloc(0x4000);
|
||||
txt_buf[0] = 0;
|
||||
|
||||
lv_obj_t * lb_desc = lv_label_create(mbox, NULL);
|
||||
lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK);
|
||||
@@ -245,28 +273,46 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
|
||||
lv_label_set_style(lb_desc, &monospace_text);
|
||||
lv_obj_set_width(lb_desc, LV_HOR_RES / 9 * 3);
|
||||
|
||||
sd_mount();
|
||||
|
||||
// Read package1.
|
||||
char *build_date = malloc(32);
|
||||
u8 *pkg1 = (u8 *)malloc(0x40000);
|
||||
static const u32 BOOTLOADER_SIZE = 0x40000;
|
||||
static const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
|
||||
static const u32 BOOTLOADER_BACKUP_OFFSET = 0x140000;
|
||||
static const u32 HOS_KEYBLOBS_OFFSET = 0x180000;
|
||||
|
||||
u8 kb = 0;
|
||||
u32 bootloader_offset = BOOTLOADER_MAIN_OFFSET;
|
||||
u8 *pkg1 = (u8 *)malloc(BOOTLOADER_SIZE);
|
||||
sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400);
|
||||
sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0);
|
||||
sdmmc_storage_read(&emmc_storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
|
||||
try_load:
|
||||
sdmmc_storage_read(&emmc_storage, bootloader_offset / NX_EMMC_BLOCKSIZE, BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
|
||||
char *build_date = malloc(32);
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date);
|
||||
|
||||
s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n", build_date);
|
||||
s_printf(txt_buf + strlen(txt_buf), "#00DDFF Found pkg1 ('%s')#\n", build_date);
|
||||
free(build_date);
|
||||
|
||||
sd_mount();
|
||||
|
||||
if (!pkg1_id)
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#");
|
||||
strcat(txt_buf, "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#\n");
|
||||
// Try backup bootloader.
|
||||
if (bootloader_offset != BOOTLOADER_BACKUP_OFFSET)
|
||||
{
|
||||
strcat(txt_buf, "Trying backup bootloader...\n");
|
||||
bootloader_offset = BOOTLOADER_BACKUP_OFFSET;
|
||||
goto try_load;
|
||||
}
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
kb = pkg1_id->kb;
|
||||
|
||||
tsec_ctxt_t tsec_ctxt;
|
||||
tsec_ctxt.fw = (u8 *)pkg1 + pkg1_id->tsec_off;
|
||||
tsec_ctxt.pkg1 = pkg1;
|
||||
@@ -275,13 +321,13 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
|
||||
|
||||
// Get keys.
|
||||
hos_eks_get();
|
||||
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
|
||||
if (kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
|
||||
{
|
||||
u32 key_idx = 0;
|
||||
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_810)
|
||||
if (kb >= KB_FIRMWARE_VERSION_810)
|
||||
key_idx = 1;
|
||||
|
||||
if (h_cfg.eks && h_cfg.eks->enabled[key_idx] >= pkg1_id->kb)
|
||||
if (h_cfg.eks && h_cfg.eks->enabled[key_idx] >= kb)
|
||||
h_cfg.sept_run = true;
|
||||
else
|
||||
{
|
||||
@@ -289,7 +335,7 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
|
||||
b_cfg->autoboot_list = 0;
|
||||
b_cfg->extra_cfg = EXTRA_CFG_NYX_BIS;
|
||||
|
||||
if (!reboot_to_sept((u8 *)tsec_ctxt.fw, pkg1_id->kb))
|
||||
if (!reboot_to_sept((u8 *)tsec_ctxt.fw, kb))
|
||||
{
|
||||
lv_label_set_text(lb_desc, "#FFDD00 Failed to run sept#\n");
|
||||
goto out;
|
||||
@@ -299,10 +345,10 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
|
||||
|
||||
// Read the correct keyblob.
|
||||
u8 *keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
|
||||
sdmmc_storage_read(&emmc_storage, 0x180000 / NX_EMMC_BLOCKSIZE + pkg1_id->kb, 1, keyblob);
|
||||
sdmmc_storage_read(&emmc_storage, HOS_KEYBLOBS_OFFSET / NX_EMMC_BLOCKSIZE + kb, 1, keyblob);
|
||||
|
||||
// Generate BIS keys
|
||||
hos_bis_keygen(keyblob, pkg1_id->kb, &tsec_ctxt);
|
||||
hos_bis_keygen(keyblob, kb, &tsec_ctxt);
|
||||
|
||||
free(keyblob);
|
||||
|
||||
@@ -352,42 +398,67 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
|
||||
cal0->bd_mac[0], cal0->bd_mac[1], cal0->bd_mac[2], cal0->bd_mac[3], cal0->bd_mac[4], cal0->bd_mac[5],
|
||||
cal0->battery_lot);
|
||||
|
||||
u8 display_rev = (nyx_str->info.disp_id >> 8) & 0xFF;
|
||||
u32 display_id = (cal0->lcd_vendor & 0xFF) << 8 | (cal0->lcd_vendor & 0xFF0000) >> 16;
|
||||
switch (display_id)
|
||||
{
|
||||
case PANEL_JDI_LAM062M109A:
|
||||
s_printf(txt_buf + strlen(txt_buf), "JDI LAM062M109A");
|
||||
strcat(txt_buf, "JDI LAM062M109A");
|
||||
break;
|
||||
case PANEL_JDI_LPM062M326A:
|
||||
s_printf(txt_buf + strlen(txt_buf), "JDI LPM062M326A");
|
||||
strcat(txt_buf, "JDI LPM062M326A");
|
||||
break;
|
||||
case PANEL_INL_P062CCA_AZ1:
|
||||
s_printf(txt_buf + strlen(txt_buf), "InnoLux P062CCA-AZ1");
|
||||
strcat(txt_buf, "InnoLux P062CCA-AZ");
|
||||
switch (display_rev)
|
||||
{
|
||||
case 0x93:
|
||||
strcat(txt_buf, "1");
|
||||
break;
|
||||
case 0x95:
|
||||
strcat(txt_buf, "2");
|
||||
break;
|
||||
default:
|
||||
strcat(txt_buf, "X");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PANEL_AUO_A062TAN01:
|
||||
s_printf(txt_buf + strlen(txt_buf), "AUO A062TAN01");
|
||||
strcat(txt_buf, "AUO A062TAN0");
|
||||
switch (display_rev)
|
||||
{
|
||||
case 0x94:
|
||||
strcat(txt_buf, "1");
|
||||
break;
|
||||
case 0x95:
|
||||
strcat(txt_buf, "2");
|
||||
break;
|
||||
default:
|
||||
strcat(txt_buf, "X");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PANEL_INL_P062CCA_AZ2:
|
||||
s_printf(txt_buf + strlen(txt_buf), "InnoLux P062CCA-AZ2");
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
strcat(txt_buf, "InnoLux 2J055IA-27A");
|
||||
break;
|
||||
case PANEL_AUO_A062TAN02:
|
||||
s_printf(txt_buf + strlen(txt_buf), "AUO A062TAN02");
|
||||
case PANEL_AUO_A055TAN01:
|
||||
strcat(txt_buf, "AUO A055TAN01");
|
||||
break;
|
||||
default:
|
||||
switch (cal0->lcd_vendor & 0xFF)
|
||||
{
|
||||
case 0:
|
||||
case PANEL_JDI_XXX062M:
|
||||
s_printf(txt_buf + strlen(txt_buf), "JDI ");
|
||||
strcat(txt_buf, "JDI ");
|
||||
break;
|
||||
case (PANEL_INL_P062CCA_AZ1 & 0xFF):
|
||||
s_printf(txt_buf + strlen(txt_buf), "InnoLux ");
|
||||
strcat(txt_buf, "InnoLux ");
|
||||
break;
|
||||
case (PANEL_AUO_A062TAN01 & 0xFF):
|
||||
s_printf(txt_buf + strlen(txt_buf), "AUO ");
|
||||
strcat(txt_buf, "AUO ");
|
||||
break;
|
||||
}
|
||||
s_printf(txt_buf + strlen(txt_buf), "Unknown");
|
||||
strcat(txt_buf, "Unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -402,7 +473,7 @@ out:
|
||||
sd_unmount();
|
||||
sdmmc_storage_end(&emmc_storage);
|
||||
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, _cal0_dump_window_action);
|
||||
|
||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_top(mbox, true);
|
||||
@@ -463,8 +534,6 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
char *txt_buf = (char *)malloc(0x4000);
|
||||
|
||||
// Decode fuses.
|
||||
u8 burntFuses7 = 0;
|
||||
u8 burntFuses6 = 0;
|
||||
u32 odm4 = fuse_read_odm(4);
|
||||
u8 dram_id = (odm4 >> 3) & 0x1F;
|
||||
char dram_man[16] = {0};
|
||||
@@ -485,17 +554,11 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < 32; i++)
|
||||
{
|
||||
if ((fuse_read_odm(7) >> i) & 1)
|
||||
burntFuses7++;
|
||||
}
|
||||
for (u32 i = 0; i < 32; i++)
|
||||
{
|
||||
if ((fuse_read_odm(6) >> i) & 1)
|
||||
burntFuses6++;
|
||||
}
|
||||
// Count burnt fuses.
|
||||
u8 burnt_fuses_7 = fuse_count_burnt(fuse_read_odm(7));
|
||||
u8 burnt_fuses_6 = fuse_count_burnt(fuse_read_odm(6));
|
||||
|
||||
// Calculate LOT.
|
||||
u32 lot_code0 = (FUSE(FUSE_OPT_LOT_CODE_0) & 0xFFFFFFF) << 2;
|
||||
u32 lot_bin = 0;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
@@ -514,7 +577,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
"%d\n%d\n%d (0x%X)\n%d\n%d\n%d\n%d\n"
|
||||
"ID: %02X, Major: A0%d, Minor: %d",
|
||||
FUSE(FUSE_SKU_INFO), odm4 & 0x30000 ? "Mariko" : "Erista", (fuse_read_odm(4) & 3) ? "Dev" : "Retail",
|
||||
dram_id, dram_man, burntFuses7, burntFuses6,
|
||||
dram_id, dram_man, burnt_fuses_7, burnt_fuses_6,
|
||||
byte_swap_32(FUSE(FUSE_PRIVATE_KEY0)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY1)),
|
||||
byte_swap_32(FUSE(FUSE_PRIVATE_KEY2)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY3)),
|
||||
byte_swap_32(FUSE(FUSE_PRIVATE_KEY4)),
|
||||
@@ -550,32 +613,32 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
switch (ram_vendor.dev0_ch0)
|
||||
{
|
||||
case 1:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Samsung");
|
||||
strcat(txt_buf, "Samsung");
|
||||
break;
|
||||
case 6:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Hynix");
|
||||
strcat(txt_buf, "Hynix");
|
||||
break;
|
||||
case 255:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Micron");
|
||||
strcat(txt_buf, "Micron");
|
||||
break;
|
||||
default:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Unknown");
|
||||
strcat(txt_buf, "Unknown");
|
||||
break;
|
||||
}
|
||||
s_printf(txt_buf + strlen(txt_buf), " (%d) #FF8000 |# ", ram_vendor.dev0_ch0);
|
||||
switch (ram_vendor.dev1_ch0)
|
||||
{
|
||||
case 1:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Samsung");
|
||||
strcat(txt_buf, "Samsung");
|
||||
break;
|
||||
case 6:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Hynix");
|
||||
strcat(txt_buf, "Hynix");
|
||||
break;
|
||||
case 255:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Micron");
|
||||
strcat(txt_buf, "Micron");
|
||||
break;
|
||||
default:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Unknown");
|
||||
strcat(txt_buf, "Unknown");
|
||||
break;
|
||||
}
|
||||
s_printf(txt_buf + strlen(txt_buf), " (%d)\n#FF8000 Rev ID:# %04X #FF8000 |# %04X\n#FF8000 Density:# ",
|
||||
@@ -583,75 +646,100 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
switch ((ram_density.dev0_ch0 & 0x3C) >> 2)
|
||||
{
|
||||
case 2:
|
||||
s_printf(txt_buf + strlen(txt_buf), "4x512MB");
|
||||
strcat(txt_buf, " x 512MB");
|
||||
break;
|
||||
case 3:
|
||||
s_printf(txt_buf + strlen(txt_buf), "4x768MB");
|
||||
strcat(txt_buf, " x 768MB");
|
||||
break;
|
||||
case 4:
|
||||
s_printf(txt_buf + strlen(txt_buf), "4x1GB");
|
||||
strcat(txt_buf, " x 1GB");
|
||||
break;
|
||||
default:
|
||||
s_printf(txt_buf + strlen(txt_buf), "4xUnk");
|
||||
strcat(txt_buf, " x Unk");
|
||||
break;
|
||||
}
|
||||
s_printf(txt_buf + strlen(txt_buf), " (%d) #FF8000 |# ", (ram_density.dev0_ch0 & 0x3C) >> 2);
|
||||
switch ((ram_density.dev1_ch0 & 0x3C) >> 2)
|
||||
{
|
||||
case 2:
|
||||
s_printf(txt_buf + strlen(txt_buf), "4x512MB");
|
||||
strcat(txt_buf, " x 512MB");
|
||||
break;
|
||||
case 3:
|
||||
s_printf(txt_buf + strlen(txt_buf), "4x768MB");
|
||||
strcat(txt_buf, " x 768MB");
|
||||
break;
|
||||
case 4:
|
||||
s_printf(txt_buf + strlen(txt_buf), "4x1GB");
|
||||
strcat(txt_buf, " x 1GB");
|
||||
break;
|
||||
default:
|
||||
s_printf(txt_buf + strlen(txt_buf), "2xUnk");
|
||||
strcat(txt_buf, " x Unk");
|
||||
break;
|
||||
}
|
||||
s_printf(txt_buf + strlen(txt_buf), " (%d)\n\n", (ram_density.dev1_ch0 & 0x3C) >> 2);
|
||||
|
||||
// Display info.
|
||||
u8 display_rev = (nyx_str->info.disp_id >> 8) & 0xFF;
|
||||
u32 display_id = ((nyx_str->info.disp_id >> 8) & 0xFF00) | (nyx_str->info.disp_id & 0xFF);
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "#00DDFF Display Panel:#\n#FF8000 Model:# ");
|
||||
strcat(txt_buf, "#00DDFF Display Panel:#\n#FF8000 Model:# ");
|
||||
|
||||
switch (display_id)
|
||||
{
|
||||
case PANEL_JDI_LAM062M109A:
|
||||
s_printf(txt_buf + strlen(txt_buf), "JDI LAM062M109A");
|
||||
strcat(txt_buf, "JDI LAM062M109A");
|
||||
break;
|
||||
case PANEL_JDI_LPM062M326A:
|
||||
s_printf(txt_buf + strlen(txt_buf), "JDI LPM062M326A");
|
||||
strcat(txt_buf, "JDI LPM062M326A");
|
||||
break;
|
||||
case PANEL_INL_P062CCA_AZ1:
|
||||
s_printf(txt_buf + strlen(txt_buf), "InnoLux P062CCA-AZ1");
|
||||
strcat(txt_buf, "InnoLux P062CCA-AZ");
|
||||
switch (display_rev)
|
||||
{
|
||||
case 0x93:
|
||||
strcat(txt_buf, "1");
|
||||
break;
|
||||
case 0x95:
|
||||
strcat(txt_buf, "2");
|
||||
break;
|
||||
default:
|
||||
strcat(txt_buf, "X #FFDD00 Contact me!#");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PANEL_AUO_A062TAN01:
|
||||
s_printf(txt_buf + strlen(txt_buf), "AUO A062TAN01");
|
||||
strcat(txt_buf, "AUO A062TAN0");
|
||||
switch (display_rev)
|
||||
{
|
||||
case 0x94:
|
||||
strcat(txt_buf, "1");
|
||||
break;
|
||||
case 0x95:
|
||||
strcat(txt_buf, "2");
|
||||
break;
|
||||
default:
|
||||
strcat(txt_buf, "X #FFDD00 Contact me!#");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PANEL_INL_P062CCA_AZ2:
|
||||
s_printf(txt_buf + strlen(txt_buf), "InnoLux P062CCA-AZ2");
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
strcat(txt_buf, "InnoLux 2J055IA-27A");
|
||||
break;
|
||||
case PANEL_AUO_A062TAN02:
|
||||
s_printf(txt_buf + strlen(txt_buf), "AUO A062TAN02");
|
||||
case PANEL_AUO_A055TAN01:
|
||||
strcat(txt_buf, "AUO A055TAN01");
|
||||
break;
|
||||
default:
|
||||
switch (display_id & 0xFF)
|
||||
{
|
||||
case PANEL_JDI_XXX062M:
|
||||
s_printf(txt_buf + strlen(txt_buf), "JDI ");
|
||||
strcat(txt_buf, "JDI ");
|
||||
break;
|
||||
case (PANEL_INL_P062CCA_AZ1 & 0xFF):
|
||||
s_printf(txt_buf + strlen(txt_buf), "InnoLux ");
|
||||
strcat(txt_buf, "InnoLux ");
|
||||
break;
|
||||
case (PANEL_AUO_A062TAN01 & 0xFF):
|
||||
s_printf(txt_buf + strlen(txt_buf), "AUO ");
|
||||
strcat(txt_buf, "AUO ");
|
||||
break;
|
||||
}
|
||||
s_printf(txt_buf + strlen(txt_buf), "Unknown");
|
||||
strcat(txt_buf, "Unknown #FFDD00 Contact me!#");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -662,30 +750,30 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
|
||||
if (!touch_get_fw_info(&touch_fw))
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n\n#00DDFF Touch Panel:#\n#FF8000 Model:# ");
|
||||
strcat(txt_buf, "\n\n#00DDFF Touch Panel:#\n#FF8000 Model:# ");
|
||||
switch (touch_fw.fw_id)
|
||||
{
|
||||
case 0x100100:
|
||||
s_printf(txt_buf + strlen(txt_buf), "NTD 4CD 1601");
|
||||
strcat(txt_buf, "NTD 4CD 1601");
|
||||
break;
|
||||
case 0x00120100:
|
||||
case 0x32000001:
|
||||
s_printf(txt_buf + strlen(txt_buf), "NTD 4CD 1801");
|
||||
strcat(txt_buf, "NTD 4CD 1801");
|
||||
break;
|
||||
case 0x001A0300:
|
||||
case 0x32000102:
|
||||
s_printf(txt_buf + strlen(txt_buf), "NTD 4CD 2602");
|
||||
strcat(txt_buf, "NTD 4CD 2602");
|
||||
break;
|
||||
case 0x00290100:
|
||||
case 0x32000302:
|
||||
s_printf(txt_buf + strlen(txt_buf), "NTD 4CD 3801");
|
||||
strcat(txt_buf, "NTD 4CD 3801");
|
||||
break;
|
||||
case 0x31051820:
|
||||
case 0x32000402:
|
||||
s_printf(txt_buf + strlen(txt_buf), "NTD 4CD XXXX");
|
||||
strcat(txt_buf, "NTD 4CD XXXX");
|
||||
break;
|
||||
default:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Unknown");
|
||||
strcat(txt_buf, "Unknown");
|
||||
}
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 ID:# %X\n#FF8000 FTB ver:# %04X\n#FF8000 FW rev:# %04X",
|
||||
@@ -694,9 +782,9 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
|
||||
// Check if patched unit.
|
||||
if (!fuse_check_patched_rcm())
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n\n#96FF00 Your unit is exploitable#\n#96FF00 to the RCM bug!#");
|
||||
strcat(txt_buf, "\n\n#96FF00 Your unit is exploitable#\n#96FF00 to the RCM bug!#");
|
||||
else
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n\n#FF8000 Your unit is patched#\n#FF8000 to the RCM bug!#");
|
||||
strcat(txt_buf, "\n\n#FF8000 Your unit is patched#\n#FF8000 to the RCM bug!#");
|
||||
|
||||
lv_label_set_text(lb_desc2, txt_buf);
|
||||
|
||||
@@ -730,7 +818,7 @@ static void _ipatch_process(u32 offset, u32 value)
|
||||
s_printf(ipatches_txt + strlen(ipatches_txt), "SVC ##0x%02X", lo);
|
||||
break;
|
||||
}
|
||||
s_printf(ipatches_txt + strlen(ipatches_txt), "\n");
|
||||
strcat(ipatches_txt, "\n");
|
||||
}
|
||||
|
||||
static lv_res_t _create_window_bootrom_info_status(lv_obj_t *btn)
|
||||
@@ -783,23 +871,40 @@ static lv_res_t _create_window_tsec_keys_status(lv_obj_t *btn)
|
||||
lv_label_set_recolor(lb_desc, true);
|
||||
lv_label_set_style(lb_desc, &monospace_text);
|
||||
|
||||
// Read package1.
|
||||
char *build_date = malloc(32);
|
||||
u8 *pkg1 = (u8 *)malloc(0x40000);
|
||||
sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400);
|
||||
sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0);
|
||||
sdmmc_storage_read(&emmc_storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
sdmmc_storage_end(&emmc_storage);
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date);
|
||||
|
||||
char *txt_buf = (char *)malloc(0x1000);
|
||||
char *txt_buf2 = (char *)malloc(0x1000);
|
||||
s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n", build_date);
|
||||
txt_buf[0] = 0;
|
||||
|
||||
// Read package1.
|
||||
static const u32 BOOTLOADER_SIZE = 0x40000;
|
||||
static const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
|
||||
static const u32 BOOTLOADER_BACKUP_OFFSET = 0x140000;
|
||||
|
||||
u8 *pkg1 = (u8 *)malloc(0x40000);
|
||||
u32 bootloader_offset = BOOTLOADER_MAIN_OFFSET;
|
||||
|
||||
try_load:
|
||||
sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400);
|
||||
sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0);
|
||||
sdmmc_storage_read(&emmc_storage, bootloader_offset / NX_EMMC_BLOCKSIZE, BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
sdmmc_storage_end(&emmc_storage);
|
||||
|
||||
char *build_date = malloc(32);
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date);
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "#00DDFF Found pkg1 ('%s')#\n", build_date);
|
||||
free(build_date);
|
||||
|
||||
if (!pkg1_id)
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#");
|
||||
strcat(txt_buf, "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#\n");
|
||||
// Try backup bootloader.
|
||||
if (bootloader_offset != BOOTLOADER_BACKUP_OFFSET)
|
||||
{
|
||||
strcat(txt_buf, "Trying backup bootloader...\n");
|
||||
bootloader_offset = BOOTLOADER_BACKUP_OFFSET;
|
||||
goto try_load;
|
||||
}
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
|
||||
|
||||
@@ -859,7 +964,7 @@ static lv_res_t _create_window_tsec_keys_status(lv_obj_t *btn)
|
||||
}
|
||||
}
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "#C7EA46 TSEC Key:#\n");
|
||||
strcat(txt_buf, "#C7EA46 TSEC Key:#\n");
|
||||
if (res >= 0)
|
||||
{
|
||||
s_printf(txt_buf2, "\n%08X%08X%08X%08X\n",
|
||||
@@ -867,7 +972,7 @@ static lv_res_t _create_window_tsec_keys_status(lv_obj_t *btn)
|
||||
|
||||
if (pkg1_id->kb == KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "#C7EA46 TSEC root:#\n");
|
||||
strcat(txt_buf, "#C7EA46 TSEC root:#\n");
|
||||
s_printf(txt_buf2 + strlen(txt_buf2), "%08X%08X%08X%08X\n",
|
||||
byte_swap_32(tsec_keys[4]), byte_swap_32(tsec_keys[5]), byte_swap_32(tsec_keys[6]), byte_swap_32(tsec_keys[7]));
|
||||
}
|
||||
@@ -909,7 +1014,7 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
||||
|
||||
char *txt_buf = (char *)malloc(0x1000);
|
||||
|
||||
s_printf(txt_buf, "#FF8000 %s Benchmark#\n[3 x %s raw reads. Cancel: VOL- & VOL+]\n",
|
||||
s_printf(txt_buf, "#FF8000 %s Benchmark#\n[3 x %s raw reads] Abort: VOL- & VOL+\n",
|
||||
sd_bench ? "SD Card" : "eMMC", sd_bench ? "2GB" : "8GB");
|
||||
|
||||
lv_mbox_set_text(mbox, txt_buf);
|
||||
@@ -959,7 +1064,7 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
||||
|
||||
u32 timer = get_tmr_ms();
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n");
|
||||
strcat(txt_buf, "\n");
|
||||
lv_mbox_set_text(mbox, txt_buf);
|
||||
|
||||
while (data_remaining)
|
||||
@@ -1046,8 +1151,15 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 card_type;
|
||||
u32 speed = 0;
|
||||
char *rsvd_blocks;
|
||||
char life_a_txt[8];
|
||||
char life_b_txt[8];
|
||||
u32 life_a = storage.ext_csd.dev_life_est_a;
|
||||
u32 life_b = storage.ext_csd.dev_life_est_b;
|
||||
u16 card_type = storage.ext_csd.card_type;
|
||||
char card_type_support[96];
|
||||
card_type_support[0] = 0;
|
||||
|
||||
s_printf(txt_buf, "\n%X\n%X\n%02X\n%c%c%c%c%c%c\n%X\n%04X\n%02d/%04d\n\n",
|
||||
storage.cid.manfid, storage.cid.card_bga, storage.cid.oemid,
|
||||
@@ -1055,9 +1167,6 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
|
||||
storage.cid.prod_name[3], storage.cid.prod_name[4], storage.cid.prod_name[5],
|
||||
storage.cid.prv, storage.cid.serial, storage.cid.month, storage.cid.year);
|
||||
|
||||
card_type = storage.ext_csd.card_type;
|
||||
char card_type_support[96];
|
||||
card_type_support[0] = 0;
|
||||
if (card_type & EXT_CSD_CARD_TYPE_HS_26)
|
||||
{
|
||||
strcat(card_type_support, "HS26");
|
||||
@@ -1084,11 +1193,45 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
|
||||
speed = (200 << 16) | 400;
|
||||
}
|
||||
|
||||
strcpy(life_a_txt, "-");
|
||||
strcpy(life_b_txt, "-");
|
||||
|
||||
// Normalize cells life.
|
||||
if (life_a)
|
||||
{
|
||||
life_a--;
|
||||
life_a = (10 - life_a) * 10;
|
||||
s_printf(life_a_txt, "%d%%", life_a);
|
||||
}
|
||||
|
||||
if (life_b) // Toshiba is 0 (undefined).
|
||||
{
|
||||
life_b--;
|
||||
life_b = (10 - life_b) * 10;
|
||||
s_printf(life_b_txt, "%d%%", life_b);
|
||||
}
|
||||
|
||||
switch (storage.ext_csd.pre_eol_info)
|
||||
{
|
||||
case 1:
|
||||
rsvd_blocks = "Normal (< 80%)";
|
||||
break;
|
||||
case 2:
|
||||
rsvd_blocks = "Warning (> 80%)";
|
||||
break;
|
||||
case 3:
|
||||
rsvd_blocks = "Urgent (> 90%)";
|
||||
break;
|
||||
default:
|
||||
rsvd_blocks = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf),
|
||||
"#00DDFF V1.%d#\n%02X\n1.%d\n%02X\n%d MB/s (%d MHz)\n%d MB/s\n%s",
|
||||
storage.ext_csd.ext_struct, storage.csd.mmca_vsn, storage.ext_csd.rev,
|
||||
"#00DDFF V1.%d (rev 1.%d)#\n%02X\n%d MB/s (%d MHz)\n%d MB/s\n%s\nA: %s, B: %s\n%s",
|
||||
storage.ext_csd.ext_struct, storage.ext_csd.rev,
|
||||
storage.csd.cmdclass, speed & 0xFFFF, (speed >> 16) & 0xFFFF,
|
||||
storage.csd.busspeed, card_type_support);
|
||||
storage.csd.busspeed, card_type_support, life_a_txt, life_b_txt, rsvd_blocks);
|
||||
|
||||
lv_label_set_static_text(lb_desc,
|
||||
"#00DDFF CID:#\n"
|
||||
@@ -1100,12 +1243,12 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
|
||||
"S/N:\n"
|
||||
"Month/Year:\n\n"
|
||||
"#00DDFF Ext CSD#\n"
|
||||
"Spec Version:\n"
|
||||
"Extended Rev:\n"
|
||||
"Cmd Classes:\n"
|
||||
"Max Rate:\n"
|
||||
"Current Rate:\n"
|
||||
"Type Support:"
|
||||
"Type Support:\n\n"
|
||||
"Estimated Life:\n"
|
||||
"Reserved Used:"
|
||||
);
|
||||
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
|
||||
|
||||
@@ -1143,7 +1286,7 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
|
||||
{
|
||||
if (idx > 10)
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Table truncated!#");
|
||||
strcat(txt_buf, "#FFDD00 Table truncated!#");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1256,13 +1399,29 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
||||
|
||||
lv_obj_t * lb_val2 = lv_label_create(val2, lb_desc);
|
||||
|
||||
char *wp_info;
|
||||
switch (sd_storage.csd.write_protect)
|
||||
{
|
||||
case 1:
|
||||
wp_info = "Temporary";
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
wp_info = "Permanent";
|
||||
break;
|
||||
default:
|
||||
wp_info = "None";
|
||||
break;
|
||||
}
|
||||
|
||||
s_printf(txt_buf,
|
||||
"#00DDFF v%d.0#\n%02X\n%d MiB\n%X\n%d\n%d MB/s (%d MHz)\n%d\nU%d\nV%d\nA%d\n%d",
|
||||
sd_storage.csd.structure + 1, sd_storage.csd.cmdclass, sd_storage.sec_cnt >> 11, sd_storage.sec_cnt,
|
||||
"#00DDFF v%d.0#\n%02X\n%d MiB\n%X (CP %X)\n%d\n%d MB/s (%d MHz)\n%d\nU%d\nV%d\nA%d\n%s",
|
||||
sd_storage.csd.structure + 1, sd_storage.csd.cmdclass,
|
||||
sd_storage.sec_cnt >> 11, sd_storage.sec_cnt, sd_storage.ssr.protected_size >> 9,
|
||||
sd_storage.ssr.bus_width, sd_storage.csd.busspeed,
|
||||
(sd_storage.csd.busspeed > 10) ? (sd_storage.csd.busspeed * 2) : 50,
|
||||
sd_storage.ssr.speed_class, sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class,
|
||||
sd_storage.ssr.app_class, sd_storage.csd.write_protect);
|
||||
sd_storage.ssr.app_class, wp_info);
|
||||
|
||||
lv_label_set_text(lb_val2, txt_buf);
|
||||
|
||||
@@ -1303,9 +1462,10 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
||||
|
||||
lv_obj_t * lb_val3 = lv_label_create(val3, lb_desc);
|
||||
|
||||
s_printf(txt_buf, "\n%s\n%d KiB\n%d MiB",
|
||||
s_printf(txt_buf, "\n%s\n%d %s\n%d MiB",
|
||||
sd_fs.fs_type == FS_EXFAT ? ("exFAT "SYMBOL_SHRK) : ("FAT32"),
|
||||
(sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512,
|
||||
(sd_fs.csize > 1) ? "KiB" : "B",
|
||||
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF);
|
||||
|
||||
lv_label_set_text(lb_val3, txt_buf);
|
||||
@@ -1454,7 +1614,11 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
||||
"Fast charge current limit:\n"
|
||||
"Charge voltage limit:\n"
|
||||
"Charge status:\n"
|
||||
"Temperature status:"
|
||||
"Temperature status:\n\n"
|
||||
"#00DDFF USB-PD IC Info:#\n"
|
||||
"Connection status:\n"
|
||||
"Input Wattage Limit:\n"
|
||||
"USB-PD Profiles:"
|
||||
);
|
||||
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
|
||||
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
|
||||
@@ -1467,8 +1631,9 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
||||
bq24193_get_property(BQ24193_InputVoltageLimit, &value);
|
||||
s_printf(txt_buf, "\n%d mV\n", value);
|
||||
|
||||
bq24193_get_property(BQ24193_InputCurrentLimit, &value);
|
||||
s_printf(txt_buf + strlen(txt_buf), "%d mA\n", value);
|
||||
int iinlim = 0;
|
||||
bq24193_get_property(BQ24193_InputCurrentLimit, &iinlim);
|
||||
s_printf(txt_buf + strlen(txt_buf), "%d mA\n", iinlim);
|
||||
|
||||
bq24193_get_property(BQ24193_SystemMinimumVoltage, &value);
|
||||
s_printf(txt_buf + strlen(txt_buf), "%d mV\n", value);
|
||||
@@ -1483,16 +1648,16 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Not charging\n");
|
||||
strcat(txt_buf, "Not charging\n");
|
||||
break;
|
||||
case 1:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Pre-charging\n");
|
||||
strcat(txt_buf, "Pre-charging\n");
|
||||
break;
|
||||
case 2:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Fast charging\n");
|
||||
strcat(txt_buf, "Fast charging\n");
|
||||
break;
|
||||
case 3:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Charge terminated\n");
|
||||
strcat(txt_buf, "Charge terminated\n");
|
||||
break;
|
||||
default:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Unknown (%d)\n", value);
|
||||
@@ -1503,25 +1668,54 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Normal");
|
||||
strcat(txt_buf, "Normal");
|
||||
break;
|
||||
case 2:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Warm");
|
||||
strcat(txt_buf, "Warm");
|
||||
break;
|
||||
case 3:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Cool");
|
||||
strcat(txt_buf, "Cool");
|
||||
break;
|
||||
case 5:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Cold");
|
||||
strcat(txt_buf, "Cold");
|
||||
break;
|
||||
case 6:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Hot");
|
||||
strcat(txt_buf, "Hot");
|
||||
break;
|
||||
default:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Unknown (%d)", value);
|
||||
break;
|
||||
}
|
||||
|
||||
bool inserted;
|
||||
u32 wattage = 0;
|
||||
usb_pd_objects_t usb_pd;
|
||||
bm92t36_get_sink_info(&inserted, &usb_pd);
|
||||
strcat(txt_buf, "\n\n\n");
|
||||
strcat(txt_buf, inserted ? "Connected" : "Disconnected");
|
||||
|
||||
// Select 5V is no PD contract.
|
||||
wattage = iinlim * (usb_pd.pdo_no ? usb_pd.selected_pdo.voltage : 5);
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n%d.%d W", wattage / 1000, (wattage % 1000) / 100);
|
||||
|
||||
if (!usb_pd.pdo_no)
|
||||
strcat(txt_buf, "\nNon PD");
|
||||
|
||||
// Limit to 5 profiles so it can fit.
|
||||
usb_pd.pdo_no = MIN(usb_pd.pdo_no, 5);
|
||||
|
||||
for (u32 i = 0; i < usb_pd.pdo_no; i++)
|
||||
{
|
||||
bool selected =
|
||||
usb_pd.pdos[i].amperage == usb_pd.selected_pdo.amperage &&
|
||||
usb_pd.pdos[i].voltage == usb_pd.selected_pdo.voltage;
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n%s%d mA, %2d V%s",
|
||||
selected ? "#D4FF00 " : "",
|
||||
usb_pd.pdos[i].amperage, usb_pd.pdos[i].voltage,
|
||||
selected ? "#" : "");
|
||||
}
|
||||
|
||||
lv_label_set_text(lb_val2, txt_buf);
|
||||
|
||||
lv_obj_set_width(lb_val2, lv_obj_get_width(val2));
|
||||
|
||||
@@ -740,10 +740,20 @@ void first_time_clock_edit(void *param)
|
||||
static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
|
||||
{
|
||||
FIL fp;
|
||||
int error;
|
||||
bool is_l_hos = false;
|
||||
bool is_r_hos = false;
|
||||
jc_gamepad_rpt_t *jc_pad = jc_get_bt_pairing_info(&is_l_hos, &is_r_hos);
|
||||
|
||||
char *data = (char *)malloc(0x4000);
|
||||
char *txt_buf = (char *)malloc(0x1000);
|
||||
|
||||
if (!jc_pad)
|
||||
{
|
||||
error = 255;
|
||||
goto disabled;
|
||||
}
|
||||
|
||||
// Count valid joycon.
|
||||
u32 joycon_found = jc_pad->bt_conn_l.type ? 1 : 0;
|
||||
if (jc_pad->bt_conn_r.type)
|
||||
@@ -753,10 +763,7 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
|
||||
jc_pad->bt_conn_l.type = is_l_hos ? jc_pad->bt_conn_l.type : 0;
|
||||
jc_pad->bt_conn_r.type = is_r_hos ? jc_pad->bt_conn_r.type : 0;
|
||||
|
||||
int error = !sd_mount();
|
||||
|
||||
char *data = (char *)malloc(0x4000);
|
||||
char *txt_buf = (char *)malloc(0x1000);
|
||||
error = !sd_mount();
|
||||
|
||||
if (!error)
|
||||
{
|
||||
@@ -798,6 +805,7 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
|
||||
sd_unmount();
|
||||
}
|
||||
|
||||
disabled:;
|
||||
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||
@@ -817,7 +825,7 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
|
||||
|
||||
// Check if pairing info was found.
|
||||
if (joycon_found == 2)
|
||||
s_printf(txt_buf + strlen(txt_buf), "#C7EA46 Found 2 out of 2 Joy-Con pairing data!#\n");
|
||||
strcat(txt_buf, "#C7EA46 Found 2 out of 2 Joy-Con pairing data!#\n");
|
||||
else
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Warning:# Found #FFDD00 %d out of 2# pairing data!\n", joycon_found);
|
||||
@@ -826,25 +834,25 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
|
||||
|
||||
// Check if pairing was done in HOS.
|
||||
if (is_l_hos && is_r_hos)
|
||||
s_printf(txt_buf + strlen(txt_buf), "#C7EA46 Both pairing data are HOS based!#");
|
||||
strcat(txt_buf, "#C7EA46 Both pairing data are HOS based!#");
|
||||
else if (!is_l_hos && is_r_hos)
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Warning:# #FFDD00 Left# pairing data is not HOS based!");
|
||||
strcat(txt_buf, "#FF8000 Warning:# #FFDD00 Left# pairing data is not HOS based!");
|
||||
success = false;
|
||||
}
|
||||
else if (is_l_hos && !is_r_hos)
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Warning:# #FFDD00 Right# pairing data is not HOS based!");
|
||||
strcat(txt_buf, "#FF8000 Warning:# #FFDD00 Right# pairing data is not HOS based!");
|
||||
success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Warning:# #FFDD00 No# pairing data is HOS based!");
|
||||
strcat(txt_buf, "#FF8000 Warning:# #FFDD00 No# pairing data is HOS based!");
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
s_printf(txt_buf + strlen(txt_buf),
|
||||
strcat(txt_buf,
|
||||
"\n\n#FFDD00 Make sure that both Joy-Con are connected,#\n"
|
||||
"#FFDD00 and that you paired them in HOS!#");
|
||||
}
|
||||
|
||||
@@ -173,16 +173,17 @@ static lv_res_t _create_mbox_hid(usb_ctxt_t *usbs)
|
||||
lv_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
|
||||
lv_mbox_set_recolor_text(mbox, true);
|
||||
|
||||
char *text_buf = malloc(0x1000);
|
||||
char *txt_buf = malloc(0x1000);
|
||||
|
||||
s_printf(text_buf, "#FF8000 HID Emulation#\n\n#C7EA46 Device:# ");
|
||||
s_printf(txt_buf, "#FF8000 HID Emulation#\n\n#C7EA46 Device:# ");
|
||||
|
||||
if (usbs->type == USB_HID_GAMEPAD)
|
||||
s_printf(text_buf + strlen(text_buf), "Gamepad");
|
||||
strcat(txt_buf, "Gamepad");
|
||||
else
|
||||
s_printf(text_buf + strlen(text_buf), "Touchpad");
|
||||
strcat(txt_buf, "Touchpad");
|
||||
|
||||
lv_mbox_set_text(mbox, text_buf);
|
||||
lv_mbox_set_text(mbox, txt_buf);
|
||||
free(txt_buf);
|
||||
|
||||
lv_obj_t *lbl_status = lv_label_create(mbox, NULL);
|
||||
lv_label_set_recolor(lbl_status, true);
|
||||
@@ -217,25 +218,25 @@ static lv_res_t _create_mbox_ums(usb_ctxt_t *usbs)
|
||||
lv_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
|
||||
lv_mbox_set_recolor_text(mbox, true);
|
||||
|
||||
char *text_buf = malloc(0x1000);
|
||||
char *txt_buf = malloc(0x1000);
|
||||
|
||||
s_printf(text_buf, "#FF8000 USB Mass Storage#\n\n#C7EA46 Device:# ");
|
||||
s_printf(txt_buf, "#FF8000 USB Mass Storage#\n\n#C7EA46 Device:# ");
|
||||
|
||||
if (usbs->type == MMC_SD)
|
||||
{
|
||||
switch (usbs->partition)
|
||||
{
|
||||
case 0:
|
||||
s_printf(text_buf + strlen(text_buf), "SD Card");
|
||||
strcat(txt_buf, "SD Card");
|
||||
break;
|
||||
case EMMC_GPP + 1:
|
||||
s_printf(text_buf + strlen(text_buf), "emuMMC GPP");
|
||||
strcat(txt_buf, "emuMMC GPP");
|
||||
break;
|
||||
case EMMC_BOOT0 + 1:
|
||||
s_printf(text_buf + strlen(text_buf), "emuMMC BOOT0");
|
||||
strcat(txt_buf, "emuMMC BOOT0");
|
||||
break;
|
||||
case EMMC_BOOT1 + 1:
|
||||
s_printf(text_buf + strlen(text_buf), "emuMMC BOOT1");
|
||||
strcat(txt_buf, "emuMMC BOOT1");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -244,18 +245,19 @@ static lv_res_t _create_mbox_ums(usb_ctxt_t *usbs)
|
||||
switch (usbs->partition)
|
||||
{
|
||||
case EMMC_GPP + 1:
|
||||
s_printf(text_buf + strlen(text_buf), "eMMC GPP");
|
||||
strcat(txt_buf, "eMMC GPP");
|
||||
break;
|
||||
case EMMC_BOOT0 + 1:
|
||||
s_printf(text_buf + strlen(text_buf), "eMMC BOOT0");
|
||||
strcat(txt_buf, "eMMC BOOT0");
|
||||
break;
|
||||
case EMMC_BOOT1 + 1:
|
||||
s_printf(text_buf + strlen(text_buf), "eMMC BOOT1");
|
||||
strcat(txt_buf, "eMMC BOOT1");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lv_mbox_set_text(mbox, text_buf);
|
||||
lv_mbox_set_text(mbox, txt_buf);
|
||||
free(txt_buf);
|
||||
|
||||
lv_obj_t *lbl_status = lv_label_create(mbox, NULL);
|
||||
lv_label_set_recolor(lbl_status, true);
|
||||
@@ -947,7 +949,7 @@ static lv_res_t _create_mbox_fix_touchscreen(lv_obj_t *btn)
|
||||
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
|
||||
lv_mbox_set_recolor_text(mbox, true);
|
||||
|
||||
char *txt_buf = malloc(0x1000);
|
||||
char *txt_buf = malloc(0x4000);
|
||||
strcpy(txt_buf, "#FF8000 Don't touch the screen!#\n\nThe tuning process will start in ");
|
||||
u32 text_idx = strlen(txt_buf);
|
||||
lv_mbox_set_text(mbox, txt_buf);
|
||||
@@ -994,45 +996,45 @@ static lv_res_t _create_mbox_fix_touchscreen(lv_obj_t *btn)
|
||||
switch (err[0])
|
||||
{
|
||||
case ITO_FORCE_OPEN:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Force Open");
|
||||
strcat(txt_buf, "Force Open");
|
||||
break;
|
||||
case ITO_SENSE_OPEN:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Sense Open");
|
||||
strcat(txt_buf, "Sense Open");
|
||||
break;
|
||||
case ITO_FORCE_SHRT_GND:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Force Short to GND");
|
||||
strcat(txt_buf, "Force Short to GND");
|
||||
break;
|
||||
case ITO_SENSE_SHRT_GND:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Sense Short to GND");
|
||||
strcat(txt_buf, "Sense Short to GND");
|
||||
break;
|
||||
case ITO_FORCE_SHRT_VCM:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Force Short to VDD");
|
||||
strcat(txt_buf, "Force Short to VDD");
|
||||
break;
|
||||
case ITO_SENSE_SHRT_VCM:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Sense Short to VDD");
|
||||
strcat(txt_buf, "Sense Short to VDD");
|
||||
break;
|
||||
case ITO_FORCE_SHRT_FORCE:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Force Short to Force");
|
||||
strcat(txt_buf, "Force Short to Force");
|
||||
break;
|
||||
case ITO_SENSE_SHRT_SENSE:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Sense Short to Sense");
|
||||
strcat(txt_buf, "Sense Short to Sense");
|
||||
break;
|
||||
case ITO_F2E_SENSE:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Force Short to Sense");
|
||||
strcat(txt_buf, "Force Short to Sense");
|
||||
break;
|
||||
case ITO_FPC_FORCE_OPEN:
|
||||
s_printf(txt_buf + strlen(txt_buf), "FPC Force Open");
|
||||
strcat(txt_buf, "FPC Force Open");
|
||||
break;
|
||||
case ITO_FPC_SENSE_OPEN:
|
||||
s_printf(txt_buf + strlen(txt_buf), "FPC Sense Open");
|
||||
strcat(txt_buf, "FPC Sense Open");
|
||||
break;
|
||||
default:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Unknown");
|
||||
strcat(txt_buf, "Unknown");
|
||||
break;
|
||||
|
||||
}
|
||||
s_printf(txt_buf + strlen(txt_buf), " (%d), Chn: %d#\n\n", err[0], err[1]);
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FFFF00 The touchscreen calibration failed!");
|
||||
strcat(txt_buf, "#FFFF00 The touchscreen calibration failed!");
|
||||
lv_mbox_set_text(mbox, txt_buf);
|
||||
goto out2;
|
||||
}
|
||||
@@ -1079,15 +1081,14 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
|
||||
char path[128];
|
||||
|
||||
u8 kb = 0;
|
||||
u8 *pkg1 = (u8 *)calloc(1, 0x40000);
|
||||
u8 *warmboot = (u8 *)calloc(1, 0x40000);
|
||||
u8 *secmon = (u8 *)calloc(1, 0x40000);
|
||||
u8 *loader = (u8 *)calloc(1, 0x40000);
|
||||
u8 *pkg2 = NULL;
|
||||
u8 kb = 0;
|
||||
|
||||
char *txt_buf = (char *)malloc(0x4000);
|
||||
char *txt_buf2 = (char *)malloc(0x4000);
|
||||
|
||||
tsec_ctxt_t tsec_ctxt;
|
||||
|
||||
@@ -1104,8 +1105,13 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
sdmmc_storage_set_mmc_partition(&storage, EMMC_BOOT0);
|
||||
|
||||
// Read package1.
|
||||
static const u32 BOOTLOADER_SIZE = 0x40000;
|
||||
static const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
|
||||
static const u32 HOS_KEYBLOBS_OFFSET = 0x180000;
|
||||
|
||||
char *build_date = malloc(32);
|
||||
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
sdmmc_storage_read(&storage, BOOTLOADER_MAIN_OFFSET / NX_EMMC_BLOCKSIZE, BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date);
|
||||
|
||||
s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n\n", build_date);
|
||||
@@ -1116,24 +1122,21 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
// Dump package1 in its encrypted state if unknown.
|
||||
if (!pkg1_id)
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf),
|
||||
"#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#");
|
||||
strcat(txt_buf, "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#");
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
emmcsn_path_impl(path, "/pkg1", "pkg1_enc.bin", &storage);
|
||||
if (sd_save_to_file(pkg1, 0x40000, path))
|
||||
if (sd_save_to_file(pkg1, BOOTLOADER_SIZE, path))
|
||||
goto out_free;
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "\nEncrypted pkg1 dumped to pkg1_enc.bin");
|
||||
strcat(txt_buf, "\nEncrypted pkg1 dumped to pkg1_enc.bin");
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
const pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + pkg1_id->pkg11_off + 0x20);
|
||||
|
||||
kb = pkg1_id->kb;
|
||||
|
||||
if (!h_cfg.se_keygen_done)
|
||||
@@ -1169,7 +1172,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
|
||||
// Read keyblob.
|
||||
u8 *keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
|
||||
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + kb, 1, keyblob);
|
||||
sdmmc_storage_read(&storage, HOS_KEYBLOBS_OFFSET / NX_EMMC_BLOCKSIZE + kb, 1, keyblob);
|
||||
|
||||
// Decrypt.
|
||||
hos_keygen(keyblob, kb, &tsec_ctxt);
|
||||
@@ -1183,7 +1186,21 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
|
||||
if (kb <= KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1);
|
||||
const u8 *sec_map = pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1);
|
||||
|
||||
pk11_hdr_t *hdr_pk11 = (pk11_hdr_t *)(pkg1 + pkg1_id->pkg11_off + 0x20);
|
||||
|
||||
// Use correct sizes.
|
||||
u32 sec_size[3] = { hdr_pk11->wb_size, hdr_pk11->ldr_size, hdr_pk11->sm_size };
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (sec_map[i] == PK11_SECTION_WB)
|
||||
hdr_pk11->wb_size = sec_size[i];
|
||||
else if (sec_map[i] == PK11_SECTION_LD)
|
||||
hdr_pk11->ldr_size = sec_size[i];
|
||||
else if (sec_map[i] == PK11_SECTION_SM)
|
||||
hdr_pk11->sm_size = sec_size[i];
|
||||
}
|
||||
|
||||
// Display info.
|
||||
s_printf(txt_buf + strlen(txt_buf),
|
||||
@@ -1192,7 +1209,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
"#C7EA46 Secure monitor size: #0x%05X\n"
|
||||
"#C7EA46 Warmboot addr: #0x%05X\n"
|
||||
"#C7EA46 Warmboot size: #0x%05X\n\n",
|
||||
hdr->ldr_size, pkg1_id->secmon_base, hdr->sm_size, pkg1_id->warmboot_base, hdr->wb_size);
|
||||
hdr_pk11->ldr_size, pkg1_id->secmon_base, hdr_pk11->sm_size, pkg1_id->warmboot_base, hdr_pk11->wb_size);
|
||||
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
@@ -1201,31 +1218,31 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
emmcsn_path_impl(path, "/pkg1", "pkg1_decr.bin", &storage);
|
||||
if (sd_save_to_file(pkg1, 0x40000, path))
|
||||
goto out_free;
|
||||
s_printf(txt_buf + strlen(txt_buf), "pkg1 dumped to pkg1_decr.bin\n");
|
||||
strcat(txt_buf, "pkg1 dumped to pkg1_decr.bin\n");
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
// Dump nxbootloader.
|
||||
emmcsn_path_impl(path, "/pkg1", "nxloader.bin", &storage);
|
||||
if (sd_save_to_file(loader, hdr->ldr_size, path))
|
||||
if (sd_save_to_file(loader, hdr_pk11->ldr_size, path))
|
||||
goto out_free;
|
||||
s_printf(txt_buf + strlen(txt_buf), "NX Bootloader dumped to nxloader.bin\n");
|
||||
strcat(txt_buf, "NX Bootloader dumped to nxloader.bin\n");
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
// Dump secmon.
|
||||
emmcsn_path_impl(path, "/pkg1", "secmon.bin", &storage);
|
||||
if (sd_save_to_file(secmon, hdr->sm_size, path))
|
||||
if (sd_save_to_file(secmon, hdr_pk11->sm_size, path))
|
||||
goto out_free;
|
||||
s_printf(txt_buf + strlen(txt_buf), "Secure Monitor dumped to secmon.bin\n");
|
||||
strcat(txt_buf, "Secure Monitor dumped to secmon.bin\n");
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
// Dump warmboot.
|
||||
emmcsn_path_impl(path, "/pkg1", "warmboot.bin", &storage);
|
||||
if (sd_save_to_file(warmboot, hdr->wb_size, path))
|
||||
if (sd_save_to_file(warmboot, hdr_pk11->wb_size, path))
|
||||
goto out_free;
|
||||
s_printf(txt_buf + strlen(txt_buf), "Warmboot dumped to warmboot.bin\n\n");
|
||||
strcat(txt_buf, "Warmboot dumped to warmboot.bin\n\n");
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
}
|
||||
@@ -1262,7 +1279,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(pkg2, kb);
|
||||
if (!pkg2_hdr)
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Pkg2 decryption failed!#");
|
||||
strcat(txt_buf, "#FFDD00 Pkg2 decryption failed!#");
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
@@ -1287,7 +1304,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
emmcsn_path_impl(path, "/pkg2", "pkg2_decr.bin", &storage);
|
||||
if (sd_save_to_file(pkg2, pkg2_hdr->sec_size[PKG2_SEC_KERNEL] + pkg2_hdr->sec_size[PKG2_SEC_INI1], path))
|
||||
goto out;
|
||||
s_printf(txt_buf + strlen(txt_buf), "pkg2 dumped to pkg2_decr.bin\n");
|
||||
strcat(txt_buf, "pkg2 dumped to pkg2_decr.bin\n");
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
@@ -1295,7 +1312,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
emmcsn_path_impl(path, "/pkg2", "kernel.bin", &storage);
|
||||
if (sd_save_to_file(pkg2_hdr->data, pkg2_hdr->sec_size[PKG2_SEC_KERNEL], path))
|
||||
goto out;
|
||||
s_printf(txt_buf + strlen(txt_buf), "Kernel dumped to kernel.bin\n");
|
||||
strcat(txt_buf, "Kernel dumped to kernel.bin\n");
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
@@ -1311,7 +1328,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
|
||||
if (!ini1_off)
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Failed to dump INI1 and kips!#\n");
|
||||
strcat(txt_buf, "#FFDD00 Failed to dump INI1 and kips!#\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1320,7 +1337,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||
if (sd_save_to_file(ini1, ini1_size, path))
|
||||
goto out;
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "INI1 dumped to ini1.bin\n\n");
|
||||
strcat(txt_buf, "INI1 dumped to ini1.bin\n\n");
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
@@ -1367,7 +1384,6 @@ out_free:
|
||||
free(loader);
|
||||
free(pkg2);
|
||||
free(txt_buf);
|
||||
free(txt_buf2);
|
||||
sdmmc_storage_end(&storage);
|
||||
sd_unmount();
|
||||
|
||||
@@ -1616,7 +1632,7 @@ static void _create_tab_tools_arc_autorcm(lv_theme_t *th, lv_obj_t *parent)
|
||||
"#FF3C28 bootloader.#");
|
||||
|
||||
if (h_cfg.rcm_patched)
|
||||
s_printf(txt_buf + strlen(txt_buf), " #FF8000 This is disabled because this unit is patched!#");
|
||||
strcat(txt_buf, " #FF8000 This is disabled because this unit is patched!#");
|
||||
|
||||
lv_obj_t *label_txt4 = lv_label_create(h2, NULL);
|
||||
lv_label_set_recolor(label_txt4, true);
|
||||
|
||||
@@ -676,7 +676,7 @@ static lv_res_t _action_flash_linux_data(lv_obj_t * btns, const char * txt)
|
||||
if (pct != prevPct)
|
||||
{
|
||||
lv_bar_set_value(bar, pct);
|
||||
s_printf(txt_buf, " "SYMBOL_DOT" %d%%", pct);
|
||||
s_printf(txt_buf, " #DDDDDD "SYMBOL_DOT"# %d%%", pct);
|
||||
lv_label_set_text(label_pct, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
prevPct = pct;
|
||||
@@ -810,8 +810,26 @@ static lv_res_t _action_check_flash_linux(lv_obj_t *btn)
|
||||
{
|
||||
if ((u64)fno.fsize % 0x400000)
|
||||
{
|
||||
lv_label_set_text(lbl_status, "#FFDD00 Error:# The image is not aligned to 4 MiB!");
|
||||
goto error;
|
||||
// Check if last part.
|
||||
idx++;
|
||||
if (idx < 10)
|
||||
{
|
||||
path[23] = '0';
|
||||
itoa(idx, &path[23 + 1], 10);
|
||||
}
|
||||
else
|
||||
itoa(idx, &path[23], 10);
|
||||
|
||||
// If not the last part, unaligned size is not permitted.
|
||||
if (!f_stat(path, NULL)) // NULL: Don't override current part fs info.
|
||||
{
|
||||
lv_label_set_text(lbl_status, "#FFDD00 Error:# The image is not aligned to 4 MiB!");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Last part. Align size to LBA (512 bytes).
|
||||
fno.fsize = ALIGN((u64)fno.fsize, 512);
|
||||
idx--;
|
||||
}
|
||||
l4t_flash_ctxt.image_size_sct += (u64)fno.fsize >> 9;
|
||||
}
|
||||
@@ -867,7 +885,7 @@ static lv_res_t _action_reboot_twrp(lv_obj_t * btns, const char * txt)
|
||||
|
||||
sd_end();
|
||||
|
||||
reconfig_hw_workaround(false, 0);
|
||||
hw_reinit_workaround(false, 0);
|
||||
|
||||
(*main_ptr)();
|
||||
}
|
||||
@@ -894,7 +912,7 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
|
||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
static const char *mbox_btn_map[] = { "\211", "\222OK", "\211", "" };
|
||||
static const char *mbox_btn_map2[] = { "\222Continue", "\222Cancel", "" };
|
||||
static const char *mbox_btn_map2[] = { "\222Continue", "\222No", "" };
|
||||
lv_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
|
||||
lv_mbox_set_recolor_text(mbox, true);
|
||||
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6);
|
||||
@@ -1008,21 +1026,21 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
|
||||
}
|
||||
|
||||
if ((file_size >> 9) > size_sct)
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Warning:# TWRP image too big!\n");
|
||||
strcat(txt_buf, "#FF8000 Warning:# TWRP image too big!\n");
|
||||
else
|
||||
{
|
||||
sdmmc_storage_write(&sd_storage, offset_sct, file_size >> 9, buf);
|
||||
s_printf(txt_buf + strlen(txt_buf), "#C7EA46 Success:# TWRP image flashed!\n");
|
||||
strcat(txt_buf, "#C7EA46 Success:# TWRP image flashed!\n");
|
||||
f_unlink(path);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
else
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Warning:# TWRP partition not found!\n");
|
||||
strcat(txt_buf, "#FF8000 Warning:# TWRP partition not found!\n");
|
||||
}
|
||||
else
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Warning:# TWRP image not found!\n");
|
||||
strcat(txt_buf, "#FF8000 Warning:# TWRP image not found!\n");
|
||||
|
||||
lv_label_set_text(lbl_status, txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
@@ -1060,21 +1078,21 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
|
||||
}
|
||||
|
||||
if ((file_size >> 9) > size_sct)
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Warning:# DTB image too big!");
|
||||
strcat(txt_buf, "#FF8000 Warning:# DTB image too big!");
|
||||
else
|
||||
{
|
||||
sdmmc_storage_write(&sd_storage, offset_sct, file_size >> 9, buf);
|
||||
s_printf(txt_buf + strlen(txt_buf), "#C7EA46 Success:# DTB image flashed!");
|
||||
strcat(txt_buf, "#C7EA46 Success:# DTB image flashed!");
|
||||
f_unlink(path);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
else
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Warning:# DTB partition not found!");
|
||||
strcat(txt_buf, "#FF8000 Warning:# DTB partition not found!");
|
||||
}
|
||||
else
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Warning:# DTB image not found!");
|
||||
strcat(txt_buf, "#FF8000 Warning:# DTB image not found!");
|
||||
|
||||
lv_label_set_text(lbl_status, txt_buf);
|
||||
|
||||
@@ -1098,7 +1116,7 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
|
||||
error:
|
||||
if (boot_twrp)
|
||||
{
|
||||
s_printf(txt_buf + strlen(txt_buf),"\n\nDo you want to reboot into TWRP\nto finish Android installation?");
|
||||
strcat(txt_buf,"\n\nDo you want to reboot into TWRP\nto finish Android installation?");
|
||||
lv_label_set_text(lbl_status, txt_buf);
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map2, _action_reboot_twrp);
|
||||
}
|
||||
@@ -1525,9 +1543,9 @@ static lv_res_t _create_mbox_partitioning_next(lv_obj_t *btn)
|
||||
s_printf(txt_buf, "#FFDD00 Warning: This will partition your SD Card!#\n\n");
|
||||
|
||||
if (part_info.backup_possible)
|
||||
s_printf(txt_buf + strlen(txt_buf), "#C7EA46 Your files will be backed up and restored!#");
|
||||
strcat(txt_buf, "#C7EA46 Your files will be backed up and restored!#");
|
||||
else
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Your files will be wiped!#\n#FFDD00 Use USB UMS to copy them over!#");
|
||||
strcat(txt_buf, "#FFDD00 Your files will be wiped!#\n#FFDD00 Use USB UMS to copy them over!#");
|
||||
|
||||
lv_label_set_text(lbl_status, txt_buf);
|
||||
|
||||
|
||||
@@ -45,23 +45,6 @@ extern hekate_config h_cfg;
|
||||
|
||||
static u8 *bis_keys = NULL;
|
||||
|
||||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
#define PKG2_LOAD_ADDR 0xA9800000
|
||||
|
||||
// Secmon mailbox.
|
||||
#define SECMON_MB_ADDR 0x40002EF8
|
||||
#define SECMON7_MB_ADDR 0x400000F8
|
||||
typedef struct _secmon_mailbox_t
|
||||
{
|
||||
// < 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot.
|
||||
// >= 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM ready, 4: pkg2 ready and continue boot.
|
||||
u32 in;
|
||||
// Non-zero: Secmon ready.
|
||||
u32 out;
|
||||
} secmon_mailbox_t;
|
||||
|
||||
static const u8 keyblob_keyseeds[][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.
|
||||
@@ -77,21 +60,21 @@ static const u8 cmac_keyseed[0x10] =
|
||||
static const u8 master_keyseed_retail[0x10] =
|
||||
{ 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C };
|
||||
|
||||
static const u8 console_keyseed[0x10] =
|
||||
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
||||
|
||||
const u8 package2_keyseed[0x10] =
|
||||
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
|
||||
|
||||
static const u8 master_keyseed_4xx_5xx_610[0x10] =
|
||||
{ 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 };
|
||||
|
||||
static const u8 master_keyseed_620[0x10] =
|
||||
{ 0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A };
|
||||
|
||||
static const u8 console_keyseed[0x10] =
|
||||
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
||||
|
||||
static const u8 console_keyseed_4xx_5xx[0x10] =
|
||||
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
|
||||
|
||||
const u8 package2_keyseed[0x10] =
|
||||
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
|
||||
|
||||
static const u8 mkey_vectors[KB_FIRMWARE_VERSION_MAX + 1][0x10] = {
|
||||
{ 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D }, // Zeroes encrypted with mkey 00.
|
||||
{ 0x29, 0x4C, 0x04, 0xC8, 0xEB, 0x10, 0xED, 0x9D, 0x51, 0x64, 0x97, 0xFB, 0xF3, 0x4D, 0x50, 0xDD }, // Mkey 00 encrypted with mkey 01.
|
||||
@@ -106,7 +89,7 @@ static const u8 mkey_vectors[KB_FIRMWARE_VERSION_MAX + 1][0x10] = {
|
||||
{ 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A }, // Mkey 09 encrypted with mkey 10.
|
||||
};
|
||||
|
||||
static const u8 new_console_keyseed_4xx[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_400 + 1][0x10] = {
|
||||
static const u8 new_console_keyseed[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_400 + 1][0x10] = {
|
||||
{ 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D }, // 4.x New Device Key Source.
|
||||
{ 0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C }, // 5.x New Device Key Source.
|
||||
{ 0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4 }, // 6.x New Device Key Source.
|
||||
@@ -117,7 +100,7 @@ static const u8 new_console_keyseed_4xx[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VE
|
||||
{ 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 }, // 9.1.0 New Device Key Source.
|
||||
};
|
||||
|
||||
static const u8 new_console_keyseed[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_400 + 1][0x10] = {
|
||||
static const u8 new_console_kekseed[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_400 + 1][0x10] = {
|
||||
{ 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D }, // 4.x New Device Keygen Source.
|
||||
{ 0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E }, // 5.x New Device Keygen Source.
|
||||
{ 0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF }, // 6.x New Device Keygen Source.
|
||||
@@ -125,7 +108,7 @@ static const u8 new_console_keyseed[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSIO
|
||||
{ 0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E }, // 7.0.0 New Device Keygen Source.
|
||||
{ 0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D }, // 8.1.0 New Device Keygen Source.
|
||||
{ 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED }, // 9.0.0 New Device Keygen Source.
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // TODO: 9.1.0 New Device Keygen Source to be added on next change-of-keys. */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // TODO: 9.1.0 New Device Keygen Source to be added on next change-of-keys.
|
||||
};
|
||||
|
||||
static const u8 gen_keyseed[0x10] =
|
||||
@@ -179,7 +162,7 @@ void hos_eks_get()
|
||||
goto out;
|
||||
|
||||
// Decrypt EKS blob.
|
||||
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x60);
|
||||
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x80);
|
||||
se_aes_crypt_ecb(14, 0, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Check if valid and for this unit.
|
||||
@@ -231,6 +214,10 @@ void hos_eks_save(u32 kb)
|
||||
u8 *keys = (u8 *)calloc(0x1000, 1);
|
||||
se_get_aes_keys(keys + 0x800, keys, 0x10);
|
||||
|
||||
// Set SBK back.
|
||||
if (h_cfg.sbk_set)
|
||||
se_aes_key_set(14, keys + 14 * 0x10, 0x10);
|
||||
|
||||
// Set magic and personalized info.
|
||||
h_cfg.eks->magic = HOS_EKS_MAGIC;
|
||||
h_cfg.eks->enabled[key_idx] = kb;
|
||||
@@ -257,7 +244,7 @@ void hos_eks_save(u32 kb)
|
||||
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x60, eks, sizeof(hos_eks_mbr_t));
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
|
||||
@@ -294,7 +281,7 @@ void hos_eks_clear(u32 kb)
|
||||
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x60, eks, sizeof(hos_eks_mbr_t));
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
EMC(EMC_SCRATCH0) &= ~EMC_SEPT_RUN;
|
||||
@@ -353,7 +340,7 @@ void hos_eks_bis_save()
|
||||
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x60, eks, sizeof(hos_eks_mbr_t));
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
|
||||
@@ -382,7 +369,7 @@ void hos_eks_bis_clear()
|
||||
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x60, eks, sizeof(hos_eks_mbr_t));
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
free(eks);
|
||||
@@ -576,18 +563,20 @@ int hos_bis_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
{
|
||||
hos_keygen(keyblob, kb, tsec_ctxt);
|
||||
|
||||
if (kb >= KB_FIRMWARE_VERSION_400)
|
||||
keygen_rev = fuse_read_odm_keygen_rev();
|
||||
// New keygen was introduced in 4.0.0.
|
||||
// We check unconditionally in order to support downgrades.
|
||||
keygen_rev = fuse_read_odm_keygen_rev();
|
||||
|
||||
if (keygen_rev)
|
||||
{
|
||||
u8 tmp_mkey[0x10];
|
||||
u32 mkey_idx = sizeof(mkey_vectors) / 0x10;
|
||||
u8 mkey_slot = kb >= KB_FIRMWARE_VERSION_700 ? (!h_cfg.aes_slots_new ? 12 : 13) : (kb == KB_FIRMWARE_VERSION_620 ? 9 : 12);
|
||||
|
||||
// Keygen revision uses bootloader version, which starts from 1.
|
||||
keygen_rev -= (KB_FIRMWARE_VERSION_400 + 1);
|
||||
|
||||
// Derive mkey 0.
|
||||
u8 tmp_mkey[0x10];
|
||||
u32 mkey_idx = sizeof(mkey_vectors) / 0x10;
|
||||
u8 mkey_slot = kb >= KB_FIRMWARE_VERSION_700 ? (!h_cfg.aes_slots_new ? 12 : 13) : (kb == KB_FIRMWARE_VERSION_620 ? 9 : 12);
|
||||
do
|
||||
{
|
||||
mkey_idx--;
|
||||
@@ -602,9 +591,9 @@ int hos_bis_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
|
||||
// Derive new device key.
|
||||
se_aes_key_clear(1);
|
||||
se_aes_unwrap_key(1, 10, new_console_keyseed_4xx[keygen_rev]); // Uses Device key 4x.
|
||||
se_aes_crypt_ecb(10, 0, tmp_mkey, 0x10, new_console_keyseed_4xx[keygen_rev], 0x10); // Uses Device key 4x.
|
||||
se_aes_unwrap_key(1, 2, new_console_keyseed[keygen_rev]); // Uses Master Key 0.
|
||||
se_aes_unwrap_key(1, 10, new_console_keyseed[keygen_rev]); // Uses Device key 4x.
|
||||
se_aes_crypt_ecb(10, 0, tmp_mkey, 0x10, new_console_keyseed[keygen_rev], 0x10); // Uses Device key 4x.
|
||||
se_aes_unwrap_key(1, 2, new_console_kekseed[keygen_rev]); // Uses Master Key 0.
|
||||
se_aes_unwrap_key(1, 1, tmp_mkey);
|
||||
|
||||
console_key_slot = 1;
|
||||
@@ -674,15 +663,18 @@ void hos_bis_keys_clear()
|
||||
se_aes_key_clear(i);
|
||||
|
||||
// Set SBK back.
|
||||
u32 sbk[4] = {
|
||||
if (!h_cfg.sbk_set)
|
||||
{
|
||||
u32 sbk[4] = {
|
||||
FUSE(FUSE_PRIVATE_KEY0),
|
||||
FUSE(FUSE_PRIVATE_KEY1),
|
||||
FUSE(FUSE_PRIVATE_KEY2),
|
||||
FUSE(FUSE_PRIVATE_KEY3)
|
||||
};
|
||||
// Set SBK to slot 14.
|
||||
se_aes_key_set(14, sbk, 0x10);
|
||||
// Set SBK to slot 14.
|
||||
se_aes_key_set(14, sbk, 0x10);
|
||||
|
||||
// Lock SBK from being read.
|
||||
se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||
// Lock SBK from being read.
|
||||
se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||
}
|
||||
}
|
||||
@@ -57,17 +57,17 @@ typedef struct _hos_eks_bis_keys_t
|
||||
typedef struct _hos_eks_mbr_t
|
||||
{
|
||||
u32 magic;
|
||||
u8 enabled[6];
|
||||
u8 enabled[5];
|
||||
u8 enabled_bis;
|
||||
u8 rsvd;
|
||||
u8 rsvd[2];
|
||||
u32 sbk_low;
|
||||
u8 dkg[0x10];
|
||||
u8 dkk[0x10];
|
||||
hos_eks_keys_t keys[6];
|
||||
hos_eks_keys_t keys[5];
|
||||
hos_eks_bis_keys_t bis_keys[3];
|
||||
} hos_eks_mbr_t;
|
||||
|
||||
static_assert(sizeof(hos_eks_mbr_t) == 336, "HOS EKS size is wrong!");
|
||||
static_assert(sizeof(hos_eks_mbr_t) == 304, "HOS EKS size is wrong!");
|
||||
|
||||
typedef struct _launch_ctxt_t
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "hos.h"
|
||||
#include "pkg1.h"
|
||||
#include <gfx_utils.h>
|
||||
#include <mem/heap.h>
|
||||
@@ -28,33 +29,31 @@
|
||||
/*
|
||||
* 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 }
|
||||
* 6.0: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 6.2: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 7.0: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 1.0: {sm, ldr, wb} { 2, 1, 0 }
|
||||
* 2.0+: {wb, ldr, sm} { 0, 1, 2 }
|
||||
* 4.0+: {ldr, sm, wb} { 1, 2, 0 }
|
||||
*/
|
||||
|
||||
static const u8 sec_map_100[3] = { PK11_SECTION_SM, PK11_SECTION_LD, PK11_SECTION_WB };
|
||||
static const u8 sec_map_2xx[3] = { PK11_SECTION_WB, PK11_SECTION_LD, PK11_SECTION_SM };
|
||||
static const u8 sec_map_4xx[3] = { PK11_SECTION_LD, PK11_SECTION_SM, PK11_SECTION_WB };
|
||||
|
||||
static const pkg1_id_t _pkg1_ids[] = {
|
||||
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, 0x8000D000 }, //1.0.0
|
||||
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000 }, //2.0.0 - 2.3.0
|
||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000 }, //3.0.0
|
||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000 }, //3.0.1 - 3.0.2
|
||||
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000 }, //4.0.0 - 4.1.0
|
||||
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000 }, //5.0.0 - 5.1.0
|
||||
{ "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800 }, //6.0.0 - 6.1.0
|
||||
{ "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800 }, //6.2.0
|
||||
{ "20181218175730", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //7.0.0
|
||||
{ "20190208150037", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //7.0.1
|
||||
{ "20190314172056", 7, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //8.0.0 - 8.0.1
|
||||
{ "20190531152432", 8, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //8.1.0
|
||||
{ "20190809135709", 9, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //9.0.0 - 9.0.1
|
||||
{ "20191021113848", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //9.1.0
|
||||
{ "20200303104606", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //10.0.0
|
||||
{ "20161121183008", 0, 0x1900, 0x3FE0, 0x40014020, 0x8000D000 }, // 1.0.0.
|
||||
{ "20170210155124", 0, 0x1900, 0x3FE0, 0x4002D000, 0x8000D000 }, // 2.0.0 - 2.3.0.
|
||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, 0x4002D000, 0x8000D000 }, // 3.0.0.
|
||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, 0x4002D000, 0x8000D000 }, // 3.0.1 - 3.0.2.
|
||||
{ "20170921172629", 3, 0x1800, 0x3FE0, 0x4002B000, 0x4003B000 }, // 4.0.0 - 4.1.0.
|
||||
{ "20180220163747", 4, 0x1900, 0x3FE0, 0x4002B000, 0x4003B000 }, // 5.0.0 - 5.1.0.
|
||||
{ "20180802162753", 5, 0x1900, 0x3FE0, 0x4002B000, 0x4003D800 }, // 6.0.0 - 6.1.0.
|
||||
{ "20181107105733", 6, 0x0E00, 0x6FE0, 0x4002B000, 0x4003D800 }, // 6.2.0.
|
||||
{ "20181218175730", 7, 0x0F00, 0x6FE0, 0x40030000, 0x4003E000 }, // 7.0.0.
|
||||
{ "20190208150037", 7, 0x0F00, 0x6FE0, 0x40030000, 0x4003E000 }, // 7.0.1.
|
||||
{ "20190314172056", 7, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 8.0.0 - 8.0.1.
|
||||
{ "20190531152432", 8, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 8.1.0.
|
||||
{ "20190809135709", 9, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 9.0.0 - 9.0.1.
|
||||
{ "20191021113848", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 9.1.0.
|
||||
{ "20200303104606", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 10.0.0.
|
||||
{ NULL } //End.
|
||||
};
|
||||
|
||||
@@ -80,22 +79,34 @@ void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1)
|
||||
se_aes_crypt_ctr(11, pkg11 + 0x20, pkg11_size, pkg11 + 0x20, pkg11_size, pkg11 + 0x10);
|
||||
}
|
||||
|
||||
void pkg1_unpack(void *warmboot_dst, void *secmon_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1)
|
||||
const u8 *pkg1_unpack(void *wm_dst, void *sm_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1)
|
||||
{
|
||||
pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + id->pkg11_off + 0x20);
|
||||
const u8 *sec_map;
|
||||
const 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 };
|
||||
|
||||
// Get correct header mapping.
|
||||
if (id->kb == KB_FIRMWARE_VERSION_100_200 && !strcmp(id->id, "20161121183008"))
|
||||
sec_map = sec_map_100;
|
||||
else if (id->kb >= KB_FIRMWARE_VERSION_100_200 && id->kb <= KB_FIRMWARE_VERSION_301)
|
||||
sec_map = sec_map_2xx;
|
||||
else
|
||||
sec_map = sec_map_4xx;
|
||||
|
||||
// Copy secmon, warmboot and nx bootloader payloads.
|
||||
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] == 1 && ldr_dst)
|
||||
memcpy(ldr_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]];
|
||||
if (sec_map[i] == PK11_SECTION_WB && wm_dst)
|
||||
memcpy(wm_dst, pdata, sec_size[sec_map[i]]);
|
||||
else if (sec_map[i] == PK11_SECTION_LD && ldr_dst)
|
||||
memcpy(ldr_dst, pdata, sec_size[sec_map[i]]);
|
||||
else if (sec_map[i] == PK11_SECTION_SM && sm_dst)
|
||||
memcpy(sm_dst, pdata, sec_size[sec_map[i]]);
|
||||
pdata += sec_size[sec_map[i]];
|
||||
}
|
||||
|
||||
return sec_map;
|
||||
}
|
||||
|
||||
@@ -19,13 +19,16 @@
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define PK11_SECTION_WB 0
|
||||
#define PK11_SECTION_LD 1
|
||||
#define PK11_SECTION_SM 2
|
||||
|
||||
typedef struct _pkg1_id_t
|
||||
{
|
||||
const char *id;
|
||||
u32 kb;
|
||||
u32 tsec_off;
|
||||
u32 pkg11_off;
|
||||
u32 sec_map[3];
|
||||
u32 secmon_base;
|
||||
u32 warmboot_base;
|
||||
} pkg1_id_t;
|
||||
@@ -44,6 +47,6 @@ typedef struct _pk11_hdr_t
|
||||
|
||||
const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date);
|
||||
void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1);
|
||||
void pkg1_unpack(void *warmboot_dst, void *secmon_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1);
|
||||
const u8 *pkg1_unpack(void *wm_dst, void *sm_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -226,7 +226,7 @@ int reboot_to_sept(const u8 *tsec_fw, u32 kb)
|
||||
PMC(APBDEV_PMC_SCRATCH33) = SEPT_PRI_ADDR;
|
||||
PMC(APBDEV_PMC_SCRATCH40) = 0x6000F208;
|
||||
|
||||
reconfig_hw_workaround(false, 0);
|
||||
hw_reinit_workaround(false, 0);
|
||||
|
||||
(*sept)();
|
||||
|
||||
|
||||
@@ -185,12 +185,12 @@ lv_res_t launch_payload(lv_obj_t *list)
|
||||
if (size < 0x30000)
|
||||
{
|
||||
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10));
|
||||
reconfig_hw_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
|
||||
hw_reinit_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
|
||||
}
|
||||
else
|
||||
{
|
||||
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000);
|
||||
reconfig_hw_workaround(true, 0);
|
||||
hw_reinit_workaround(true, 0);
|
||||
}
|
||||
|
||||
void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR;
|
||||
@@ -241,10 +241,8 @@ void load_saved_configuration()
|
||||
h_cfg.autonogc = atoi(kv->val);
|
||||
else if (!strcmp("updater2p", kv->key))
|
||||
h_cfg.updater2p = atoi(kv->val);
|
||||
else if (!strcmp("brand", kv->key))
|
||||
h_cfg.brand = kv->val;
|
||||
else if (!strcmp("tagline", kv->key))
|
||||
h_cfg.tagline = kv->val;
|
||||
else if (!strcmp("bootprotect", kv->key))
|
||||
h_cfg.bootprotect = atoi(kv->val);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -272,6 +270,8 @@ void load_saved_configuration()
|
||||
n_cfg.verification = atoi(kv->val);
|
||||
else if (!strcmp("umsemmcrw", kv->key))
|
||||
n_cfg.ums_emmc_rw = atoi(kv->val) == 1;
|
||||
else if (!strcmp("jcdisable", kv->key))
|
||||
n_cfg.jc_disable = atoi(kv->val) == 1;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -281,10 +281,10 @@ void load_saved_configuration()
|
||||
}
|
||||
|
||||
#define EXCP_EN_ADDR 0x4003FFFC
|
||||
#define EXCP_MAGIC 0x30505645 // EVP0
|
||||
#define EXCP_MAGIC 0x30505645 // EVP0
|
||||
#define EXCP_TYPE_ADDR 0x4003FFF8
|
||||
#define EXCP_TYPE_RESET 0x545352 // RST
|
||||
#define EXCP_TYPE_UNDEF 0x464455 // UDF
|
||||
#define EXCP_TYPE_RESET 0x545352 // RST
|
||||
#define EXCP_TYPE_UNDEF 0x464455 // UDF
|
||||
#define EXCP_TYPE_PABRT 0x54424150 // PABT
|
||||
#define EXCP_TYPE_DABRT 0x54424144 // DABT
|
||||
#define EXCP_LR_ADDR 0x4003FFF4
|
||||
@@ -307,16 +307,16 @@ static void _show_errors()
|
||||
switch (*excp_type)
|
||||
{
|
||||
case EXCP_TYPE_RESET:
|
||||
WPRINTF("Reset");
|
||||
WPRINTF("RESET");
|
||||
break;
|
||||
case EXCP_TYPE_UNDEF:
|
||||
WPRINTF("Undefined instruction");
|
||||
WPRINTF("UNDEF");
|
||||
break;
|
||||
case EXCP_TYPE_PABRT:
|
||||
WPRINTF("Prefetch abort");
|
||||
WPRINTF("PABRT");
|
||||
break;
|
||||
case EXCP_TYPE_DABRT:
|
||||
WPRINTF("Data abort");
|
||||
WPRINTF("DABRT");
|
||||
break;
|
||||
}
|
||||
WPRINTF("\n");
|
||||
@@ -359,9 +359,11 @@ void nyx_init_load_res()
|
||||
load_saved_configuration();
|
||||
|
||||
FIL fp;
|
||||
f_open(&fp, "bootloader/sys/res.pak", FA_READ);
|
||||
f_read(&fp, (void *)NYX_RES_ADDR, f_size(&fp), NULL);
|
||||
f_close(&fp);
|
||||
if (!f_open(&fp, "bootloader/sys/res.pak", FA_READ))
|
||||
{
|
||||
f_read(&fp, (void *)NYX_RES_ADDR, f_size(&fp), NULL);
|
||||
f_close(&fp);
|
||||
}
|
||||
|
||||
// If no custom switch icon exists, load normal.
|
||||
if (f_stat("bootloader/res/icon_switch_custom.bmp", NULL))
|
||||
@@ -400,15 +402,21 @@ void ipl_main()
|
||||
// Important: Preserve version header!
|
||||
__asm__ ("" : : "" (ipl_ver));
|
||||
|
||||
#if (LV_LOG_PRINTF == 1)
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
pinmux_config_uart(UART_B);
|
||||
clock_enable_uart(UART_B);
|
||||
uart_init(UART_B, 115200);
|
||||
#ifdef DEBUG_UART_PORT
|
||||
#if DEBUG_UART_PORT == UART_B
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
#endif
|
||||
#if DEBUG_UART_PORT == UART_C
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
#endif
|
||||
pinmux_config_uart(DEBUG_UART_PORT);
|
||||
clock_enable_uart(DEBUG_UART_PORT);
|
||||
uart_init(DEBUG_UART_PORT, 115200);
|
||||
|
||||
uart_send(UART_B, (u8 *)"hekate-NYX: Hello!\r\n", 20);
|
||||
uart_wait_idle(UART_B, UART_TX_IDLE);
|
||||
uart_send(DEBUG_UART_PORT, (u8 *)"hekate-NYX: Hello!\r\n", 20);
|
||||
uart_wait_idle(DEBUG_UART_PORT, UART_TX_IDLE);
|
||||
#endif
|
||||
|
||||
// Initialize the rest of hw and load nyx's resources.
|
||||
|
||||
@@ -174,7 +174,7 @@ bool sd_mount()
|
||||
|
||||
static void _sd_deinit(bool deinit)
|
||||
{
|
||||
if (sd_mode == SD_INIT_FAIL)
|
||||
if (deinit && sd_mode == SD_INIT_FAIL)
|
||||
sd_mode = SD_UHS_SDR104;
|
||||
|
||||
if (sd_init_done && sd_mounted)
|
||||
|
||||
Reference in New Issue
Block a user