mirror of
https://github.com/CTCaer/hekate.git
synced 2025-08-02 14:18:43 +00:00
Compare commits
No commits in common. "master" and "v6.2.1" have entirely different histories.
84 changed files with 1072 additions and 1632 deletions
23
Makefile
23
Makefile
|
@ -48,7 +48,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
|||
|
||||
# Horizon.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
hos.o hos_config.o pkg1.o pkg2.o pkg3.o pkg2_ini_kippatch.o secmon_exo.o \
|
||||
hos.o hos_config.o pkg1.o pkg2.o pkg2_ini_kippatch.o fss.o secmon_exo.o \
|
||||
)
|
||||
|
||||
# Libraries.
|
||||
|
@ -76,15 +76,15 @@ CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
|
|||
|
||||
# UART Logging: Max baudrate 12.5M.
|
||||
# DEBUG_UART_PORT - 0: UART_A, 1: UART_B, 2: UART_C.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_BAUDRATE=115200 -DDEBUG_UART_INVERT=0 -DDEBUG_UART_PORT=1
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_BAUDRATE=115200 -DDEBUG_UART_INVERT=0 -DDEBUG_UART_PORT=0
|
||||
|
||||
#TODO: Considering reinstating some of these when pointer warnings have been fixed.
|
||||
WARNINGS := -Wall -Wsign-compare -Wtype-limits -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
|
||||
WARNINGS := -Wall -Wsign-compare -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
|
||||
#-fno-delete-null-pointer-checks
|
||||
#-Wstack-usage=byte-size -fstack-usage
|
||||
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork $(WARNINGS)
|
||||
CFLAGS = $(ARCH) -O2 -g -gdwarf-4 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(CUSTOMDEFINES)
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
CFLAGS = $(ARCH) -O2 -g -gdwarf-4 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
|
||||
MODULEDIRS := $(wildcard modules/*)
|
||||
|
@ -101,14 +101,15 @@ TOOLS := $(TOOLSLZ) $(TOOLSB2C)
|
|||
all: $(TARGET).bin $(LDRDIR)
|
||||
@printf ICTC49 >> $(OUTPUTDIR)/$(TARGET).bin
|
||||
@echo "--------------------------------------"
|
||||
@echo "$(TARGET) size:"
|
||||
@echo -n "Uncompr: "
|
||||
@echo -n "Uncompr size: "
|
||||
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET)_unc.bin))
|
||||
@echo $(BIN_SIZE)" Bytes"
|
||||
@echo "Uncompr Max: 140288 Bytes + 3 KiB BSS"
|
||||
@if [ ${BIN_SIZE} -gt 140288 ]; then echo "\e[1;33mUncompr size exceeds limit!\e[0m"; fi
|
||||
@echo -n "Payload: "
|
||||
@echo -n "Payload size: "
|
||||
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET).bin))
|
||||
@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 "--------------------------------------"
|
||||
|
||||
|
@ -125,7 +126,7 @@ $(NYXDIR):
|
|||
|
||||
$(LDRDIR): $(TARGET).bin
|
||||
@$(TOOLSLZ)/lz77 $(OUTPUTDIR)/$(TARGET).bin
|
||||
@mv $(OUTPUTDIR)/$(TARGET).bin $(OUTPUTDIR)/$(TARGET)_unc.bin
|
||||
mv $(OUTPUTDIR)/$(TARGET).bin $(OUTPUTDIR)/$(TARGET)_unc.bin
|
||||
@mv $(OUTPUTDIR)/$(TARGET).bin.00.lz payload_00
|
||||
@mv $(OUTPUTDIR)/$(TARGET).bin.01.lz payload_01
|
||||
@$(TOOLSB2C)/bin2c payload_00 > $(LDRDIR)/payload_00.h
|
||||
|
@ -138,11 +139,11 @@ $(TOOLS):
|
|||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) $(NYXDIR) $(TOOLS)
|
||||
@$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||
@$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||
@printf "$(TARGET) was built with the following flags:\nCFLAGS: $(CFLAGS)\nLDFLAGS: $(LDFLAGS)\n"
|
||||
@echo "hekate was built with the following flags:\nCFLAGS: "$(CFLAGS)"\nLDFLAGS: "$(LDFLAGS)
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/%.o: %.c
|
||||
@echo Building $@
|
||||
|
|
42
README.md
42
README.md
|
@ -50,14 +50,13 @@ Custom Graphical Nintendo Switch bootloader, firmware patcher, tools, and many m
|
|||
| \|__ background.bmp | Nyx - Custom background. User provided. |
|
||||
| \|__ icon_switch.bmp | Nyx - Default icon for CFWs. |
|
||||
| \|__ icon_payload.bmp | Nyx - Default icon for Payloads. |
|
||||
| bootloader/sys/ | hekate and Nyx system modules folder. !Important! |
|
||||
| \|__ emummc.kipm | emuMMC KIP1 module. |
|
||||
| \|__ libsys_lp0.bso | LP0 (sleep mode) module. |
|
||||
| \|__ libsys_minerva.bso | Minerva Training Cell. Used for DRAM Frequency training. |
|
||||
| \|__ nyx.bin | Nyx - hekate's GUI. |
|
||||
| \|__ res.pak | Nyx resources package. |
|
||||
| \|__ thk.bin | Atmosphère Tsec Hovi Keygen. |
|
||||
| \|__ /l4t/ | Folder with firmware relevant to L4T (Linux/Android). |
|
||||
| bootloader/sys/ | hekate and Nyx system modules folder. |
|
||||
| \|__ emummc.kipm | emuMMC KIP1 module. !Important! |
|
||||
| \|__ libsys_lp0.bso | LP0 (sleep mode) module. Important! |
|
||||
| \|__ libsys_minerva.bso | Minerva Training Cell. Used for DRAM Frequency training. !Important! |
|
||||
| \|__ nyx.bin | Nyx - hekate's GUI. !Important! |
|
||||
| \|__ res.pak | Nyx resources package. !Important! |
|
||||
| \|__ thk.bin | Atmosphère Tsec Hovi Keygen. !Important! |
|
||||
| bootloader/screenshots/ | Folder where Nyx screenshots are saved |
|
||||
| bootloader/payloads/ | For the `Payloads` menu. All CFW bootloaders, tools, Linux payloads are supported. Autoboot only supported by including them into an ini. |
|
||||
| bootloader/libtools/ | Reserved |
|
||||
|
@ -78,7 +77,7 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
|||
### hekate Global Configuration keys/values (when entry is *[config]*):
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | -------------------------------------------------------------- |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| autoboot=0 | 0: Disable, #: Boot entry number to auto boot. |
|
||||
| autoboot_list=0 | 0: Read `autoboot` boot entry from hekate_ipl.ini, 1: Read from ini folder (ini files are ASCII ordered). |
|
||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. Max: 20s. |
|
||||
|
@ -99,20 +98,18 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
|||
| kernel={FILE path} | Replaces the kernel binary |
|
||||
| kip1={FILE path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||
| kip1={FOLDER path}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||
| pkg3={FILE path} | Takes an Atmosphere `package3` binary and `extracts` all needed parts from it. kips, exosphere, warmboot and mesophere. |
|
||||
| fss0={FILE path} | Same as above. !Deprecated! |
|
||||
| pkg3ex=1 | Enables loading of experimental content from a PKG3/FSS0 storage |
|
||||
| pkg3kip1skip={KIP name} | Skips loading a kip from `pkg3`/`fss0`. Allows multiple and `,` as separator. The name must exactly match the name in `PKG3`. |
|
||||
| fss0={FILE path} | Takes an Atmosphere `package3` binary (formerly fusee-secondary.bin) and `extracts` all needed parts from it. kips, exosphere, warmboot and mesophere if enabled. |
|
||||
| fss0experimental=1 | Enables loading of experimental content from a FSS0 storage |
|
||||
| exofatal={FILE path} | Replaces the exosphere fatal binary for Mariko |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| kip1patch=patchname | Enables a kip1 patch. Allows multiple and `,` as separator. If actual patch is not found, a warning will show up. |
|
||||
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or in one line with `,` as separator. If actual patch is not found, a warning will show up |
|
||||
| emupath={FOLDER path} | Forces emuMMC to use the selected one. (=emuMMC/RAW1, =emuMMC/SD00, etc). emuMMC must be created by hekate because it uses the raw_based/file_based files. |
|
||||
| emummcforce=1 | Forces the use of emuMMC. If emummc.ini is disabled or not found, then it causes an error. |
|
||||
| emummc_force_disable=1 | Disables emuMMC, if it's enabled. |
|
||||
| stock=1 | OFW via hekate bootloader. Disables unneeded kernel patching and CFW kips when running stock. `If emuMMC is enabled, emummc_force_disable=1` is required. emuMMC is not supported on stock. If additional KIPs are needed other than OFW's, you can define them with `kip1` key. No kip should be used that relies on Atmosphère patching, because it will hang. If `NOGC` is needed, use `kip1patch=nogc`. |
|
||||
| stock=1 | Disables unneeded kernel patching and CFW kips when running stock or semi-stock. `If emuMMC is enabled, emummc_force_disable=1` is required. emuMMC is not supported on stock. If additional KIPs are needed other than OFW's, you can define them with `kip1` key. No kip should be used that relies on Atmosphère patching, because it will hang. If `NOGC` is needed, use `kip1patch=nogc`. |
|
||||
| fullsvcperm=1 | Disables SVC verification (full services permission). Doesn't work with Mesosphere as kernel. |
|
||||
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
||||
| kernelprocid=1 | Enables stock kernel process id send/recv patching. Not needed when `pkg3`/`fss0` is used. |
|
||||
| atmosphere=1 | Enables Atmosphère patching. Not needed when `fss0` is used. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| payload={FILE path} | Payload launching. Tools, Android/Linux, CFW bootloaders, etc. Any key above when used with that, doesn't get into account. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
|
@ -122,7 +119,6 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
|||
| ram_oc_vdd2=1100 | L4T RAM VDD2 Voltage. Set VDD2 (T210B01) or VDD2/VDDQ (T210) voltage. 1050-1175. |
|
||||
| ram_oc_vddq=600 | L4T RAM VDDQ Voltage. Set VDDQ (T210B01). 550-650. |
|
||||
| uart_port=0 | Enables logging on serial port for L4T uboot/kernel. |
|
||||
| sld_type=0x31444C53 | Controls the type of seamless display support. 0x0: Disable, 0x31444C53: L4T seamless display. |
|
||||
| Additional keys | Each distro supports more keys. Check README_CONFIG.txt for more info. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| bootwait=3 | Overrides global bootwait from `[config]`. |
|
||||
|
@ -133,11 +129,11 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
|||
|
||||
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
|
||||
|
||||
**Note2**: When using PKG3/FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `pkg3`/`fss0`.
|
||||
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
|
||||
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
|
||||
|
||||
**Warning**: Careful when you override *pkg3/fss core* kips with `kip1`.
|
||||
That's in case the kips are incompatible between them. If compatible, you can override `pkg3`/`fss0` kips with no issues (useful for testing with intermediate kip changes). In such cases, the `kip1` line must be **after** `pkg3`/`fss0` line.
|
||||
**Warning**: Careful when you define *fss0 core* kips when using `fss0` or the folder (when using `/*`) includes them.
|
||||
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes). In such cases, the `kip1` line must be under `fss0` line.
|
||||
|
||||
|
||||
### Boot entry key/value combinations for Exosphère:
|
||||
|
@ -159,7 +155,7 @@ That's in case the kips are incompatible between them. If compatible, you can ov
|
|||
|
||||
### Payload storage:
|
||||
|
||||
hekate has a boot storage in the binary that helps it configure it outside of BPMP environment:
|
||||
hekate has a boot storage in the binary that helps it configure it outside of BPMP enviroment:
|
||||
|
||||
| Offset / Name | Description |
|
||||
| ----------------------- | ----------------------------------------------------------------- |
|
||||
|
@ -192,9 +188,9 @@ hekate has a boot storage in the binary that helps it configure it outside of BP
|
|||
|
||||
```
|
||||
hekate (c) 2018, naehrwert, st4rk.
|
||||
(c) 2018-2025, CTCaer.
|
||||
(c) 2018-2024, CTCaer.
|
||||
|
||||
Nyx GUI (c) 2019-2025, CTCaer.
|
||||
Nyx GUI (c) 2019-2024, CTCaer.
|
||||
|
||||
Thanks to: derrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8.
|
||||
Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# IPL Version.
|
||||
BLVERSION_MAJOR := 6
|
||||
BLVERSION_MINOR := 3
|
||||
BLVERSION_MINOR := 2
|
||||
BLVERSION_HOTFX := 1
|
||||
BLVERSION_REL := 0
|
||||
|
||||
# Nyx Version.
|
||||
NYXVERSION_MAJOR := 1
|
||||
NYXVERSION_MINOR := 7
|
||||
NYXVERSION_HOTFX := 0
|
||||
NYXVERSION_MINOR := 6
|
||||
NYXVERSION_HOTFX := 3
|
||||
NYXVERSION_REL := 0
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#include <soc/gpio.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/irq.h>
|
||||
#include <soc/kfuse.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -265,9 +265,16 @@ int display_dsi_vblank_read(u8 cmd, u32 len, void *data)
|
|||
|
||||
void display_dsi_write(u8 cmd, u32 len, void *data)
|
||||
{
|
||||
static u8 *fifo8 = NULL;
|
||||
static u32 *fifo32 = NULL;
|
||||
u32 host_control;
|
||||
u32 fifo32[DSI_STATUS_TX_FIFO_SIZE] = {0};
|
||||
u8 *fifo8 = (u8 *)fifo32;
|
||||
|
||||
// Allocate fifo buffer.
|
||||
if (!fifo32)
|
||||
{
|
||||
fifo32 = malloc(DSI_STATUS_RX_FIFO_SIZE * 8 * sizeof(u32));
|
||||
fifo8 = (u8 *)fifo32;
|
||||
}
|
||||
|
||||
// Prepare data for long write.
|
||||
if (len >= 2)
|
||||
|
@ -312,8 +319,15 @@ void display_dsi_write(u8 cmd, u32 len, void *data)
|
|||
|
||||
void display_dsi_vblank_write(u8 cmd, u32 len, void *data)
|
||||
{
|
||||
u32 fifo32[DSI_STATUS_TX_FIFO_SIZE] = {0};
|
||||
u8 *fifo8 = (u8 *)fifo32;
|
||||
static u8 *fifo8 = NULL;
|
||||
static u32 *fifo32 = NULL;
|
||||
|
||||
// Allocate fifo buffer.
|
||||
if (!fifo32)
|
||||
{
|
||||
fifo32 = malloc(DSI_STATUS_RX_FIFO_SIZE * 8 * sizeof(u32));
|
||||
fifo8 = (u8 *)fifo32;
|
||||
}
|
||||
|
||||
// Prepare data for long write.
|
||||
if (len >= 2)
|
||||
|
@ -557,7 +571,7 @@ void display_init()
|
|||
* When switching to the 16ff pad brick, the clock lane termination control
|
||||
* is separated from data lane termination. This change of the mipi cal
|
||||
* brings in a bug that the DSI pad clock termination code can't be loaded
|
||||
* in one time calibration on T210B01. Trigger calibration twice.
|
||||
* in one time calibration. Trigger calibration twice.
|
||||
*/
|
||||
reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_pad_cal_config, ARRAY_SIZE(_di_mipi_pad_cal_config));
|
||||
for (u32 i = 0; i < 2; i++)
|
||||
|
@ -921,7 +935,7 @@ void display_move_framebuffer(u32 window, void *fb)
|
|||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = BIT(WINDOW_SELECT + window);
|
||||
|
||||
// Get current framebuffer address.
|
||||
const void *fb_curr = (void *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
||||
void *fb_curr = (void *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
||||
u32 win_size = DISPLAY_A(_DIREG(DC_WIN_PRESCALED_SIZE));
|
||||
win_size = (win_size & 0x7FFF) * ((win_size >> 16) & 0x1FFF);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -520,7 +520,6 @@
|
|||
|
||||
#define DSI_STATUS 0x15
|
||||
#define DSI_STATUS_RX_FIFO_SIZE 0x1F
|
||||
#define DSI_STATUS_TX_FIFO_SIZE 0x20 // Actual depth is 64.
|
||||
|
||||
#define DSI_INIT_SEQ_CONTROL 0x1A
|
||||
#define DSI_INIT_SEQ_DATA_0 0x1B
|
||||
|
@ -718,7 +717,7 @@
|
|||
#define MIPI_DCS_READ_DDB_CONTINUE 0xA8 // 0x100 size.
|
||||
|
||||
/*! MIPI DCS Panel Private CMDs. */
|
||||
#define MIPI_DCS_PRIV_SM_SET_COLOR_MODE 0xA0 // 43 bytes.
|
||||
#define MIPI_DCS_PRIV_SM_SET_COLOR_MODE 0xA0
|
||||
#define MIPI_DCS_PRIV_SM_SET_REG_OFFSET 0xB0
|
||||
#define MIPI_DCS_PRIV_SM_SET_ELVSS 0xB1 // OLED backlight tuning. Byte7: PWM transition time in frames.
|
||||
#define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1
|
||||
|
@ -728,7 +727,6 @@
|
|||
#define MIPI_DCS_PRIV_UNK_D6 0xD6
|
||||
#define MIPI_DCS_PRIV_UNK_D8 0xD8
|
||||
#define MIPI_DCS_PRIV_UNK_D9 0xD9
|
||||
#define MIPI_DCS_PRIV_SM_DISPLAY_ID 0xDD
|
||||
// LVL1 LVL2 LVL3 UNK0 UNK1
|
||||
#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Unlock: A5A5 5A5A 5A5A UNK UNK.
|
||||
#define MIPI_DCS_PRIV_READ_EXTC_CMD_SPI 0xFE // Read EXTC Command In SPI. 1 byte. 0-6: EXT_SPI_CNT, 7:EXT_SP.
|
||||
|
@ -767,21 +765,19 @@
|
|||
|
||||
#define DCS_CONTROL_DISPLAY_SM_FLASHLIGHT BIT(2)
|
||||
#define DCS_CONTROL_DISPLAY_BACKLIGHT_CTRL BIT(2)
|
||||
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3) // Transition fading.
|
||||
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3)
|
||||
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL BIT(5)
|
||||
#define DCS_CONTROL_DISPLAY_HBM_CTRL0 BIT(6)
|
||||
#define DCS_CONTROL_DISPLAY_HBM_CTRL1 BIT(7)
|
||||
|
||||
#define DCS_SM_COLOR_MODE_SATURATED 0x00 // Disabled. Based on Vivid but over-saturated.
|
||||
#define DCS_SM_COLOR_MODE_SATURATED 0x00 // Disabled. Similar to vivid but over-saturated. Wide gamut?
|
||||
#define DCS_SM_COLOR_MODE_WASHED 0x45
|
||||
#define DCS_SM_COLOR_MODE_BASIC 0x03 // Real natural profile.
|
||||
#define DCS_SM_COLOR_MODE_BASIC 0x03
|
||||
#define DCS_SM_COLOR_MODE_POR_RESET 0x20 // Reset value on power on.
|
||||
#define DCS_SM_COLOR_MODE_NATURAL 0x23 // Not actually natural.. Extra saturation.
|
||||
#define DCS_SM_COLOR_MODE_VIVID 0x65 // Saturated.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT0 0x43 // Based on Washed Out.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT1 0x15 // Based on Basic.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT2 0x35 // Based on Natural.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT3 0x75 // Based on Vivid.
|
||||
#define DCS_SM_COLOR_MODE_NATURAL 0x23 // Not actually natural..
|
||||
#define DCS_SM_COLOR_MODE_VIVID 0x65
|
||||
#define DCS_SM_COLOR_MODE_NIGHT0 0x43 // Based on washed out.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT1 0x15 // Based on basic.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT2 0x35 // Based on natural.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT3 0x75 // Based on vivid.
|
||||
|
||||
#define DCS_SM_COLOR_MODE_ENABLE BIT(0)
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ static int _vic_wait_idle()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void vic_set_surface(const vic_surface_t *sfc)
|
||||
void vic_set_surface(vic_surface_t *sfc)
|
||||
{
|
||||
u32 flip_x = 0;
|
||||
u32 flip_y = 0;
|
||||
|
|
|
@ -58,7 +58,7 @@ typedef struct _vic_surface_t
|
|||
u32 rotation;
|
||||
} vic_surface_t;
|
||||
|
||||
void vic_set_surface(const vic_surface_t *sfc);
|
||||
void vic_set_surface(vic_surface_t *sfc);
|
||||
int vic_compose();
|
||||
int vic_init();
|
||||
void vic_end();
|
||||
|
|
|
@ -70,6 +70,8 @@ void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
|||
|
||||
if (!cycle)
|
||||
cycle = 1;
|
||||
else if (cycle > 255)
|
||||
cycle = 255;
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <gfx_utils.h>
|
||||
#include <power/max17050.h>
|
||||
#include <power/regulator_5v.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/gpio.h>
|
||||
|
@ -222,8 +223,8 @@ typedef struct _jc_hid_in_rpt_t
|
|||
{
|
||||
u8 cmd;
|
||||
u8 pkt_id;
|
||||
u8 conn_info:4; // Connection detect.
|
||||
u8 batt_info:4; // Power info.
|
||||
u8 conn_info:4;
|
||||
u8 batt_info:4;
|
||||
u8 btn_right;
|
||||
u8 btn_shared;
|
||||
u8 btn_left;
|
||||
|
@ -316,10 +317,9 @@ typedef struct _joycon_ctxt_t
|
|||
u8 uart;
|
||||
u8 type;
|
||||
u8 state;
|
||||
u8 mac[6];
|
||||
u32 last_received_time;
|
||||
u32 last_status_req_time;
|
||||
u8 mac[6];
|
||||
u8 pkt_id;
|
||||
u8 rumble_sent;
|
||||
u8 connected;
|
||||
u8 detected;
|
||||
|
@ -330,10 +330,11 @@ static joycon_ctxt_t jc_l = {0};
|
|||
static joycon_ctxt_t jc_r = {0};
|
||||
|
||||
static bool jc_init_done = false;
|
||||
static u32 hid_pkt_inc = 0;
|
||||
|
||||
static jc_gamepad_rpt_t jc_gamepad;
|
||||
|
||||
static u8 _jc_crc(const u8 *data, u16 len, u8 init)
|
||||
static u8 _jc_crc(u8 *data, u16 len, u8 init)
|
||||
{
|
||||
u8 crc = init;
|
||||
for (u16 i = 0; i < len; i++)
|
||||
|
@ -447,7 +448,7 @@ static void _jc_conn_check()
|
|||
if (jc_l.connected)
|
||||
_jc_power_supply(UART_C, false);
|
||||
|
||||
jc_l.pkt_id = 0;
|
||||
hid_pkt_inc = 0;
|
||||
|
||||
jc_l.connected = false;
|
||||
jc_l.rumble_sent = false;
|
||||
|
@ -464,7 +465,7 @@ static void _jc_conn_check()
|
|||
if (jc_r.connected)
|
||||
_jc_power_supply(UART_B, false);
|
||||
|
||||
jc_r.pkt_id = 0;
|
||||
hid_pkt_inc = 0;
|
||||
|
||||
jc_r.connected = false;
|
||||
jc_r.rumble_sent = false;
|
||||
|
@ -483,7 +484,7 @@ static void _joycon_send_raw(u8 uart_port, const u8 *buf, u16 size)
|
|||
uart_wait_xfer(uart_port, UART_TX_IDLE);
|
||||
}
|
||||
|
||||
static u16 _jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, const u8 *data, u16 size, bool crc)
|
||||
static u16 _jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u16 size, bool crc)
|
||||
{
|
||||
out->uart_hdr.magic[0] = 0x19;
|
||||
out->uart_hdr.magic[1] = 0x01;
|
||||
|
@ -503,7 +504,7 @@ static u16 _jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, const u8 *
|
|||
return sizeof(jc_wired_hdr_t);
|
||||
}
|
||||
|
||||
static u16 _jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, const u8 *payload, u16 size, bool crc)
|
||||
static u16 _jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size, bool crc)
|
||||
{
|
||||
u16 pkt_size = _jc_packet_add_uart_hdr(rpt, JC_WIRED_HID, NULL, 0, crc);
|
||||
pkt_size += size;
|
||||
|
@ -518,18 +519,22 @@ static u16 _jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, const u8 *payload, u16
|
|||
return pkt_size;
|
||||
}
|
||||
|
||||
static void _jc_send_hid_output_rpt(joycon_ctxt_t *jc, jc_hid_out_rpt_t *hid_pkt, u16 size, bool crc)
|
||||
static void _jc_send_hid_output_rpt(u8 uart, u8 *payload, u16 size, bool crc)
|
||||
{
|
||||
u8 rpt[0x50];
|
||||
memset(rpt, 0, sizeof(rpt));
|
||||
|
||||
hid_pkt->pkt_id = (jc->pkt_id++ & 0xF);
|
||||
u32 rpt_size = _jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, (u8 *)hid_pkt, size, crc);
|
||||
u32 rpt_size = _jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, payload, size, crc);
|
||||
|
||||
_joycon_send_raw(jc->uart, rpt, rpt_size);
|
||||
_joycon_send_raw(uart, rpt, rpt_size);
|
||||
}
|
||||
|
||||
static void _jc_send_hid_cmd(joycon_ctxt_t *jc, u8 subcmd, const u8 *data, u16 size)
|
||||
static u8 _jc_hid_pkt_id_incr()
|
||||
{
|
||||
return (hid_pkt_inc++ & 0xF);
|
||||
}
|
||||
|
||||
static void _jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size)
|
||||
{
|
||||
static const u8 rumble_neutral[8] = { 0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40 };
|
||||
static const u8 rumble_init[8] = { 0xc2, 0xc8, 0x03, 0x72, 0xc2, 0xc8, 0x03, 0x72 };
|
||||
|
@ -546,43 +551,47 @@ static void _jc_send_hid_cmd(joycon_ctxt_t *jc, u8 subcmd, const u8 *data, u16 s
|
|||
|
||||
// Enable rumble.
|
||||
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
||||
hid_pkt->pkt_id = _jc_hid_pkt_id_incr();
|
||||
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
|
||||
hid_pkt->subcmd_data[0] = 1;
|
||||
if (send_r_rumble)
|
||||
_jc_send_hid_output_rpt(&jc_r, hid_pkt, 0x10, false);
|
||||
_jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false);
|
||||
if (send_l_rumble)
|
||||
_jc_send_hid_output_rpt(&jc_l, hid_pkt, 0x10, false);
|
||||
_jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false);
|
||||
|
||||
// Send rumble.
|
||||
hid_pkt->cmd = JC_HID_RUMBLE_RPT;
|
||||
hid_pkt->pkt_id = _jc_hid_pkt_id_incr();
|
||||
memcpy(hid_pkt->rumble, rumble_init, sizeof(rumble_init));
|
||||
if (send_r_rumble)
|
||||
_jc_send_hid_output_rpt(&jc_r, hid_pkt, 10, false);
|
||||
_jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 10, false);
|
||||
if (send_l_rumble)
|
||||
_jc_send_hid_output_rpt(&jc_l, hid_pkt, 10, false);
|
||||
_jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 10, false);
|
||||
|
||||
msleep(15);
|
||||
|
||||
// Disable rumble.
|
||||
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
||||
hid_pkt->pkt_id = _jc_hid_pkt_id_incr();
|
||||
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
|
||||
hid_pkt->subcmd_data[0] = 0;
|
||||
memcpy(hid_pkt->rumble, rumble_neutral, sizeof(rumble_neutral));
|
||||
if (send_r_rumble)
|
||||
_jc_send_hid_output_rpt(&jc_r, hid_pkt, 0x10, false);
|
||||
_jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false);
|
||||
if (send_l_rumble)
|
||||
_jc_send_hid_output_rpt(&jc_l, hid_pkt, 0x10, false);
|
||||
_jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool crc_needed = jc->type & JC_ID_HORI;
|
||||
bool crc_needed = (jc_l.uart == uart) ? (jc_l.type & JC_ID_HORI) : (jc_r.type & JC_ID_HORI);
|
||||
|
||||
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
||||
hid_pkt->pkt_id = _jc_hid_pkt_id_incr();
|
||||
hid_pkt->subcmd = subcmd;
|
||||
if (data)
|
||||
memcpy(hid_pkt->subcmd_data, data, size);
|
||||
|
||||
_jc_send_hid_output_rpt(jc, hid_pkt, sizeof(jc_hid_out_rpt_t) + size, crc_needed);
|
||||
_jc_send_hid_output_rpt(uart, (u8 *)hid_pkt, sizeof(jc_hid_out_rpt_t) + size, crc_needed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -814,7 +823,7 @@ static bool _jc_send_init_rumble(joycon_ctxt_t *jc)
|
|||
// Send init rumble or request nx pad status report.
|
||||
if ((jc_r.connected && !jc_r.rumble_sent) || (jc_l.connected && !jc_l.rumble_sent))
|
||||
{
|
||||
_jc_send_hid_cmd(jc, JC_HID_SUBCMD_SND_RUMBLE, NULL, 0);
|
||||
_jc_send_hid_cmd(jc->uart, JC_HID_SUBCMD_SND_RUMBLE, NULL, 0);
|
||||
|
||||
if (jc_l.connected)
|
||||
jc_l.rumble_sent = true;
|
||||
|
@ -855,7 +864,7 @@ static void _jc_req_nx_pad_status(joycon_ctxt_t *jc)
|
|||
jc->last_status_req_time = get_tmr_ms() + (!jc->sio_mode ? 15 : 7);
|
||||
}
|
||||
|
||||
static bool _jc_validate_pairing_info(const u8 *buf, bool *is_hos)
|
||||
static bool _jc_validate_pairing_info(u8 *buf, bool *is_hos)
|
||||
{
|
||||
u8 crc = 0;
|
||||
for (u32 i = 0; i < 0x22; i++)
|
||||
|
@ -924,13 +933,13 @@ retry:
|
|||
{
|
||||
if (!jc_l_found)
|
||||
{
|
||||
_jc_send_hid_cmd(&jc_l, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_l, 5);
|
||||
_jc_send_hid_cmd(jc_l.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_l, 5);
|
||||
jc_l.last_status_req_time = get_tmr_ms() + 15;
|
||||
}
|
||||
|
||||
if (!jc_r_found)
|
||||
{
|
||||
_jc_send_hid_cmd(&jc_r, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_r, 5);
|
||||
_jc_send_hid_cmd(jc_r.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_r, 5);
|
||||
jc_r.last_status_req_time = get_tmr_ms() + 15;
|
||||
}
|
||||
|
||||
|
@ -1121,7 +1130,7 @@ static void _jc_init_conn(joycon_ctxt_t *jc)
|
|||
|
||||
// Initialize the controller.
|
||||
u32 retries = 10;
|
||||
while (!jc->connected && retries)
|
||||
while (!jc->connected)
|
||||
{
|
||||
_joycon_send_raw(jc->uart, sio_init, sizeof(sio_init));
|
||||
msleep(5);
|
||||
|
@ -1230,12 +1239,12 @@ void jc_deinit()
|
|||
u8 data = HCI_STATE_SLEEP;
|
||||
if (jc_r.connected && !(jc_r.type & JC_ID_HORI))
|
||||
{
|
||||
_jc_send_hid_cmd(&jc_r, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
||||
_jc_send_hid_cmd(UART_B, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
||||
_jc_rcv_pkt(&jc_r);
|
||||
}
|
||||
if (jc_l.connected && !(jc_l.type & JC_ID_HORI))
|
||||
{
|
||||
_jc_send_hid_cmd(&jc_l, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
||||
_jc_send_hid_cmd(UART_C, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
||||
_jc_rcv_pkt(&jc_l);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4698,20 +4698,13 @@ FRESULT f_lseek (
|
|||
|
||||
DWORD *f_expand_cltbl (
|
||||
FIL* fp, /* Pointer to the file object */
|
||||
UINT tblsz, /* Size of table (2 DWORDs + 2 DWORDs per fragment) */
|
||||
UINT tblsz, /* Size of table */
|
||||
FSIZE_t ofs /* File pointer from top of file */
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Cluster table structure:
|
||||
* Size (DWORD)
|
||||
* Padding (DWORD)
|
||||
* (Cluster Offset (DWORD) + Sequential clusters (DWORD)) * Fragments
|
||||
*/
|
||||
if (fp->flag & FA_WRITE) f_lseek(fp, ofs); /* Expand file if write is enabled */
|
||||
if (!fp->cltbl) { /* Allocate memory for cluster link table */
|
||||
fp->cltbl = (DWORD *)ff_memalloc(tblsz);
|
||||
if (!fp->cltbl) return (void *)0;
|
||||
fp->cltbl[0] = tblsz;
|
||||
}
|
||||
if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
|
||||
|
|
|
@ -38,7 +38,7 @@ typedef struct
|
|||
bool emc_2X_clk_src_is_pllmb;
|
||||
bool fsp_for_src_freq;
|
||||
bool train_ram_patterns;
|
||||
u32 init_done;
|
||||
bool init_done;
|
||||
} mtc_config_t;
|
||||
|
||||
enum train_mode_t
|
||||
|
|
|
@ -75,7 +75,7 @@ void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
|||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
_bm92t36_read_reg(buf, 2, STATUS1_REG);
|
||||
*inserted = (buf[0] & STATUS1_INSERT) ? true : false;
|
||||
*inserted = buf[0] & STATUS1_INSERT ? true : false;
|
||||
}
|
||||
|
||||
if (usb_pd)
|
||||
|
|
|
@ -29,8 +29,7 @@ int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
|
|||
{
|
||||
u8 data;
|
||||
|
||||
switch (prop)
|
||||
{
|
||||
switch (prop) {
|
||||
case BQ24193_InputVoltageLimit: // Input voltage limit (mV).
|
||||
data = bq24193_get_reg(BQ24193_InputSource);
|
||||
data = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;
|
||||
|
|
|
@ -327,7 +327,7 @@ void max77620_config_default()
|
|||
return;
|
||||
|
||||
// Set default voltages and enable regulators.
|
||||
for (u32 i = REGULATOR_SD1; i <= REGULATOR_LDO8; i++)
|
||||
for (u32 i = 1; i <= REGULATOR_LDO8; i++)
|
||||
{
|
||||
max77620_regulator_config_fps(i);
|
||||
max7762x_regulator_set_voltage(i, _pmic_regulators[i].uv_default);
|
||||
|
|
47
bdk/sec/se.c
47
bdk/sec/se.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "se.h"
|
||||
#include <memory_map.h>
|
||||
#include <mem/heap.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
|
@ -181,7 +182,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
|
|||
if (!src || !dst)
|
||||
return 0;
|
||||
|
||||
u32 block[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
|
||||
u8 *block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
|
||||
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||
|
||||
|
@ -189,10 +190,11 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
|
|||
int res = _se_execute_oneshot(op, block, SE_AES_BLOCK_SIZE, block, SE_AES_BLOCK_SIZE);
|
||||
memcpy(dst, block, dst_size);
|
||||
|
||||
free(block);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void _se_aes_ctr_set(const void *ctr)
|
||||
static void _se_aes_ctr_set(void *ctr)
|
||||
{
|
||||
u32 data[SE_AES_IV_SIZE / 4];
|
||||
memcpy(data, ctr, SE_AES_IV_SIZE);
|
||||
|
@ -224,7 +226,7 @@ u32 se_key_acc_ctrl_get(u32 ks)
|
|||
return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks);
|
||||
}
|
||||
|
||||
void se_aes_key_set(u32 ks, const void *key, u32 size)
|
||||
void se_aes_key_set(u32 ks, void *key, u32 size)
|
||||
{
|
||||
u32 data[SE_AES_MAX_KEY_SIZE / 4];
|
||||
memcpy(data, key, size);
|
||||
|
@ -236,7 +238,7 @@ void se_aes_key_set(u32 ks, const void *key, u32 size)
|
|||
}
|
||||
}
|
||||
|
||||
void se_aes_iv_set(u32 ks, const void *iv)
|
||||
void se_aes_iv_set(u32 ks, void *iv)
|
||||
{
|
||||
u32 data[SE_AES_IV_SIZE / 4];
|
||||
memcpy(data, iv, SE_AES_IV_SIZE);
|
||||
|
@ -387,8 +389,7 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
|
|||
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
|
||||
{
|
||||
int res = 0;
|
||||
u32 tmp[SE_AES_BLOCK_SIZE / sizeof(u32)];
|
||||
u8 *tweak = (u8 *)tmp;
|
||||
u8 *tweak = (u8 *)malloc(SE_AES_BLOCK_SIZE);
|
||||
u8 *pdst = (u8 *)dst;
|
||||
u8 *psrc = (u8 *)src;
|
||||
|
||||
|
@ -417,7 +418,8 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst
|
|||
|
||||
res = 1;
|
||||
|
||||
out:
|
||||
out:;
|
||||
free(tweak);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -512,15 +514,15 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
|
|||
return 0;
|
||||
|
||||
// Src size of 0 is not supported, so return null string sha256.
|
||||
if (!src_size)
|
||||
{
|
||||
const u8 null_hash[SE_SHA_256_SIZE] = {
|
||||
0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
|
||||
0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
|
||||
};
|
||||
memcpy(hash, null_hash, SE_SHA_256_SIZE);
|
||||
return 1;
|
||||
}
|
||||
// if (!src_size)
|
||||
// {
|
||||
// const u8 null_hash[SE_SHA_256_SIZE] = {
|
||||
// 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
|
||||
// 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
|
||||
// };
|
||||
// memcpy(hash, null_hash, SE_SHA_256_SIZE);
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
// Setup config for SHA256.
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
|
||||
|
@ -655,11 +657,8 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
|||
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
u32 tmp1[SE_KEY_128_SIZE / sizeof(u32)] = {0};
|
||||
u32 tmp2[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
|
||||
u8 *key = (u8 *)tmp1;
|
||||
u8 *last_block = (u8 *)tmp2;
|
||||
u8 *key = (u8 *)zalloc(SE_KEY_128_SIZE);
|
||||
u8 *last_block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
|
||||
|
||||
se_aes_iv_clear(ks);
|
||||
se_aes_iv_updated_clear(ks);
|
||||
|
@ -708,6 +707,8 @@ int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
|
|||
for (u32 i = 0; i < (SE_KEY_128_SIZE / 4); i++)
|
||||
dst32[i] = SE(SE_HASH_RESULT_REG + (i * 4));
|
||||
|
||||
out:
|
||||
out:;
|
||||
free(key);
|
||||
free(last_block);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags);
|
|||
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, const void *key, u32 size);
|
||||
void se_aes_iv_set(u32 ks, const void *iv);
|
||||
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);
|
||||
|
|
|
@ -237,7 +237,6 @@ void bpmp_clk_rate_relaxed(bool enable)
|
|||
// APB clock affects RTC, PWM, MEMFETCH, APE, USB, SOR PWM,
|
||||
// I2C host, DC/DSI/DISP. UART gives extra stress.
|
||||
// 92: 100% success ratio. 93-94: 595-602MHz has 99% success ratio. 95: 608MHz less.
|
||||
// APB clock max is supposed to be 204 MHz though.
|
||||
static const u8 pll_divn[] = {
|
||||
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
||||
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
||||
|
@ -301,13 +300,6 @@ void bpmp_clk_rate_set(bpmp_freq_t fid)
|
|||
}
|
||||
}
|
||||
|
||||
// State is reset to RUN on any clock or source set via SW.
|
||||
void bpmp_state_set(bpmp_state_t state)
|
||||
{
|
||||
u32 cfg = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & ~0xF0000000u;
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = cfg | (state << 28u);
|
||||
}
|
||||
|
||||
// The following functions halt BPMP to reduce power while sleeping.
|
||||
// They are not as accurate as RTC at big values but they guarantee time+ delay.
|
||||
void bpmp_usleep(u32 us)
|
||||
|
|
|
@ -54,16 +54,6 @@ typedef enum
|
|||
BPMP_CLK_MAX
|
||||
} bpmp_freq_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BPMP_STATE_STANDBY = 0, // 32KHz.
|
||||
BPMP_STATE_IDLE = 1,
|
||||
BPMP_STATE_RUN = 2,
|
||||
|
||||
BPMP_STATE_IRQ = BIT(2),
|
||||
BPMP_STATE_FIQ = BIT(3),
|
||||
} bpmp_state_t;
|
||||
|
||||
#define BPMP_CLK_LOWEST_BOOST BPMP_CLK_HIGH2_BOOST
|
||||
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST
|
||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
||||
|
@ -75,7 +65,6 @@ void bpmp_mmu_disable();
|
|||
void bpmp_clk_rate_relaxed(bool enable);
|
||||
void bpmp_clk_rate_get();
|
||||
void bpmp_clk_rate_set(bpmp_freq_t fid);
|
||||
void bpmp_state_set(bpmp_state_t state);
|
||||
void bpmp_usleep(u32 us);
|
||||
void bpmp_msleep(u32 ms);
|
||||
void bpmp_halt();
|
||||
|
|
|
@ -701,7 +701,7 @@ static void _clock_sdmmc_clear_enable(u32 id)
|
|||
|
||||
static void _clock_sdmmc_config_legacy_tm()
|
||||
{
|
||||
const clk_rst_t *clk = &_clock_sdmmc_legacy_tm;
|
||||
clk_rst_t *clk = &_clock_sdmmc_legacy_tm;
|
||||
if (!(CLOCK(clk->enable) & BIT(clk->index)))
|
||||
clock_enable(clk);
|
||||
}
|
||||
|
|
|
@ -150,7 +150,6 @@
|
|||
#define CLK_RST_CONTROLLER_PLLC_MISC_2 0x5D0
|
||||
#define CLK_RST_CONTROLLER_PLLC4_OUT 0x5E4
|
||||
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
|
||||
#define CLK_RST_CONTROLLER_PLLMB_MISC1 0x5EC
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS 0x608
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_DEV 0x60C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS 0x610
|
||||
|
|
|
@ -24,9 +24,7 @@
|
|||
#include <sec/se_t210.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <soc/timer.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
static const u32 evp_thunk_template[] = {
|
||||
|
@ -191,7 +189,7 @@ void fuse_read_array(u32 *words)
|
|||
words[i] = fuse_read(i);
|
||||
}
|
||||
|
||||
static u32 _parity32_even(const u32 *words, u32 count)
|
||||
static u32 _parity32_even(u32 *words, u32 count)
|
||||
{
|
||||
u32 acc = words[0];
|
||||
for (u32 i = 1; i < count; i++)
|
||||
|
@ -305,7 +303,7 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
|||
u32 words[80];
|
||||
u32 word_count;
|
||||
u32 word_addr;
|
||||
u32 word0;
|
||||
u32 word0 = 0;
|
||||
u32 total_read = 0;
|
||||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
|
@ -365,7 +363,7 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
|||
u32 words[80];
|
||||
u32 word_count;
|
||||
u32 word_addr;
|
||||
u32 word0;
|
||||
u32 word0 = 0;
|
||||
u32 total_read = 0;
|
||||
int evp_thunk_written = 0;
|
||||
void *evp_thunk_dst_addr = 0;
|
||||
|
|
|
@ -96,7 +96,7 @@ static void _i2c_load_cfg_wait(vu32 *base)
|
|||
}
|
||||
}
|
||||
|
||||
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, const u8 *buf, u32 size)
|
||||
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
|
||||
{
|
||||
if (size > 8)
|
||||
return 0;
|
||||
|
@ -384,7 +384,7 @@ 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, const u8 *buf, u32 size)
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size)
|
||||
{
|
||||
u8 tmp[8];
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ 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, const u8 *buf, u32 size);
|
||||
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);
|
||||
|
|
|
@ -124,8 +124,8 @@ static irq_status_t _irq_handle_source(u32 irq)
|
|||
}
|
||||
}
|
||||
|
||||
// Do not re-enable if not handled or error.
|
||||
if (status != IRQ_HANDLED)
|
||||
// Do not re-enable if not handled.
|
||||
if (status == IRQ_NONE)
|
||||
return status;
|
||||
|
||||
if (irqs[idx].flags & IRQ_FLAG_ONE_OFF)
|
||||
|
|
|
@ -85,7 +85,6 @@
|
|||
#define AXBAR_BASE 0x702D0800
|
||||
#define I2S_BASE 0x702D1000
|
||||
#define ADMA_BASE 0x702E2000
|
||||
#define AMC_BASE 0x702EF000
|
||||
#define SE2_BASE 0x70412000
|
||||
#define SE_PKA1_BASE 0x70420000
|
||||
#define TZRAM_BASE 0x7C010000
|
||||
|
@ -152,7 +151,6 @@
|
|||
#define CL_DVFS(off) MMIO_REG32(CL_DVFS_BASE, off)
|
||||
#define I2S(off) MMIO_REG32(I2S_BASE, off)
|
||||
#define ADMA(off) MMIO_REG32(ADMA_BASE, off)
|
||||
#define AMC(off) MMIO_REG32(AMC_BASE, off)
|
||||
#define SE2(off) MMIO_REG32(SE2_BASE, off)
|
||||
#define SE_PKA1(off) MMIO_REG32(SE_PKA1_BASE, off)
|
||||
#define USB(off) MMIO_REG32(USB_BASE, off)
|
||||
|
@ -212,7 +210,7 @@
|
|||
#define AHB_GIZMO_USB 0x20
|
||||
#define AHB_GIZMO_SDMMC4 0x48
|
||||
#define AHB_GIZMO_USB2 0x7C
|
||||
#define AHB_GIZMO_USB3 0x80 // Doesn't exist on T21x??
|
||||
#define AHB_GIZMO_USB3 0x80
|
||||
#define AHB_GIZMO_IMMEDIATE BIT(18)
|
||||
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG3 0xE4
|
||||
|
@ -221,9 +219,9 @@
|
|||
#define AHB_AHB_MEM_PREFETCH_CFG2 0xF4
|
||||
#define MST_ID(x) (((x) & 0x1F) << 26)
|
||||
#define MEM_PREFETCH_AHBDMA_MST_ID MST_ID(5)
|
||||
#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG. Doesn't exist on T210B01.
|
||||
#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC. Doesn't exist on T210B01.
|
||||
#define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB. Doesn't exist on T210B01.
|
||||
#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG.
|
||||
#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC.
|
||||
#define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB.
|
||||
#define MEM_PREFETCH_ADDR_BNDRY(x) (((x) & 0xF) << 21)
|
||||
#define MEM_PREFETCH_ENABLE BIT(31)
|
||||
#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xFC
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
#define EXCP_TYPE_ADDR 0x4003FFF8
|
||||
#define EXCP_TYPE_WDT 0x544457 // "WDT".
|
||||
|
||||
#define USE_RTC_TIMER
|
||||
|
||||
u32 get_tmr_s()
|
||||
{
|
||||
(void)RTC(APBDEV_RTC_MILLI_SECONDS);
|
||||
|
|
|
@ -174,14 +174,14 @@ void uart_empty_fifo(u32 idx, u32 which)
|
|||
(void)uart->UART_SPR;
|
||||
usleep(96);
|
||||
|
||||
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | which;
|
||||
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_TX_CLR | UART_IIR_FCR_RX_CLR;
|
||||
(void)uart->UART_SPR;
|
||||
usleep(18);
|
||||
u32 tries = 0;
|
||||
|
||||
if (UART_IIR_FCR_TX_CLR & which)
|
||||
{
|
||||
while (tries < 10 && !(uart->UART_LSR & UART_LSR_TMTY))
|
||||
while (tries < 10 && uart->UART_LSR & UART_LSR_TMTY)
|
||||
{
|
||||
tries++;
|
||||
usleep(100);
|
||||
|
@ -191,7 +191,7 @@ void uart_empty_fifo(u32 idx, u32 which)
|
|||
|
||||
if (UART_IIR_FCR_RX_CLR & which)
|
||||
{
|
||||
while (tries < 10 && (uart->UART_LSR & UART_LSR_RDR))
|
||||
while (tries < 10 && !uart->UART_LSR & UART_LSR_RDR)
|
||||
{
|
||||
tries++;
|
||||
usleep(100);
|
||||
|
|
|
@ -70,8 +70,6 @@
|
|||
#define UART_MCR_CTS_EN BIT(5)
|
||||
#define UART_MCR_RTS_EN BIT(6)
|
||||
|
||||
#define UART_FIFO_SIZE 36
|
||||
|
||||
typedef struct _uart_t
|
||||
{
|
||||
/* 0x00 */ vu32 UART_THR_DLAB;
|
||||
|
|
|
@ -274,7 +274,7 @@ void *sd_file_read(const char *path, u32 *fsize)
|
|||
return buf;
|
||||
}
|
||||
|
||||
int sd_save_to_file(const void *buf, u32 size, const char *filename)
|
||||
int sd_save_to_file(void *buf, u32 size, const char *filename)
|
||||
{
|
||||
FIL fp;
|
||||
u32 res = 0;
|
||||
|
|
|
@ -61,6 +61,6 @@ void sd_unmount();
|
|||
void sd_end();
|
||||
bool sd_is_gpt();
|
||||
void *sd_file_read(const char *path, u32 *fsize);
|
||||
int sd_save_to_file(const void *buf, u32 size, const char *filename);
|
||||
int sd_save_to_file(void *buf, u32 size, const char *filename);
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,16 +17,11 @@
|
|||
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
|
||||
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
|
||||
#define SD_SWITCH_VOLTAGE 11 /* ac R1 */
|
||||
/* Class 2 */
|
||||
#define SD_ADDR_EXT 22 /* ac [5:0] R1 */
|
||||
/* class 10 */
|
||||
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
|
||||
/* class 5 */
|
||||
#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */
|
||||
#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
|
||||
/* class 11 */
|
||||
#define SD_READ_EXTR_SINGLE 48 /* adtc [31:0] R1 */
|
||||
#define SD_WRITE_EXTR_SINGLE 49 /* adtc [31:0] R1 */
|
||||
|
||||
/* Application commands */
|
||||
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2023 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,7 +18,6 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <mem/heap.h>
|
||||
#include <mem/mc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/sdmmc.h>
|
||||
|
@ -28,26 +27,14 @@
|
|||
#include <memory_map.h>
|
||||
#include <gfx_utils.h>
|
||||
|
||||
//#define SDMMC_DEBUG_PRINT_SD_REGS
|
||||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
//#define SDMMC_DEBUG_PRINT_SD_REGS
|
||||
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
|
||||
#define DREGPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DREGPRINTF(...)
|
||||
#endif
|
||||
|
||||
#ifdef BDK_SDMMC_EXTRA_PRINT
|
||||
#define ERROR_EXTRA_PRINTING
|
||||
#endif
|
||||
|
||||
u32 sd_power_cycle_time_start;
|
||||
|
||||
static inline u32 unstuff_bits(const u32 *resp, u32 start, u32 size)
|
||||
static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
|
||||
{
|
||||
start %= 128;
|
||||
|
||||
const u32 mask = (size < 32 ? 1 << size : 0) - 1;
|
||||
const u32 off = 3 - ((start) / 32);
|
||||
const u32 shft = (start) & 31;
|
||||
|
@ -65,7 +52,7 @@ static inline u32 unstuff_bits(const u32 *resp, u32 start, u32 size)
|
|||
static int _sdmmc_storage_check_card_status(u32 res)
|
||||
{
|
||||
//Error mask:
|
||||
//!WARN: R1_SWITCH_ERROR is reserved on SD. The card isn't supposed to use it.
|
||||
//TODO: R1_SWITCH_ERROR can be skipped for certain card types.
|
||||
if (res &
|
||||
(R1_OUT_OF_RANGE | R1_ADDRESS_ERROR | R1_BLOCK_LEN_ERROR |
|
||||
R1_ERASE_SEQ_ERROR | R1_ERASE_PARAM | R1_WP_VIOLATION |
|
||||
|
@ -86,7 +73,7 @@ static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *re
|
|||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||
return 0;
|
||||
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, resp, SDMMC_RSP_TYPE_1);
|
||||
sdmmc_get_rsp(storage->sdmmc, resp, 4, SDMMC_RSP_TYPE_1);
|
||||
if (mask)
|
||||
*resp &= ~mask;
|
||||
|
||||
|
@ -118,7 +105,7 @@ static int _sdmmc_storage_get_cid(sdmmc_storage_t *storage)
|
|||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||
return 0;
|
||||
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, (u32 *)storage->raw_cid, SDMMC_RSP_TYPE_2);
|
||||
sdmmc_get_rsp(storage->sdmmc, (u32 *)storage->raw_cid, 16, SDMMC_RSP_TYPE_2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -135,7 +122,7 @@ static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage)
|
|||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||
return 0;
|
||||
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, (u32 *)storage->raw_csd, SDMMC_RSP_TYPE_2);
|
||||
sdmmc_get_rsp(storage->sdmmc, (u32 *)storage->raw_csd, 16, SDMMC_RSP_TYPE_2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -164,7 +151,7 @@ int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg)
|
|||
return 0;
|
||||
|
||||
u32 resp;
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_1);
|
||||
sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_1);
|
||||
|
||||
resp = -1;
|
||||
u32 timeout = get_tmr_ms() + 1500;
|
||||
|
@ -241,10 +228,6 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
|
|||
return 0;
|
||||
}
|
||||
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
||||
if (!_sdmmc_storage_check_card_status(tmp))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -262,12 +245,40 @@ int sdmmc_storage_end(sdmmc_storage_t *storage)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int _sdmmc_storage_handle_io_error(sdmmc_storage_t *storage, bool first_reinit)
|
||||
static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write)
|
||||
{
|
||||
int res = 0;
|
||||
u8 *bbuf = (u8 *)buf;
|
||||
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.
|
||||
u32 retries = 5;
|
||||
do
|
||||
{
|
||||
reinit_try:
|
||||
if (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sct_off, MIN(sct_total, 0xFFFF), bbuf, is_write))
|
||||
goto out;
|
||||
else
|
||||
retries--;
|
||||
|
||||
sd_error_count_increment(SD_ERROR_RW_RETRY);
|
||||
|
||||
msleep(50);
|
||||
} while (retries);
|
||||
|
||||
// Disk IO failure! Reinit SD/EMMC to a lower speed.
|
||||
if (storage->sdmmc->id == SDMMC_1 || storage->sdmmc->id == SDMMC_4)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
if (storage->sdmmc->id == SDMMC_1)
|
||||
{
|
||||
sd_error_count_increment(SD_ERROR_RW_FAIL);
|
||||
|
@ -294,63 +305,22 @@ static int _sdmmc_storage_handle_io_error(sdmmc_storage_t *storage, bool first_r
|
|||
emmc_error_count_increment(EMMC_ERROR_INIT_FAIL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write)
|
||||
{
|
||||
u8 *bbuf = (u8 *)buf;
|
||||
u32 sct_off = sector;
|
||||
u32 sct_total = num_sectors;
|
||||
bool first_reinit = true;
|
||||
|
||||
// Exit if not initialized.
|
||||
if (!storage->initialized)
|
||||
return 0;
|
||||
|
||||
// Check if out of bounds.
|
||||
if (((u64)sector + num_sectors) > storage->sec_cnt)
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTFARGS("SDMMC%d: Out of bounds!", storage->sdmmc->id + 1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (sct_total)
|
||||
{
|
||||
u32 blkcnt = 0;
|
||||
// Retry 5 times if failed.
|
||||
u32 retries = 5;
|
||||
do
|
||||
{
|
||||
reinit_try:
|
||||
if (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sct_off, MIN(sct_total, 0xFFFF), bbuf, is_write))
|
||||
goto out;
|
||||
else
|
||||
retries--;
|
||||
|
||||
sd_error_count_increment(SD_ERROR_RW_RETRY);
|
||||
|
||||
msleep(50);
|
||||
} while (retries);
|
||||
|
||||
// Disk IO failure! Reinit SD/EMMC to a lower speed.
|
||||
if (_sdmmc_storage_handle_io_error(storage, first_reinit))
|
||||
{
|
||||
// Reset values for a retry.
|
||||
blkcnt = 0;
|
||||
retries = 3;
|
||||
first_reinit = false;
|
||||
|
||||
// If successful reinit, restart xfer.
|
||||
if (res)
|
||||
{
|
||||
bbuf = (u8 *)buf;
|
||||
sct_off = sector;
|
||||
sct_total = num_sectors;
|
||||
|
||||
goto reinit_try;
|
||||
}
|
||||
}
|
||||
|
||||
// Failed.
|
||||
return 0;
|
||||
|
@ -423,7 +393,7 @@ static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u
|
|||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||
return 0;
|
||||
|
||||
return sdmmc_get_cached_rsp(storage->sdmmc, pout, SDMMC_RSP_TYPE_3);
|
||||
return sdmmc_get_rsp(storage->sdmmc, pout, 4, SDMMC_RSP_TYPE_3);
|
||||
}
|
||||
|
||||
static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
|
||||
|
@ -561,40 +531,12 @@ int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf)
|
|||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
||||
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
|
||||
_mmc_storage_parse_ext_csd(storage, buf);
|
||||
|
||||
return _sdmmc_storage_check_card_status(tmp);
|
||||
}
|
||||
|
||||
int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 address, u32 len, void *buf)
|
||||
{
|
||||
if (!(storage->scr.cmds & BIT(2)))
|
||||
return 0;
|
||||
|
||||
sdmmc_cmd_t cmdbuf;
|
||||
|
||||
u32 arg = fno << 27 | page << 18 | address << 9 | (len - 1);
|
||||
|
||||
sdmmc_init_cmd(&cmdbuf, SD_READ_EXTR_SINGLE, arg, SDMMC_RSP_TYPE_1, 0);
|
||||
|
||||
sdmmc_req_t reqbuf;
|
||||
reqbuf.buf = buf;
|
||||
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
|
||||
reqbuf.num_sectors = 1;
|
||||
reqbuf.is_write = 0;
|
||||
reqbuf.is_multi_block = 0;
|
||||
reqbuf.is_auto_stop_trn = 0;
|
||||
|
||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
||||
|
||||
return _sdmmc_storage_check_card_status(tmp);
|
||||
}
|
||||
|
||||
static int _mmc_storage_switch(sdmmc_storage_t *storage, u32 arg)
|
||||
{
|
||||
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SWITCH, arg, 1, R1_SKIP_STATE_CHECK);
|
||||
|
@ -841,7 +783,7 @@ static int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp
|
|||
}
|
||||
|
||||
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
|
||||
void _sd_storage_debug_print_cid(const u32 *raw_cid)
|
||||
void _sd_storage_debug_print_cid(u32 *raw_cid)
|
||||
{
|
||||
gfx_printf("Card Identification\n");
|
||||
|
||||
|
@ -857,7 +799,7 @@ void _sd_storage_debug_print_cid(const u32 *raw_cid)
|
|||
gfx_printf("--RSVD-- %X\n", unstuff_bits(raw_cid, 20, 4));
|
||||
}
|
||||
|
||||
void _sd_storage_debug_print_csd(const u32 *raw_csd)
|
||||
void _sd_storage_debug_print_csd(u32 *raw_csd)
|
||||
{
|
||||
gfx_printf("\n");
|
||||
|
||||
|
@ -871,7 +813,7 @@ void _sd_storage_debug_print_csd(const u32 *raw_csd)
|
|||
gfx_printf("WRITE_BLK_MISALIGN: %X\n", unstuff_bits(raw_csd, 78, 1));
|
||||
gfx_printf("READ_BLK_MISALIGN: %X\n", unstuff_bits(raw_csd, 77, 1));
|
||||
gfx_printf("DSR_IMP: %X\n", unstuff_bits(raw_csd, 76, 1));
|
||||
gfx_printf("C_SIZE: %06X\n", unstuff_bits(raw_csd, 48, 28)); // CSD 3 (SDUC).
|
||||
gfx_printf("C_SIZE: %06X\n", unstuff_bits(raw_csd, 48, 22));
|
||||
|
||||
gfx_printf("ERASE_BLK_LEN: %X\n", unstuff_bits(raw_csd, 46, 1));
|
||||
gfx_printf("SECTOR_SIZE: %02X\n", unstuff_bits(raw_csd, 39, 6));
|
||||
|
@ -888,13 +830,13 @@ void _sd_storage_debug_print_csd(const u32 *raw_csd)
|
|||
gfx_printf("TMP_WRITE_PROTECT: %X\n", unstuff_bits(raw_csd, 12, 1));
|
||||
gfx_printf("FILE_FORMAT: %X\n", unstuff_bits(raw_csd, 10, 2));
|
||||
|
||||
gfx_printf("--RSVD-- %02X %X %X %02X %X\n",
|
||||
unstuff_bits(raw_csd, 120, 6),
|
||||
gfx_printf("--RSVD-- %02X %02X %X %X %02X %X\n",
|
||||
unstuff_bits(raw_csd, 120, 6), unstuff_bits(raw_csd, 70, 6),
|
||||
unstuff_bits(raw_csd, 47, 1), unstuff_bits(raw_csd, 29, 2),
|
||||
unstuff_bits(raw_csd, 16, 5), unstuff_bits(raw_csd, 8, 2));
|
||||
}
|
||||
|
||||
void _sd_storage_debug_print_scr(const u32 *raw_scr)
|
||||
void _sd_storage_debug_print_scr(u32 *raw_scr)
|
||||
{
|
||||
u32 resp[4];
|
||||
memcpy(&resp[2], raw_scr, 8);
|
||||
|
@ -915,7 +857,7 @@ void _sd_storage_debug_print_scr(const u32 *raw_scr)
|
|||
gfx_printf("--RSVD-- %X\n", unstuff_bits(resp, 36, 2));
|
||||
}
|
||||
|
||||
void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
|
||||
void _sd_storage_debug_print_ssr(u8 *raw_ssr)
|
||||
{
|
||||
u32 raw_ssr0[4]; // 511:384.
|
||||
u32 raw_ssr1[4]; // 383:256.
|
||||
|
@ -928,39 +870,39 @@ void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
|
|||
|
||||
gfx_printf("\nSD Status:\n");
|
||||
|
||||
gfx_printf("DAT_BUS_WIDTH: %X\n", unstuff_bits(raw_ssr0, 510, 2));
|
||||
gfx_printf("SECURED_MODE: %X\n", unstuff_bits(raw_ssr0, 509, 1));
|
||||
gfx_printf("SECURITY_FUNCTIONS: %02X\n", unstuff_bits(raw_ssr0, 502, 6));
|
||||
gfx_printf("SD_CARD_TYPE: %04X\n", unstuff_bits(raw_ssr0, 480, 16));
|
||||
gfx_printf("SZ_OF_PROTECTED_AREA: %08X\n", unstuff_bits(raw_ssr0, 448, 32));
|
||||
gfx_printf("SPEED_CLASS: %02X\n", unstuff_bits(raw_ssr0, 440, 8));
|
||||
gfx_printf("PERFORMANCE_MOVE: %02X\n", unstuff_bits(raw_ssr0, 432, 8));
|
||||
gfx_printf("AU_SIZE: %X\n", unstuff_bits(raw_ssr0, 428, 4));
|
||||
gfx_printf("ERAZE_SIZE: %04X\n", unstuff_bits(raw_ssr0, 408, 16));
|
||||
gfx_printf("ERASE_TIMEOUT: %02X\n", unstuff_bits(raw_ssr0, 402, 6));
|
||||
gfx_printf("ERASE_OFFSET: %X\n", unstuff_bits(raw_ssr0, 400, 2));
|
||||
gfx_printf("UHS_SPEED_GRADE: %X\n", unstuff_bits(raw_ssr0, 396, 4));
|
||||
gfx_printf("UHS_AU_SIZE: %X\n", unstuff_bits(raw_ssr0, 392, 4));
|
||||
gfx_printf("VIDEO_SPEED_CLASS: %02X\n", unstuff_bits(raw_ssr0, 384, 8));
|
||||
gfx_printf("DAT_BUS_WIDTH: %X\n", unstuff_bits(raw_ssr0, 510 - 384, 2));
|
||||
gfx_printf("SECURED_MODE: %X\n", unstuff_bits(raw_ssr0, 509 - 384, 1));
|
||||
gfx_printf("SECURITY_FUNCTIONS: %02X\n", unstuff_bits(raw_ssr0, 502 - 384, 6));
|
||||
gfx_printf("SD_CARD_TYPE: %04X\n", unstuff_bits(raw_ssr0, 480 - 384, 16));
|
||||
gfx_printf("SZ_OF_PROTECTED_AREA: %08X\n", unstuff_bits(raw_ssr0, 448 - 384, 32));
|
||||
gfx_printf("SPEED_CLASS: %02X\n", unstuff_bits(raw_ssr0, 440 - 384, 8));
|
||||
gfx_printf("PERFORMANCE_MOVE: %02X\n", unstuff_bits(raw_ssr0, 432 - 384, 8));
|
||||
gfx_printf("AU_SIZE: %X\n", unstuff_bits(raw_ssr0, 428 - 384, 4));
|
||||
gfx_printf("ERAZE_SIZE: %04X\n", unstuff_bits(raw_ssr0, 408 - 384, 16));
|
||||
gfx_printf("ERASE_TIMEOUT: %02X\n", unstuff_bits(raw_ssr0, 402 - 384, 6));
|
||||
gfx_printf("ERASE_OFFSET: %X\n", unstuff_bits(raw_ssr0, 400 - 384, 2));
|
||||
gfx_printf("UHS_SPEED_GRADE: %X\n", unstuff_bits(raw_ssr0, 396 - 384, 4));
|
||||
gfx_printf("UHS_AU_SIZE: %X\n", unstuff_bits(raw_ssr0, 392 - 384, 4));
|
||||
gfx_printf("VIDEO_SPEED_CLASS: %02X\n", unstuff_bits(raw_ssr0, 384 - 384, 8));
|
||||
|
||||
gfx_printf("VSC_AU_SIZE: %03X\n", unstuff_bits(raw_ssr1, 368, 10));
|
||||
gfx_printf("SUS_ADDR: %06X\n", unstuff_bits(raw_ssr1, 346, 22));
|
||||
gfx_printf("APP_PERF_CLASS: %X\n", unstuff_bits(raw_ssr1, 336, 4));
|
||||
gfx_printf("PERFORMANCE_ENHANCE: %02X\n", unstuff_bits(raw_ssr1, 328, 8));
|
||||
gfx_printf("DISCARD_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 313, 1));
|
||||
gfx_printf("FULE_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 312, 1));
|
||||
gfx_printf("VSC_AU_SIZE: %03X\n", unstuff_bits(raw_ssr1, 368 - 256, 10));
|
||||
gfx_printf("SUS_ADDR: %06X\n", unstuff_bits(raw_ssr1, 346 - 256, 22));
|
||||
gfx_printf("APP_PERF_CLASS: %X\n", unstuff_bits(raw_ssr1, 336 - 256, 4));
|
||||
gfx_printf("PERFORMANCE_ENHANCE: %02X\n", unstuff_bits(raw_ssr1, 328 - 256, 8));
|
||||
gfx_printf("DISCARD_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 313 - 256, 1));
|
||||
gfx_printf("FULE_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 312 - 256, 1));
|
||||
|
||||
gfx_printf("--RSVD-- %02X %X %02X %02X %04X\n",
|
||||
unstuff_bits(raw_ssr0, 496, 6), unstuff_bits(raw_ssr0, 424, 4),
|
||||
unstuff_bits(raw_ssr1, 378, 6), unstuff_bits(raw_ssr1, 340, 6),
|
||||
unstuff_bits(raw_ssr1, 314, 14));
|
||||
unstuff_bits(raw_ssr0, 496 - 384, 6), unstuff_bits(raw_ssr0, 424 - 384, 4),
|
||||
unstuff_bits(raw_ssr1, 378 - 256, 6), unstuff_bits(raw_ssr1, 340 - 256, 6),
|
||||
unstuff_bits(raw_ssr1, 314 - 256, 14));
|
||||
|
||||
gfx_printf("VENDOR_1: %06X %08X\n",
|
||||
unstuff_bits(raw_ssr1, 288, 24), unstuff_bits(raw_ssr1, 256, 32));
|
||||
unstuff_bits(raw_ssr1, 288 - 256, 24), unstuff_bits(raw_ssr1, 256 - 256, 32));
|
||||
|
||||
gfx_printf("VENDOR_2: %08X %08X %08X %08X\n",
|
||||
unstuff_bits(raw_ssr2, 224, 32), unstuff_bits(raw_ssr2, 192, 32),
|
||||
unstuff_bits(raw_ssr2, 160, 32), unstuff_bits(raw_ssr2, 128, 32));
|
||||
unstuff_bits(raw_ssr2, 224 - 128, 32), unstuff_bits(raw_ssr2, 192 - 128, 32),
|
||||
unstuff_bits(raw_ssr2, 160 - 128, 32), unstuff_bits(raw_ssr2, 128 - 128, 32));
|
||||
gfx_printf("VENDOR_3: %08X %08X %08X %08X\n",
|
||||
unstuff_bits(raw_ssr3, 96 - 0, 32), unstuff_bits(raw_ssr3, 64, 32),
|
||||
unstuff_bits(raw_ssr3, 32 - 0, 32), unstuff_bits(raw_ssr3, 0, 32));
|
||||
|
@ -974,19 +916,13 @@ static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc)
|
|||
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_5, 0);
|
||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||
{
|
||||
// The SD Card is version 1.X (SDSC) if there is no response.
|
||||
if (storage->sdmmc->error_sts == SDHCI_ERR_INT_CMD_TIMEOUT)
|
||||
{
|
||||
*is_sdsc = 1;
|
||||
*is_sdsc = 1; // The SD Card is version 1.X
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// For Card version >= 2.0, parse results.
|
||||
u32 resp = 0;
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_5);
|
||||
sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_5);
|
||||
|
||||
// Check if VHD was accepted and pattern was properly returned.
|
||||
if ((resp & 0xFFF) == vhd_pattern)
|
||||
|
@ -1012,7 +948,7 @@ static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, boo
|
|||
if (!_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_sdsc ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL))
|
||||
return 0;
|
||||
|
||||
return sdmmc_get_cached_rsp(storage->sdmmc, cond, SDMMC_RSP_TYPE_3);
|
||||
return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3);
|
||||
}
|
||||
|
||||
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sdsc, int bus_uhs_support)
|
||||
|
@ -1035,7 +971,7 @@ static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sdsc, int b
|
|||
storage->has_sector_access = 1;
|
||||
|
||||
// Check if card supports 1.8V signaling.
|
||||
if (cond & SD_ROCR_S18A && bus_uhs_support && !storage->is_low_voltage)
|
||||
if (cond & SD_ROCR_S18A && bus_uhs_support)
|
||||
{
|
||||
// Switch to 1.8V signaling.
|
||||
if (_sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY))
|
||||
|
@ -1079,7 +1015,7 @@ static int _sd_storage_get_rca(sdmmc_storage_t *storage)
|
|||
break;
|
||||
|
||||
u32 resp = 0;
|
||||
if (!sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_4))
|
||||
if (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_4))
|
||||
break;
|
||||
|
||||
if (resp >> 16)
|
||||
|
@ -1110,17 +1046,11 @@ static void _sd_storage_parse_scr(sdmmc_storage_t *storage)
|
|||
storage->scr.sda_vsn = unstuff_bits(resp, 56, 4);
|
||||
storage->scr.bus_widths = unstuff_bits(resp, 48, 4);
|
||||
|
||||
// If v2.0 is supported, check if Physical Layer Spec v3.0 is supported.
|
||||
/* If v2.0 is supported, check if Physical Layer Spec v3.0 is supported */
|
||||
if (storage->scr.sda_vsn == SCR_SPEC_VER_2)
|
||||
storage->scr.sda_spec3 = unstuff_bits(resp, 47, 1);
|
||||
if (storage->scr.sda_spec3)
|
||||
{
|
||||
u8 sda_spec4 = unstuff_bits(resp, 42, 1);
|
||||
if (sda_spec4)
|
||||
storage->scr.cmds = unstuff_bits(resp, 32, 4);
|
||||
else
|
||||
storage->scr.cmds = unstuff_bits(resp, 32, 2);
|
||||
}
|
||||
}
|
||||
|
||||
int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf)
|
||||
|
@ -1140,9 +1070,9 @@ int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf)
|
|||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
||||
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
|
||||
//Prepare buffer for unstuff_bits
|
||||
for (u32 i = 0; i < 8; i+=4)
|
||||
for (int i = 0; i < 8; i+=4)
|
||||
{
|
||||
storage->raw_scr[i + 3] = buf[i];
|
||||
storage->raw_scr[i + 2] = buf[i + 1];
|
||||
|
@ -1171,7 +1101,7 @@ static int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)
|
|||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
||||
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
|
||||
return _sdmmc_storage_check_card_status(tmp);
|
||||
}
|
||||
|
||||
|
@ -1195,7 +1125,7 @@ static int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int
|
|||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
||||
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
|
||||
return _sdmmc_storage_check_card_status(tmp);
|
||||
}
|
||||
|
||||
|
@ -1311,7 +1241,7 @@ static int _sd_storage_enable_DDR200(sdmmc_storage_t *storage, u8 *buf)
|
|||
|
||||
u16 total_pwr_consumption = ((u16)buf[0] << 8) | buf[1];
|
||||
DPRINTF("[SD] max power: %d mW\n", total_pwr_consumption * 3600 / 1000);
|
||||
storage->max_power = total_pwr_consumption;
|
||||
storage->card_power_limit = total_pwr_consumption;
|
||||
|
||||
if (total_pwr_consumption <= 800)
|
||||
{
|
||||
|
@ -1350,7 +1280,7 @@ static int _sd_storage_set_card_bus_speed(sdmmc_storage_t *storage, u32 hs_type,
|
|||
|
||||
u16 total_pwr_consumption = ((u16)buf[0] << 8) | buf[1];
|
||||
DPRINTF("[SD] max power: %d mW\n", total_pwr_consumption * 3600 / 1000);
|
||||
storage->max_power = total_pwr_consumption;
|
||||
storage->card_power_limit = total_pwr_consumption;
|
||||
|
||||
if (total_pwr_consumption <= 800)
|
||||
{
|
||||
|
@ -1562,10 +1492,10 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage)
|
|||
_sd_storage_debug_print_ssr(storage->raw_ssr);
|
||||
#endif
|
||||
|
||||
storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510, 2) & SD_BUS_WIDTH_4) ? 4 : 1;
|
||||
storage->ssr.protected_size = unstuff_bits(raw_ssr1, 448, 32);
|
||||
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);
|
||||
|
||||
u32 speed_class = unstuff_bits(raw_ssr1, 440, 8);
|
||||
u32 speed_class = unstuff_bits(raw_ssr1, 440 - 384, 8);
|
||||
switch(speed_class)
|
||||
{
|
||||
case 0:
|
||||
|
@ -1583,94 +1513,12 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage)
|
|||
storage->ssr.speed_class = speed_class;
|
||||
break;
|
||||
}
|
||||
storage->ssr.uhs_grade = unstuff_bits(raw_ssr1, 396, 4);
|
||||
storage->ssr.video_class = unstuff_bits(raw_ssr1, 384, 8);
|
||||
storage->ssr.app_class = unstuff_bits(raw_ssr2, 336, 4);
|
||||
storage->ssr.uhs_grade = unstuff_bits(raw_ssr1, 396 - 384, 4);
|
||||
storage->ssr.video_class = unstuff_bits(raw_ssr1, 384 - 384, 8);
|
||||
storage->ssr.app_class = unstuff_bits(raw_ssr2, 336 - 256, 4);
|
||||
|
||||
storage->ssr.au_size = unstuff_bits(raw_ssr1, 428, 4);
|
||||
storage->ssr.uhs_au_size = unstuff_bits(raw_ssr1, 392, 4);
|
||||
|
||||
storage->ssr.perf_enhance = unstuff_bits(raw_ssr2, 328, 8);
|
||||
}
|
||||
|
||||
int sd_storage_parse_perf_enhance(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u8 *buf)
|
||||
{
|
||||
// Check status reg for support.
|
||||
storage->ser.cache = (storage->ssr.perf_enhance >> 2) & BIT(0);
|
||||
storage->ser.cmdq = (storage->ssr.perf_enhance >> 3) & 0x1F;
|
||||
|
||||
if (!sd_storage_get_ext_reg(storage, fno, page, offset, 512, buf))
|
||||
{
|
||||
storage->ser.cache_ext = 0;
|
||||
storage->ser.cmdq_ext = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
storage->ser.cache_ext = buf[4] & BIT(0);
|
||||
storage->ser.cmdq_ext = buf[6] & 0x1F;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _sd_storage_parse_ext_reg(sdmmc_storage_t *storage, u8 *buf, u16 *addr_next)
|
||||
{
|
||||
u16 addr = *addr_next;
|
||||
|
||||
// Address to the next extension.
|
||||
*addr_next = (buf[addr + 41] << 8) | buf[addr + 40];
|
||||
|
||||
u16 sfc = (buf[addr + 1] << 8) | buf[addr];
|
||||
|
||||
u32 reg_sets = buf[addr + 42];
|
||||
|
||||
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
|
||||
for (u32 i = 0; i < reg_sets; i++)
|
||||
{
|
||||
u32 reg_set_addr;
|
||||
memcpy(®_set_addr, &buf[addr + 44 + 4 * i], 4);
|
||||
u16 off = reg_set_addr & 0x1FF;
|
||||
u8 page = reg_set_addr >> 9 & 0xFF;
|
||||
u8 fno = reg_set_addr >> 18 & 0xFF;
|
||||
gfx_printf("Addr: %04X sfc:%02X - fno:%02X, page:%02X, off:%04X\n", addr, sfc, fno, page, off);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Parse Performance Enhance.
|
||||
if (sfc == 2 && reg_sets == 1)
|
||||
{
|
||||
u32 reg_set0_addr;
|
||||
memcpy(®_set0_addr, &buf[addr + 44], 4);
|
||||
u16 off = reg_set0_addr & 0x1FF;
|
||||
u8 page = reg_set0_addr >> 9 & 0xFF;
|
||||
u8 fno = reg_set0_addr >> 18 & 0xFF;
|
||||
|
||||
if (sd_storage_parse_perf_enhance(storage, fno, page, off, buf))
|
||||
storage->ser.valid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sd_storage_get_ext_regs(sdmmc_storage_t *storage, u8 *buf)
|
||||
{
|
||||
DREGPRINTF("SD Extension Registers:\n\n");
|
||||
|
||||
if (!(storage->scr.cmds & BIT(2)))
|
||||
{
|
||||
DREGPRINTF("Not Supported!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sd_storage_get_ext_reg(storage, 0, 0, 0, 512, buf))
|
||||
{
|
||||
DREGPRINTF("Failed to get general info!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
u16 size = (buf[3] << 8) | buf[2];
|
||||
u16 addr_next = 16;
|
||||
u32 num_ext = buf[4];
|
||||
for (u32 i = 0; i < num_ext && addr_next < size; i++)
|
||||
_sd_storage_parse_ext_reg(storage, buf, &addr_next);
|
||||
storage->ssr.au_size = unstuff_bits(raw_ssr1, 428 - 384, 4);
|
||||
storage->ssr.uhs_au_size = unstuff_bits(raw_ssr1, 392 - 384, 4);
|
||||
}
|
||||
|
||||
int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf)
|
||||
|
@ -1696,10 +1544,10 @@ int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf)
|
|||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
||||
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
|
||||
|
||||
// Convert buffer to LE.
|
||||
for (u32 i = 0; i < SDMMC_CMD_BLOCKSIZE; i += 4)
|
||||
for (int i = 0; i < SDMMC_CMD_BLOCKSIZE; i += 4)
|
||||
{
|
||||
storage->raw_ssr[i + 3] = buf[i];
|
||||
storage->raw_ssr[i + 2] = buf[i + 1];
|
||||
|
@ -1796,7 +1644,7 @@ void sdmmc_storage_init_wait_sd()
|
|||
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
bool is_sdsc = 0;
|
||||
int is_sdsc = 0;
|
||||
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
|
||||
bool bus_uhs_support = _sdmmc_storage_get_bus_uhs_support(bus_width, type);
|
||||
|
||||
|
@ -1941,7 +1789,7 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_1))
|
||||
if (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_1))
|
||||
return 0;
|
||||
if (!_sdmmc_storage_check_card_status(resp))
|
||||
return 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2022 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,
|
||||
|
@ -174,30 +174,20 @@ typedef struct _sd_ssr
|
|||
u8 app_class;
|
||||
u8 au_size;
|
||||
u8 uhs_au_size;
|
||||
u8 perf_enhance;
|
||||
u32 protected_size;
|
||||
} sd_ssr_t;
|
||||
|
||||
typedef struct _sd_ext_reg_t
|
||||
{
|
||||
u8 cmdq;
|
||||
u8 cmdq_ext;
|
||||
u8 cache;
|
||||
u8 cache_ext;
|
||||
int valid;
|
||||
} sd_ext_reg_t;
|
||||
|
||||
/*! SDMMC storage context. */
|
||||
typedef struct _sdmmc_storage_t
|
||||
{
|
||||
sdmmc_t *sdmmc;
|
||||
int initialized;
|
||||
int is_low_voltage;
|
||||
int has_sector_access;
|
||||
u32 rca;
|
||||
int has_sector_access;
|
||||
u32 sec_cnt;
|
||||
int is_low_voltage;
|
||||
u32 partition;
|
||||
u32 max_power;
|
||||
int initialized;
|
||||
u32 card_power_limit;
|
||||
u8 raw_cid[0x10];
|
||||
u8 raw_csd[0x10];
|
||||
u8 raw_scr[8];
|
||||
|
@ -207,7 +197,6 @@ typedef struct _sdmmc_storage_t
|
|||
mmc_ext_csd_t ext_csd;
|
||||
sd_scr_t scr;
|
||||
sd_ssr_t ssr;
|
||||
sd_ext_reg_t ser;
|
||||
} sdmmc_storage_t;
|
||||
|
||||
typedef struct _sd_func_modes_t
|
||||
|
@ -232,13 +221,9 @@ int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf);
|
|||
|
||||
int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf);
|
||||
|
||||
int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u32 len, void *buf);
|
||||
int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *functions);
|
||||
int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf);
|
||||
int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf);
|
||||
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage);
|
||||
|
||||
void sd_storage_get_ext_regs(sdmmc_storage_t *storage, u8 *buf);
|
||||
int sd_storage_parse_perf_enhance(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u8 *buf);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -212,7 +212,7 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
|
|||
// Use 0x1F mask for all.
|
||||
u8 autocal_pu_status = sdmmc->regs->autocalsts & 0x1F;
|
||||
if (!autocal_pu_status)
|
||||
EPRINTFARGS("SDMMC%d: Comp Pad open!", sdmmc->id + 1); // Or resistance is extreme.
|
||||
EPRINTFARGS("SDMMC%d: Comp Pad open!", sdmmc->id + 1);
|
||||
else if (autocal_pu_status == 0x1F)
|
||||
EPRINTFARGS("SDMMC%d: Comp Pad short to gnd!", sdmmc->id + 1);
|
||||
#endif
|
||||
|
@ -394,8 +394,8 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
|||
|
||||
static void _sdmmc_card_clock_enable(sdmmc_t *sdmmc)
|
||||
{
|
||||
// Recalibrate periodically if needed.
|
||||
if (sdmmc->periodic_calibration && !sdmmc->powersave_enabled)
|
||||
// Recalibrate conditionally.
|
||||
if (sdmmc->manual_cal && !sdmmc->powersave_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
if (!sdmmc->powersave_enabled)
|
||||
|
@ -414,8 +414,8 @@ static void _sdmmc_card_clock_disable(sdmmc_t *sdmmc)
|
|||
|
||||
void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable)
|
||||
{
|
||||
// Recalibrate periodically if needed.
|
||||
if (sdmmc->periodic_calibration && !powersave_enable && sdmmc->card_clock_enabled)
|
||||
// Recalibrate periodically for SDMMC1.
|
||||
if (sdmmc->manual_cal && !powersave_enable && sdmmc->card_clock_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
sdmmc->powersave_enabled = powersave_enable;
|
||||
|
@ -431,7 +431,7 @@ void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable)
|
|||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
}
|
||||
|
||||
static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
|
||||
static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
@ -439,14 +439,33 @@ static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
|
|||
case SDMMC_RSP_TYPE_3:
|
||||
case SDMMC_RSP_TYPE_4:
|
||||
case SDMMC_RSP_TYPE_5:
|
||||
rsp[0] = sdmmc->regs->rspreg[0];
|
||||
if (size < 4)
|
||||
return 0;
|
||||
rsp[0] = sdmmc->regs->rspreg0;
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_2:
|
||||
if (size < 0x10)
|
||||
return 0;
|
||||
// CRC is stripped, so shifting is needed.
|
||||
for (u32 i = 0; i < 4; i++)
|
||||
u32 tempreg;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
u32 tempreg = sdmmc->regs->rspreg[3 - i];
|
||||
switch(i)
|
||||
{
|
||||
case 0:
|
||||
tempreg = sdmmc->regs->rspreg3;
|
||||
break;
|
||||
case 1:
|
||||
tempreg = sdmmc->regs->rspreg2;
|
||||
break;
|
||||
case 2:
|
||||
tempreg = sdmmc->regs->rspreg1;
|
||||
break;
|
||||
case 3:
|
||||
tempreg = sdmmc->regs->rspreg0;
|
||||
break;
|
||||
}
|
||||
rsp[i] = tempreg << 8;
|
||||
|
||||
if (i != 0)
|
||||
|
@ -461,7 +480,7 @@ static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int sdmmc_get_cached_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
|
||||
int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
{
|
||||
if (!rsp || sdmmc->expected_rsp_type != type)
|
||||
return 0;
|
||||
|
@ -472,12 +491,18 @@ int sdmmc_get_cached_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
|
|||
case SDMMC_RSP_TYPE_3:
|
||||
case SDMMC_RSP_TYPE_4:
|
||||
case SDMMC_RSP_TYPE_5:
|
||||
if (size < 4)
|
||||
return 0;
|
||||
rsp[0] = sdmmc->rsp[0];
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_2:
|
||||
for (u32 i = 0; i < 4; i++)
|
||||
rsp[i] = sdmmc->rsp[i];
|
||||
if (size < 16)
|
||||
return 0;
|
||||
rsp[0] = sdmmc->rsp[0];
|
||||
rsp[1] = sdmmc->rsp[1];
|
||||
rsp[2] = sdmmc->rsp[2];
|
||||
rsp[3] = sdmmc->rsp[3];
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -550,7 +575,7 @@ static int _sdmmc_setup_read_small_block(sdmmc_t *sdmmc)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int _sdmmc_send_cmd(sdmmc_t *sdmmc, const sdmmc_cmd_t *cmd, bool is_data_present)
|
||||
static int _sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_present)
|
||||
{
|
||||
u16 cmdflags = 0;
|
||||
|
||||
|
@ -890,7 +915,6 @@ static void _sdmmc_enable_interrupts(sdmmc_t *sdmmc)
|
|||
sdmmc->regs->errintstsen |= SDHCI_ERR_INT_ALL_EXCEPT_ADMA_BUSPWR;
|
||||
sdmmc->regs->norintsts = sdmmc->regs->norintsts;
|
||||
sdmmc->regs->errintsts = sdmmc->regs->errintsts;
|
||||
sdmmc->error_sts = 0;
|
||||
}
|
||||
|
||||
static void _sdmmc_mask_interrupts(sdmmc_t *sdmmc)
|
||||
|
@ -913,9 +937,8 @@ static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
|||
if (norintsts & SDHCI_INT_ERROR)
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTFARGS("SDMMC%d: intsts %08X, errintsts %08X", sdmmc->id + 1, norintsts, errintsts);
|
||||
EPRINTFARGS("SDMMC%d: norintsts %08X, errintsts %08X", sdmmc->id + 1, norintsts, errintsts);
|
||||
#endif
|
||||
sdmmc->error_sts = errintsts;
|
||||
sdmmc->regs->errintsts = errintsts;
|
||||
return SDMMC_MASKINT_ERROR;
|
||||
}
|
||||
|
@ -970,7 +993,7 @@ static int _sdmmc_stop_transmission_inner(sdmmc_t *sdmmc, u32 *rsp)
|
|||
if (!result)
|
||||
return 0;
|
||||
|
||||
_sdmmc_cache_rsp(sdmmc, rsp, SDMMC_RSP_TYPE_1);
|
||||
_sdmmc_cache_rsp(sdmmc, rsp, 4, SDMMC_RSP_TYPE_1);
|
||||
|
||||
return _sdmmc_wait_card_busy(sdmmc);
|
||||
}
|
||||
|
@ -980,8 +1003,8 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
|
|||
if (!sdmmc->card_clock_enabled)
|
||||
return 0;
|
||||
|
||||
// Recalibrate periodically if needed.
|
||||
if (sdmmc->periodic_calibration && sdmmc->powersave_enabled)
|
||||
// Recalibrate periodically for SDMMC1.
|
||||
if (sdmmc->manual_cal && sdmmc->powersave_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
bool should_disable_sd_clock = false;
|
||||
|
@ -1002,7 +1025,7 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
|
|||
return result;
|
||||
}
|
||||
|
||||
static int _sdmmc_config_sdma(sdmmc_t *sdmmc, u32 *blkcnt_out, const sdmmc_req_t *req)
|
||||
static int _sdmmc_config_sdma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
||||
{
|
||||
if (!req->blksize || !req->num_sectors)
|
||||
return 0;
|
||||
|
@ -1097,7 +1120,7 @@ static int _sdmmc_update_sdma(sdmmc_t *sdmmc)
|
|||
|
||||
static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out)
|
||||
{
|
||||
bool has_req_or_check_busy = req || cmd->check_busy;
|
||||
int has_req_or_check_busy = req || cmd->check_busy;
|
||||
if (!_sdmmc_wait_cmd_data_inhibit(sdmmc, has_req_or_check_busy))
|
||||
return 0;
|
||||
|
||||
|
@ -1135,13 +1158,13 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
|||
EPRINTFARGS("SDMMC%d: Transfer error!", sdmmc->id + 1);
|
||||
#endif
|
||||
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
||||
sdmmc->regs->rspreg[0], sdmmc->regs->rspreg[1], sdmmc->regs->rspreg[2], sdmmc->regs->rspreg[3]);
|
||||
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
|
||||
if (result)
|
||||
{
|
||||
if (cmd->rsp_type)
|
||||
{
|
||||
sdmmc->expected_rsp_type = cmd->rsp_type;
|
||||
result = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, cmd->rsp_type);
|
||||
result = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type);
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
if (!result)
|
||||
EPRINTFARGS("SDMMC%d: Unknown response type!", sdmmc->id + 1);
|
||||
|
@ -1170,10 +1193,10 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
|||
*blkcnt_out = blkcnt;
|
||||
|
||||
if (req->is_auto_stop_trn)
|
||||
sdmmc->stop_trn_rsp = sdmmc->regs->rspreg[3];
|
||||
sdmmc->rsp3 = sdmmc->regs->rspreg3;
|
||||
}
|
||||
|
||||
if (has_req_or_check_busy)
|
||||
if (cmd->check_busy || req)
|
||||
{
|
||||
result = _sdmmc_wait_card_busy(sdmmc);
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
|
@ -1225,7 +1248,7 @@ static void _sdmmc_config_sdmmc1_pads(bool discharge)
|
|||
u32 level = GPIO_LOW;
|
||||
u32 output = GPIO_OUTPUT_DISABLE;
|
||||
|
||||
// Set values for discharging.
|
||||
// Set values for dicharging.
|
||||
if (discharge)
|
||||
{
|
||||
function = GPIO_MODE_GPIO;
|
||||
|
@ -1281,7 +1304,7 @@ static int _sdmmc_config_sdmmc1(bool t210b01)
|
|||
// Enable SD card power. Powers LDO2 also.
|
||||
PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2;
|
||||
gpio_direction_output(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH);
|
||||
usleep(10000); // Minimum 3 to 10 ms.
|
||||
usleep(10000);
|
||||
|
||||
// Inform IO pads that voltage is gonna be 3.3V.
|
||||
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_33V_SDMMC1;
|
||||
|
@ -1362,7 +1385,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
|
|||
if (sdmmc->t210b01)
|
||||
vref_sel = 0;
|
||||
else
|
||||
sdmmc->periodic_calibration = 1;
|
||||
sdmmc->manual_cal = 1;
|
||||
break;
|
||||
|
||||
case SDMMC_2:
|
||||
|
@ -1396,8 +1419,6 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
|
|||
if (!_sdmmc_autocal_config_offset(sdmmc, power))
|
||||
return 0;
|
||||
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
// Calibrate pads.
|
||||
_sdmmc_autocal_execute(sdmmc, power);
|
||||
|
||||
|
@ -1485,8 +1506,8 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b
|
|||
if (!sdmmc->card_clock_enabled)
|
||||
return 0;
|
||||
|
||||
// Recalibrate periodically if needed.
|
||||
if (sdmmc->periodic_calibration && sdmmc->powersave_enabled)
|
||||
// Recalibrate periodically for SDMMC1.
|
||||
if (sdmmc->manual_cal && sdmmc->powersave_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
int should_disable_sd_clock = 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2023 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,
|
||||
|
@ -101,7 +101,6 @@
|
|||
#define SDHCI_CMD_TYPE_SUSPEND (1U << 6)
|
||||
#define SDHCI_CMD_TYPE_RESUME (2U << 6)
|
||||
#define SDHCI_CMD_TYPE_ABORT (3U << 6)
|
||||
#define SDHCI_CMD_SPI_CS_LOW BIT(7)
|
||||
#define SDHCI_CMD_IDX(cmd) ((cmd) << 8)
|
||||
|
||||
|
||||
|
@ -171,10 +170,10 @@
|
|||
#define SDHCI_INT_ERROR BIT(15)
|
||||
|
||||
/*! SDMMC error interrupt status and control. 0x32/0x36. */
|
||||
#define SDHCI_ERR_INT_CMD_TIMEOUT BIT(0)
|
||||
#define SDHCI_ERR_INT_CMD_CRC BIT(1)
|
||||
#define SDHCI_ERR_INT_CMD_END_BIT BIT(2)
|
||||
#define SDHCI_ERR_INT_CMD_INDEX BIT(3)
|
||||
#define SDHCI_ERR_INT_TIMEOUT BIT(0)
|
||||
#define SDHCI_ERR_INT_CRC BIT(1)
|
||||
#define SDHCI_ERR_INT_END_BIT BIT(2)
|
||||
#define SDHCI_ERR_INT_INDEX BIT(3)
|
||||
#define SDHCI_ERR_INT_DATA_TIMEOUT BIT(4)
|
||||
#define SDHCI_ERR_INT_DATA_CRC BIT(5)
|
||||
#define SDHCI_ERR_INT_DATA_END_BIT BIT(6)
|
||||
|
@ -191,8 +190,8 @@
|
|||
#define SDHCI_ERR_INT_ALL_EXCEPT_ADMA_BUSPWR \
|
||||
(SDHCI_ERR_INT_AUTO_CMD12 | SDHCI_ERR_INT_DATA_END_BIT | \
|
||||
SDHCI_ERR_INT_DATA_CRC | SDHCI_ERR_INT_DATA_TIMEOUT | \
|
||||
SDHCI_ERR_INT_CMD_INDEX | SDHCI_ERR_INT_CMD_END_BIT | \
|
||||
SDHCI_ERR_INT_CMD_CRC | SDHCI_ERR_INT_CMD_TIMEOUT)
|
||||
SDHCI_ERR_INT_INDEX | SDHCI_ERR_INT_END_BIT | \
|
||||
SDHCI_ERR_INT_CRC | SDHCI_ERR_INT_TIMEOUT)
|
||||
|
||||
/*! Host Capability 1. 0x40. */
|
||||
#define SDHCI_CAP_TM_CLK_FREQ_MASK 0x3F
|
||||
|
@ -286,15 +285,14 @@ typedef struct _sdmmc_t
|
|||
u32 card_clock;
|
||||
u32 clock_stopped;
|
||||
int powersave_enabled;
|
||||
int periodic_calibration;
|
||||
int manual_cal;
|
||||
int card_clock_enabled;
|
||||
int venclkctl_set;
|
||||
u32 venclkctl_tap;
|
||||
u32 expected_rsp_type;
|
||||
u32 dma_addr_next;
|
||||
u32 rsp[4];
|
||||
u32 stop_trn_rsp;
|
||||
u32 error_sts;
|
||||
u32 rsp3;
|
||||
int t210b01;
|
||||
} sdmmc_t;
|
||||
|
||||
|
@ -325,7 +323,7 @@ void sdmmc_save_tap_value(sdmmc_t *sdmmc);
|
|||
void sdmmc_setup_drv_type(sdmmc_t *sdmmc, u32 type);
|
||||
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type);
|
||||
void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable);
|
||||
int sdmmc_get_cached_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type);
|
||||
int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type);
|
||||
int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd);
|
||||
int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp);
|
||||
bool sdmmc_get_sd_inserted();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2023 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,
|
||||
|
@ -39,7 +39,10 @@ typedef struct _t210_sdmmc_t
|
|||
/* 0x08 */ vu32 argument;
|
||||
/* 0x0C */ vu16 trnmod;
|
||||
/* 0x0E */ vu16 cmdreg;
|
||||
/* 0x10 */ vu32 rspreg[4];
|
||||
/* 0x10 */ vu32 rspreg0;
|
||||
/* 0x14 */ vu32 rspreg1;
|
||||
/* 0x18 */ vu32 rspreg2;
|
||||
/* 0x1C */ vu32 rspreg3;
|
||||
/* 0x20 */ vu32 bdata; // Buffer data port.
|
||||
/* 0x24 */ vu32 prnsts;
|
||||
/* 0x28 */ vu8 hostctl;
|
||||
|
|
|
@ -99,7 +99,7 @@ typedef struct _usb_cfg_descr_t
|
|||
u8 bConfigurationValue; // Value of this configuration (1 based).
|
||||
u8 iConfiguration; // Index of String Descriptor describing the configuration.
|
||||
u8 bmAttributes; // Configuration characteristics.
|
||||
u8 bMaxPower; // Maximum power consumed by this configuration. In 2mA (usb2) or 8mA (usb3).
|
||||
u8 bMaxPower; // Maximum power consumed by this configuration.
|
||||
} __attribute__((packed)) usb_cfg_descr_t;
|
||||
|
||||
/* Interface descriptor structure */
|
||||
|
|
|
@ -80,7 +80,7 @@ enum {
|
|||
static jc_cal_t jc_cal_ctx;
|
||||
static usb_ops_t usb_ops;
|
||||
|
||||
static bool _jc_calibration(const jc_gamepad_rpt_t *jc_pad)
|
||||
static bool _jc_calibration(jc_gamepad_rpt_t *jc_pad)
|
||||
{
|
||||
// Calibrate left stick.
|
||||
if (jc_cal_ctx.cl_step != JC_CAL_MAX_STEPS)
|
||||
|
|
|
@ -1936,9 +1936,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
|||
|
||||
_handle_ep0_ctrl(&ums);
|
||||
|
||||
_parse_scsi_cmd(&ums, &ums.bulk_ctxt);
|
||||
|
||||
if (ums.state > UMS_STATE_NORMAL)
|
||||
if (_parse_scsi_cmd(&ums, &ums.bulk_ctxt) || (ums.state > UMS_STATE_NORMAL))
|
||||
continue;
|
||||
|
||||
_handle_ep0_ctrl(&ums);
|
||||
|
|
|
@ -1011,7 +1011,7 @@ static void _xusb_device_power_down()
|
|||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_XUSB);
|
||||
}
|
||||
|
||||
static int _xusb_queue_trb(u32 ep_idx, const void *trb, bool ring_doorbell)
|
||||
static int _xusb_queue_trb(u32 ep_idx, void *trb, bool ring_doorbell)
|
||||
{
|
||||
int res = USB_RES_OK;
|
||||
data_trb_t *next_trb;
|
||||
|
@ -1226,7 +1226,7 @@ static int _xusb_wait_ep_stopped(u32 endpoint)
|
|||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
static int _xusb_handle_transfer_event(const transfer_event_trb_t *trb)
|
||||
static int _xusb_handle_transfer_event(transfer_event_trb_t *trb)
|
||||
{
|
||||
// Advance dequeue list.
|
||||
data_trb_t *next_trb;
|
||||
|
@ -1461,7 +1461,7 @@ static int _xusb_handle_get_ep_status(u32 ep_idx)
|
|||
return _xusb_issue_data_trb(xusb_ep_status_descriptor, 2, USB_DIR_IN);
|
||||
}
|
||||
|
||||
static int _xusb_handle_get_class_request(const usb_ctrl_setup_t *ctrl_setup)
|
||||
static int _xusb_handle_get_class_request(usb_ctrl_setup_t *ctrl_setup)
|
||||
{
|
||||
u8 _bRequest = ctrl_setup->bRequest;
|
||||
u16 _wIndex = ctrl_setup->wIndex;
|
||||
|
@ -1492,7 +1492,7 @@ stall:
|
|||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
static int _xusb_handle_get_descriptor(usb_ctrl_setup_t *ctrl_setup)
|
||||
{
|
||||
u32 size;
|
||||
void *descriptor;
|
||||
|
@ -1621,7 +1621,7 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
|||
return _xusb_issue_data_trb(descriptor, size, USB_DIR_IN);
|
||||
}
|
||||
|
||||
static void _xusb_handle_set_request_dev_address(const usb_ctrl_setup_t *ctrl_setup)
|
||||
static void _xusb_handle_set_request_dev_address(usb_ctrl_setup_t *ctrl_setup)
|
||||
{
|
||||
u32 addr = ctrl_setup->wValue & 0xFF;
|
||||
|
||||
|
@ -1633,7 +1633,7 @@ static void _xusb_handle_set_request_dev_address(const usb_ctrl_setup_t *ctrl_se
|
|||
usbd_xotg->device_state = XUSB_ADDRESSED_STS_WAIT;
|
||||
}
|
||||
|
||||
static void _xusb_handle_set_request_configuration(const usb_ctrl_setup_t *ctrl_setup)
|
||||
static void _xusb_handle_set_request_configuration(usb_ctrl_setup_t *ctrl_setup)
|
||||
{
|
||||
usbd_xotg->config_num = ctrl_setup->wValue;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -17,23 +17,21 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "dirlist.h"
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include <mem/heap.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
dirlist_t *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs)
|
||||
#define MAX_ENTRIES 64
|
||||
|
||||
char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs)
|
||||
{
|
||||
int res = 0;
|
||||
u32 k = 0;
|
||||
u32 i = 0, j = 0, k = 0;
|
||||
DIR dir;
|
||||
FILINFO fno;
|
||||
|
||||
dirlist_t *dir_entries = (dirlist_t *)malloc(sizeof(dirlist_t));
|
||||
|
||||
// Setup pointer tree.
|
||||
for (u32 i = 0; i < DIR_MAX_ENTRIES; i++)
|
||||
dir_entries->name[i] = &dir_entries->data[i * 256];
|
||||
char *dir_entries = (char *)zalloc(MAX_ENTRIES * 256);
|
||||
char *temp = (char *)zalloc(256);
|
||||
|
||||
if (!pattern && !f_opendir(&dir, directory))
|
||||
{
|
||||
|
@ -49,8 +47,9 @@ dirlist_t *dirlist(const char *directory, const char *pattern, bool includeHidde
|
|||
{
|
||||
if ((fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
|
||||
{
|
||||
strcpy(&dir_entries->data[k * 256], fno.fname);
|
||||
if (++k >= DIR_MAX_ENTRIES)
|
||||
strcpy(dir_entries + (k * 256), fno.fname);
|
||||
k++;
|
||||
if (k > (MAX_ENTRIES - 1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +62,9 @@ dirlist_t *dirlist(const char *directory, const char *pattern, bool includeHidde
|
|||
{
|
||||
if (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
|
||||
{
|
||||
strcpy(&dir_entries->data[k * 256], fno.fname);
|
||||
if (++k >= DIR_MAX_ENTRIES)
|
||||
strcpy(dir_entries + (k * 256), fno.fname);
|
||||
k++;
|
||||
if (k > (MAX_ENTRIES - 1))
|
||||
break;
|
||||
}
|
||||
res = f_findnext(&dir, &fno);
|
||||
|
@ -74,27 +74,27 @@ dirlist_t *dirlist(const char *directory, const char *pattern, bool includeHidde
|
|||
|
||||
if (!k)
|
||||
{
|
||||
free(temp);
|
||||
free(dir_entries);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Terminate name list.
|
||||
dir_entries->name[k] = NULL;
|
||||
// Reorder ini files by ASCII ordering.
|
||||
for (i = 0; i < k - 1 ; i++)
|
||||
{
|
||||
for (j = i + 1; j < k; j++)
|
||||
{
|
||||
if (strcmp(&dir_entries[i * 256], &dir_entries[j * 256]) > 0)
|
||||
{
|
||||
strcpy(temp, &dir_entries[i * 256]);
|
||||
strcpy(&dir_entries[i * 256], &dir_entries[j * 256]);
|
||||
strcpy(&dir_entries[j * 256], temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reorder ini files Alphabetically.
|
||||
for (u32 i = 0; i < k - 1 ; i++)
|
||||
{
|
||||
for (u32 j = i + 1; j < k; j++)
|
||||
{
|
||||
if (strcasecmp(dir_entries->name[i], dir_entries->name[j]) > 0)
|
||||
{
|
||||
char *tmp = dir_entries->name[i];
|
||||
dir_entries->name[i] = dir_entries->name[j];
|
||||
dir_entries->name[j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(temp);
|
||||
|
||||
return dir_entries;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -16,12 +16,4 @@
|
|||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define DIR_MAX_ENTRIES 64
|
||||
|
||||
typedef struct _dirlist_t
|
||||
{
|
||||
char *name[DIR_MAX_ENTRIES];
|
||||
char data[DIR_MAX_ENTRIES * 256];
|
||||
} dirlist_t;
|
||||
|
||||
dirlist_t *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs);
|
||||
char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs);
|
||||
|
|
|
@ -53,7 +53,7 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type
|
|||
return csec;
|
||||
}
|
||||
|
||||
int ini_parse(link_t *dst, const char *ini_path, bool is_dir)
|
||||
int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
{
|
||||
FIL fp;
|
||||
u32 lblen;
|
||||
|
@ -62,7 +62,7 @@ int ini_parse(link_t *dst, const char *ini_path, bool is_dir)
|
|||
ini_sec_t *csec = NULL;
|
||||
|
||||
char *lbuf = NULL;
|
||||
dirlist_t *filelist = NULL;
|
||||
char *filelist = NULL;
|
||||
char *filename = (char *)malloc(256);
|
||||
|
||||
strcpy(filename, ini_path);
|
||||
|
@ -85,9 +85,9 @@ int ini_parse(link_t *dst, const char *ini_path, bool is_dir)
|
|||
// Copy ini filename in path string.
|
||||
if (is_dir)
|
||||
{
|
||||
if (filelist->name[k])
|
||||
if (filelist[k * 256])
|
||||
{
|
||||
strcpy(filename + pathlen, filelist->name[k]);
|
||||
strcpy(filename + pathlen, &filelist[k * 256]);
|
||||
k++;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef struct _ini_sec_t
|
|||
u32 color;
|
||||
} ini_sec_t;
|
||||
|
||||
int ini_parse(link_t *dst, const char *ini_path, bool is_dir);
|
||||
int ini_parse(link_t *dst, char *ini_path, bool is_dir);
|
||||
char *ini_check_special_section(ini_sec_t *cfg);
|
||||
void ini_free(link_t *src);
|
||||
|
||||
|
|
|
@ -172,14 +172,14 @@ parse_padding_dec:
|
|||
_s_putc(c);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
_s_putn(va_arg(ap, u32), 10, fill, fcnt);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
_s_puts(va_arg(ap, char *), fill, fcnt);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
_s_putn(va_arg(ap, u32), 10, fill, fcnt);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
case 'P':
|
||||
case 'x':
|
||||
|
@ -261,14 +261,14 @@ parse_padding_dec:
|
|||
_s_putc(c);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
_s_putn(va_arg(ap, u32), 10, fill, fcnt);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
_s_puts(va_arg(ap, char *), fill, fcnt);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
_s_putn(va_arg(ap, u32), 10, fill, fcnt);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
case 'P':
|
||||
case 'x':
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 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/>.
|
||||
*/
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 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>
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
|||
#include <storage/sd.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define USE_RTC_TIMER
|
||||
|
||||
u8 bit_count(u32 val)
|
||||
{
|
||||
u8 cnt = 0;
|
||||
|
@ -239,21 +241,6 @@ u32 crc32_calc(u32 crc, const u8 *buf, u32 len)
|
|||
return ~crc;
|
||||
}
|
||||
|
||||
int qsort_compare_int(const void *a, const void *b)
|
||||
{
|
||||
return (*(int *)a - *(int *)b);
|
||||
}
|
||||
|
||||
int qsort_compare_char(const void *a, const void *b)
|
||||
{
|
||||
return strcmp(*(const char **)a, *(const char **)b);
|
||||
}
|
||||
|
||||
int qsort_compare_char_case(const void *a, const void *b)
|
||||
{
|
||||
return strcasecmp(*(const char **)a, *(const char **)b);
|
||||
}
|
||||
|
||||
void panic(u32 val)
|
||||
{
|
||||
// Set panic code.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -89,10 +89,6 @@ int atoi(const char *nptr);
|
|||
void reg_write_array(u32 *base, const reg_cfg_t *cfg, u32 num_cfg);
|
||||
u32 crc32_calc(u32 crc, const u8 *buf, u32 len);
|
||||
|
||||
int qsort_compare_int(const void *a, const void *b);
|
||||
int qsort_compare_char(const void *a, const void *b);
|
||||
int qsort_compare_char_case(const void *a, const void *b);
|
||||
|
||||
void panic(u32 val);
|
||||
void power_set_state(power_state_t state);
|
||||
void power_set_state_ex(void *param);
|
||||
|
|
|
@ -313,14 +313,17 @@ void print_battery_charger_info()
|
|||
|
||||
gfx_printf("%k\n\nBattery Charger Info:\n%k", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT);
|
||||
|
||||
bq24193_get_property(BQ24193_InputVoltageLimit, &value);
|
||||
gfx_printf("Input voltage limit: %4d mV\n", value);
|
||||
|
||||
bq24193_get_property(BQ24193_InputCurrentLimit, &value);
|
||||
gfx_printf("Input current limit: %4d mA\n", value);
|
||||
|
||||
bq24193_get_property(BQ24193_SystemMinimumVoltage, &value);
|
||||
gfx_printf("System voltage limit: %4d mV\n", value);
|
||||
gfx_printf("Min voltage limit: %4d mV\n", value);
|
||||
|
||||
bq24193_get_property(BQ24193_FastChargeCurrentLimit, &value);
|
||||
gfx_printf("Charge current limit: %4d mA\n", value);
|
||||
gfx_printf("Fast charge current limit: %4d mA\n", value);
|
||||
|
||||
bq24193_get_property(BQ24193_ChargeVoltageLimit, &value);
|
||||
gfx_printf("Charge voltage limit: %4d mV\n", value);
|
||||
|
|
|
@ -155,8 +155,6 @@ void menu_autorcm()
|
|||
tui_do_menu(&menu);
|
||||
|
||||
emmc_end();
|
||||
|
||||
free(ments);
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Atmosphère Package 3 parser.
|
||||
* Atmosphère Fusée Secondary Storage (Package3) parser.
|
||||
*
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
* Copyright (c) 2019-2024 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,
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <bdk.h>
|
||||
|
||||
#include "pkg3.h"
|
||||
#include "fss.h"
|
||||
#include "hos.h"
|
||||
#include "../config.h"
|
||||
#include <libs/fatfs/ff.h>
|
||||
|
@ -31,16 +31,14 @@
|
|||
|
||||
extern hekate_config h_cfg;
|
||||
|
||||
extern bool is_ipl_updated(void *buf, const char *path, bool force);
|
||||
extern bool is_ipl_updated(void *buf, char *path, bool force);
|
||||
|
||||
#define PKG3_KIP_SKIP_MAX 16
|
||||
// FSS0 Magic and Meta header offset.
|
||||
#define FSS0_MAGIC 0x30535346
|
||||
#define FSS0_META_OFFSET 0x4
|
||||
#define FSS0_VERSION_0_17_0 0x110000
|
||||
|
||||
// PKG3 Magic and Meta header offset.
|
||||
#define PKG3_MAGIC 0x30535346 // FSS0.
|
||||
#define PKG3_META_OFFSET 0x4
|
||||
#define PKG3_VERSION_0_17_0 0x110000
|
||||
|
||||
// PKG3 Content Types.
|
||||
// FSS0 Content Types.
|
||||
#define CNT_TYPE_FSP 0
|
||||
#define CNT_TYPE_EXO 1 // Exosphere (Secure Monitor).
|
||||
#define CNT_TYPE_WBT 2 // Warmboot (SC7Exit fw).
|
||||
|
@ -55,11 +53,11 @@ extern bool is_ipl_updated(void *buf, const char *path, bool force);
|
|||
#define CNT_TYPE_EXF 11 // Exosphere Mariko fatal payload.
|
||||
#define CNT_TYPE_TKG 12 // Tsec Keygen.
|
||||
|
||||
// PKG3 Content Flags.
|
||||
// FSS0 Content Flags.
|
||||
#define CNT_FLAG0_EXPERIMENTAL BIT(0)
|
||||
|
||||
// PKG3 Meta Header.
|
||||
typedef struct _pkg3_meta_t
|
||||
// FSS0 Meta Header.
|
||||
typedef struct _fss_meta_t
|
||||
{
|
||||
u32 magic;
|
||||
u32 size;
|
||||
|
@ -69,10 +67,10 @@ typedef struct _pkg3_meta_t
|
|||
u32 hos_ver;
|
||||
u32 version;
|
||||
u32 git_rev;
|
||||
} pkg3_meta_t;
|
||||
} fss_meta_t;
|
||||
|
||||
// PKG3 Content Header.
|
||||
typedef struct _pkg3_content_t
|
||||
// FSS0 Content Header.
|
||||
typedef struct _fss_content_t
|
||||
{
|
||||
u32 offset;
|
||||
u32 size;
|
||||
|
@ -82,9 +80,9 @@ typedef struct _pkg3_content_t
|
|||
u8 flags2;
|
||||
u32 rsvd1;
|
||||
char name[0x10];
|
||||
} pkg3_content_t;
|
||||
} fss_content_t;
|
||||
|
||||
static void _pkg3_update_r2p()
|
||||
static void _fss_update_r2p()
|
||||
{
|
||||
u8 *r2p_payload = sd_file_read("atmosphere/reboot_payload.bin", NULL);
|
||||
|
||||
|
@ -93,44 +91,10 @@ static void _pkg3_update_r2p()
|
|||
free(r2p_payload);
|
||||
}
|
||||
|
||||
static int _pkg3_kip1_skip(char ***pkg3_kip1_skip, u32 *pkg3_kip1_skip_num, char *value)
|
||||
{
|
||||
int len = strlen(value);
|
||||
if (!len || (*pkg3_kip1_skip_num) >= PKG3_KIP_SKIP_MAX)
|
||||
return 0;
|
||||
|
||||
// Allocate pointer list memory.
|
||||
if (!(*pkg3_kip1_skip))
|
||||
(*pkg3_kip1_skip) = calloc(PKG3_KIP_SKIP_MAX, sizeof(char *));
|
||||
|
||||
// Set first kip name.
|
||||
(*pkg3_kip1_skip)[(*pkg3_kip1_skip_num)++] = value;
|
||||
|
||||
// Check if more names are set separated by comma.
|
||||
for (char *c = value; *c != 0; c++)
|
||||
{
|
||||
if (*c == ',')
|
||||
{
|
||||
*c = 0; // Null termination.
|
||||
|
||||
// Set next kip name to the list.
|
||||
(*pkg3_kip1_skip)[(*pkg3_kip1_skip_num)++] = c + 1;
|
||||
|
||||
if ((*pkg3_kip1_skip_num) >= PKG3_KIP_SKIP_MAX)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parse_pkg3(launch_ctxt_t *ctxt, const char *path)
|
||||
int parse_fss(launch_ctxt_t *ctxt, const char *path)
|
||||
{
|
||||
FIL fp;
|
||||
|
||||
char **pkg3_kip1_skip = NULL;
|
||||
u32 pkg3_kip1_skip_num = 0;
|
||||
|
||||
bool stock = false;
|
||||
bool experimental = false;
|
||||
|
||||
|
@ -144,12 +108,9 @@ int parse_pkg3(launch_ctxt_t *ctxt, const char *path)
|
|||
if (kv->val[0] == '1')
|
||||
stock = true;
|
||||
|
||||
if (!strcmp("pkg3ex", kv->key))
|
||||
if (!strcmp("fss0experimental", kv->key))
|
||||
if (kv->val[0] == '1')
|
||||
experimental = true;
|
||||
|
||||
if (!strcmp("pkg3kip1skip", kv->key))
|
||||
_pkg3_kip1_skip(&pkg3_kip1_skip, &pkg3_kip1_skip_num, kv->val);
|
||||
}
|
||||
|
||||
#ifdef HOS_MARIKO_STOCK_SECMON
|
||||
|
@ -160,93 +121,79 @@ int parse_pkg3(launch_ctxt_t *ctxt, const char *path)
|
|||
return 1;
|
||||
#endif
|
||||
|
||||
// Try to open PKG3.
|
||||
// Try to open FSS0.
|
||||
if (f_open(&fp, path, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
|
||||
void *pkg3 = malloc(f_size(&fp));
|
||||
void *fss = malloc(f_size(&fp));
|
||||
|
||||
// Read first 1024 bytes of the PKG3 file.
|
||||
f_read(&fp, pkg3, 1024, NULL);
|
||||
// Read first 1024 bytes of the FSS0 file.
|
||||
f_read(&fp, fss, 1024, NULL);
|
||||
|
||||
// Get PKG3 Meta header offset.
|
||||
u32 pkg3_meta_addr = *(u32 *)(pkg3 + PKG3_META_OFFSET);
|
||||
pkg3_meta_t *pkg3_meta = (pkg3_meta_t *)(pkg3 + pkg3_meta_addr);
|
||||
// Get FSS0 Meta header offset.
|
||||
u32 fss_meta_addr = *(u32 *)(fss + FSS0_META_OFFSET);
|
||||
fss_meta_t *fss_meta = (fss_meta_t *)(fss + fss_meta_addr);
|
||||
|
||||
// Check if valid PKG3 and parse it.
|
||||
if (pkg3_meta->magic == PKG3_MAGIC)
|
||||
// Check if valid FSS0 and parse it.
|
||||
if (fss_meta->magic == FSS0_MAGIC)
|
||||
{
|
||||
gfx_printf("Atmosphere %d.%d.%d-%08x via PKG3\n"
|
||||
gfx_printf("Atmosphere %d.%d.%d-%08x via FSS0/PKG3\n"
|
||||
"Max HOS: %d.%d.%d\n"
|
||||
"Unpacking.. ",
|
||||
pkg3_meta->version >> 24, (pkg3_meta->version >> 16) & 0xFF, (pkg3_meta->version >> 8) & 0xFF, pkg3_meta->git_rev,
|
||||
pkg3_meta->hos_ver >> 24, (pkg3_meta->hos_ver >> 16) & 0xFF, (pkg3_meta->hos_ver >> 8) & 0xFF);
|
||||
fss_meta->version >> 24, (fss_meta->version >> 16) & 0xFF, (fss_meta->version >> 8) & 0xFF, fss_meta->git_rev,
|
||||
fss_meta->hos_ver >> 24, (fss_meta->hos_ver >> 16) & 0xFF, (fss_meta->hos_ver >> 8) & 0xFF);
|
||||
|
||||
ctxt->patch_krn_proc_id = true;
|
||||
ctxt->pkg3_hosver = pkg3_meta->hos_ver;
|
||||
ctxt->atmosphere = true;
|
||||
ctxt->fss0_hosver = fss_meta->hos_ver;
|
||||
|
||||
// Parse PKG3 contents.
|
||||
pkg3_content_t *curr_pkg3_cnt = (pkg3_content_t *)(pkg3 + pkg3_meta->cnt_off);
|
||||
// Parse FSS0 contents.
|
||||
fss_content_t *curr_fss_cnt = (fss_content_t *)(fss + fss_meta->cnt_off);
|
||||
void *content;
|
||||
for (u32 i = 0; i < pkg3_meta->cnt_count; i++)
|
||||
for (u32 i = 0; i < fss_meta->cnt_count; i++)
|
||||
{
|
||||
content = (void *)(pkg3 + curr_pkg3_cnt[i].offset);
|
||||
content = (void *)(fss + curr_fss_cnt[i].offset);
|
||||
|
||||
// Check if offset is inside limits.
|
||||
if ((curr_pkg3_cnt[i].offset + curr_pkg3_cnt[i].size) > pkg3_meta->size)
|
||||
if ((curr_fss_cnt[i].offset + curr_fss_cnt[i].size) > fss_meta->size)
|
||||
continue;
|
||||
|
||||
// If content is experimental and experimental config is not enabled, skip it.
|
||||
if ((curr_pkg3_cnt[i].flags0 & CNT_FLAG0_EXPERIMENTAL) && !experimental)
|
||||
if ((curr_fss_cnt[i].flags0 & CNT_FLAG0_EXPERIMENTAL) && !experimental)
|
||||
continue;
|
||||
|
||||
// Prepare content.
|
||||
switch (curr_pkg3_cnt[i].type)
|
||||
switch (curr_fss_cnt[i].type)
|
||||
{
|
||||
case CNT_TYPE_KIP:
|
||||
if (stock)
|
||||
continue;
|
||||
|
||||
bool should_skip = false;
|
||||
for (u32 k = 0; k < pkg3_kip1_skip_num; k++)
|
||||
{
|
||||
if (!strcmp(curr_pkg3_cnt[i].name, pkg3_kip1_skip[k]))
|
||||
{
|
||||
gfx_printf("Skipped %s.kip1 from PKG3\n", curr_pkg3_cnt[i].name);
|
||||
should_skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (should_skip)
|
||||
continue;
|
||||
|
||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||
mkip1->kip1 = content;
|
||||
list_append(&ctxt->kip1_list, &mkip1->link);
|
||||
DPRINTF("Loaded %s.kip1 from PKG3 (size %08X)\n", curr_pkg3_cnt[i].name, curr_pkg3_cnt[i].size);
|
||||
DPRINTF("Loaded %s.kip1 from FSS0 (size %08X)\n", curr_fss_cnt[i].name, curr_fss_cnt[i].size);
|
||||
break;
|
||||
|
||||
case CNT_TYPE_KRN:
|
||||
if (stock)
|
||||
continue;
|
||||
ctxt->kernel_size = curr_pkg3_cnt[i].size;
|
||||
ctxt->kernel_size = curr_fss_cnt[i].size;
|
||||
ctxt->kernel = content;
|
||||
break;
|
||||
|
||||
case CNT_TYPE_EXO:
|
||||
ctxt->secmon_size = curr_pkg3_cnt[i].size;
|
||||
ctxt->secmon_size = curr_fss_cnt[i].size;
|
||||
ctxt->secmon = content;
|
||||
break;
|
||||
|
||||
case CNT_TYPE_EXF:
|
||||
ctxt->exofatal_size = curr_pkg3_cnt[i].size;
|
||||
ctxt->exofatal_size = curr_fss_cnt[i].size;
|
||||
ctxt->exofatal = content;
|
||||
break;
|
||||
|
||||
case CNT_TYPE_WBT:
|
||||
if (h_cfg.t210b01)
|
||||
continue;
|
||||
ctxt->warmboot_size = curr_pkg3_cnt[i].size;
|
||||
ctxt->warmboot_size = curr_fss_cnt[i].size;
|
||||
ctxt->warmboot = content;
|
||||
break;
|
||||
|
||||
|
@ -255,28 +202,23 @@ int parse_pkg3(launch_ctxt_t *ctxt, const char *path)
|
|||
}
|
||||
|
||||
// Load content to launch context.
|
||||
f_lseek(&fp, curr_pkg3_cnt[i].offset);
|
||||
f_read(&fp, content, curr_pkg3_cnt[i].size, NULL);
|
||||
f_lseek(&fp, curr_fss_cnt[i].offset);
|
||||
f_read(&fp, content, curr_fss_cnt[i].size, NULL);
|
||||
}
|
||||
|
||||
gfx_printf("Done!\n");
|
||||
f_close(&fp);
|
||||
|
||||
ctxt->pkg3 = pkg3;
|
||||
ctxt->fss0 = fss;
|
||||
|
||||
// Update r2p if needed.
|
||||
_pkg3_update_r2p();
|
||||
|
||||
free(pkg3_kip1_skip);
|
||||
_fss_update_r2p();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Failed. Close and free all.
|
||||
f_close(&fp);
|
||||
|
||||
free(pkg3_kip1_skip);
|
||||
free(pkg3);
|
||||
free(fss);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -14,11 +14,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _PKG3_H_
|
||||
#define _PKG3_H_
|
||||
#ifndef _FSS_H_
|
||||
#define _FSS_H_
|
||||
|
||||
#include "hos.h"
|
||||
|
||||
int parse_pkg3(launch_ctxt_t *ctxt, const char *path);
|
||||
int parse_fss(launch_ctxt_t *ctxt, const char *path);
|
||||
|
||||
#endif
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018 Ced2911
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -123,8 +123,6 @@ static const u8 master_kekseed_t210_tsec_v4[HOS_KB_VERSION_MAX - HOS_KB_VERSION_
|
|||
{ 0x99, 0x22, 0x09, 0x57, 0xA7, 0xF9, 0x5E, 0x94, 0xFE, 0x78, 0x7F, 0x41, 0xD6, 0xE7, 0x56, 0xE6 }, // 16.0.0.
|
||||
{ 0x71, 0xB9, 0xA6, 0xC0, 0xFF, 0x97, 0x6B, 0x0C, 0xB4, 0x40, 0xB9, 0xD5, 0x81, 0x5D, 0x81, 0x90 }, // 17.0.0.
|
||||
{ 0x00, 0x04, 0x5D, 0xF0, 0x4D, 0xCD, 0x14, 0xA3, 0x1C, 0xBF, 0xDE, 0x48, 0x55, 0xBA, 0x35, 0xC1 }, // 18.0.0.
|
||||
{ 0xD7, 0x63, 0x74, 0x46, 0x4E, 0xBA, 0x78, 0x0A, 0x7C, 0x9D, 0xB3, 0xE8, 0x7A, 0x3D, 0x71, 0xE3 }, // 19.0.0.
|
||||
{ 0xA1, 0x7D, 0x34, 0xDB, 0x2D, 0x9D, 0xDA, 0xE5, 0xF8, 0x15, 0x63, 0x4C, 0x8F, 0xE7, 0x6C, 0xD8 }, // 20.0.0.
|
||||
};
|
||||
|
||||
//!TODO: Update on mkey changes.
|
||||
|
@ -142,8 +140,6 @@ static const u8 master_kekseed_t210b01[HOS_KB_VERSION_MAX - HOS_KB_VERSION_600 +
|
|||
{ 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 }, // 16.0.0.
|
||||
{ 0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80 }, // 17.0.0.
|
||||
{ 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 }, // 18.0.0.
|
||||
{ 0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80 }, // 19.0.0.
|
||||
{ 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A }, // 20.0.0.
|
||||
};
|
||||
|
||||
static const u8 console_keyseed[SE_KEY_128_SIZE] =
|
||||
|
@ -196,7 +192,7 @@ static void _se_lock(bool lock_se)
|
|||
gfx_hexdump(SE_BASE, (void *)SE_BASE, 0x400);*/
|
||||
}
|
||||
|
||||
static bool _hos_eks_rw_try(u8 *buf, bool write)
|
||||
bool hos_eks_rw_try(u8 *buf, bool write)
|
||||
{
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
|
@ -226,7 +222,7 @@ static void _hos_eks_get()
|
|||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = zalloc(SD_BLOCKSIZE);
|
||||
if (!_hos_eks_rw_try(mbr, false))
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
goto out;
|
||||
|
||||
// Decrypt EKS blob.
|
||||
|
@ -264,7 +260,7 @@ static void _hos_eks_save()
|
|||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = zalloc(SD_BLOCKSIZE);
|
||||
if (!_hos_eks_rw_try(mbr, false))
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
{
|
||||
if (new_eks)
|
||||
{
|
||||
|
@ -296,7 +292,7 @@ static void _hos_eks_save()
|
|||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
_hos_eks_rw_try(mbr, true);
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
free(eks);
|
||||
free(keys);
|
||||
|
@ -305,7 +301,7 @@ out:
|
|||
}
|
||||
}
|
||||
|
||||
static void _hos_eks_clear(u32 kb)
|
||||
void hos_eks_clear(u32 kb)
|
||||
{
|
||||
// Check if Erista based unit.
|
||||
if (h_cfg.t210b01)
|
||||
|
@ -318,7 +314,7 @@ static void _hos_eks_clear(u32 kb)
|
|||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = zalloc(SD_BLOCKSIZE);
|
||||
if (!_hos_eks_rw_try(mbr, false))
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
goto out;
|
||||
|
||||
// Disable current Master key version.
|
||||
|
@ -331,7 +327,7 @@ static void _hos_eks_clear(u32 kb)
|
|||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
_hos_eks_rw_try(mbr, true);
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
free(eks);
|
||||
out:
|
||||
|
@ -340,21 +336,8 @@ out:
|
|||
}
|
||||
}
|
||||
|
||||
static int _hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock, bool is_exo)
|
||||
int hos_keygen_t210b01(u32 kb)
|
||||
{
|
||||
static bool sbk_is_set = true;
|
||||
|
||||
u32 retries = 0;
|
||||
bool use_tsec = false;
|
||||
tsec_keys_t tsec_keys;
|
||||
kb_t *kb_data = (kb_t *)keyblob;
|
||||
|
||||
if (kb > HOS_KB_VERSION_MAX)
|
||||
return 0;
|
||||
|
||||
// Do Mariko keygen.
|
||||
if (h_cfg.t210b01)
|
||||
{
|
||||
// Use SBK as Device key 4x unsealer and KEK for mkey in T210B01 units.
|
||||
se_aes_unwrap_key(10, 14, console_keyseed_4xx);
|
||||
|
||||
|
@ -366,15 +349,30 @@ static int _hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock
|
|||
se_aes_unwrap_key(8, 7, package2_keyseed);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock, bool is_exo)
|
||||
{
|
||||
static bool sbk_wiped = false;
|
||||
|
||||
u32 retries = 0;
|
||||
bool use_tsec = false;
|
||||
tsec_keys_t tsec_keys;
|
||||
kb_t *kb_data = (kb_t *)keyblob;
|
||||
|
||||
if (kb > HOS_KB_VERSION_MAX)
|
||||
return 0;
|
||||
|
||||
if (h_cfg.t210b01)
|
||||
return hos_keygen_t210b01(kb);
|
||||
|
||||
// Do Erista keygen.
|
||||
|
||||
// Check if SBK is wiped and try to restore it from fuses.
|
||||
if (!sbk_is_set)
|
||||
// SBK is wiped. Try to restore it from fuses.
|
||||
if (sbk_wiped)
|
||||
{
|
||||
if (fuse_set_sbk())
|
||||
sbk_is_set = true;
|
||||
sbk_wiped = false;
|
||||
else
|
||||
return 1; // Continue with current SE keys.
|
||||
}
|
||||
|
@ -383,7 +381,7 @@ static int _hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock
|
|||
_hos_eks_get();
|
||||
|
||||
// Use tsec keygen for old firmware or if EKS keys does not exist for newer.
|
||||
if (kb <= HOS_KB_VERSION_620 || !h_cfg.eks || (h_cfg.eks->enabled != HOS_EKS_TSEC_VER))
|
||||
if (kb <= HOS_KB_VERSION_620 || !h_cfg.eks || (h_cfg.eks && h_cfg.eks->enabled != HOS_EKS_TSEC_VER))
|
||||
use_tsec = true;
|
||||
|
||||
if (kb <= HOS_KB_VERSION_600)
|
||||
|
@ -412,7 +410,7 @@ static int _hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock
|
|||
tsec_ctxt->fw = sd_file_read("bootloader/sys/thk.bin", NULL);
|
||||
if (!tsec_ctxt->fw)
|
||||
{
|
||||
_hos_crit_error("Failed to load thk.bin");
|
||||
_hos_crit_error("\nFailed to load thk.bin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -436,7 +434,7 @@ static int _hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock
|
|||
// We rely on racing conditions, make sure we cover even the unluckiest cases.
|
||||
if (retries > 15)
|
||||
{
|
||||
_hos_crit_error("Failed to get TSEC keys.");
|
||||
_hos_crit_error("\nFailed to get TSEC keys. Please try again.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -570,7 +568,7 @@ static int _hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock
|
|||
se_aes_unwrap_key(15, 15, console_keyseed);
|
||||
se_aes_unwrap_key(14, 12, master_keyseed_4xx);
|
||||
se_aes_unwrap_key(12, 12, master_keyseed_retail);
|
||||
sbk_is_set = false;
|
||||
sbk_wiped = true;
|
||||
break;
|
||||
case HOS_KB_VERSION_500:
|
||||
case HOS_KB_VERSION_600:
|
||||
|
@ -578,7 +576,7 @@ static int _hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock
|
|||
se_aes_unwrap_key(15, 15, console_keyseed);
|
||||
se_aes_unwrap_key(14, 12, master_keyseed_4xx);
|
||||
se_aes_unwrap_key(12, 12, master_keyseed_retail);
|
||||
sbk_is_set = false;
|
||||
sbk_wiped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -700,7 +698,7 @@ out:
|
|||
static void _free_launch_components(launch_ctxt_t *ctxt)
|
||||
{
|
||||
// Free the malloc'ed guaranteed addresses.
|
||||
free(ctxt->pkg3);
|
||||
free(ctxt->fss0);
|
||||
free(ctxt->keyblob);
|
||||
free(ctxt->pkg1);
|
||||
free(ctxt->pkg2);
|
||||
|
@ -750,7 +748,7 @@ static bool _get_fs_exfat_compatible(link_t *info, u32 *hos_revision)
|
|||
return true;
|
||||
}
|
||||
|
||||
void hos_launch(ini_sec_t *cfg)
|
||||
int hos_launch(ini_sec_t *cfg)
|
||||
{
|
||||
u8 kb;
|
||||
u32 secmon_base;
|
||||
|
@ -758,6 +756,7 @@ void hos_launch(ini_sec_t *cfg)
|
|||
bool is_exo = false;
|
||||
launch_ctxt_t ctxt = {0};
|
||||
tsec_ctxt_t tsec_ctxt = {0};
|
||||
volatile secmon_mailbox_t *secmon_mailbox;
|
||||
|
||||
minerva_change_freq(FREQ_1600);
|
||||
sdram_src_pllc(true);
|
||||
|
@ -775,7 +774,10 @@ void hos_launch(ini_sec_t *cfg)
|
|||
int res = emummc_storage_init_mmc();
|
||||
if (res)
|
||||
{
|
||||
_hos_crit_error(res == 2 ? "Failed to init eMMC." : "Failed to init emuMMC.");
|
||||
if (res == 2)
|
||||
_hos_crit_error("Failed to init eMMC.");
|
||||
else
|
||||
_hos_crit_error("Failed to init emuMMC.");
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
@ -783,12 +785,12 @@ void hos_launch(ini_sec_t *cfg)
|
|||
// Check if SD Card is GPT.
|
||||
if (sd_is_gpt())
|
||||
{
|
||||
_hos_crit_error("SD has GPT only! Run Fix Hybrid MBR!");
|
||||
_hos_crit_error("SD has GPT only!");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Try to parse config if present.
|
||||
if (!parse_boot_config(&ctxt))
|
||||
if (ctxt.cfg && !parse_boot_config(&ctxt))
|
||||
{
|
||||
_hos_crit_error("Wrong ini cfg or missing/corrupt files!");
|
||||
goto error;
|
||||
|
@ -800,7 +802,6 @@ void hos_launch(ini_sec_t *cfg)
|
|||
// Check if stock is enabled and device can boot in OFW.
|
||||
if (ctxt.stock && (h_cfg.t210b01 || !tools_autorcm_enabled()))
|
||||
{
|
||||
sdram_src_pllc(false);
|
||||
emmc_end();
|
||||
|
||||
WPRINTF("\nRebooting to OFW in 5s...");
|
||||
|
@ -824,7 +825,7 @@ void hos_launch(ini_sec_t *cfg)
|
|||
goto error;
|
||||
}
|
||||
|
||||
ctxt.patch_krn_proc_id = true; // Set kernel process id patching in case of no pkg3.
|
||||
ctxt.atmosphere = true; // Set atmosphere patching in case of no fss0.
|
||||
config_kip1patch(&ctxt, "emummc");
|
||||
}
|
||||
else if (!emu_cfg.enabled && ctxt.emummc_forced)
|
||||
|
@ -876,7 +877,7 @@ void hos_launch(ini_sec_t *cfg)
|
|||
tsec_ctxt.pkg11_off = ctxt.pkg1_id->pkg11_off;
|
||||
|
||||
// Generate keys.
|
||||
if (!_hos_keygen(ctxt.keyblob, kb, &tsec_ctxt, ctxt.stock, is_exo))
|
||||
if (!hos_keygen(ctxt.keyblob, kb, &tsec_ctxt, ctxt.stock, is_exo))
|
||||
goto error;
|
||||
gfx_puts("Generated keys\n");
|
||||
|
||||
|
@ -978,7 +979,7 @@ void hos_launch(ini_sec_t *cfg)
|
|||
_hos_crit_error("Pkg2 decryption failed!\npkg1/pkg2 mismatch or old hekate!");
|
||||
|
||||
// Clear EKS slot, in case something went wrong with tsec keygen.
|
||||
_hos_eks_clear(kb);
|
||||
hos_eks_clear(kb);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -997,7 +998,7 @@ void hos_launch(ini_sec_t *cfg)
|
|||
ctxt.kernel = pkg2_hdr->data;
|
||||
ctxt.kernel_size = pkg2_hdr->sec_size[PKG2_SEC_KERNEL];
|
||||
|
||||
if (!ctxt.stock && (ctxt.svcperm || ctxt.debugmode || ctxt.patch_krn_proc_id))
|
||||
if (!ctxt.stock && (ctxt.svcperm || ctxt.debugmode || ctxt.atmosphere))
|
||||
{
|
||||
// Hash only Kernel when it embeds INI1.
|
||||
u8 kernel_hash[0x20];
|
||||
|
@ -1024,10 +1025,10 @@ void hos_launch(ini_sec_t *cfg)
|
|||
for (u32 i = 0; kernel_patchset[i].id != 0xFFFFFFFF; i++)
|
||||
{
|
||||
if ((ctxt.svcperm && kernel_patchset[i].id == SVC_VERIFY_DS)
|
||||
|| (ctxt.debugmode && kernel_patchset[i].id == DEBUG_MODE_EN && !(ctxt.patch_krn_proc_id && ctxt.secmon))
|
||||
|| (ctxt.patch_krn_proc_id && kernel_patchset[i].id == ATM_GEN_PATCH))
|
||||
|| (ctxt.debugmode && kernel_patchset[i].id == DEBUG_MODE_EN && !(ctxt.atmosphere && ctxt.secmon))
|
||||
|| (ctxt.atmosphere && kernel_patchset[i].id == ATM_GEN_PATCH))
|
||||
*(vu32 *)(ctxt.kernel + kernel_patchset[i].off) = kernel_patchset[i].val;
|
||||
else if (ctxt.patch_krn_proc_id && kernel_patchset[i].id == ATM_ARR_PATCH)
|
||||
else if (ctxt.atmosphere && kernel_patchset[i].id == ATM_ARR_PATCH)
|
||||
{
|
||||
temp = (u32 *)kernel_patchset[i].ptr;
|
||||
for (u32 j = 0; j < kernel_patchset[i].val; j++)
|
||||
|
@ -1147,7 +1148,6 @@ void hos_launch(ini_sec_t *cfg)
|
|||
//pmc_scratch_lock(PMC_SEC_LOCK_LP0_PARAMS);
|
||||
|
||||
// Set secmon mailbox address and clear it.
|
||||
volatile secmon_mailbox_t *secmon_mailbox;
|
||||
if (kb >= HOS_KB_VERSION_700 || is_exo)
|
||||
{
|
||||
memset((void *)SECMON7_MAILBOX_ADDR, 0, 0x200);
|
||||
|
@ -1199,4 +1199,6 @@ error:
|
|||
emmc_end();
|
||||
|
||||
EPRINTF("\nFailed to launch HOS!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -45,9 +45,7 @@ enum {
|
|||
HOS_KB_VERSION_1600 = 15,
|
||||
HOS_KB_VERSION_1700 = 16,
|
||||
HOS_KB_VERSION_1800 = 17,
|
||||
HOS_KB_VERSION_1900 = 18,
|
||||
HOS_KB_VERSION_2000 = 19,
|
||||
HOS_KB_VERSION_MAX = HOS_KB_VERSION_2000
|
||||
HOS_KB_VERSION_MAX = HOS_KB_VERSION_1800
|
||||
};
|
||||
|
||||
#define HOS_TSEC_VERSION 4 //! TODO: Update on TSEC Root Key changes.
|
||||
|
@ -105,16 +103,16 @@ typedef struct _launch_ctxt_t
|
|||
u32 kernel_size;
|
||||
|
||||
link_t kip1_list;
|
||||
char *kip1_patches;
|
||||
char* kip1_patches;
|
||||
|
||||
bool svcperm;
|
||||
bool debugmode;
|
||||
bool stock;
|
||||
bool emummc_forced;
|
||||
|
||||
void *pkg3;
|
||||
u32 pkg3_hosver;
|
||||
bool patch_krn_proc_id;
|
||||
void *fss0;
|
||||
u32 fss0_hosver;
|
||||
bool atmosphere;
|
||||
|
||||
int ucid;
|
||||
|
||||
|
@ -129,6 +127,8 @@ typedef struct _merge_kip_t
|
|||
link_t link;
|
||||
} merge_kip_t;
|
||||
|
||||
void hos_launch(ini_sec_t *cfg);
|
||||
void hos_eks_clear(u32 kb);
|
||||
int hos_launch(ini_sec_t *cfg);
|
||||
int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock, bool is_exo);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "hos.h"
|
||||
#include "hos_config.h"
|
||||
#include "pkg3.h"
|
||||
#include "fss.h"
|
||||
#include <libs/fatfs/ff.h>
|
||||
|
||||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
|
@ -58,14 +58,14 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
|||
{
|
||||
u32 size;
|
||||
|
||||
if (value[strlen(value) - 1] == '*')
|
||||
if (!memcmp(value + strlen(value) - 1, "*", 1))
|
||||
{
|
||||
char *dir = (char *)malloc(256);
|
||||
strcpy(dir, value);
|
||||
|
||||
u32 dirlen = 0;
|
||||
dir[strlen(dir) - 2] = 0;
|
||||
dirlist_t *filelist = dirlist(dir, "*.kip*", false, false);
|
||||
char *filelist = dirlist(dir, "*.kip*", false, false);
|
||||
|
||||
strcat(dir, "/");
|
||||
dirlen = strlen(dir);
|
||||
|
@ -75,10 +75,10 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
|||
{
|
||||
while (true)
|
||||
{
|
||||
if (!filelist->name[i])
|
||||
if (!filelist[i * 256])
|
||||
break;
|
||||
|
||||
strcpy(dir + dirlen, filelist->name[i]);
|
||||
strcpy(dir + dirlen, &filelist[i * 256]);
|
||||
|
||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||
mkip1->kip1 = sd_file_read(dir, &size);
|
||||
|
@ -119,6 +119,9 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
|||
|
||||
int config_kip1patch(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return 0;
|
||||
|
||||
int len = strlen(value);
|
||||
if (!len)
|
||||
return 0;
|
||||
|
@ -185,12 +188,12 @@ static int _config_emummc_forced(launch_ctxt_t *ctxt, const char *value)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int _config_kernel_proc_id(launch_ctxt_t *ctxt, const char *value)
|
||||
static int _config_atmosphere(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (*value == '1')
|
||||
{
|
||||
DPRINTF("Enabled kernel process id send/recv patching\n");
|
||||
ctxt->patch_krn_proc_id = true;
|
||||
DPRINTF("Enabled atmosphere patching\n");
|
||||
ctxt->atmosphere = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -255,9 +258,9 @@ static int _config_exo_cal0_writes_enable(launch_ctxt_t *ctxt, const char *value
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int _config_pkg3(launch_ctxt_t *ctxt, const char *value)
|
||||
static int _config_fss(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
return parse_pkg3(ctxt, value);
|
||||
return parse_fss(ctxt, value);
|
||||
}
|
||||
|
||||
static int _config_exo_fatal_payload(launch_ctxt_t *ctxt, const char *value)
|
||||
|
@ -284,7 +287,6 @@ typedef struct _cfg_handler_t
|
|||
} cfg_handler_t;
|
||||
|
||||
static const cfg_handler_t _config_handlers[] = {
|
||||
{ "stock", _config_stock },
|
||||
{ "warmboot", _config_warmboot },
|
||||
{ "secmon", _config_secmon },
|
||||
{ "kernel", _config_kernel },
|
||||
|
@ -292,12 +294,9 @@ static const cfg_handler_t _config_handlers[] = {
|
|||
{ "kip1patch", config_kip1patch },
|
||||
{ "fullsvcperm", _config_svcperm },
|
||||
{ "debugmode", _config_debugmode },
|
||||
{ "kernelprocid", _config_kernel_proc_id },
|
||||
|
||||
// To override elements from PKG3, it should be set before others.
|
||||
{ "pkg3", _config_pkg3 },
|
||||
{ "fss0", _config_pkg3 },
|
||||
|
||||
{ "stock", _config_stock },
|
||||
{ "atmosphere", _config_atmosphere },
|
||||
{ "fss0", _config_fss },
|
||||
{ "exofatal", _config_exo_fatal_payload},
|
||||
{ "emummcforce", _config_emummc_forced },
|
||||
{ "nouserexceptions", _config_dis_exo_user_exceptions },
|
||||
|
@ -311,15 +310,10 @@ static const cfg_handler_t _config_handlers[] = {
|
|||
|
||||
int parse_boot_config(launch_ctxt_t *ctxt)
|
||||
{
|
||||
if (!ctxt->cfg)
|
||||
return 1;
|
||||
|
||||
// Check each config key.
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link)
|
||||
{
|
||||
for (u32 i = 0; _config_handlers[i].key; i++)
|
||||
{
|
||||
// If key matches, call its handler.
|
||||
if (!strcmp(_config_handlers[i].key, kv->key))
|
||||
{
|
||||
if (!_config_handlers[i].handler(ctxt, kv->val))
|
||||
|
@ -329,8 +323,6 @@ int parse_boot_config(launch_ctxt_t *ctxt)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -33,7 +33,7 @@ extern hekate_config h_cfg;
|
|||
#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, TZRAM_BASE + 0x3000 - _PAGEOFF(SM_100_ADR)) },
|
||||
{ 0x1E0, _ADRP(0, 0x7C013000 - _PAGEOFF(SM_100_ADR)) },
|
||||
// Patch package2 signature/hash checks.
|
||||
{ 0x9F0 + 0xADC, _NOP() }
|
||||
);
|
||||
|
@ -143,7 +143,7 @@ static const u8 sec_map_100[3] = { PK11_SECTION_SM, PK11_SECTION_LD, PK11_SECTIO
|
|||
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 };
|
||||
|
||||
// Timestamp KB FU TSEC PK11 SECMON Warmboot
|
||||
// ID (Timestamp), KB, Fuses, TSEC, PK11, SECMON, Warmboot.
|
||||
static const pkg1_id_t _pkg1_ids[] = {
|
||||
{ "20161121", 0, 1, 0x1900, 0x3FE0, SM_100_ADR, 0x8000D000, _secmon_1_patchset }, // 1.0.0 (Patched relocator).
|
||||
{ "20170210", 0, 2, 0x1900, 0x3FE0, 0x4002D000, 0x8000D000, _secmon_2_patchset }, // 2.0.0 - 2.3.0.
|
||||
|
@ -170,9 +170,7 @@ static const pkg1_id_t _pkg1_ids[] = {
|
|||
{ "20220801", 14, 17, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 15.0.0 - 15.0.1.
|
||||
{ "20230111", 15, 18, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 16.0.0 - 16.1.0.
|
||||
{ "20230906", 16, 19, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 17.0.0 - 17.0.1.
|
||||
{ "20240207", 17, 19, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 18.0.0 - 18.1.0.
|
||||
{ "20240808", 18, 20, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 19.0.0 - 19.0.1.
|
||||
{ "20250206", 19, 21, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 20.0.0+
|
||||
{ "20240207", 17, 19, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 18.0.0+
|
||||
};
|
||||
|
||||
const pkg1_id_t *pkg1_get_latest()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -37,7 +37,6 @@ extern const u8 package2_keyseed[];
|
|||
u32 pkg2_newkern_ini1_info;
|
||||
u32 pkg2_newkern_ini1_start;
|
||||
u32 pkg2_newkern_ini1_end;
|
||||
u32 pkg2_newkern_ini1_rela;
|
||||
|
||||
enum kip_offset_section
|
||||
{
|
||||
|
@ -171,7 +170,7 @@ static void parse_external_kip_patches()
|
|||
ext_patches_parsed = true;
|
||||
}
|
||||
|
||||
const pkg2_kernel_id_t *pkg2_identify(const u8 *hash)
|
||||
const pkg2_kernel_id_t *pkg2_identify(u8 *hash)
|
||||
{
|
||||
for (u32 i = 0; i < ARRAY_SIZE(_pkg2_kernel_ids); i++)
|
||||
{
|
||||
|
@ -189,12 +188,11 @@ static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
|
|||
return size;
|
||||
}
|
||||
|
||||
static void _pkg2_get_newkern_info(u8 *kern_data)
|
||||
void pkg2_get_newkern_info(u8 *kern_data)
|
||||
{
|
||||
u32 crt_start = 0;
|
||||
pkg2_newkern_ini1_info = 0;
|
||||
pkg2_newkern_ini1_start = 0;
|
||||
pkg2_newkern_ini1_rela = 0;
|
||||
|
||||
u32 first_op = *(u32 *)kern_data;
|
||||
if ((first_op & 0xFE000000) == 0x14000000)
|
||||
|
@ -231,7 +229,6 @@ static void _pkg2_get_newkern_info(u8 *kern_data)
|
|||
// On v2 kernel with dynamic crt, values are relative to value address.
|
||||
if (crt_start)
|
||||
{
|
||||
pkg2_newkern_ini1_rela = pkg2_newkern_ini1_info;
|
||||
pkg2_newkern_ini1_start += pkg2_newkern_ini1_info;
|
||||
pkg2_newkern_ini1_end += pkg2_newkern_ini1_info + 0x8;
|
||||
}
|
||||
|
@ -243,7 +240,7 @@ bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
|
|||
// Check for new pkg2 type.
|
||||
if (!pkg2->sec_size[PKG2_SEC_INI1])
|
||||
{
|
||||
_pkg2_get_newkern_info(pkg2->data);
|
||||
pkg2_get_newkern_info(pkg2->data);
|
||||
|
||||
if (!pkg2_newkern_ini1_start)
|
||||
return false;
|
||||
|
@ -686,10 +683,6 @@ const char *pkg2_patch_kips(link_t *info, char *patch_names)
|
|||
return patches[i];
|
||||
}
|
||||
|
||||
// Check if emuMMC was applied.
|
||||
if (emummc_patch_selected)
|
||||
return "emummc";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -852,15 +845,10 @@ DPRINTF("%s @ %08X (%08X)\n", is_meso ? "Mesosphere": "kernel",(u32)ctxt->kernel
|
|||
|
||||
// Set new INI1 offset to kernel.
|
||||
u32 meso_meta_offset = *(u32 *)(pdst + 8);
|
||||
if (is_meso && (meso_magic & 0x0F000000)) // MSS1.
|
||||
if (is_meso && (meso_magic & 0xF000000)) // MSS1.
|
||||
*(u32 *)(pdst + meso_meta_offset) = kernel_size - meso_meta_offset;
|
||||
else if (ini1_size)
|
||||
{
|
||||
if (is_meso) // MSS0.
|
||||
*(u32 *)(pdst + 8) = kernel_size;
|
||||
else
|
||||
*(u32 *)(pdst + pkg2_newkern_ini1_info) = kernel_size - pkg2_newkern_ini1_rela;
|
||||
}
|
||||
*(u32 *)(pdst + (is_meso ? 8 : pkg2_newkern_ini1_info)) = kernel_size;
|
||||
|
||||
kernel_size += ini1_size;
|
||||
}
|
||||
|
@ -877,13 +865,13 @@ DPRINTF("INI1 encrypted\n");
|
|||
|
||||
if (!is_exo) // Not needed on Exosphere 1.0.0 and up.
|
||||
{
|
||||
// Calculate SHA256 over encrypted sections. Only 3 have valid hashes.
|
||||
// Calculate SHA256 over encrypted Kernel and INI1.
|
||||
u8 *pk2_hash_data = (u8 *)dst + 0x100 + sizeof(pkg2_hdr_t);
|
||||
for (u32 i = PKG2_SEC_KERNEL; i <= PKG2_SEC_UNUSED; i++)
|
||||
{
|
||||
se_calc_sha256_oneshot(&hdr->sec_sha256[SE_SHA_256_SIZE * i], (void *)pk2_hash_data, hdr->sec_size[i]);
|
||||
pk2_hash_data += hdr->sec_size[i];
|
||||
}
|
||||
se_calc_sha256_oneshot(&hdr->sec_sha256[SE_SHA_256_SIZE * PKG2_SEC_KERNEL],
|
||||
(void *)pk2_hash_data, hdr->sec_size[PKG2_SEC_KERNEL]);
|
||||
pk2_hash_data += hdr->sec_size[PKG2_SEC_KERNEL];
|
||||
se_calc_sha256_oneshot(&hdr->sec_sha256[SE_SHA_256_SIZE * PKG2_SEC_INI1],
|
||||
(void *)pk2_hash_data, hdr->sec_size[PKG2_SEC_INI1]);
|
||||
}
|
||||
|
||||
// Encrypt header.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -24,13 +24,12 @@
|
|||
#define PKG2_SEC_BASE 0x80000000
|
||||
#define PKG2_SEC_KERNEL 0
|
||||
#define PKG2_SEC_INI1 1
|
||||
#define PKG2_SEC_UNUSED 2
|
||||
|
||||
#define INI1_MAGIC 0x31494E49
|
||||
|
||||
//! TODO: Update on kernel change if needed.
|
||||
// Offset of OP + 12 is the INI1 offset. On v2 with dynamic crt0 it's + 16.
|
||||
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // MOV X21, #0.
|
||||
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015
|
||||
#define PKG2_NEWKERN_START 0x800
|
||||
|
||||
#define ATM_MESOSPHERE 0x3053534D
|
||||
|
@ -68,18 +67,18 @@ enum
|
|||
|
||||
typedef struct _pkg2_hdr_t
|
||||
{
|
||||
/* 0x000 */ u8 ctr[0x10];
|
||||
/* 0x010 */ u8 sec_ctr[0x40];
|
||||
/* 0x050 */ u32 magic;
|
||||
/* 0x054 */ u32 base;
|
||||
/* 0x058 */ u32 pad0;
|
||||
/* 0x05C */ u8 pkg2_ver;
|
||||
/* 0x05D */ u8 bl_ver;
|
||||
/* 0x05E */ u16 pad1;
|
||||
/* 0x060 */ u32 sec_size[4];
|
||||
/* 0x070 */ u32 sec_off[4];
|
||||
/* 0x080 */ u8 sec_sha256[0x80];
|
||||
/* 0x100 */ u8 data[];
|
||||
u8 ctr[0x10];
|
||||
u8 sec_ctr[0x40];
|
||||
u32 magic;
|
||||
u32 base;
|
||||
u32 pad0;
|
||||
u8 pkg2_ver;
|
||||
u8 bl_ver;
|
||||
u16 pad1;
|
||||
u32 sec_size[4];
|
||||
u32 sec_off[4];
|
||||
u8 sec_sha256[0x80];
|
||||
u8 data[];
|
||||
} pkg2_hdr_t;
|
||||
|
||||
typedef struct _pkg2_ini1_t
|
||||
|
@ -103,7 +102,7 @@ typedef struct _pkg2_kip1_sec_t
|
|||
typedef struct _pkg2_kip1_t
|
||||
{
|
||||
/* 0x000 */ u32 magic;
|
||||
/* 0x004 */ u8 name[12];
|
||||
/* 0x004*/ u8 name[12];
|
||||
/* 0x010 */ u64 tid;
|
||||
/* 0x018 */ u32 proc_cat;
|
||||
/* 0x01C */ u8 main_thrd_prio;
|
||||
|
@ -151,6 +150,7 @@ typedef struct _kip1_id_t
|
|||
const kip1_patchset_t *patchset;
|
||||
} kip1_id_t;
|
||||
|
||||
void pkg2_get_newkern_info(u8 *kern_data);
|
||||
bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2);
|
||||
int pkg2_has_kip(link_t *info, u64 tid);
|
||||
void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1);
|
||||
|
@ -159,7 +159,7 @@ void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1);
|
|||
void pkg2_get_ids(kip1_id_t **ids, u32 *entries);
|
||||
const char *pkg2_patch_kips(link_t *info, char *patch_names);
|
||||
|
||||
const pkg2_kernel_id_t *pkg2_identify(const u8 *hash);
|
||||
const pkg2_kernel_id_t *pkg2_identify(u8 *hash);
|
||||
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb, bool is_exo);
|
||||
void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info, bool is_exo);
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ static ini_kip_sec_t *_ini_create_kip_section(link_t *dst, ini_kip_sec_t *ksec,
|
|||
return ksec;
|
||||
}
|
||||
|
||||
int ini_patch_parse(link_t *dst, const char *ini_path)
|
||||
int ini_patch_parse(link_t *dst, char *ini_path)
|
||||
{
|
||||
FIL fp;
|
||||
u32 lblen;
|
||||
|
@ -154,15 +154,15 @@ int ini_patch_parse(link_t *dst, const char *ini_path)
|
|||
pt->length = strtol(&lbuf[pos], NULL, 16);
|
||||
pos += str_start + 1;
|
||||
|
||||
u8 *data = malloc(pt->length * 2);
|
||||
u8 *buf = malloc(pt->length * 2);
|
||||
|
||||
// Set patch source data.
|
||||
str_start = _find_patch_section_name(&lbuf[pos], lblen - pos, ',');
|
||||
pt->src_data = _htoa(NULL, &lbuf[pos], pt->length, data);
|
||||
pt->src_data = _htoa(NULL, &lbuf[pos], pt->length, buf);
|
||||
pos += str_start + 1;
|
||||
|
||||
// Set patch destination data.
|
||||
pt->dst_data = _htoa(NULL, &lbuf[pos], pt->length, data + pt->length);
|
||||
pt->dst_data = _htoa(NULL, &lbuf[pos], pt->length, buf + pt->length);
|
||||
}
|
||||
|
||||
list_append(&ksec->pts, &pt->link);
|
||||
|
|
|
@ -37,6 +37,6 @@ typedef struct _ini_kip_sec_t
|
|||
link_t link;
|
||||
} ini_kip_sec_t;
|
||||
|
||||
int ini_patch_parse(link_t *dst, const char *ini_path);
|
||||
int ini_patch_parse(link_t *dst, char *ini_path);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -794,54 +794,6 @@ static const kip1_patchset_t _fs_patches_1800_exfat[] = {
|
|||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const kip1_patch_t _fs_nogc_1900[] = {
|
||||
{ KPS(KIP_TEXT) | 0x16F070, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x195B74, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x195D74, 4, KIP1_PATCH_SRC_NO_CHECK, "\x16\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static const kip1_patchset_t _fs_patches_1900[] = {
|
||||
{ "nogc", _fs_nogc_1900 },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const kip1_patch_t _fs_nogc_1900_exfat[] = {
|
||||
{ KPS(KIP_TEXT) | 0x17A8A0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x1A13A4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x1A15A4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x16\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static const kip1_patchset_t _fs_patches_1900_exfat[] = {
|
||||
{ "nogc", _fs_nogc_1900_exfat },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const kip1_patch_t _fs_nogc_2000[] = {
|
||||
{ KPS(KIP_TEXT) | 0x17C150, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x1A7D24, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x1A7F24, 4, KIP1_PATCH_SRC_NO_CHECK, "\x16\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static const kip1_patchset_t _fs_patches_2000[] = {
|
||||
{ "nogc", _fs_nogc_2000 },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const kip1_patch_t _fs_nogc_2000_exfat[] = {
|
||||
{ KPS(KIP_TEXT) | 0x187A70, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x1B3644, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x1B3844, 4, KIP1_PATCH_SRC_NO_CHECK, "\x16\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static const kip1_patchset_t _fs_patches_2000_exfat[] = {
|
||||
{ "nogc", _fs_nogc_2000_exfat },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// SHA256 hashes.
|
||||
static const kip1_id_t _kip_ids[] =
|
||||
{
|
||||
|
@ -905,10 +857,4 @@ static const kip1_id_t _kip_ids[] =
|
|||
{ "FS", "\x1E\x2C\x64\xB1\xCC\xE2\x78\x24", _fs_patches_1800_exfat }, // FS 18.0.0 exFAT
|
||||
{ "FS", "\xA3\x39\xF0\x1C\x95\xBF\xA7\x68", _fs_patches_1800 }, // FS 18.1.0
|
||||
{ "FS", "\x20\x4C\xBA\x86\xDE\x08\x44\x6A", _fs_patches_1800_exfat }, // FS 18.1.0 exFAT
|
||||
{ "FS", "\xD9\x4C\x68\x15\xF8\xF5\x0A\x20", _fs_patches_1900 }, // FS 19.0.0
|
||||
{ "FS", "\xED\xA8\x78\x68\xA4\x49\x07\x50", _fs_patches_1900_exfat }, // FS 19.0.0 exFAT
|
||||
{ "FS", "\x63\x54\x96\x9E\x60\xA7\x97\x7B", _fs_patches_2000 }, // FS 20.0.0
|
||||
{ "FS", "\x47\x41\x07\x10\x65\x4F\xA4\x3F", _fs_patches_2000_exfat }, // FS 20.0.0 exFAT
|
||||
{ "FS", "\xED\x34\xB4\x50\x58\x4A\x5B\x43", _fs_patches_2000 }, // FS 20.1.0
|
||||
{ "FS", "\xA5\x1A\xA4\x92\x6C\x41\x87\x59", _fs_patches_2000_exfat }, // FS 20.1.0 exFAT
|
||||
};
|
||||
|
|
|
@ -199,7 +199,7 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
|
|||
case 12:
|
||||
exo_fw_no = EXO_FW_VER(9, 1);
|
||||
break;
|
||||
case 13 ... 23: //!TODO: Update on API changes. 23: 20.0.0.
|
||||
case 13 ... 21: //!TODO: Update on API changes. 21: 18.0.0.
|
||||
exo_fw_no = EXO_FW_VER(exo_fw_no - 3, ctxt->exo_ctx.hos_revision);
|
||||
break;
|
||||
}
|
||||
|
@ -207,10 +207,10 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
|
|||
// Parse exosphere.ini.
|
||||
if (!ctxt->stock)
|
||||
{
|
||||
LIST_INIT(ini_exo_sections);
|
||||
if (ini_parse(&ini_exo_sections, "exosphere.ini", false))
|
||||
LIST_INIT(ini_sections);
|
||||
if (ini_parse(&ini_sections, "exosphere.ini", false))
|
||||
{
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_exo_sections, link)
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||
{
|
||||
// Only parse exosphere section.
|
||||
if (!(ini_sec->type == INI_CHOICE) || strcmp(ini_sec->name, "exosphere"))
|
||||
|
@ -241,15 +241,14 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
|
|||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse usb mtim settings. Avoid parsing if it's overridden.
|
||||
if (!ctxt->exo_ctx.usb3_force)
|
||||
{
|
||||
LIST_INIT(ini_sys_sections);
|
||||
if (ini_parse(&ini_sys_sections, "atmosphere/config/system_settings.ini", false))
|
||||
LIST_INIT(ini_sections);
|
||||
if (ini_parse(&ini_sections, "atmosphere/config/system_settings.ini", false))
|
||||
{
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sys_sections, link)
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||
{
|
||||
// Only parse usb section.
|
||||
if (!(ini_sec->type == INI_CHOICE) || strcmp(ini_sec->name, "usb"))
|
||||
|
@ -268,9 +267,10 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Private debug mode always on for CFW mode.
|
||||
if (!ctxt->stock)
|
||||
// To avoid problems, make private debug mode always on if not semi-stock.
|
||||
if (!ctxt->stock || (emu_cfg.enabled && !h_cfg.emummc_force_disable))
|
||||
exo_flags |= EXO_FLAG_DBG_PRIV;
|
||||
|
||||
// Enable user debug.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* L4T Loader for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2020-2025 CTCaer
|
||||
* Copyright (c) 2020-2024 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,
|
||||
|
@ -36,11 +36,10 @@
|
|||
* 4: Arachne Register Cell v3. DRAM OPT and DDR200 changes.
|
||||
* 5: Arachne Register Cell v4. DRAM FREQ and DDR200 changes.
|
||||
* 6: Arachne Register Cell v5. Signal quality and performance changes. TZ param changes.
|
||||
* 7: Arachne Register Cell v6. Decouple of rd/wr latencies.
|
||||
*/
|
||||
|
||||
#define L4T_LOADER_API_REV 7
|
||||
#define L4T_FIRMWARE_REV 0x37524556 // REV7.
|
||||
#define L4T_LOADER_API_REV 6
|
||||
#define L4T_FIRMWARE_REV 0x36524556 // REV6.
|
||||
|
||||
#ifdef DEBUG_UART_PORT
|
||||
#include <soc/uart.h>
|
||||
|
@ -272,8 +271,6 @@ typedef struct _l4t_ctxt_t
|
|||
int ram_oc_opt;
|
||||
|
||||
u32 serial_port;
|
||||
u32 sld_type;
|
||||
|
||||
u32 sc7entry_size;
|
||||
|
||||
emc_table_t *mtc_table;
|
||||
|
@ -290,22 +287,18 @@ typedef struct _l4t_ctxt_t
|
|||
#define DRAM_VDDQ_OC_MAX_VOLTAGE 650
|
||||
#define DRAM_T210B01_TBL_MAX_FREQ 1600000
|
||||
|
||||
#define NA 0 // Default to 0 for incorrect dram ids.
|
||||
|
||||
//!TODO: Update on dram config changes.
|
||||
//! TODO: Update on dram config changes.
|
||||
static const u8 mtc_table_idx_t210b01[] = {
|
||||
/* 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 */
|
||||
NA, NA, NA, 7, NA, 7, 7, NA, 0, 1, 2, 3, 0, 1, 2, 3, NA, 4, 5, 4, 8, 8, 8, 5, 4, 6, 6, 6, 5, 9, 9, 9, 10, 10, 10
|
||||
-1, -1, -1, 7, -1, 7, 7, -1, 0, 1, 2, 3, 0, 1, 2, 3, -1, 4, 5, 4, 8, 8, 8, 5, 4, 6, 6, 6, 5, 9, 9, 9, 10, 10, 10
|
||||
};
|
||||
|
||||
#undef NA
|
||||
|
||||
static const l4t_fw_t l4t_fw[] = {
|
||||
{ TZDRAM_BASE, "bl31.bin" },
|
||||
{ BL33_LOAD_BASE, "bl33.bin" },
|
||||
{ SC7ENTRY_BASE, "sc7entry.bin" },
|
||||
{ SC7EXIT_BASE, "sc7exit.bin" },
|
||||
{ SC7EXIT_B01_BASE, "sc7exit_b01.bin" }, //!TODO: Update on fuse burns.
|
||||
{ SC7EXIT_B01_BASE, "sc7exit_b01.bin" },
|
||||
{ BPMPFW_BASE, "bpmpfw.bin" },
|
||||
{ BPMPFW_B01_BASE, "bpmpfw_b01.bin" },
|
||||
{ BPMPFW_B01_MTC_TABLE_BASE, "mtc_tbl_b01.bin" },
|
||||
|
@ -386,7 +379,7 @@ static void _l4t_sdram_lp0_save_params(bool t210b01)
|
|||
s(MC_VIDEO_PROTECT_REG_CTRL, 1:0, secure_scratch14, 31:30);
|
||||
}
|
||||
|
||||
// TZDRAM.
|
||||
// TZD.
|
||||
s(MC_SEC_CARVEOUT_BOM, 31:20, secure_scratch53, 23:12);
|
||||
s(MC_SEC_CARVEOUT_SIZE_MB, 11:0, secure_scratch54, 11:0);
|
||||
if (!t210b01) {
|
||||
|
@ -528,6 +521,11 @@ static void _l4t_mc_config_carveout(bool t210b01)
|
|||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_TSEC | SEC_CARVEOUT_CA2_W_TSEC;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = SEC_CARVEOUT_CA3_R_NVDEC | SEC_CARVEOUT_CA3_W_NVDEC;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_RD_SEC |
|
||||
|
@ -559,6 +557,11 @@ static void _l4t_mc_config_carveout(bool t210b01)
|
|||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CFG0) = SEC_CARVEOUT_CFG_RD_NS |
|
||||
SEC_CARVEOUT_CFG_RD_SEC |
|
||||
SEC_CARVEOUT_CFG_WR_NS |
|
||||
|
@ -595,6 +598,11 @@ static void _l4t_mc_config_carveout(bool t210b01)
|
|||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU | SEC_CARVEOUT_CA2_R_TSEC;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = SEC_CARVEOUT_CA4_R_GPU2 | SEC_CARVEOUT_CA4_W_GPU2;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_RD_NS |
|
||||
|
@ -623,6 +631,11 @@ static void _l4t_mc_config_carveout(bool t210b01)
|
|||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = 0; // HOS: SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = 0; // HOS: SEC_CARVEOUT_CA4_R_GPU2 | SEC_CARVEOUT_CA4_W_GPU2
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_RD_NS |
|
||||
|
@ -838,7 +851,7 @@ static int _l4t_sc7_exit_config(bool t210b01)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void _l4t_bl33_cfg_set_key(char *env, const char *key, const char *val)
|
||||
static void _l4t_bl33_cfg_set_key(char *env, char *key, char *val)
|
||||
{
|
||||
strcat(env, key);
|
||||
strcat(env, "=");
|
||||
|
@ -852,9 +865,6 @@ static void _l4t_set_config(l4t_ctxt_t *ctxt, const ini_sec_t *ini_sec, int entr
|
|||
bl33_env[0] = '\0';
|
||||
char val[4] = {0};
|
||||
|
||||
// Set default SLD type.
|
||||
ctxt->sld_type = BL_MAGIC_L4TLDR_SLD;
|
||||
|
||||
// Parse ini section and prepare BL33 env.
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
|
||||
{
|
||||
|
@ -888,8 +898,6 @@ static void _l4t_set_config(l4t_ctxt_t *ctxt, const ini_sec_t *ini_sec, int entr
|
|||
ctxt->ram_oc_opt = atoi(kv->val);
|
||||
else if (!strcmp("uart_port", kv->key))
|
||||
ctxt->serial_port = atoi(kv->val);
|
||||
else if (!strcmp("sld_type", kv->key))
|
||||
ctxt->sld_type = strtol(kv->val, NULL, 16);
|
||||
|
||||
// Set key/val to BL33 env.
|
||||
_l4t_bl33_cfg_set_key(bl33_env, kv->key, kv->val);
|
||||
|
@ -1156,7 +1164,7 @@ void launch_l4t(const ini_sec_t *ini_sec, int entry_idx, int is_list, bool t210b
|
|||
_l4t_mc_config_carveout(t210b01);
|
||||
|
||||
// Deinit any unneeded HW.
|
||||
hw_deinit(false, ctxt->sld_type);
|
||||
hw_deinit(false, BL_MAGIC_L4TLDR_SLD);
|
||||
|
||||
// Do late hardware config.
|
||||
_l4t_late_hw_config(t210b01);
|
||||
|
|
|
@ -256,7 +256,7 @@
|
|||
#define FF_FS_NORTC 1
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2025
|
||||
#define FF_NORTC_YEAR 2024
|
||||
/* The option FF_FS_NORTC switches timestamp function. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
||||
|
|
|
@ -120,7 +120,7 @@ static void _reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
|
|||
}
|
||||
}
|
||||
|
||||
bool is_ipl_updated(void *buf, const char *path, bool force)
|
||||
bool is_ipl_updated(void *buf, char *path, bool force)
|
||||
{
|
||||
ipl_ver_meta_t *update_ft = (ipl_ver_meta_t *)(buf + PATCHED_RELOC_SZ + sizeof(boot_cfg_t));
|
||||
|
||||
|
@ -257,9 +257,9 @@ static void _launch_payloads()
|
|||
{
|
||||
u8 max_entries = 61;
|
||||
ment_t *ments = NULL;
|
||||
char *filelist = NULL;
|
||||
char *file_sec = NULL;
|
||||
char *dir = NULL;
|
||||
dirlist_t *filelist = NULL;
|
||||
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
@ -286,11 +286,11 @@ static void _launch_payloads()
|
|||
|
||||
while (true)
|
||||
{
|
||||
if (i > max_entries || !filelist->name[i])
|
||||
if (i > max_entries || !filelist[i * 256])
|
||||
break;
|
||||
ments[i + 2].type = INI_CHOICE;
|
||||
ments[i + 2].caption = filelist->name[i];
|
||||
ments[i + 2].data = filelist->name[i];
|
||||
ments[i + 2].caption = &filelist[i * 256];
|
||||
ments[i + 2].data = &filelist[i * 256];
|
||||
|
||||
i++;
|
||||
}
|
||||
|
@ -444,10 +444,8 @@ parse_failed:
|
|||
launch_l4t(cfg_sec, entry_idx, 1, h_cfg.t210b01);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!hos_launch(cfg_sec))
|
||||
{
|
||||
hos_launch(cfg_sec);
|
||||
|
||||
wrong_emupath:
|
||||
if (emummc_path)
|
||||
{
|
||||
|
@ -589,10 +587,8 @@ parse_failed:
|
|||
launch_l4t(cfg_sec, entry_idx, 0, h_cfg.t210b01);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!hos_launch(cfg_sec))
|
||||
{
|
||||
hos_launch(cfg_sec);
|
||||
|
||||
wrong_emupath:
|
||||
if (emummc_path)
|
||||
{
|
||||
|
@ -1354,7 +1350,7 @@ static void _about()
|
|||
{
|
||||
static const char credits[] =
|
||||
"\nhekate (c) 2018, naehrwert, st4rk\n\n"
|
||||
" (c) 2018-2025, CTCaer\n\n"
|
||||
" (c) 2018-2024, CTCaer\n\n"
|
||||
" ___________________________________________\n\n"
|
||||
"Thanks to: %kderrek, nedwill, plutoo,\n"
|
||||
" shuffle2, smea, thexyz, yellows8%k\n"
|
||||
|
@ -1450,7 +1446,7 @@ ment_t ment_top[] = {
|
|||
MDEF_END()
|
||||
};
|
||||
|
||||
menu_t menu_top = { ment_top, "hekate v6.3.1", 0, 0 };
|
||||
menu_t menu_top = { ment_top, "hekate v6.2.1", 0, 0 };
|
||||
|
||||
extern void pivot_stack(u32 stack_top);
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ clean:
|
|||
@rm -rf $(OBJS)
|
||||
|
||||
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf
|
||||
@$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$(PAYLOAD_NAME).bin
|
||||
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$(PAYLOAD_NAME).bin
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||
@$(CC) $(LDFLAGS) -T link.ld $^ -o $@
|
||||
|
|
|
@ -85,7 +85,7 @@ typedef struct
|
|||
bool emc_2X_clk_src_is_pllmb;
|
||||
bool fsp_for_src_freq;
|
||||
bool train_ram_patterns;
|
||||
u32 init_done;
|
||||
bool init_done;
|
||||
} mtc_config_t;
|
||||
|
||||
enum train_mode_t
|
||||
|
|
10
nyx/Makefile
10
nyx/Makefile
|
@ -93,12 +93,12 @@ CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
|
|||
#CUSTOMDEFINES += -DDEBUG_UART_LV_LOG
|
||||
|
||||
#TODO: Considering reinstating some of these when pointer warnings have been fixed.
|
||||
WARNINGS := -Wall -Wsign-compare -Wtype-limits -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
|
||||
WARNINGS := -Wall -Wsign-compare -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
|
||||
#-fno-delete-null-pointer-checks
|
||||
#-Wstack-usage=byte-size -fstack-usage
|
||||
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork $(WARNINGS)
|
||||
CFLAGS = $(ARCH) -O2 -g -gdwarf-4 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 $(CUSTOMDEFINES)
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
|
||||
CFLAGS = $(ARCH) -O2 -g -gdwarf-4 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=NYX_LOAD_ADDR=$(NYX_LOAD_ADDR)
|
||||
|
||||
################################################################################
|
||||
|
@ -118,11 +118,11 @@ clean:
|
|||
@rm -rf $(OUTPUTDIR)
|
||||
|
||||
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf
|
||||
@$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||
@$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||
@printf "$(TARGET) was built with the following flags:\nCFLAGS: $(CFLAGS)\nLDFLAGS: $(LDFLAGS)\n"
|
||||
@echo "Nyx was built with the following flags:\nCFLAGS: "$(CFLAGS)"\nLDFLAGS: "$(LDFLAGS)
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/%.o: %.c
|
||||
@echo Building $@
|
||||
|
|
|
@ -53,19 +53,19 @@ static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_
|
|||
*sector_start = mbr->partitions[i].start_sct;
|
||||
u8 type = mbr->partitions[i].type;
|
||||
u32 sector_size_safe = backup ? 0x400000 : (*sector_size) + 0x8000; // 2GB min safe size for backup.
|
||||
if ((curr_part_size >= sector_size_safe) && (*sector_start) && type != 0x83 && (!backup || type == 0xE0))
|
||||
if ((curr_part_size >= sector_size_safe) && *sector_start && type != 0x83 && (!backup || type == 0xE0))
|
||||
{
|
||||
if (backup)
|
||||
{
|
||||
u8 gpt_check[SD_BLOCKSIZE] = { 0 };
|
||||
sdmmc_storage_read(&sd_storage, (*sector_start) + 0xC001, 1, gpt_check);
|
||||
sdmmc_storage_read(&sd_storage, *sector_start + 0xC001, 1, gpt_check);
|
||||
if (!memcmp(gpt_check, "EFI PART", 8))
|
||||
{
|
||||
*sector_size = curr_part_size;
|
||||
*sector_start = (*sector_start) + 0x8000;
|
||||
*sector_start = *sector_start + 0x8000;
|
||||
break;
|
||||
}
|
||||
sdmmc_storage_read(&sd_storage, (*sector_start) + 0x4001, 1, gpt_check);
|
||||
sdmmc_storage_read(&sd_storage, *sector_start + 0x4001, 1, gpt_check);
|
||||
if (!memcmp(gpt_check, "EFI PART", 8))
|
||||
{
|
||||
*sector_size = curr_part_size;
|
||||
|
@ -91,7 +91,7 @@ static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_
|
|||
if (backup && *part_idx && *sector_size)
|
||||
{
|
||||
gpt_t *gpt = (gpt_t *)zalloc(sizeof(gpt_t));
|
||||
sdmmc_storage_read(&sd_storage, (*sector_start) + 0x4001, 1, gpt);
|
||||
sdmmc_storage_read(&sd_storage, *sector_start + 0x4001, 1, gpt);
|
||||
|
||||
u32 new_size = gpt->header.alt_lba + 1;
|
||||
if (*sector_size > new_size)
|
||||
|
@ -102,10 +102,10 @@ static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_
|
|||
free(gpt);
|
||||
}
|
||||
else if (!backup && *part_idx)
|
||||
*sector_start = (*sector_start) + 0x8000;
|
||||
*sector_start = *sector_start + 0x8000;
|
||||
}
|
||||
|
||||
static lv_obj_t *create_mbox_text(const char *text, bool button_ok)
|
||||
static lv_obj_t *create_mbox_text(char *text, bool button_ok)
|
||||
{
|
||||
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
|
@ -137,7 +137,7 @@ static void _update_filename(char *outFilename, u32 sdPathLen, u32 currPartIdx)
|
|||
itoa(currPartIdx, &outFilename[sdPathLen], 10);
|
||||
}
|
||||
|
||||
static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32 lba_curr, const char *outFilename, const emmc_part_t *part)
|
||||
static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32 lba_curr, char *outFilename, emmc_part_t *part)
|
||||
{
|
||||
FIL fp;
|
||||
FIL hashFp;
|
||||
|
@ -621,21 +621,11 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_part,
|
|||
res_read = !sdmmc_storage_read(&sd_storage, lba_curr + sd_sector_off, num, buf);
|
||||
|
||||
while (res_read)
|
||||
{
|
||||
if (!gui->raw_emummc)
|
||||
{
|
||||
s_printf(gui->txt_buf,
|
||||
"\n#FFDD00 Error reading %d blocks @ LBA %08X,#\n"
|
||||
"#FFDD00 from eMMC (try %d). #",
|
||||
num, lba_curr, ++retryCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_printf(gui->txt_buf,
|
||||
"\n#FFDD00 Error reading %d blocks @ LBA %08X,#\n"
|
||||
"#FFDD00 from emuMMC @ %08X (try %d). #",
|
||||
num, lba_curr + sd_sector_off, lba_curr, ++retryCount);
|
||||
}
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
|
@ -1128,7 +1118,7 @@ multipart_not_allowed:
|
|||
manual_system_maintenance(true);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
else if (!use_multipart && (((u32)((u64)f_size(&fp) >> (u64)9)) != totalSectors)) // Check total restore size vs emmc size.
|
||||
{
|
||||
|
@ -1485,13 +1475,10 @@ void restore_emmc_selected(emmcPartType_t restoreType, emmc_tool_gui_t *gui)
|
|||
|
||||
if (!res)
|
||||
s_printf(txt_buf, "#FFDD00 Failed!#\n");
|
||||
else if (res > 0)
|
||||
else
|
||||
s_printf(txt_buf, "Done!\n");
|
||||
|
||||
if (res >= 0)
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
|
||||
else
|
||||
res = 0;
|
||||
manual_system_maintenance(true);
|
||||
}
|
||||
}
|
||||
|
@ -1521,13 +1508,10 @@ void restore_emmc_selected(emmcPartType_t restoreType, emmc_tool_gui_t *gui)
|
|||
|
||||
if (!res)
|
||||
s_printf(txt_buf, "#FFDD00 Failed!#\n");
|
||||
else if (res > 0)
|
||||
else
|
||||
s_printf(txt_buf, "Done!\n");
|
||||
|
||||
if (res >= 0)
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
|
||||
else
|
||||
res = 0;
|
||||
manual_system_maintenance(true);
|
||||
}
|
||||
emmc_gpt_free(&gpt);
|
||||
|
@ -1560,13 +1544,10 @@ void restore_emmc_selected(emmcPartType_t restoreType, emmc_tool_gui_t *gui)
|
|||
|
||||
if (!res)
|
||||
s_printf(txt_buf, "#FFDD00 Failed!#\n");
|
||||
else if (res > 0)
|
||||
else
|
||||
s_printf(txt_buf, "Done!\n");
|
||||
|
||||
if (res >= 0)
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
|
||||
else
|
||||
res = 0;
|
||||
manual_system_maintenance(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ void update_emummc_base_folder(char *outFilename, u32 sdPathLen, u32 currPartIdx
|
|||
itoa(currPartIdx, &outFilename[sdPathLen], 10);
|
||||
}
|
||||
|
||||
static int _dump_emummc_file_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_storage_t *storage, const emmc_part_t *part)
|
||||
static int _dump_emummc_file_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
|
||||
{
|
||||
static const u32 FAT32_FILESIZE_LIMIT = 0xFFFFFFFF;
|
||||
static const u32 SECTORS_TO_MIB_COEFF = 11;
|
||||
|
@ -779,7 +779,7 @@ static int _emummc_raw_derive_bis_keys(emmc_tool_gui_t *gui, u32 resized_count)
|
|||
// Generate BIS keys.
|
||||
hos_bis_keygen();
|
||||
|
||||
u8 *cal0_buff = malloc(SZ_64K);
|
||||
u8 *cal0_buf = malloc(SZ_64K);
|
||||
|
||||
// Read and decrypt CAL0 for validation of working BIS keys.
|
||||
emmc_set_partition(EMMC_GPP);
|
||||
|
@ -787,11 +787,11 @@ static int _emummc_raw_derive_bis_keys(emmc_tool_gui_t *gui, u32 resized_count)
|
|||
emmc_gpt_parse(&gpt);
|
||||
emmc_part_t *cal0_part = emmc_part_find(&gpt, "PRODINFO"); // check if null
|
||||
nx_emmc_bis_init(cal0_part, false, 0);
|
||||
nx_emmc_bis_read(0, 0x40, cal0_buff);
|
||||
nx_emmc_bis_read(0, 0x40, cal0_buf);
|
||||
nx_emmc_bis_end();
|
||||
emmc_gpt_free(&gpt);
|
||||
|
||||
nx_emmc_cal0_t *cal0 = (nx_emmc_cal0_t *)cal0_buff;
|
||||
nx_emmc_cal0_t *cal0 = (nx_emmc_cal0_t *)cal0_buf;
|
||||
|
||||
// Check keys validity.
|
||||
if (memcmp(&cal0->magic, "CAL0", 4))
|
||||
|
@ -803,7 +803,7 @@ static int _emummc_raw_derive_bis_keys(emmc_tool_gui_t *gui, u32 resized_count)
|
|||
error = true;
|
||||
}
|
||||
|
||||
free(cal0_buff);
|
||||
free(cal0_buf);
|
||||
|
||||
if (error)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -38,7 +38,7 @@ extern volatile nyx_storage_t *nyx_str;
|
|||
extern lv_res_t launch_payload(lv_obj_t *list);
|
||||
|
||||
static bool disp_init_done = false;
|
||||
static bool do_auto_reload = false;
|
||||
static bool do_reload = false;
|
||||
|
||||
lv_style_t hint_small_style;
|
||||
lv_style_t hint_small_style_white;
|
||||
|
@ -200,8 +200,8 @@ static void _save_fb_to_bmp()
|
|||
if (get_tmr_ms() < timer)
|
||||
return;
|
||||
|
||||
if (do_auto_reload)
|
||||
goto exit;
|
||||
if (do_reload)
|
||||
return;
|
||||
|
||||
// Invalidate data.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||
|
@ -304,7 +304,6 @@ static void _save_fb_to_bmp()
|
|||
manual_system_maintenance(true);
|
||||
lv_mbox_start_auto_close(mbox, 4000);
|
||||
|
||||
exit:
|
||||
// Set timer to 2s.
|
||||
timer = get_tmr_ms() + 2000;
|
||||
}
|
||||
|
@ -695,7 +694,7 @@ lv_img_dsc_t *bmp_to_lvimg_obj(const char *path)
|
|||
img_desc->header.always_zero = 0;
|
||||
img_desc->header.w = bmpData.size_x;
|
||||
img_desc->header.h = bmpData.size_y;
|
||||
img_desc->header.cf = (bitmap[28] == 32) ? LV_IMG_CF_TRUE_COLOR_ALPHA : LV_IMG_CF_TRUE_COLOR; // Only LV_IMG_CF_TRUE_COLOR_ALPHA is actually allowed.
|
||||
img_desc->header.cf = (bitmap[28] == 32) ? LV_IMG_CF_TRUE_COLOR_ALPHA : LV_IMG_CF_TRUE_COLOR;
|
||||
img_desc->data_size = bmpData.size - bmpData.offset;
|
||||
img_desc->data = (u8 *)offset_copy;
|
||||
|
||||
|
@ -816,7 +815,7 @@ bool nyx_emmc_check_battery_enough()
|
|||
return true;
|
||||
}
|
||||
|
||||
static void _nyx_sd_card_issues_warning(void *param)
|
||||
static void _nyx_sd_card_issues(void *param)
|
||||
{
|
||||
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
|
@ -827,7 +826,7 @@ static void _nyx_sd_card_issues_warning(void *param)
|
|||
lv_mbox_set_recolor_text(mbox, true);
|
||||
|
||||
lv_mbox_set_text(mbox,
|
||||
"#FF8000 SD Card Issues Warning#\n\n"
|
||||
"#FF8000 SD Card Issues Check#\n\n"
|
||||
"#FFDD00 The SD Card is initialized in 1-bit mode!#\n"
|
||||
"#FFDD00 This might mean detached or broken connector!#\n\n"
|
||||
"You might want to check\n#C7EA46 Console Info# -> #C7EA46 microSD#");
|
||||
|
@ -867,7 +866,7 @@ void nyx_window_toggle_buttons(lv_obj_t *win, bool disable)
|
|||
}
|
||||
}
|
||||
|
||||
lv_res_t nyx_win_close_action_custom(lv_obj_t * btn)
|
||||
lv_res_t lv_win_close_action_custom(lv_obj_t * btn)
|
||||
{
|
||||
close_btn = NULL;
|
||||
|
||||
|
@ -887,7 +886,7 @@ lv_obj_t *nyx_create_standard_window(const char *win_title)
|
|||
lv_win_set_style(win, LV_WIN_STYLE_BG, &win_bg_style);
|
||||
lv_obj_set_size(win, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
close_btn = lv_win_add_btn(win, NULL, SYMBOL_CLOSE" Close", nyx_win_close_action_custom);
|
||||
close_btn = lv_win_add_btn(win, NULL, SYMBOL_CLOSE" Close", lv_win_close_action_custom);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
@ -929,27 +928,8 @@ static void _launch_hos(u8 autoboot, u8 autoboot_list)
|
|||
(*main_ptr)();
|
||||
}
|
||||
|
||||
void reload_nyx(lv_obj_t *obj, bool force)
|
||||
void reload_nyx()
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
sd_mount();
|
||||
|
||||
// Check that Nyx still exists.
|
||||
if (f_stat("bootloader/sys/nyx.bin", NULL))
|
||||
{
|
||||
sd_unmount();
|
||||
|
||||
// Remove lvgl object in case of being invoked from a window.
|
||||
if (obj)
|
||||
lv_obj_del(obj);
|
||||
|
||||
do_auto_reload = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
b_cfg->boot_cfg = BOOT_CFG_AUTOBOOT_EN;
|
||||
b_cfg->autoboot = 0;
|
||||
b_cfg->autoboot_list = 0;
|
||||
|
@ -967,7 +947,7 @@ void reload_nyx(lv_obj_t *obj, bool force)
|
|||
static lv_res_t reload_action(lv_obj_t *btns, const char *txt)
|
||||
{
|
||||
if (!lv_btnm_get_pressed(btns))
|
||||
reload_nyx(NULL, false);
|
||||
reload_nyx();
|
||||
|
||||
return mbox_action(btns, txt);
|
||||
}
|
||||
|
@ -989,7 +969,7 @@ static lv_res_t _removed_sd_action(lv_obj_t *btns, const char *txt)
|
|||
break;
|
||||
case 2:
|
||||
sd_end();
|
||||
do_auto_reload = false;
|
||||
do_reload = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -998,14 +978,12 @@ static lv_res_t _removed_sd_action(lv_obj_t *btns, const char *txt)
|
|||
|
||||
static void _check_sd_card_removed(void *params)
|
||||
{
|
||||
static lv_obj_t *dark_bg = NULL;
|
||||
|
||||
// The following checks if SDMMC_1 is initialized.
|
||||
// If yes and card was removed, shows a message box,
|
||||
// that will reload Nyx, when the card is inserted again.
|
||||
if (!do_auto_reload && sd_get_card_removed())
|
||||
if (!do_reload && sd_get_card_removed())
|
||||
{
|
||||
dark_bg = lv_obj_create(lv_scr_act(), NULL);
|
||||
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);
|
||||
|
||||
|
@ -1021,16 +999,16 @@ static void _check_sd_card_removed(void *params)
|
|||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_top(mbox, true);
|
||||
|
||||
do_auto_reload = true;
|
||||
do_reload = true;
|
||||
}
|
||||
|
||||
// If in reload state and card was inserted, reload nyx.
|
||||
if (do_auto_reload && !sd_get_card_removed())
|
||||
reload_nyx(dark_bg, false);
|
||||
if (do_reload && !sd_get_card_removed())
|
||||
reload_nyx();
|
||||
}
|
||||
|
||||
lv_task_t *task_emmc_errors;
|
||||
static void _nyx_emmc_issues_warning(void *params)
|
||||
static void _nyx_emmc_issues(void *params)
|
||||
{
|
||||
if (emmc_get_mode() < EMMC_MMC_HS400)
|
||||
{
|
||||
|
@ -1046,8 +1024,8 @@ static void _nyx_emmc_issues_warning(void *params)
|
|||
lv_mbox_set_recolor_text(mbox, true);
|
||||
|
||||
lv_mbox_set_text(mbox,
|
||||
"#FF8000 eMMC Issues Warning#\n\n"
|
||||
"#FFDD00 Your eMMC is initialized in a slower mode!#\n"
|
||||
"#FF8000 eMMC Issues Check#\n\n"
|
||||
"#FFDD00 Your eMMC is initialized in slower mode!#\n"
|
||||
"#FFDD00 This might mean hardware issues!#\n\n"
|
||||
"You might want to check\n#C7EA46 Console Info# -> #C7EA46 eMMC#");
|
||||
|
||||
|
@ -1254,9 +1232,9 @@ static void _create_tab_about(lv_theme_t * th, lv_obj_t * parent)
|
|||
lv_label_set_recolor(lbl_credits, true);
|
||||
lv_label_set_static_text(lbl_credits,
|
||||
"#C7EA46 hekate# (c) 2018, #C7EA46 naehrwert#, #C7EA46 st4rk#\n"
|
||||
" (c) 2018-2025, #C7EA46 CTCaer#\n"
|
||||
" (c) 2018-2024, #C7EA46 CTCaer#\n"
|
||||
"\n"
|
||||
"#C7EA46 Nyx# (c) 2019-2025, #C7EA46 CTCaer#\n"
|
||||
"#C7EA46 Nyx# (c) 2019-2024, #C7EA46 CTCaer#\n"
|
||||
"\n"
|
||||
"Thanks to: #00CCFF derrek, nedwill, plutoo, #\n"
|
||||
" #00CCFF shuffle2, smea, thexyz, yellows8 #\n"
|
||||
|
@ -1416,7 +1394,7 @@ static lv_res_t _create_mbox_payloads(lv_obj_t *btn)
|
|||
goto out_end;
|
||||
}
|
||||
|
||||
dirlist_t *filelist = dirlist("bootloader/payloads", NULL, false, false);
|
||||
char *filelist = dirlist("bootloader/payloads", NULL, false, false);
|
||||
sd_unmount();
|
||||
|
||||
u32 i = 0;
|
||||
|
@ -1424,9 +1402,9 @@ static lv_res_t _create_mbox_payloads(lv_obj_t *btn)
|
|||
{
|
||||
while (true)
|
||||
{
|
||||
if (!filelist->name[i])
|
||||
if (!filelist[i * 256])
|
||||
break;
|
||||
lv_list_add(list, NULL, filelist->name[i], launch_payload);
|
||||
lv_list_add(list, NULL, &filelist[i * 256], launch_payload);
|
||||
i++;
|
||||
}
|
||||
free(filelist);
|
||||
|
@ -1462,15 +1440,15 @@ static lv_res_t _launch_more_cfg_action(lv_obj_t *btn)
|
|||
static lv_res_t _win_launch_close_action(lv_obj_t * btn)
|
||||
{
|
||||
// Cleanup icons.
|
||||
for (u32 i = 0; i < (n_cfg.entries_5_col ? 10 : 8); i++)
|
||||
for (u32 i = 0; i < 8; i++)
|
||||
{
|
||||
lv_obj_t *btns = launch_ctxt.btn[i];
|
||||
lv_btn_ext_t *ext = lv_obj_get_ext_attr(btns);
|
||||
lv_obj_t *btn = launch_ctxt.btn[i];
|
||||
lv_btn_ext_t *ext = lv_obj_get_ext_attr(btn);
|
||||
if (ext->idx)
|
||||
{
|
||||
// This gets latest object, which is the button overlay. So iterate 2 times.
|
||||
lv_obj_t * img = lv_obj_get_child(btns, NULL);
|
||||
img = lv_obj_get_child(btns, img);
|
||||
lv_obj_t * img = lv_obj_get_child(btn, NULL);
|
||||
img = lv_obj_get_child(btn, img);
|
||||
|
||||
lv_img_dsc_t *src = (lv_img_dsc_t *)lv_img_get_src(img);
|
||||
|
||||
|
@ -1854,7 +1832,7 @@ ini_parsing:
|
|||
}
|
||||
|
||||
// Add button mask/radius and align icon.
|
||||
lv_obj_t *btns = lv_btn_create(launch_ctxt.btn[curr_btn_idx], NULL);
|
||||
lv_obj_t *btn = lv_btn_create(launch_ctxt.btn[curr_btn_idx], NULL);
|
||||
u32 btn_width = 200;
|
||||
u32 btn_height = 200;
|
||||
if (img_noborder)
|
||||
|
@ -1870,25 +1848,25 @@ ini_parsing:
|
|||
lv_btn_set_style(launch_ctxt.btn[curr_btn_idx], LV_BTN_STYLE_REL, &btn_home_noborder_rel);
|
||||
lv_btn_set_style(launch_ctxt.btn[curr_btn_idx], LV_BTN_STYLE_PR, &btn_home_noborder_rel);
|
||||
}
|
||||
lv_obj_set_size(btns, btn_width, btn_height);
|
||||
lv_btn_set_style(btns, LV_BTN_STYLE_REL, img_noborder ? &btn_home_noborder_rel : &btn_home_transp_rel);
|
||||
lv_btn_set_style(btns, LV_BTN_STYLE_PR, &btn_home_transp_pr);
|
||||
lv_obj_set_size(btn, btn_width, btn_height);
|
||||
lv_btn_set_style(btn, LV_BTN_STYLE_REL, img_noborder ? &btn_home_noborder_rel : &btn_home_transp_rel);
|
||||
lv_btn_set_style(btn, LV_BTN_STYLE_PR, &btn_home_transp_pr);
|
||||
if (img)
|
||||
lv_obj_align(img, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
if (img_noborder)
|
||||
lv_obj_align(btns, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_align(btn, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
// Set autoboot index.
|
||||
ext = lv_obj_get_ext_attr(btns);
|
||||
ext = lv_obj_get_ext_attr(btn);
|
||||
ext->idx = entry_idx;
|
||||
ext = lv_obj_get_ext_attr(launch_ctxt.btn[curr_btn_idx]); // Redundancy.
|
||||
ext->idx = entry_idx;
|
||||
|
||||
// Set action.
|
||||
if (!more_cfg)
|
||||
lv_btn_set_action(btns, LV_BTN_ACTION_CLICK, _launch_action);
|
||||
lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _launch_action);
|
||||
else
|
||||
lv_btn_set_action(btns, LV_BTN_ACTION_CLICK, _launch_more_cfg_action);
|
||||
lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _launch_more_cfg_action);
|
||||
|
||||
// Set button's label text.
|
||||
lv_label_set_text(launch_ctxt.label[curr_btn_idx], ini_sec->name);
|
||||
|
@ -2101,7 +2079,6 @@ static void _create_status_bar(lv_theme_t * th)
|
|||
{
|
||||
static lv_obj_t *status_bar_bg;
|
||||
status_bar_bg = lv_cont_create(lv_layer_top(), NULL);
|
||||
status_bar.bar_bg = status_bar_bg;
|
||||
|
||||
static lv_style_t status_bar_style;
|
||||
lv_style_copy(&status_bar_style, &lv_style_plain_color);
|
||||
|
@ -2154,9 +2131,9 @@ static void _create_status_bar(lv_theme_t * th)
|
|||
lv_obj_set_size(btn_mid, LV_DPI * 5 / 2, LV_DPI / 2);
|
||||
lv_obj_align(btn_mid, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
status_bar.mid = btn_mid;
|
||||
lv_obj_set_opa_scale(btn_mid, LV_OPA_0);
|
||||
lv_obj_set_opa_scale_enable(btn_mid, true);
|
||||
lv_obj_set_click(btn_mid, false);
|
||||
lv_obj_set_opa_scale(status_bar.mid, LV_OPA_0);
|
||||
lv_obj_set_opa_scale_enable(status_bar.mid, true);
|
||||
lv_obj_set_click(status_bar.mid, false);
|
||||
lv_btn_set_action(btn_mid, LV_BTN_ACTION_CLICK, _save_options_action);
|
||||
}
|
||||
|
||||
|
@ -2377,7 +2354,7 @@ static void _nyx_main_menu(lv_theme_t * th)
|
|||
|
||||
lv_task_create(_check_sd_card_removed, 2000, LV_TASK_PRIO_LOWEST, NULL);
|
||||
|
||||
task_emmc_errors = lv_task_create(_nyx_emmc_issues_warning, 2000, LV_TASK_PRIO_LOWEST, NULL);
|
||||
task_emmc_errors = lv_task_create(_nyx_emmc_issues, 2000, LV_TASK_PRIO_LOWEST, NULL);
|
||||
lv_task_ready(task_emmc_errors);
|
||||
|
||||
// Create top level global line separators.
|
||||
|
@ -2477,19 +2454,16 @@ void nyx_load_and_run()
|
|||
// Check if sd card issues.
|
||||
if (sd_get_mode() == SD_1BIT_HS25)
|
||||
{
|
||||
lv_task_t *task_run_sd_errors = lv_task_create(_nyx_sd_card_issues_warning, LV_TASK_ONESHOT, LV_TASK_PRIO_LOWEST, NULL);
|
||||
lv_task_t *task_run_sd_errors = lv_task_create(_nyx_sd_card_issues, LV_TASK_ONESHOT, LV_TASK_PRIO_LOWEST, NULL);
|
||||
lv_task_once(task_run_sd_errors);
|
||||
}
|
||||
|
||||
// Gui loop.
|
||||
if (h_cfg.t210b01)
|
||||
{
|
||||
// Minerva not supported on T210B01 yet. Slight power saving via spinlock.
|
||||
// Minerva not supported on T210B01 yet. No power saving.
|
||||
while (true)
|
||||
{
|
||||
lv_task_handler();
|
||||
usleep(400);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2019 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,
|
||||
|
@ -36,7 +36,6 @@ typedef struct _emmc_tool_gui_t
|
|||
|
||||
typedef struct _gui_status_bar_ctx
|
||||
{
|
||||
lv_obj_t *bar_bg;
|
||||
lv_obj_t *mid;
|
||||
lv_obj_t *time_temp;
|
||||
lv_obj_t *temp_symbol;
|
||||
|
@ -73,7 +72,6 @@ void reload_nyx();
|
|||
lv_img_dsc_t *bmp_to_lvimg_obj(const char *path);
|
||||
lv_res_t mbox_action(lv_obj_t * btns, const char * txt);
|
||||
bool nyx_emmc_check_battery_enough();
|
||||
lv_res_t nyx_win_close_action_custom(lv_obj_t * btn);
|
||||
void nyx_window_toggle_buttons(lv_obj_t *win, bool disable);
|
||||
lv_obj_t *nyx_create_standard_window(const char *win_title);
|
||||
lv_obj_t *nyx_create_window_custom_close_btn(const char *win_title, lv_action_t rel_action);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
* Copyright (c) 2019-2022 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,
|
||||
|
@ -42,7 +42,8 @@ static lv_res_t (*emummc_tools)(lv_obj_t *btn);
|
|||
|
||||
static lv_res_t _action_emummc_window_close(lv_obj_t *btn)
|
||||
{
|
||||
nyx_win_close_action_custom(btn);
|
||||
lv_win_close_action(btn);
|
||||
close_btn = NULL;
|
||||
|
||||
// Delete and relaunch main emuMMC window.
|
||||
lv_obj_del(emummc_manage_window);
|
||||
|
@ -748,7 +749,7 @@ static lv_res_t _create_emummc_migrate_action(lv_obj_t * btns, const char * txt)
|
|||
|
||||
typedef struct _emummc_images_t
|
||||
{
|
||||
dirlist_t *dirlist;
|
||||
char *dirlist;
|
||||
u32 part_sector[3];
|
||||
u32 part_type[3];
|
||||
u32 part_end[3];
|
||||
|
@ -1008,9 +1009,9 @@ static lv_res_t _create_change_emummc_window(lv_obj_t *btn_caller)
|
|||
FIL fp;
|
||||
|
||||
// Check for sd raw partitions, based on the folders in /emuMMC.
|
||||
while (emummc_img->dirlist->name[emummc_idx])
|
||||
while (emummc_img->dirlist[emummc_idx * 256])
|
||||
{
|
||||
s_printf(path, "emuMMC/%s/raw_based", emummc_img->dirlist->name[emummc_idx]);
|
||||
s_printf(path, "emuMMC/%s/raw_based", &emummc_img->dirlist[emummc_idx * 256]);
|
||||
|
||||
if (!f_stat(path, NULL))
|
||||
{
|
||||
|
@ -1023,21 +1024,21 @@ static lv_res_t _create_change_emummc_window(lv_obj_t *btn_caller)
|
|||
if ((curr_list_sector == 2) || (emummc_img->part_sector[0] && curr_list_sector >= emummc_img->part_sector[0] &&
|
||||
curr_list_sector < emummc_img->part_end[0] && emummc_img->part_type[0] != 0x83))
|
||||
{
|
||||
s_printf(&emummc_img->part_path[0], "emuMMC/%s", emummc_img->dirlist->name[emummc_idx]);
|
||||
s_printf(&emummc_img->part_path[0], "emuMMC/%s", &emummc_img->dirlist[emummc_idx * 256]);
|
||||
emummc_img->part_sector[0] = curr_list_sector;
|
||||
emummc_img->part_end[0] = 0;
|
||||
}
|
||||
else if (emummc_img->part_sector[1] && curr_list_sector >= emummc_img->part_sector[1] &&
|
||||
curr_list_sector < emummc_img->part_end[1] && emummc_img->part_type[1] != 0x83)
|
||||
{
|
||||
s_printf(&emummc_img->part_path[1 * 128], "emuMMC/%s", emummc_img->dirlist->name[emummc_idx]);
|
||||
s_printf(&emummc_img->part_path[1 * 128], "emuMMC/%s", &emummc_img->dirlist[emummc_idx * 256]);
|
||||
emummc_img->part_sector[1] = curr_list_sector;
|
||||
emummc_img->part_end[1] = 0;
|
||||
}
|
||||
else if (emummc_img->part_sector[2] && curr_list_sector >= emummc_img->part_sector[2] &&
|
||||
curr_list_sector < emummc_img->part_end[2] && emummc_img->part_type[2] != 0x83)
|
||||
{
|
||||
s_printf(&emummc_img->part_path[2 * 128], "emuMMC/%s", emummc_img->dirlist->name[emummc_idx]);
|
||||
s_printf(&emummc_img->part_path[2 * 128], "emuMMC/%s", &emummc_img->dirlist[emummc_idx * 256]);
|
||||
emummc_img->part_sector[2] = curr_list_sector;
|
||||
emummc_img->part_end[2] = 0;
|
||||
}
|
||||
|
@ -1049,19 +1050,19 @@ static lv_res_t _create_change_emummc_window(lv_obj_t *btn_caller)
|
|||
u32 file_based_idx = 0;
|
||||
|
||||
// Sanitize the directory list with sd file based ones.
|
||||
while (emummc_img->dirlist->name[emummc_idx])
|
||||
while (emummc_img->dirlist[emummc_idx * 256])
|
||||
{
|
||||
s_printf(path, "emuMMC/%s/file_based", emummc_img->dirlist->name[emummc_idx]);
|
||||
s_printf(path, "emuMMC/%s/file_based", &emummc_img->dirlist[emummc_idx * 256]);
|
||||
|
||||
if (!f_stat(path, NULL))
|
||||
{
|
||||
char *tmp = emummc_img->dirlist->name[emummc_idx];
|
||||
memcpy(emummc_img->dirlist->name[file_based_idx], tmp, strlen(tmp) + 1);
|
||||
char *tmp = &emummc_img->dirlist[emummc_idx * 256];
|
||||
memcpy(&emummc_img->dirlist[file_based_idx * 256], tmp, strlen(tmp) + 1);
|
||||
file_based_idx++;
|
||||
}
|
||||
emummc_idx++;
|
||||
}
|
||||
emummc_img->dirlist->name[file_based_idx] = NULL;
|
||||
emummc_img->dirlist[file_based_idx * 256] = 0;
|
||||
|
||||
out0:;
|
||||
static lv_style_t h_style;
|
||||
|
@ -1178,9 +1179,9 @@ out0:;
|
|||
emummc_idx = 0;
|
||||
|
||||
// Add file based to the list.
|
||||
while (emummc_img->dirlist->name[emummc_idx])
|
||||
while (emummc_img->dirlist[emummc_idx * 256])
|
||||
{
|
||||
s_printf(path, "emuMMC/%s", emummc_img->dirlist->name[emummc_idx]);
|
||||
s_printf(path, "emuMMC/%s", &emummc_img->dirlist[emummc_idx * 256]);
|
||||
|
||||
lv_list_add(list_sd_based, NULL, path, _save_file_emummc_cfg_action);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -24,8 +24,6 @@
|
|||
#include "../hos/pkg1.h"
|
||||
#include <libs/fatfs/ff.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SECTORS_TO_MIB_COEFF 11
|
||||
|
||||
extern hekate_config h_cfg;
|
||||
|
@ -353,21 +351,9 @@ out:
|
|||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
static lv_obj_t *hw_info_ver = NULL;
|
||||
static lv_res_t _action_win_hw_info_status_close(lv_obj_t *btn)
|
||||
static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
{
|
||||
if (hw_info_ver)
|
||||
{
|
||||
lv_obj_del(hw_info_ver);
|
||||
hw_info_ver = NULL;
|
||||
}
|
||||
|
||||
return nyx_win_close_action_custom(btn);
|
||||
}
|
||||
|
||||
static lv_res_t _create_window_hw_info_status(lv_obj_t *btn)
|
||||
{
|
||||
lv_obj_t *win = nyx_create_window_custom_close_btn(SYMBOL_CHIP" HW & Fuses Info", _action_win_hw_info_status_close);
|
||||
lv_obj_t *win = nyx_create_standard_window(SYMBOL_CHIP" HW & Fuses Info");
|
||||
lv_win_add_btn(win, NULL, SYMBOL_DOWNLOAD" Dump fuses", _fuse_dump_window_action);
|
||||
lv_win_add_btn(win, NULL, SYMBOL_INFO" CAL0 Info", _create_mbox_cal0);
|
||||
|
||||
|
@ -379,14 +365,6 @@ static lv_res_t _create_window_hw_info_status(lv_obj_t *btn)
|
|||
lv_label_set_recolor(lb_desc, true);
|
||||
lv_label_set_style(lb_desc, &monospace_text);
|
||||
|
||||
char version[32];
|
||||
s_printf(version, "%s%d.%d.%d%c", NYX_VER_RL ? "v" : "", NYX_VER_MJ, NYX_VER_MN, NYX_VER_HF, NYX_VER_RL > 'A' ? NYX_VER_RL : 0);
|
||||
lv_obj_t * lbl_ver = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_label_set_style(lbl_ver, &hint_small_style_white);
|
||||
lv_label_set_text(lbl_ver, version);
|
||||
lv_obj_align(lbl_ver, status_bar.bar_bg, LV_ALIGN_OUT_TOP_RIGHT, -LV_DPI * 9 / 23, -LV_DPI * 2 / 13);
|
||||
hw_info_ver = lbl_ver;
|
||||
|
||||
lv_label_set_static_text(lb_desc,
|
||||
"#FF8000 SoC:#\n"
|
||||
"#FF8000 SKU:#\n"
|
||||
|
@ -609,13 +587,7 @@ static lv_res_t _create_window_hw_info_status(lv_obj_t *btn)
|
|||
strcpy(fuses_hos_version, "16.0.0 - 16.1.0");
|
||||
break;
|
||||
case 19:
|
||||
strcpy(fuses_hos_version, "17.0.0 - 18.1.0");
|
||||
break;
|
||||
case 20:
|
||||
strcpy(fuses_hos_version, "19.0.0 - 19.0.1");
|
||||
break;
|
||||
case 21:
|
||||
strcpy(fuses_hos_version, "20.0.0+");
|
||||
strcpy(fuses_hos_version, "17.0.0+");
|
||||
break;
|
||||
case 255:
|
||||
strcpy(fuses_hos_version, "#FFD000 Overburnt#");
|
||||
|
@ -688,7 +660,7 @@ static lv_res_t _create_window_hw_info_status(lv_obj_t *btn)
|
|||
u32 ranks = EMC(EMC_ADR_CFG) + 1;
|
||||
u32 channels = (EMC(EMC_FBIO_CFG7) >> 1) & 3;
|
||||
channels = (channels & 1) + ((channels & 2) >> 1);
|
||||
s_printf(txt_buf, "#00DDFF %s SDRAM ##FF8000 (Module 0 | 1):#\n#FF8000 Vendor:# ", h_cfg.t210b01 ? "LPDDR4X" : "LPDDR4");
|
||||
s_printf(txt_buf, "#00DDFF %s SDRAM ##FF8000 (Ch 0 | Ch 1):#\n#FF8000 Vendor:# ", h_cfg.t210b01 ? "LPDDR4X" : "LPDDR4");
|
||||
switch (ram_vendor.chip0.rank0_ch0)
|
||||
{
|
||||
case 1:
|
||||
|
@ -760,76 +732,49 @@ static lv_res_t _create_window_hw_info_status(lv_obj_t *btn)
|
|||
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Unknown# (%d)", ram_vendor.chip1.rank0_ch0);
|
||||
break;
|
||||
}
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 Rev ID:# %X.%02X #FF8000 |# %X.%02X\n#FF8000 Density:# ",
|
||||
ram_rev0.chip0.rank0_ch0, ram_rev1.chip0.rank0_ch0, ram_rev0.chip1.rank0_ch0, ram_rev1.chip1.rank0_ch0);
|
||||
|
||||
u32 actual_ranks = (ram_vendor.chip0.rank0_ch0 == ram_vendor.chip0.rank1_ch0 &&
|
||||
ram_vendor.chip0.rank0_ch1 == ram_vendor.chip0.rank1_ch1 &&
|
||||
ram_rev0.chip0.rank0_ch0 == ram_rev0.chip0.rank1_ch0 &&
|
||||
ram_rev0.chip0.rank0_ch1 == ram_rev0.chip0.rank1_ch1 &&
|
||||
ram_rev1.chip0.rank0_ch0 == ram_rev1.chip0.rank1_ch0 &&
|
||||
ram_rev1.chip0.rank0_ch1 == ram_rev1.chip0.rank1_ch1 &&
|
||||
ram_density.chip0.rank0_ch0 == ram_density.chip0.rank1_ch0 &&
|
||||
ram_density.chip0.rank0_ch1 == ram_density.chip0.rank1_ch1)
|
||||
? 2 : 1;
|
||||
bool rank_bad = ranks != actual_ranks;
|
||||
s_printf(txt_buf + strlen(txt_buf), "%s %d x %s", rank_bad ? "#FFDD00" : "", actual_ranks * channels, rank_bad ? "#" : "");
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 Rev ID:# %X.%02X #FF8000 |# %X.%02X\n#FF8000 Density:# %d",
|
||||
ram_rev0.chip0.rank0_ch0, ram_rev1.chip0.rank0_ch0, ram_rev0.chip1.rank0_ch0, ram_rev1.chip1.rank0_ch0, ranks * channels);
|
||||
switch ((ram_density.chip0.rank0_ch0 & 0x3C) >> 2)
|
||||
{
|
||||
case 2:
|
||||
strcat(txt_buf, "512MB");
|
||||
strcat(txt_buf, " x 512MB");
|
||||
break;
|
||||
case 3:
|
||||
strcat(txt_buf, "768MB");
|
||||
strcat(txt_buf, " x 768MB");
|
||||
break;
|
||||
case 4:
|
||||
strcat(txt_buf, "1GB");
|
||||
strcat(txt_buf, " x 1GB");
|
||||
break;
|
||||
case 5:
|
||||
strcat(txt_buf, "1.5GB");
|
||||
strcat(txt_buf, " x 1.5GB");
|
||||
break;
|
||||
case 6:
|
||||
strcat(txt_buf, "2GB");
|
||||
strcat(txt_buf, " x 2GB");
|
||||
break;
|
||||
default:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Unk (%d)", (ram_density.chip0.rank0_ch0 & 0x3C) >> 2);
|
||||
s_printf(txt_buf + strlen(txt_buf), " x Unk (%d)", (ram_density.chip0.rank0_ch0 & 0x3C) >> 2);
|
||||
break;
|
||||
}
|
||||
|
||||
actual_ranks = (ram_vendor.chip1.rank0_ch0 == ram_vendor.chip1.rank1_ch0 &&
|
||||
ram_vendor.chip1.rank0_ch1 == ram_vendor.chip1.rank1_ch1 &&
|
||||
ram_rev0.chip1.rank0_ch0 == ram_rev0.chip1.rank1_ch0 &&
|
||||
ram_rev0.chip1.rank0_ch1 == ram_rev0.chip1.rank1_ch1 &&
|
||||
ram_rev1.chip1.rank0_ch0 == ram_rev1.chip1.rank1_ch0 &&
|
||||
ram_rev1.chip1.rank0_ch1 == ram_rev1.chip1.rank1_ch1 &&
|
||||
ram_density.chip1.rank0_ch0 == ram_density.chip1.rank1_ch0 &&
|
||||
ram_density.chip1.rank0_ch1 == ram_density.chip1.rank1_ch1)
|
||||
? 2 : 1;
|
||||
rank_bad = ranks != actual_ranks;
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), " #FF8000 |# %s %d x %s", rank_bad ? "#FFDD00" : "", actual_ranks * channels, rank_bad ? "#" : "");
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), " #FF8000 |# %d", ranks * channels);
|
||||
switch ((ram_density.chip1.rank0_ch0 & 0x3C) >> 2)
|
||||
{
|
||||
case 2:
|
||||
strcat(txt_buf, "512MB");
|
||||
strcat(txt_buf, " x 512MB");
|
||||
break;
|
||||
case 3:
|
||||
strcat(txt_buf, "768MB");
|
||||
strcat(txt_buf, " x 768MB");
|
||||
break;
|
||||
case 4:
|
||||
strcat(txt_buf, "1GB");
|
||||
strcat(txt_buf, " x 1GB");
|
||||
break;
|
||||
case 5:
|
||||
strcat(txt_buf, "1.5GB");
|
||||
strcat(txt_buf, " x 1.5GB");
|
||||
break;
|
||||
case 6:
|
||||
strcat(txt_buf, "2GB");
|
||||
strcat(txt_buf, " x 2GB");
|
||||
break;
|
||||
default:
|
||||
s_printf(txt_buf + strlen(txt_buf), "Unk (%d)", (ram_density.chip1.rank0_ch0 & 0x3C) >> 2);
|
||||
s_printf(txt_buf + strlen(txt_buf), " x Unk (%d)", (ram_density.chip1.rank0_ch0 & 0x3C) >> 2);
|
||||
break;
|
||||
}
|
||||
strcat(txt_buf, "\n\n");
|
||||
|
@ -992,13 +937,13 @@ static lv_res_t _create_window_hw_info_status(lv_obj_t *btn)
|
|||
if (touch_panel)
|
||||
panel_ic_paired = touch_panel->idx == 0; // NISSHA NFT-K12D.
|
||||
break;
|
||||
// case 0x98000004: // New 6.2" panel?
|
||||
// case 0x50000001:
|
||||
// case 0x50000002:
|
||||
// strcat(txt_buf, "FST2 UNK");
|
||||
// if (touch_panel)
|
||||
// panel_ic_paired = touch_panel->idx == 0;
|
||||
// break;
|
||||
case 0x98000004: // New 6.2" panel?
|
||||
case 0x50000001:
|
||||
case 0x50000002:
|
||||
strcat(txt_buf, "FST2 UNK");
|
||||
if (touch_panel)
|
||||
panel_ic_paired = touch_panel->idx == 0;
|
||||
break;
|
||||
case 0x001A0300:
|
||||
case 0x32000102:
|
||||
strcat(txt_buf, "4CD60D/2");
|
||||
|
@ -1026,7 +971,7 @@ static lv_res_t _create_window_hw_info_status(lv_obj_t *btn)
|
|||
panel_ic_paired = touch_panel->idx == 4; // Samsung BH2109.
|
||||
break;
|
||||
default:
|
||||
strcat(txt_buf, "#FF8000 Contact me#");
|
||||
strcat(txt_buf, "#FF8000 Unknown#");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1051,6 +996,9 @@ static lv_res_t _create_window_hw_info_status(lv_obj_t *btn)
|
|||
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
|
||||
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 4, 0);
|
||||
|
||||
if (!btn)
|
||||
_create_mbox_cal0(NULL);
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
|
@ -1348,11 +1296,12 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
|||
static const char * mbox_btn_map[] = { "\251", "\222OK", "\251", "" };
|
||||
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 * 3 / 7);
|
||||
lv_obj_set_width(mbox, LV_HOR_RES / 7 * 4);
|
||||
|
||||
char *txt_buf = (char *)malloc(SZ_16K);
|
||||
|
||||
s_printf(txt_buf, "#FF8000 %s Benchmark#\n[Raw Reads] Abort: VOL- & VOL+", sd_bench ? "SD Card" : "eMMC");
|
||||
s_printf(txt_buf, "#FF8000 %s Benchmark#\n[Raw Reads] Abort: VOL- & VOL+",
|
||||
sd_bench ? "SD Card" : "eMMC");
|
||||
|
||||
lv_mbox_set_text(mbox, txt_buf);
|
||||
txt_buf[0] = 0;
|
||||
|
@ -1401,60 +1350,30 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
|||
goto out;
|
||||
}
|
||||
|
||||
// Set benchmark parameters.
|
||||
const u32 sct_blk_seq = 0x8000; // 16MB. A2 spec denotes 4MB, but using older big AU.
|
||||
const u32 sct_blk_4kb = 8; // 4KB.
|
||||
const u32 sct_rem_seq = 0x200000; // 1GB. A2 spec.
|
||||
const u32 sct_rem_4kb = 0x80000; // 256MB. A2 spec.
|
||||
const u32 sct_num_1mb = 0x800; // 1MB.
|
||||
const u32 size_bytes_seq = sct_rem_seq * SDMMC_DAT_BLOCKSIZE;
|
||||
const u32 size_bytes_4kb = sct_rem_4kb * SDMMC_DAT_BLOCKSIZE;
|
||||
|
||||
// Set calculation divider. 1000 or 1024. (Does not affect IOPS).
|
||||
u32 mb_div = 1000; // Unfortunately most software uses fake MB.
|
||||
|
||||
char *mbs_text;
|
||||
switch (mb_div)
|
||||
{
|
||||
case 1000:
|
||||
mbs_text = "MB/s";
|
||||
break;
|
||||
case 1024:
|
||||
mbs_text = "MiB/s";
|
||||
break;
|
||||
}
|
||||
|
||||
// Set actual div in MB/MiB.
|
||||
mb_div *= mb_div;
|
||||
|
||||
int error = 0;
|
||||
u32 iters = 3;
|
||||
u32 offset_chunk_start = ALIGN_DOWN(storage->sec_cnt / 3, sct_blk_seq); // Align to block.
|
||||
u32 offset_chunk_start = ALIGN_DOWN(storage->sec_cnt / 3, 0x8000); // Align to 16MB.
|
||||
if (storage->sec_cnt < 0xC00000)
|
||||
iters -= 2; // 4GB card.
|
||||
|
||||
u32 rnd_off_cnt = sct_rem_4kb / sct_blk_4kb;
|
||||
u32 *random_offsets = malloc(rnd_off_cnt * sizeof(u32));
|
||||
u32 *times_taken_4k = malloc(rnd_off_cnt * sizeof(u32));
|
||||
|
||||
for (u32 iter_curr = 0; iter_curr < iters; iter_curr++)
|
||||
{
|
||||
u32 pct = 0;
|
||||
u32 prevPct = 200;
|
||||
u32 timer = 0;
|
||||
u32 lba_curr = 0;
|
||||
u32 sector_off = offset_chunk_start * iter_curr;
|
||||
u32 sector_num = sct_blk_seq;
|
||||
u32 data_remaining = sct_rem_seq;
|
||||
u32 sector = offset_chunk_start * iter_curr;
|
||||
u32 sector_num = 0x8000; // 16MB chunks.
|
||||
u32 data_remaining = 0x200000; // 1GB.
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "#C7EA46 %d/3# - Sector Offset #C7EA46 %08X#:\n", iter_curr + 1, sector_off);
|
||||
s_printf(txt_buf + strlen(txt_buf), "#C7EA46 %d/3# - Sector Offset #C7EA46 %08X#:\n", iter_curr + 1, sector);
|
||||
|
||||
u32 render_min_ms = 66;
|
||||
u32 render_timer = get_tmr_ms() + render_min_ms;
|
||||
while (data_remaining)
|
||||
{
|
||||
u32 time_taken = get_tmr_us();
|
||||
error = !sdmmc_storage_read(storage, sector_off + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED);
|
||||
error = !sdmmc_storage_read(storage, sector + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED);
|
||||
time_taken = get_tmr_us() - time_taken;
|
||||
timer += time_taken;
|
||||
|
||||
|
@ -1462,7 +1381,7 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
|||
data_remaining -= sector_num;
|
||||
lba_curr += sector_num;
|
||||
|
||||
pct = (lba_curr * 100) / sct_rem_seq;
|
||||
pct = (lba_curr * 100) / 0x200000;
|
||||
if (pct != prevPct && render_timer < get_tmr_ms())
|
||||
{
|
||||
lv_bar_set_value(bar, pct);
|
||||
|
@ -1480,10 +1399,10 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
|||
}
|
||||
lv_bar_set_value(bar, 100);
|
||||
|
||||
// Calculate rate for transfer.
|
||||
u32 rate_1k = (u64)size_bytes_seq * 1000 * 1000 * 1000 / mb_div / timer;
|
||||
s_printf(txt_buf + strlen(txt_buf), " SEQ 16MB - Rate: #C7EA46 %3d.%02d %s#",
|
||||
rate_1k / 1000, (rate_1k % 1000) / 10, mbs_text);
|
||||
u32 rate_1k = ((u64)1024 * 1000 * 1000 * 1000) / timer;
|
||||
s_printf(txt_buf + strlen(txt_buf),
|
||||
" Sequential 16MiB - Rate: #C7EA46 %3d.%02d MiB/s#\n",
|
||||
rate_1k / 1000, (rate_1k % 1000) / 10);
|
||||
lv_label_set_text(lbl_status, txt_buf);
|
||||
lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
|
@ -1493,25 +1412,22 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
|||
prevPct = 200;
|
||||
timer = 0;
|
||||
lba_curr = 0;
|
||||
sector_num = sct_blk_4kb;
|
||||
data_remaining = sct_rem_4kb;
|
||||
sector_num = 8; // 4KB chunks.
|
||||
data_remaining = 0x100000; // 512MB.
|
||||
|
||||
u32 loop_idx = 0;
|
||||
render_timer = get_tmr_ms() + render_min_ms;
|
||||
while (data_remaining)
|
||||
{
|
||||
u32 time_taken = get_tmr_us();
|
||||
error = !sdmmc_storage_read(storage, sector_off + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED);
|
||||
error = !sdmmc_storage_read(storage, sector + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED);
|
||||
time_taken = get_tmr_us() - time_taken;
|
||||
|
||||
timer += time_taken;
|
||||
times_taken_4k[loop_idx++] = time_taken;
|
||||
|
||||
manual_system_maintenance(false);
|
||||
data_remaining -= sector_num;
|
||||
lba_curr += sector_num;
|
||||
|
||||
pct = (lba_curr * 100) / sct_rem_4kb;
|
||||
pct = (lba_curr * 100) / 0x100000;
|
||||
if (pct != prevPct && render_timer < get_tmr_ms())
|
||||
{
|
||||
lv_bar_set_value(bar, pct);
|
||||
|
@ -1529,64 +1445,49 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
|||
}
|
||||
lv_bar_set_value(bar, 100);
|
||||
|
||||
qsort(times_taken_4k, loop_idx, sizeof(u32), qsort_compare_int); // Use int for faster compare. Value can't exceed 2s.
|
||||
|
||||
u32 pct95 = 0;
|
||||
for (u32 i = 0; i < loop_idx * 95 / 100; i++)
|
||||
pct95 += times_taken_4k[i];
|
||||
pct95 /= loop_idx * 95 / 100;
|
||||
|
||||
u32 pct05 = 0;
|
||||
for (u32 i = 0; i < loop_idx * 5 / 100; i++)
|
||||
pct05 += times_taken_4k[loop_idx - 1 - i];
|
||||
pct05 /= loop_idx * 5 / 100;
|
||||
|
||||
// Calculate rate and IOPS for transfer.
|
||||
rate_1k = (u64)size_bytes_4kb * 1000 * 1000 * 1000 / mb_div / timer;
|
||||
u32 iops = ((u64)(sct_rem_4kb / sct_num_1mb) * 1024 * 1000 * 1000 * 1000) / (4096 / 1024) / timer / 1000;
|
||||
s_printf(txt_buf + strlen(txt_buf), " AVG #C7EA46 95th# #FF3C28 5th#\n");
|
||||
s_printf(txt_buf + strlen(txt_buf), " SEQ 4KB - Rate: #C7EA46 %3d.%02d %s# IOPS: #C7EA46 %4d# %4d %4d \n",
|
||||
rate_1k / 1000, (rate_1k % 1000) / 10, mbs_text, iops, 1000000 / pct95, 1000000 / pct05);
|
||||
rate_1k = ((u64)512 * 1000 * 1000 * 1000) / timer;
|
||||
u32 iops_1k = ((u64)512 * 1024 * 1000 * 1000 * 1000) / (4096 / 1024) / timer / 1000;
|
||||
s_printf(txt_buf + strlen(txt_buf),
|
||||
" Sequential 4KiB - Rate: #C7EA46 %3d.%02d MiB/s#, IOPS: #C7EA46 %4d#\n",
|
||||
rate_1k / 1000, (rate_1k % 1000) / 10, iops_1k);
|
||||
lv_label_set_text(lbl_status, txt_buf);
|
||||
lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
u32 lba_idx = 0;
|
||||
u32 *random_offsets = malloc(0x20000 * sizeof(u32));
|
||||
u32 random_numbers[4];
|
||||
for (u32 i = 0; i < rnd_off_cnt; i += 4)
|
||||
for (u32 i = 0; i < 0x20000; i += 4)
|
||||
{
|
||||
// Generate new random numbers.
|
||||
while (!se_gen_prng128(random_numbers))
|
||||
;
|
||||
// Clamp offsets to 256MB range.
|
||||
random_offsets[i + 0] = random_numbers[0] % sct_rem_4kb;
|
||||
random_offsets[i + 1] = random_numbers[1] % sct_rem_4kb;
|
||||
random_offsets[i + 2] = random_numbers[2] % sct_rem_4kb;
|
||||
random_offsets[i + 3] = random_numbers[3] % sct_rem_4kb;
|
||||
// Clamp offsets to 512MB range.
|
||||
random_offsets[i + 0] = random_numbers[0] % 0x100000;
|
||||
random_offsets[i + 1] = random_numbers[1] % 0x100000;
|
||||
random_offsets[i + 2] = random_numbers[2] % 0x100000;
|
||||
random_offsets[i + 3] = random_numbers[3] % 0x100000;
|
||||
}
|
||||
|
||||
pct = 0;
|
||||
prevPct = 200;
|
||||
timer = 0;
|
||||
data_remaining = sct_rem_4kb;
|
||||
data_remaining = 0x100000; // 512MB.
|
||||
|
||||
loop_idx = 0;
|
||||
render_timer = get_tmr_ms() + render_min_ms;
|
||||
while (data_remaining)
|
||||
{
|
||||
u32 time_taken = get_tmr_us();
|
||||
error = !sdmmc_storage_read(storage, sector_off + random_offsets[lba_idx], sector_num, (u8 *)MIXD_BUF_ALIGNED);
|
||||
error = !sdmmc_storage_read(storage, sector + random_offsets[lba_idx], sector_num, (u8 *)MIXD_BUF_ALIGNED);
|
||||
time_taken = get_tmr_us() - time_taken;
|
||||
|
||||
timer += time_taken;
|
||||
times_taken_4k[loop_idx++] = time_taken;
|
||||
|
||||
manual_system_maintenance(false);
|
||||
data_remaining -= sector_num;
|
||||
lba_idx++;
|
||||
|
||||
pct = (lba_idx * 100) / rnd_off_cnt;
|
||||
pct = (lba_idx * 100) / 0x20000;
|
||||
if (pct != prevPct && render_timer < get_tmr_ms())
|
||||
{
|
||||
lv_bar_set_value(bar, pct);
|
||||
|
@ -1600,39 +1501,29 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
|||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
free(random_offsets);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
lv_bar_set_value(bar, 100);
|
||||
|
||||
qsort(times_taken_4k, loop_idx, sizeof(u32), qsort_compare_int); // Use int for faster compare. Value can't exceed 2s.
|
||||
|
||||
pct95 = 0;
|
||||
for (u32 i = 0; i < loop_idx * 95 / 100; i++)
|
||||
pct95 += times_taken_4k[i];
|
||||
pct95 /= loop_idx * 95 / 100;
|
||||
|
||||
pct05 = 0;
|
||||
for (u32 i = 0; i < loop_idx * 5 / 100; i++)
|
||||
pct05 += times_taken_4k[loop_idx - 1 - i];
|
||||
pct05 /= loop_idx * 5 / 100;
|
||||
|
||||
// Calculate rate and IOPS for transfer.
|
||||
rate_1k = (u64)size_bytes_4kb * 1000 * 1000 * 1000 / mb_div / timer;
|
||||
iops = ((u64)(sct_rem_4kb / sct_num_1mb) * 1024 * 1000 * 1000 * 1000) / (4096 / 1024) / timer / 1000;
|
||||
s_printf(txt_buf + strlen(txt_buf), " RND 4KB - Rate: #C7EA46 %3d.%02d %s# IOPS: #C7EA46 %4d# %4d %4d \n",
|
||||
rate_1k / 1000, (rate_1k % 1000) / 10, mbs_text, iops, 1000000 / pct95, 1000000 / pct05);
|
||||
// Calculate rate and IOPS for 512MB transfer.
|
||||
rate_1k = ((u64)512 * 1000 * 1000 * 1000) / timer;
|
||||
iops_1k = ((u64)512 * 1024 * 1000 * 1000 * 1000) / (4096 / 1024) / timer / 1000;
|
||||
s_printf(txt_buf + strlen(txt_buf),
|
||||
" Random 4KiB - Rate: #C7EA46 %3d.%02d MiB/s#, IOPS: #C7EA46 %4d#\n",
|
||||
rate_1k / 1000, (rate_1k % 1000) / 10, iops_1k);
|
||||
if (iter_curr == iters - 1)
|
||||
txt_buf[strlen(txt_buf) - 1] = 0; // Cut off last new line.
|
||||
txt_buf[strlen(txt_buf) - 1] = 0; // Cut off last line change.
|
||||
lv_label_set_text(lbl_status, txt_buf);
|
||||
lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
manual_system_maintenance(true);
|
||||
free(random_offsets);
|
||||
}
|
||||
|
||||
error:
|
||||
free(random_offsets);
|
||||
free(times_taken_4k);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (error == -1)
|
||||
|
@ -1659,8 +1550,6 @@ error:
|
|||
emmc_end();
|
||||
|
||||
out:
|
||||
s_printf(txt_buf, "#FF8000 %s Benchmark#\n[Raw Reads]", sd_bench ? "SD Card" : "eMMC");
|
||||
lv_mbox_set_text(mbox, txt_buf);
|
||||
free(txt_buf);
|
||||
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); // Important. After set_text.
|
||||
|
@ -1867,7 +1756,7 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
|
|||
emmc_gpt_parse(&gpt);
|
||||
|
||||
u32 idx = 0;
|
||||
int lines_left = 20;
|
||||
u32 lines_left = 20;
|
||||
s_printf(txt_buf + strlen(txt_buf), "#FFBA00 Idx Name Size Offset Sectors#\n");
|
||||
LIST_FOREACH_ENTRY(emmc_part_t, part, &gpt, link)
|
||||
{
|
||||
|
@ -1919,8 +1808,8 @@ out_error:
|
|||
lv_mbox_set_recolor_text(mbox, true);
|
||||
|
||||
s_printf(txt_buf,
|
||||
"#FF8000 eMMC Issues Warning#\n\n"
|
||||
"#FFDD00 Your eMMC is initialized in a slower mode,#\n"
|
||||
"#FF8000 eMMC Issues Check#\n\n"
|
||||
"#FFDD00 Your eMMC is initialized in slower mode,#\n"
|
||||
"#FFDD00 or init/read/write errors occurred!#\n"
|
||||
"#FFDD00 This might mean hardware issues!#\n\n"
|
||||
"#00DDFF Bus Speed:# %d MB/s\n\n"
|
||||
|
@ -1952,7 +1841,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
lv_win_add_btn(win, NULL, SYMBOL_SD" Benchmark", _create_mbox_sd_bench);
|
||||
|
||||
lv_obj_t *desc = lv_cont_create(win, NULL);
|
||||
lv_obj_set_size(desc, LV_HOR_RES / 2 / 6 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
|
||||
lv_obj_set_size(desc, LV_HOR_RES / 2 / 5 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
|
||||
|
||||
lv_obj_t * lb_desc = lv_label_create(desc, NULL);
|
||||
lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK);
|
||||
|
@ -1973,7 +1862,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
}
|
||||
|
||||
lv_label_set_text(lb_desc,
|
||||
"#00DDFF Card ID:#\n"
|
||||
"#00DDFF Card IDentification:#\n"
|
||||
"Vendor ID:\n"
|
||||
"Model:\n"
|
||||
"OEM ID:\n"
|
||||
|
@ -1982,11 +1871,11 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
"S/N:\n"
|
||||
"Month/Year:\n\n"
|
||||
"Max Power:\n"
|
||||
"Initial bus:"
|
||||
"Bootloader bus:"
|
||||
);
|
||||
|
||||
lv_obj_t *val = lv_cont_create(win, NULL);
|
||||
lv_obj_set_size(val, LV_HOR_RES / 12 * 3, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
|
||||
lv_obj_set_size(val, LV_HOR_RES / 9 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
|
||||
|
||||
lv_obj_t * lb_val = lv_label_create(val, lb_desc);
|
||||
|
||||
|
@ -2093,7 +1982,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
}
|
||||
|
||||
// UHS-I max power limit is 400mA, no matter what the card says.
|
||||
u32 max_power_nominal = sd_storage.max_power > 400 ? 400 : sd_storage.max_power;
|
||||
u32 card_power_limit_nominal = sd_storage.card_power_limit > 400 ? 400 : sd_storage.card_power_limit;
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c\n%c%c (%04X)\n%X\n%X\n%08x\n%02d/%04d\n\n%d mW (%d mA)\n",
|
||||
sd_storage.cid.manfid,
|
||||
|
@ -2102,7 +1991,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
(sd_storage.cid.oemid >> 8) & 0xFF, sd_storage.cid.oemid & 0xFF, sd_storage.cid.oemid,
|
||||
sd_storage.cid.hwrev, sd_storage.cid.fwrev, sd_storage.cid.serial,
|
||||
sd_storage.cid.month, sd_storage.cid.year,
|
||||
max_power_nominal * 3600 / 1000, sd_storage.max_power);
|
||||
card_power_limit_nominal * 3600 / 1000, sd_storage.card_power_limit);
|
||||
|
||||
switch (nyx_str->info.sd_init)
|
||||
{
|
||||
|
@ -2128,7 +2017,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
lv_obj_align(val, desc, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
|
||||
|
||||
lv_obj_t *desc2 = lv_cont_create(win, NULL);
|
||||
lv_obj_set_size(desc2, LV_HOR_RES / 2 / 11 * 5, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
|
||||
lv_obj_set_size(desc2, LV_HOR_RES / 2 / 4 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
|
||||
|
||||
lv_obj_t * lb_desc2 = lv_label_create(desc2, lb_desc);
|
||||
|
||||
|
@ -2145,10 +2034,10 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
"Write Protect:"
|
||||
);
|
||||
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
|
||||
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 5 * 3, 0);
|
||||
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
|
||||
|
||||
lv_obj_t *val2 = lv_cont_create(win, NULL);
|
||||
lv_obj_set_size(val2, LV_HOR_RES / 4, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
|
||||
lv_obj_set_size(val2, LV_HOR_RES / 13 * 3, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
|
||||
|
||||
lv_obj_t * lb_val2 = lv_label_create(val2, lb_desc);
|
||||
|
||||
|
@ -2192,64 +2081,15 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
else
|
||||
bus_speed = "SDR12";
|
||||
|
||||
char *cpe = NULL;
|
||||
if (sd_storage.ssr.app_class == 2)
|
||||
{
|
||||
u8 *buf = zalloc(512);
|
||||
|
||||
// Directly get and parse ext reg for performance enhance.
|
||||
sd_storage_parse_perf_enhance(&sd_storage, 2, 0, 0, buf);
|
||||
|
||||
bool has_perf_enhance = sd_storage.ser.cache &&
|
||||
sd_storage.ser.cmdq &&
|
||||
sd_storage.ser.cache == sd_storage.ser.cache_ext &&
|
||||
sd_storage.ser.cmdq == sd_storage.ser.cmdq_ext;
|
||||
if (has_perf_enhance)
|
||||
cpe = "#FFDD00 "; // CMDQ/CACHE support via a quirk.
|
||||
else
|
||||
cpe = "#FF3C28 "; // Broken.
|
||||
|
||||
// Get and parse ext reg for performance enhance in spec.
|
||||
sd_storage_get_ext_regs(&sd_storage, buf);
|
||||
|
||||
if (sd_storage.ser.valid)
|
||||
{
|
||||
has_perf_enhance = sd_storage.ser.cache &&
|
||||
sd_storage.ser.cmdq &&
|
||||
sd_storage.ser.cache == sd_storage.ser.cache_ext &&
|
||||
sd_storage.ser.cmdq == sd_storage.ser.cmdq_ext;
|
||||
|
||||
if (has_perf_enhance)
|
||||
cpe = NULL; // CMDQ/CACHE support in spec.
|
||||
else
|
||||
cpe = "#FF3C28 "; // Broken.
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
s_printf(txt_buf,
|
||||
"#00DDFF v%d.0#\n"
|
||||
"%02X\n"
|
||||
"%d MiB\n"
|
||||
"%X (CP %X)\n"
|
||||
"%d\n"
|
||||
"%d MB/s (%d MHz)\n"
|
||||
"%d (AU: %d %s\n"
|
||||
"U%d V%d %sA%d%s\n"
|
||||
"%s\n\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,
|
||||
"#00DDFF v%d.0#\n%02X\n%d MiB\n%X (CP %X)\n%d\n%d MB/s (%d MHz)\n%d (AU: %d %s\nU%d V%d A%d\n%s\n\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, uhs_au_size, uhs_au_mb ? "MiB)" : "KiB)",
|
||||
sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class, cpe ? cpe : "", sd_storage.ssr.app_class, cpe ? "#" : "",
|
||||
bus_speed,
|
||||
wp_info);
|
||||
sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class, sd_storage.ssr.app_class,
|
||||
bus_speed, wp_info);
|
||||
|
||||
lv_label_set_text(lb_val2, txt_buf);
|
||||
|
||||
|
@ -2266,29 +2106,47 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
lv_obj_set_size(desc3, LV_HOR_RES / 2 / 2 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 4);
|
||||
|
||||
lv_obj_t * lb_desc3 = lv_label_create(desc3, lb_desc);
|
||||
lv_label_set_text(lb_desc3, "#D4FF00 Acquiring info...#");
|
||||
lv_label_set_text(lb_desc3, "#D4FF00 Acquiring FAT volume info...#");
|
||||
lv_obj_set_width(lb_desc3, lv_obj_get_width(desc3));
|
||||
|
||||
lv_obj_align(desc3, desc, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
|
||||
|
||||
manual_system_maintenance(true);
|
||||
|
||||
lv_obj_set_size(desc3, LV_HOR_RES / 2 / 6 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 4);
|
||||
f_getfree("", &sd_fs.free_clst, NULL);
|
||||
|
||||
lv_label_set_text(lb_desc3,
|
||||
"#00DDFF Found FAT volume:#\n"
|
||||
"Filesystem:\n"
|
||||
"Cluster:\n"
|
||||
"Size free/total:"
|
||||
);
|
||||
lv_obj_set_size(desc3, LV_HOR_RES / 2 / 5 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 4);
|
||||
lv_obj_set_width(lb_desc3, lv_obj_get_width(desc3));
|
||||
lv_obj_align(desc3, desc, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
|
||||
|
||||
lv_obj_t *val3 = lv_cont_create(win, NULL);
|
||||
lv_obj_set_size(val3, LV_HOR_RES / 12 * 3, LV_VER_RES - (LV_DPI * 11 / 8) * 4);
|
||||
lv_obj_set_size(val3, LV_HOR_RES / 13 * 3, LV_VER_RES - (LV_DPI * 11 / 8) * 4);
|
||||
|
||||
lv_obj_t * lb_val3 = lv_label_create(val3, lb_desc);
|
||||
lv_label_set_text(lb_val3, "");
|
||||
|
||||
s_printf(txt_buf, "\n%s\n%d %s\n%d/%d MiB",
|
||||
sd_fs.fs_type == FS_EXFAT ? ("exFAT "SYMBOL_SHRK) : ("FAT32"),
|
||||
(sd_fs.csize > 1) ? (sd_fs.csize >> 1) : SD_BLOCKSIZE,
|
||||
(sd_fs.csize > 1) ? "KiB" : "B",
|
||||
(u32)(sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF),
|
||||
(u32)(sd_fs.n_fatent * sd_fs.csize >> SECTORS_TO_MIB_COEFF));
|
||||
|
||||
lv_label_set_text(lb_val3, txt_buf);
|
||||
|
||||
lv_obj_set_width(lb_val3, lv_obj_get_width(val3));
|
||||
lv_obj_align(val3, desc3, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
|
||||
|
||||
lv_obj_t *desc4 = lv_cont_create(win, NULL);
|
||||
lv_obj_set_size(desc4, LV_HOR_RES / 2 / 2 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 4);
|
||||
|
||||
lv_obj_t * lb_desc4 = lv_label_create(desc4, lb_desc);
|
||||
lv_label_set_text(lb_desc4, " ");
|
||||
lv_label_set_text(lb_desc4, "#D4FF00 Acquiring FAT volume info...#");
|
||||
lv_obj_set_width(lb_desc4, lv_obj_get_width(desc4));
|
||||
|
||||
lv_label_set_text(lb_desc4,
|
||||
|
@ -2297,12 +2155,12 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
"Read/Write fails:\n"
|
||||
"Read/Write errors:"
|
||||
);
|
||||
lv_obj_set_size(desc4, LV_HOR_RES / 2 / 11 * 5, LV_VER_RES - (LV_DPI * 11 / 8) * 4);
|
||||
lv_obj_set_size(desc4, LV_HOR_RES / 2 / 5 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 4);
|
||||
lv_obj_set_width(lb_desc4, lv_obj_get_width(desc4));
|
||||
lv_obj_align(desc4, val3, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 5 * 3, 0);
|
||||
lv_obj_align(desc4, val3, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
|
||||
|
||||
lv_obj_t *val4 = lv_cont_create(win, NULL);
|
||||
lv_obj_set_size(val4, LV_HOR_RES / 4, LV_VER_RES - (LV_DPI * 11 / 8) * 4);
|
||||
lv_obj_set_size(val4, LV_HOR_RES / 13 * 3, LV_VER_RES - (LV_DPI * 11 / 8) * 4);
|
||||
|
||||
lv_obj_t * lb_val4 = lv_label_create(val4, lb_desc);
|
||||
|
||||
|
@ -2315,31 +2173,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||
lv_label_set_text(lb_val4, txt_buf);
|
||||
|
||||
lv_obj_set_width(lb_val4, lv_obj_get_width(val4));
|
||||
lv_obj_align(val4, desc4, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
|
||||
|
||||
manual_system_maintenance(true);
|
||||
|
||||
f_getfree("", &sd_fs.free_clst, NULL);
|
||||
|
||||
lv_label_set_text(lb_desc3,
|
||||
"#00DDFF Found FAT FS:#\n"
|
||||
"Filesystem:\n"
|
||||
"Cluster:\n"
|
||||
"Size free/total:"
|
||||
);
|
||||
|
||||
lv_obj_set_width(lb_desc3, lv_obj_get_width(desc3));
|
||||
|
||||
s_printf(txt_buf, "\n%s\n%d %s\n%d/%d MiB",
|
||||
sd_fs.fs_type == FS_EXFAT ? ("exFAT "SYMBOL_SHRK) : ("FAT32"),
|
||||
(sd_fs.csize > 1) ? (sd_fs.csize >> 1) : SD_BLOCKSIZE,
|
||||
(sd_fs.csize > 1) ? "KiB" : "B",
|
||||
(u32)(sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF),
|
||||
(u32)(sd_fs.n_fatent * sd_fs.csize >> SECTORS_TO_MIB_COEFF));
|
||||
|
||||
lv_label_set_text(lb_val3, txt_buf);
|
||||
|
||||
lv_obj_set_width(lb_val3, lv_obj_get_width(val3));
|
||||
lv_obj_align(val4, desc4, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
|
||||
|
||||
free(txt_buf);
|
||||
sd_unmount();
|
||||
|
@ -2470,9 +2304,10 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
|||
|
||||
lv_label_set_static_text(lb_desc2,
|
||||
"#00DDFF Battery Charger IC Info:#\n"
|
||||
"Input voltage limit:\n"
|
||||
"Input current limit:\n"
|
||||
"System voltage limit:\n"
|
||||
"Charge current limit:\n"
|
||||
"Min voltage limit:\n"
|
||||
"Fast charge current limit:\n"
|
||||
"Charge voltage limit:\n"
|
||||
"Charge status:\n"
|
||||
"Temperature status:\n\n"
|
||||
|
@ -2490,9 +2325,12 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
|||
lv_obj_t * lb_val2 = lv_label_create(val2, lb_desc);
|
||||
|
||||
// Charger IC info.
|
||||
bq24193_get_property(BQ24193_InputVoltageLimit, &value);
|
||||
s_printf(txt_buf, "\n%d mV\n", value);
|
||||
|
||||
int iinlim = 0;
|
||||
bq24193_get_property(BQ24193_InputCurrentLimit, &iinlim);
|
||||
s_printf(txt_buf, "\n%d mA\n", 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);
|
||||
|
@ -2562,8 +2400,8 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
|||
if (!usb_pd.pdo_no)
|
||||
strcat(txt_buf, "\nNon PD");
|
||||
|
||||
// Limit to 6 profiles so it can fit.
|
||||
usb_pd.pdo_no = MIN(usb_pd.pdo_no, 6);
|
||||
// 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++)
|
||||
{
|
||||
|
@ -2714,7 +2552,7 @@ void create_tab_info(lv_theme_t *th, lv_obj_t *parent)
|
|||
lv_btn_set_fit(btn3, true, true);
|
||||
lv_label_set_static_text(label_btn, SYMBOL_CIRCUIT" HW & Fuses");
|
||||
lv_obj_align(btn3, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 2);
|
||||
lv_btn_set_action(btn3, LV_BTN_ACTION_CLICK, _create_window_hw_info_status);
|
||||
lv_btn_set_action(btn3, LV_BTN_ACTION_CLICK, _create_window_fuses_info_status);
|
||||
|
||||
// Create KFuses button.
|
||||
lv_obj_t *btn4 = lv_btn_create(h1, btn);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 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,
|
||||
|
@ -24,9 +24,9 @@
|
|||
#include <libs/lvgl/lv_themes/lv_theme_hekate.h>
|
||||
#include <libs/lvgl/lvgl.h>
|
||||
|
||||
#define CLOCK_MIN_YEAR 2025
|
||||
#define CLOCK_MIN_YEAR 2024
|
||||
#define CLOCK_MAX_YEAR (CLOCK_MIN_YEAR + 10)
|
||||
#define CLOCK_YEARLIST "2025\n2026\n2027\n2028\n2029\n2030\n2031\n2032\n2033\n2034\n2035"
|
||||
#define CLOCK_YEARLIST "2024\n2025\n2026\n2027\n2028\n2029\n2030\n2031\n2032\n2033\n2034"
|
||||
|
||||
extern hekate_config h_cfg;
|
||||
extern nyx_config n_cfg;
|
||||
|
@ -432,7 +432,7 @@ static lv_res_t _save_theme_color_action(lv_obj_t *btn)
|
|||
// Save nyx config.
|
||||
create_nyx_config_entry(true);
|
||||
|
||||
reload_nyx(NULL, false);
|
||||
reload_nyx();
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
@ -954,7 +954,7 @@ save_data:
|
|||
cal0->gyro_offset[0], cal0->gyro_offset[1], cal0->gyro_offset[2],
|
||||
cal0->gyro_scale[0], cal0->gyro_scale[1], cal0->gyro_scale[2],
|
||||
cal0->bd_mac[0], cal0->bd_mac[1], cal0->bd_mac[2], cal0->bd_mac[3], cal0->bd_mac[4], cal0->bd_mac[5]);
|
||||
|
||||
if (!error)
|
||||
error = f_open(&fp, "switchroot/switch.cal", FA_WRITE | FA_CREATE_ALWAYS) ? 4 : 0;
|
||||
if (!error)
|
||||
{
|
||||
|
@ -1168,11 +1168,13 @@ static lv_res_t _action_win_nyx_options_close(lv_obj_t *btn)
|
|||
lv_obj_set_opa_scale(status_bar.mid, LV_OPA_0);
|
||||
lv_obj_set_click(status_bar.mid, false);
|
||||
|
||||
lv_res_t res = nyx_win_close_action_custom(btn);
|
||||
lv_win_close_action(btn);
|
||||
|
||||
close_btn = NULL;
|
||||
|
||||
_check_nyx_changes();
|
||||
|
||||
return res;
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
lv_res_t create_win_nyx_options(lv_obj_t *parrent_btn)
|
||||
|
|
|
@ -85,7 +85,7 @@ l4t_flasher_ctxt_t l4t_flash_ctxt;
|
|||
lv_obj_t *btn_flash_l4t;
|
||||
lv_obj_t *btn_flash_android;
|
||||
|
||||
int _copy_file(const char *src, const char *dst, const char *path)
|
||||
int _copy_file(const char *src, const char *dst, char *path)
|
||||
{
|
||||
FIL fp_src;
|
||||
FIL fp_dst;
|
||||
|
@ -265,7 +265,7 @@ out:
|
|||
return res;
|
||||
}
|
||||
|
||||
static void _create_gpt_partition(gpt_t *gpt, u8 *gpt_idx, u32 *curr_part_lba, u32 size_lba, const char *name, int name_size)
|
||||
static void _create_gpt_partition(gpt_t *gpt, u8 *gpt_idx, u32 *curr_part_lba, u32 size_lba, char *name, int name_size)
|
||||
{
|
||||
static const u8 linux_part_guid[] = { 0xAF, 0x3D, 0xC6, 0x0F, 0x83, 0x84, 0x72, 0x47, 0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4 };
|
||||
u8 random_number[16];
|
||||
|
@ -813,7 +813,7 @@ static u32 _get_available_l4t_partition()
|
|||
return size_sct;
|
||||
}
|
||||
|
||||
static int _get_available_android_partition()
|
||||
static bool _get_available_android_partition()
|
||||
{
|
||||
gpt_t *gpt = zalloc(sizeof(gpt_t));
|
||||
|
||||
|
@ -827,17 +827,11 @@ static int _get_available_android_partition()
|
|||
// Find kernel partition.
|
||||
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
|
||||
{
|
||||
if (gpt->entries[i].lba_start)
|
||||
{
|
||||
int found = !memcmp(gpt->entries[i].name, (char[]) { 'b', 0, 'o', 0, 'o', 0, 't', 0 }, 8) ? 2 : 0;
|
||||
found |= !memcmp(gpt->entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6) ? 1 : 0;
|
||||
|
||||
if (found)
|
||||
if (gpt->entries[i].lba_start && (!memcmp(gpt->entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6) || !memcmp(gpt->entries[i].name, (char[]) { 'b', 0, 'o', 0, 'o', 0, 't', 0 }, 8)))
|
||||
{
|
||||
free(gpt);
|
||||
|
||||
return found;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i > 126)
|
||||
|
@ -888,7 +882,7 @@ static lv_res_t _action_check_flash_linux(lv_obj_t *btn)
|
|||
|
||||
// Find an applicable partition for L4T.
|
||||
u32 size_sct = _get_available_l4t_partition();
|
||||
if (!l4t_flash_ctxt.offset_sct || size_sct < 0x800000)
|
||||
if (!l4t_flash_ctxt.offset_sct || !size_sct || size_sct < 0x800000)
|
||||
{
|
||||
lv_label_set_text(lbl_status, "#FFDD00 Error:# No partition found!");
|
||||
goto error;
|
||||
|
@ -2057,9 +2051,9 @@ static void _create_mbox_check_files_total_size()
|
|||
bar_l4t_ind.body.main_color = LV_COLOR_HEX(0x00DDFF);
|
||||
bar_l4t_ind.body.grad_color = bar_l4t_ind.body.main_color;
|
||||
|
||||
// Set GPT bar style.
|
||||
// Set Android bar style.
|
||||
lv_style_copy(&bar_and_ind, lv_theme_get_current()->bar.indic);
|
||||
bar_and_ind.body.main_color = LV_COLOR_HEX(0xC000FF);
|
||||
bar_and_ind.body.main_color = LV_COLOR_HEX(0xFF8000);
|
||||
bar_and_ind.body.grad_color = bar_and_ind.body.main_color;
|
||||
|
||||
// Set separator styles.
|
||||
|
@ -2071,7 +2065,7 @@ static void _create_mbox_check_files_total_size()
|
|||
sep_l4t_bg.body.main_color = LV_COLOR_HEX(0x00DDFF);
|
||||
sep_l4t_bg.body.grad_color = sep_l4t_bg.body.main_color;
|
||||
lv_style_copy(&sep_and_bg, &sep_emu_bg);
|
||||
sep_and_bg.body.main_color = LV_COLOR_HEX(0xC000FF);
|
||||
sep_and_bg.body.main_color = LV_COLOR_HEX(0xFF8000);
|
||||
sep_and_bg.body.grad_color = sep_and_bg.body.main_color;
|
||||
|
||||
char *txt_buf = malloc(SZ_8K);
|
||||
|
@ -2691,7 +2685,7 @@ lv_res_t create_window_partition_manager(lv_obj_t *btn)
|
|||
// Create Android size slider.
|
||||
lv_obj_t *slider_and = lv_slider_create(h1, NULL);
|
||||
lv_obj_set_size(slider_and, LV_DPI * 7, LV_DPI / 3);
|
||||
lv_slider_set_range(slider_and, 0, (part_info.total_sct - extra_sct) / SECTORS_PER_GB - (ANDROID_SYSTEM_SIZE_MB / 1024)); // Subtract android reserved size.
|
||||
lv_slider_set_range(slider_and, 0, (part_info.total_sct - extra_sct) / SECTORS_PER_GB - 4); // Subtract android reserved size.
|
||||
lv_slider_set_value(slider_and, 0);
|
||||
lv_slider_set_style(slider_and, LV_SLIDER_STYLE_BG, &bar_and_bg);
|
||||
lv_slider_set_style(slider_and, LV_SLIDER_STYLE_INDIC, &bar_and_ind);
|
||||
|
@ -2754,35 +2748,27 @@ lv_res_t create_window_partition_manager(lv_obj_t *btn)
|
|||
|
||||
// Disable Flash Linux button if partition not found.
|
||||
u32 size_sct = _get_available_l4t_partition();
|
||||
if (!l4t_flash_ctxt.offset_sct || size_sct < 0x800000)
|
||||
if (!l4t_flash_ctxt.offset_sct || !size_sct || size_sct < 0x800000)
|
||||
{
|
||||
lv_obj_set_click(btn_flash_l4t, false);
|
||||
lv_btn_set_state(btn_flash_l4t, LV_BTN_STATE_INA);
|
||||
}
|
||||
|
||||
int part_type_and = _get_available_android_partition();
|
||||
|
||||
// Create Flash Android button.
|
||||
btn_flash_android = lv_btn_create(h1, NULL);
|
||||
label_btn = lv_label_create(btn_flash_android, NULL);
|
||||
lv_btn_set_fit(btn_flash_android, true, true);
|
||||
switch (part_type_and)
|
||||
{
|
||||
case 0: // Disable Flash Android button if partition not found.
|
||||
lv_label_set_static_text(label_btn, SYMBOL_DOWNLOAD" Flash Android");
|
||||
lv_obj_set_click(btn_flash_android, false);
|
||||
lv_btn_set_state(btn_flash_android, LV_BTN_STATE_INA);
|
||||
break;
|
||||
case 1: // Android 10/11.
|
||||
lv_label_set_static_text(label_btn, SYMBOL_DOWNLOAD" Flash Android 10/11");
|
||||
break;
|
||||
case 2: // Android 13+
|
||||
lv_label_set_static_text(label_btn, SYMBOL_DOWNLOAD" Flash Android 13+");
|
||||
break;
|
||||
}
|
||||
lv_obj_align(btn_flash_android, btn_flash_l4t, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 3, 0);
|
||||
lv_btn_set_action(btn_flash_android, LV_BTN_ACTION_CLICK, _action_flash_android);
|
||||
|
||||
// Disable Flash Android button if partition not found.
|
||||
if (!_get_available_android_partition())
|
||||
{
|
||||
lv_obj_set_click(btn_flash_android, false);
|
||||
lv_btn_set_state(btn_flash_android, LV_BTN_STATE_INA);
|
||||
}
|
||||
|
||||
// Create next step button.
|
||||
btn1 = lv_btn_create(h1, NULL);
|
||||
label_btn = lv_label_create(btn1, NULL);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018 Ced2911
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -76,7 +76,7 @@ static const u8 master_kekseed_620[SE_KEY_128_SIZE] =
|
|||
|
||||
//!TODO: Update on mkey changes.
|
||||
static const u8 master_kekseed_t210_max[SE_KEY_128_SIZE] =
|
||||
{ 0xA1, 0x7D, 0x34, 0xDB, 0x2D, 0x9D, 0xDA, 0xE5, 0xF8, 0x15, 0x63, 0x4C, 0x8F, 0xE7, 0x6C, 0xD8 }; // 20.0.0.
|
||||
{ 0x00, 0x04, 0x5D, 0xF0, 0x4D, 0xCD, 0x14, 0xA3, 0x1C, 0xBF, 0xDE, 0x48, 0x55, 0xBA, 0x35, 0xC1 }; // 18.0.0.
|
||||
|
||||
//!TODO: Update on mkey changes.
|
||||
static const u8 master_kekseed_t210b01[HOS_KB_VERSION_MAX - HOS_KB_VERSION_600 + 1][SE_KEY_128_SIZE] = {
|
||||
|
@ -93,8 +93,6 @@ static const u8 master_kekseed_t210b01[HOS_KB_VERSION_MAX - HOS_KB_VERSION_600 +
|
|||
{ 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 }, // 16.0.0.
|
||||
{ 0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80 }, // 17.0.0.
|
||||
{ 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 }, // 18.0.0.
|
||||
{ 0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80 }, // 19.0.0.
|
||||
{ 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A }, // 20.0.0.
|
||||
};
|
||||
|
||||
static const u8 console_keyseed[SE_KEY_128_SIZE] =
|
||||
|
@ -126,8 +124,6 @@ static const u8 mkey_vectors[HOS_KB_VERSION_MAX + 1][SE_KEY_128_SIZE] = {
|
|||
{ 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 }, // Mkey 14 encrypted with mkey 15.
|
||||
{ 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD }, // Mkey 15 encrypted with mkey 16.
|
||||
{ 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 }, // Mkey 16 encrypted with mkey 17.
|
||||
{ 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 }, // Mkey 17 encrypted with mkey 18.
|
||||
{ 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 }, // Mkey 18 encrypted with mkey 19.
|
||||
};
|
||||
|
||||
//!TODO: Update on mkey changes.
|
||||
|
@ -147,8 +143,6 @@ static const u8 new_console_keyseed[HOS_KB_VERSION_MAX - HOS_KB_VERSION_400 + 1]
|
|||
{ 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C }, // 16.0.0 New Device Key Source.
|
||||
{ 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 }, // 17.0.0 New Device Key Source.
|
||||
{ 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 }, // 18.0.0 New Device Key Source.
|
||||
{ 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 }, // 19.0.0 New Device Key Source.
|
||||
{ 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 }, // 20.0.0 New Device Key Source.
|
||||
};
|
||||
|
||||
//!TODO: Update on mkey changes.
|
||||
|
@ -168,8 +162,6 @@ static const u8 new_console_kekseed[HOS_KB_VERSION_MAX - HOS_KB_VERSION_400 + 1]
|
|||
{ 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F }, // 16.0.0 New Device Keygen Source.
|
||||
{ 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E }, // 17.0.0 New Device Keygen Source.
|
||||
{ 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B }, // 18.0.0 New Device Keygen Source.
|
||||
{ 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F }, // 19.0.0 New Device Keygen Source.
|
||||
{ 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 }, // 20.0.0 New Device Keygen Source.
|
||||
};
|
||||
|
||||
static const u8 gen_keyseed[SE_KEY_128_SIZE] =
|
||||
|
@ -273,7 +265,7 @@ static void _hos_eks_save()
|
|||
}
|
||||
|
||||
// Get keys.
|
||||
u8 *keys = (u8 *)zalloc(SZ_8K);
|
||||
u8 *keys = (u8 *)calloc(2, SZ_4K);
|
||||
se_get_aes_keys(keys + SZ_4K, keys, SE_KEY_128_SIZE);
|
||||
|
||||
// Set magic and personalized info.
|
||||
|
@ -337,19 +329,8 @@ out:
|
|||
}
|
||||
}
|
||||
|
||||
int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
int hos_keygen_t210b01(u32 kb)
|
||||
{
|
||||
u32 retries = 0;
|
||||
bool use_tsec = false;
|
||||
tsec_keys_t tsec_keys;
|
||||
kb_t *kb_data = (kb_t *)keyblob;
|
||||
|
||||
if (kb > HOS_KB_VERSION_MAX)
|
||||
return 0;
|
||||
|
||||
// Do Mariko keygen.
|
||||
if (h_cfg.t210b01)
|
||||
{
|
||||
// Use SBK as Device key 4x unsealer and KEK for mkey in T210B01 units.
|
||||
se_aes_unwrap_key(10, 14, console_keyseed_4xx);
|
||||
|
||||
|
@ -361,7 +342,20 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
se_aes_unwrap_key(8, 7, package2_keyseed);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
{
|
||||
u32 retries = 0;
|
||||
bool use_tsec = false;
|
||||
tsec_keys_t tsec_keys;
|
||||
kb_t *kb_data = (kb_t *)keyblob;
|
||||
|
||||
if (kb > HOS_KB_VERSION_MAX)
|
||||
return 0;
|
||||
|
||||
if (h_cfg.t210b01)
|
||||
return hos_keygen_t210b01(kb);
|
||||
|
||||
// Do Erista keygen.
|
||||
|
||||
|
@ -369,7 +363,7 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
_hos_eks_get();
|
||||
|
||||
// Use tsec keygen for old firmware or if EKS keys does not exist for newer.
|
||||
if (kb <= HOS_KB_VERSION_620 || !h_cfg.eks || (h_cfg.eks->enabled != HOS_EKS_TSEC_VER))
|
||||
if (kb <= HOS_KB_VERSION_620 || !h_cfg.eks || (h_cfg.eks && h_cfg.eks->enabled != HOS_EKS_TSEC_VER))
|
||||
use_tsec = true;
|
||||
|
||||
if (kb <= HOS_KB_VERSION_600)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2023 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,
|
||||
|
@ -45,9 +45,7 @@ enum {
|
|||
HOS_KB_VERSION_1600 = 15,
|
||||
HOS_KB_VERSION_1700 = 16,
|
||||
HOS_KB_VERSION_1800 = 17,
|
||||
HOS_KB_VERSION_1900 = 18,
|
||||
HOS_KB_VERSION_2000 = 19,
|
||||
HOS_KB_VERSION_MAX = HOS_KB_VERSION_2000
|
||||
HOS_KB_VERSION_MAX = HOS_KB_VERSION_1800
|
||||
};
|
||||
|
||||
#define HOS_TSEC_VERSION 4 //! TODO: Update on TSEC Root Key changes.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -39,7 +39,7 @@ static const u8 sec_map_100[3] = { PK11_SECTION_SM, PK11_SECTION_LD, PK11_SECTIO
|
|||
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 };
|
||||
|
||||
// Timestamp KB TSEC PK11 SECMON Warmboot
|
||||
// ID (Timestamp), KB, TSEC, PK11, SECMON, Warmboot.
|
||||
static const pkg1_id_t _pkg1_ids[] = {
|
||||
{ "20161121", 0, 0x1900, 0x3FE0, 0x40014020, 0x8000D000 }, // 1.0.0.
|
||||
{ "20170210", 0, 0x1900, 0x3FE0, 0x4002D000, 0x8000D000 }, // 2.0.0 - 2.3.0.
|
||||
|
@ -66,9 +66,7 @@ static const pkg1_id_t _pkg1_ids[] = {
|
|||
{ "20220801", 14, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 15.0.0 - 15.0.1.
|
||||
{ "20230111", 15, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 16.0.0 - 16.1.0.
|
||||
{ "20230906", 16, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 17.0.0 - 17.0.1.
|
||||
{ "20240207", 17, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 18.0.0 - 18.1.0.
|
||||
{ "20240808", 18, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 19.0.0 - 19.0.1.
|
||||
{ "20250206", 19, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 20.0.0+
|
||||
{ "20240207", 17, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 18.0.0+
|
||||
};
|
||||
|
||||
const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date)
|
||||
|
@ -125,7 +123,7 @@ const u8 *pkg1_unpack(void *wm_dst, void *sm_dst, void *ldr_dst, const pkg1_id_t
|
|||
// Get correct header mapping.
|
||||
if (id->kb == HOS_KB_VERSION_100 && !memcmp(id->id, "20161121", 8))
|
||||
sec_map = sec_map_100;
|
||||
else if (id->kb <= HOS_KB_VERSION_301)
|
||||
else if (id->kb >= HOS_KB_VERSION_100 && id->kb <= HOS_KB_VERSION_301)
|
||||
sec_map = sec_map_2xx;
|
||||
else
|
||||
sec_map = sec_map_4xx;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2023 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,
|
||||
|
@ -113,10 +113,6 @@ static const u8 mkey_vector_7xx[HOS_KB_VERSION_MAX - HOS_KB_VERSION_810 + 1][SE_
|
|||
{ 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD },
|
||||
// Master key 16 encrypted with 17. (17.0.0 with 18.0.0)
|
||||
{ 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 },
|
||||
// Master key 17 encrypted with 18. (18.0.0 with 19.0.0)
|
||||
{ 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 },
|
||||
// Master key 18 encrypted with 19. (19.0.0 with 20.0.0)
|
||||
{ 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 },
|
||||
};
|
||||
|
||||
static bool _pkg2_key_unwrap_validate(pkg2_hdr_t *tmp_test, pkg2_hdr_t *hdr, u8 src_slot, u8 *mkey, const u8 *key_seed)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018-2023 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,
|
||||
|
@ -24,13 +24,12 @@
|
|||
#define PKG2_SEC_BASE 0x80000000
|
||||
#define PKG2_SEC_KERNEL 0
|
||||
#define PKG2_SEC_INI1 1
|
||||
#define PKG2_SEC_UNUSED 2
|
||||
|
||||
#define INI1_MAGIC 0x31494E49
|
||||
|
||||
//! TODO: Update on kernel change if needed.
|
||||
// Offset of OP + 12 is the INI1 offset. On v2 with dynamic crt0 it's + 16.
|
||||
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // MOV X21, #0.
|
||||
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015
|
||||
#define PKG2_NEWKERN_START 0x800
|
||||
|
||||
extern u32 pkg2_newkern_ini1_start;
|
||||
|
|
|
@ -402,7 +402,7 @@ error_occured:
|
|||
msleep(1000);
|
||||
btn_wait();
|
||||
|
||||
reload_nyx(NULL, true);
|
||||
reload_nyx();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ _reloc_ipl:
|
|||
|
||||
_real_start:
|
||||
/* We place our stack in SDRAM. */
|
||||
LDR SP, =0x4003F000
|
||||
LDR SP, =0x83100000
|
||||
LDR R0, =__bss_start
|
||||
EOR R1, R1, R1
|
||||
LDR R2, =__bss_end
|
||||
|
|
|
@ -9,13 +9,10 @@ autonogc=1
|
|||
updater2p=1
|
||||
bootprotect=0
|
||||
|
||||
# Only include above what you want to change from defaults.
|
||||
# config.c in bootloader and Nyx have all the defaults.
|
||||
|
||||
|
||||
{-------- Stock -------}
|
||||
[Stock]
|
||||
pkg3=atmosphere/package3
|
||||
fss0=atmosphere/package3
|
||||
stock=1
|
||||
emummc_force_disable=1
|
||||
|
||||
|
@ -29,7 +26,7 @@ emummc_force_disable=1
|
|||
|
||||
{-- Custom Firmwares --}
|
||||
[Atmo Vanilla]
|
||||
pkg3=atmosphere/package3
|
||||
fss0=atmosphere/package3
|
||||
kip1=atmosphere/kips/*
|
||||
|
||||
# Note:
|
||||
|
@ -39,11 +36,11 @@ kip1=atmosphere/kips/*
|
|||
|
||||
|
||||
[Atmo EMU]
|
||||
pkg3=atmosphere/package3
|
||||
fss0=atmosphere/package3
|
||||
emummcforce=1
|
||||
|
||||
[Atmo SYS]
|
||||
pkg3=atmosphere/package3
|
||||
fss0=atmosphere/package3
|
||||
emummc_force_disable=1
|
||||
|
||||
# Note:
|
||||
|
@ -58,7 +55,7 @@ emummc_force_disable=1
|
|||
|
||||
|
||||
[Atmo EMU2]
|
||||
pkg3=atmosphere/package3
|
||||
fss0=atmosphere/package3
|
||||
emupath=emuMMC/SD02
|
||||
emummcforce=1
|
||||
|
||||
|
@ -71,26 +68,26 @@ emummcforce=1
|
|||
|
||||
|
||||
[Atmo with extra kips]
|
||||
pkg3=atmosphere/package3
|
||||
fss0=atmosphere/package3
|
||||
kip1=cfw/mods/mods_extra/*
|
||||
kip1=cfw/mods/mods_extra/single/extra.kip
|
||||
|
||||
# Note:
|
||||
# The above can be used with any pkg3 entry. Like the ones above.
|
||||
# You can even override atmosphere (pkg3) kips with this.
|
||||
# The above can be used with any fss0 entry. Like the ones above.
|
||||
# You can even override atmosphere (fss0) kips with this.
|
||||
# The wildcard '*' like above can be used to load all kips from a selected directory.
|
||||
|
||||
|
||||
{-- Custom Firmwares Old methods --}
|
||||
[CFW PKG3 extra kips & patches]
|
||||
pkg3=atmosphere/package3
|
||||
[CFW FSS0 extra kips & patches]
|
||||
fss0=atmosphere/package3
|
||||
kip1patch=name_of_patch
|
||||
kip1=cfw/mods/mods_extra/*
|
||||
kip1=cfw/mods/mods_extra/single/extra.kip
|
||||
|
||||
# Note:
|
||||
# Both options for kip1 can be used. Wildcard and single.
|
||||
# You can override kips loaded from PKG3/FSS0 if you define them after the pkg3 key.
|
||||
# You can override kips loaded from FSS0/PKG3 if you define them after the fss0 key.
|
||||
# If kip1 patch resides in patches.ini and that file OR the patch for
|
||||
# current HOS version does not exist, it will error out.
|
||||
|
||||
|
@ -109,7 +106,7 @@ atmosphere=1
|
|||
|
||||
# Note:
|
||||
# All kips defined method. This can be changed to what is below also.
|
||||
# atmosphere=1 key is IMPORTANT when no PKG3/FSS0 is defined.
|
||||
# atmosphere=1 key is IMPORTANT when no FFS0 is defined.
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue