Compare commits

...

36 commits

Author SHA1 Message Date
CTCaer
9e1b2ee573 Bump hekate to v6.1.1 and Nyx to v1.6.1 2024-03-29 16:34:08 +02:00
CTCaer
9cfe1d2162 nyx: add info about 6.2" oem panel clone 2024-03-29 16:34:08 +02:00
CTCaer
cfbbafe72f nyx: change imu cal warning message 2024-03-29 13:42:41 +02:00
CTCaer
5607fd18ea hos: 18.0.0 support 2024-03-29 13:21:53 +02:00
CTCaer
d71903abf2 hos: simplify nogc patch 2024-03-29 13:21:53 +02:00
CTCaer
547cfca0c9 hos: simplify emummc patch 2024-03-29 13:21:53 +02:00
CTCaer
dca350bfe9 hos: use strcmp for kip name
KIP1 names are NULL terminated, so use strcmp to reduce codesize.
2024-03-29 13:21:53 +02:00
CTCaer
06b7a38d47 nyx: retry to dump imu cal and skip it failed
On devices with mangled cal0 imu calibration can now be skipped (still mandatory on Lite).
2024-03-29 13:21:53 +02:00
CTCaer
9567ba19c8 l4t: bump loader/firmware revisions 2024-03-29 13:21:53 +02:00
CTCaer
c9ff5179f9 exo: use mixed version identification 2024-03-29 13:21:53 +02:00
CTCaer
f764bf04b1 hos: reboot to ofw if stock fails
If package1 fails to be read and conditions are valid, reboot to OFW automatically when stock mode is enabled.
2024-03-29 13:21:53 +02:00
CTCaer
8b1486c74b hekate: expose autorcm check 2024-03-29 13:21:53 +02:00
CTCaer
471b99366d hos: small refactor 2024-03-29 13:21:53 +02:00
CTCaer
368ca21316 hos: fix sys counters reset and always apply it 2024-03-29 13:21:53 +02:00
CTCaer
c021aef9b0 fss: save fss0 for being able to free it if error
Also do not free secmon/kernel in case it's from fss
2024-03-29 13:21:53 +02:00
CTCaer
622f7124ac fss: remove dynamic path
Atmosphere never implemented per sysMMC/emuMMC support for configs.
So remove path parsing to reduce codesize.
2024-03-29 13:21:53 +02:00
CTCaer
e846f4576e bdk: minerva: l4t: adjust sdmmc1 la and freq table
- LA is tightened up
- Copied frequencies are now 204/408/800/1333/1600/OC (from 204/666/800/1600/OC)
2024-03-29 13:21:53 +02:00
CTCaer
42c02e97e8 bdk: display: add 6.2" panel clone 2024-03-29 13:21:53 +02:00
CTCaer
4b3014bc18 hos: pkg2: simple refactor 2024-03-29 13:21:53 +02:00
CTCaer
4effaab241 hekate/nyx: use zalloc where appropriate 2024-03-27 09:16:06 +02:00
CTCaer
d687b53249 bdk: heap: add zalloc and utilize it 2024-03-27 09:00:53 +02:00
CTCaer
9e41aa7759 bdk: smmu: refactor and update driver
- Allow ASID to be configured
- Allow 34-bit PAs
- Use special type for setting PDE/PTE config
- Initialize all pages as non accessible
- Add function for mapping 4MB regions directly
- Add SMMU heap reset function
- Correct address load OP to 32-bit and remove alignment on SMMU enable payload
- Refactor all defines
2024-03-14 09:21:06 +02:00
CTCaer
0100c11757 nyx: info: show unknown for relevant eMMC vendors 2024-03-13 02:02:09 +02:00
CTCaer
9ba7c44b89 bdk: clock: use real source clock dividers
Use CLK_SRC_DIV macro in order to have the actual divider showing.
2024-03-13 02:01:01 +02:00
CTCaer
cdf0f30b17 hekate/nyx: smmu refactor 2024-03-13 01:56:31 +02:00
CTCaer
9a520d63a6 bdk: smmu: refactor driver and allow other asid 2024-03-13 01:54:46 +02:00
CTCaer
20e661fc01 bdk: refactor flow control defines 2024-03-13 01:50:45 +02:00
CTCaer
e341cf39f2 hekate/nyx: apply ccplex changes
HOS procedure can now launch secmon from coldboot again when HOS is 6.2.0.
And update L4T for the function signature change.
2024-03-13 01:49:31 +02:00
CTCaer
3a4fa12f42 bdk: smmu: powergate ccplex after enabling smmu 2024-03-13 01:44:58 +02:00
CTCaer
fb31cb2926 bdk: ccplex: add no rst vector lock & powergating
Allow not locking the reset vectors and launch a new payload after powergating ccplex.
2024-03-13 01:37:52 +02:00
CTCaer
82925845e3 hekate/nyx: utilize existing block size defines 2024-03-12 15:53:05 +02:00
CTCaer
f126486266 bdk: sdmmc: utilize block size defines 2024-03-12 15:47:14 +02:00
CTCaer
25b7ffecd1 bdk: fatfs: always align malloc to lba 2024-03-12 15:43:44 +02:00
CTCaer
7d1600b85c bdk: consolidate ffsystem into bdk 2024-03-12 15:16:18 +02:00
CTCaer
b1e6661a7a nyx: get rtc adjustments via driver 2024-03-12 15:11:32 +02:00
CTCaer
83ac40c4b9 bdk: rtc: handle offset adjustment in-place 2024-03-12 15:08:55 +02:00
63 changed files with 1127 additions and 1083 deletions

View file

@ -1,11 +1,11 @@
# IPL Version. # IPL Version.
BLVERSION_MAJOR := 6 BLVERSION_MAJOR := 6
BLVERSION_MINOR := 1 BLVERSION_MINOR := 1
BLVERSION_HOTFX := 0 BLVERSION_HOTFX := 1
BLVERSION_RSVD := 0 BLVERSION_RSVD := 0
# Nyx Version. # Nyx Version.
NYXVERSION_MAJOR := 1 NYXVERSION_MAJOR := 1
NYXVERSION_MINOR := 6 NYXVERSION_MINOR := 6
NYXVERSION_HOTFX := 0 NYXVERSION_HOTFX := 1
NYXVERSION_RSVD := 0 NYXVERSION_RSVD := 0

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -398,10 +398,10 @@ void display_init()
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_DISP1); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_DISP1);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL);
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz). CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = CLK_SRC_DIV(6); // Set PLLP_OUT3 and div 6 (17MHz).
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz). CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = CLK_SRC_DIV(6); // Set PLLP_OUT and div 6 (68MHz).
// Bring every IO rail out of deep power down. // Bring every IO rail out of deep power down.
PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF; PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;

View file

@ -789,10 +789,12 @@ enum
PANEL_SHP_LQ055T1SW10 = 0x1040, PANEL_SHP_LQ055T1SW10 = 0x1040,
PANEL_SAM_AMS699VC01 = 0x2050, PANEL_SAM_AMS699VC01 = 0x2050,
// Found on 6/2" clones. Unknown markings. Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F].
PANEL_OEM_CLONE_6_2 = 0x0F83,
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings. // Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
PANEL_OEM_CLONE_5_5 = 0xB3, PANEL_OEM_CLONE_5_5 = 0x00B3,
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings. // Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
PANEL_OEM_CLONE = 0 PANEL_OEM_CLONE = 0x0000
}; };
void display_init(); void display_init();

View file

@ -107,7 +107,7 @@
**************************************/ **************************************/
#include <mem/heap.h> /* malloc, calloc, free */ #include <mem/heap.h> /* malloc, calloc, free */
#define ALLOC(s) malloc(s) #define ALLOC(s) malloc(s)
#define ALLOC_AND_ZERO(s) calloc(1,s) #define ALLOC_AND_ZERO(s) zalloc(s)
#define FREEMEM free #define FREEMEM free
#include <string.h> /* memset, memcpy */ #include <string.h> /* memset, memcpy */
#define MEM_INIT memset #define MEM_INIT memset

View file

@ -1,15 +1,12 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs */ /* Sample Code of OS Dependent Functions for FatFs */
/* (C) ChaN, 2018 */ /* (C) ChaN, 2018 */
/* (C) CTCaer, 2018 */ /* (C) CTCaer, 2018-2024 */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
#include <bdk.h> #include <bdk.h>
#include <libs/fatfs/ff.h> #include <libs/fatfs/ff.h>
#include "../../config.h"
extern nyx_config n_cfg;
#if FF_USE_LFN == 3 /* Dynamic memory allocation */ #if FF_USE_LFN == 3 /* Dynamic memory allocation */
@ -21,7 +18,8 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if no
UINT msize /* Number of bytes to allocate */ UINT msize /* Number of bytes to allocate */
) )
{ {
return malloc(msize); /* Allocate a new memory block with POSIX API */ // Ensure size is aligned to SDMMC block size.
return malloc(ALIGN(msize, SDMMC_DAT_BLOCKSIZE)); /* Allocate a new memory block with POSIX API */
} }
@ -50,12 +48,7 @@ DWORD get_fattime (
{ {
rtc_time_t time; rtc_time_t time;
max77620_rtc_get_time(&time); max77620_rtc_get_time_adjusted(&time);
if (n_cfg.timeoff)
{
u32 epoch = (u32)((s32)max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff);
max77620_rtc_epoch_to_date(epoch, &time);
}
return (((DWORD)(time.year - 1980) << 25) | ((DWORD)time.month << 21) | ((DWORD)time.day << 16) | return (((DWORD)(time.year - 1980) << 25) | ((DWORD)time.month << 21) | ((DWORD)time.day << 16) |
((DWORD)time.hour << 11) | ((DWORD)time.min << 5) | (time.sec >> 1)); ((DWORD)time.hour << 11) | ((DWORD)time.min << 5) | (time.sec >> 1));

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -159,6 +159,13 @@ void *calloc(u32 num, u32 size)
return res; return res;
} }
void *zalloc(u32 size)
{
void *res = (void *)_heap_alloc(size);
memset(res, 0, ALIGN(size, sizeof(hnode_t))); // Clear the aligned size.
return res;
}
void free(void *buf) void free(void *buf)
{ {
if (buf >= _heap.start) if (buf >= _heap.start)

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -48,6 +48,7 @@ void heap_init(void *base);
void heap_set(heap_t *heap); void heap_set(heap_t *heap);
void *malloc(u32 size); void *malloc(u32 size);
void *calloc(u32 num, u32 size); void *calloc(u32 num, u32 size);
void *zalloc(u32 size);
void free(void *buf); void free(void *buf);
void heap_monitor(heap_monitor_t *mon, bool print_node_stats); void heap_monitor(heap_monitor_t *mon, bool print_node_stats);

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved. * Copyright (c) 2014, NVIDIA Corporation.
* Copyright (c) 2018-2023, CTCaer
* *
* This software is licensed under the terms of the GNU General Public * This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and * License version 2, as published by the Free Software Foundation, and
@ -14,6 +15,22 @@
#ifndef _MC_T210_H_ #ifndef _MC_T210_H_
#define _MC_T210_H_ #define _MC_T210_H_
/*! MC SMMU registers */
#define MC_SMMU_CONFIG 0x10
#define MC_SMMU_TLB_CONFIG 0x14
#define MC_SMMU_PTC_CONFIG 0x18
#define MC_SMMU_PTB_ASID 0x1c
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH 0x34
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
/*! MC General registers */
#define MC_INTSTATUS 0x0 #define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4 #define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8 #define MC_ERR_STATUS 0x8
@ -464,7 +481,7 @@
#define MC_UNTRANSLATED_REGION_CHECK 0x948 #define MC_UNTRANSLATED_REGION_CHECK 0x948
#define MC_DA_CONFIG0 0x9dc #define MC_DA_CONFIG0 0x9dc
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS0 */ /*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS0 */
#define SEC_CARVEOUT_CA0_R_PTCR BIT(0) #define SEC_CARVEOUT_CA0_R_PTCR BIT(0)
#define SEC_CARVEOUT_CA0_R_DISPLAY0A BIT(1) #define SEC_CARVEOUT_CA0_R_DISPLAY0A BIT(1)
#define SEC_CARVEOUT_CA0_R_DISPLAY0AB BIT(2) #define SEC_CARVEOUT_CA0_R_DISPLAY0AB BIT(2)
@ -484,7 +501,7 @@
#define SEC_CARVEOUT_CA0_R_PPCSAHBSLV BIT(30) #define SEC_CARVEOUT_CA0_R_PPCSAHBSLV BIT(30)
#define SEC_CARVEOUT_CA0_R_SATAR BIT(31) #define SEC_CARVEOUT_CA0_R_SATAR BIT(31)
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS1 */ /*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS1 */
#define SEC_CARVEOUT_CA1_R_VDEBSEV BIT(2) #define SEC_CARVEOUT_CA1_R_VDEBSEV BIT(2)
#define SEC_CARVEOUT_CA1_R_VDEMBE BIT(3) #define SEC_CARVEOUT_CA1_R_VDEMBE BIT(3)
#define SEC_CARVEOUT_CA1_R_VDEMCE BIT(4) #define SEC_CARVEOUT_CA1_R_VDEMCE BIT(4)
@ -504,7 +521,7 @@
#define SEC_CARVEOUT_CA1_W_VDEBSEV BIT(30) #define SEC_CARVEOUT_CA1_W_VDEBSEV BIT(30)
#define SEC_CARVEOUT_CA1_W_VDEDBG BIT(31) #define SEC_CARVEOUT_CA1_W_VDEDBG BIT(31)
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS2 */ /*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS2 */
#define SEC_CARVEOUT_CA2_W_VDEMBE BIT(0) #define SEC_CARVEOUT_CA2_W_VDEMBE BIT(0)
#define SEC_CARVEOUT_CA2_W_VDETPM BIT(1) #define SEC_CARVEOUT_CA2_W_VDETPM BIT(1)
#define SEC_CARVEOUT_CA2_R_ISPRA BIT(4) #define SEC_CARVEOUT_CA2_R_ISPRA BIT(4)
@ -524,7 +541,7 @@
#define SEC_CARVEOUT_CA2_W_GPU BIT(25) #define SEC_CARVEOUT_CA2_W_GPU BIT(25)
#define SEC_CARVEOUT_CA2_R_DISPLAYT BIT(26) #define SEC_CARVEOUT_CA2_R_DISPLAYT BIT(26)
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS3 */ /*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS3 */
#define SEC_CARVEOUT_CA3_R_SDMMCA BIT(0) #define SEC_CARVEOUT_CA3_R_SDMMCA BIT(0)
#define SEC_CARVEOUT_CA3_R_SDMMCAA BIT(1) #define SEC_CARVEOUT_CA3_R_SDMMCAA BIT(1)
#define SEC_CARVEOUT_CA3_R_SDMMC BIT(2) #define SEC_CARVEOUT_CA3_R_SDMMC BIT(2)
@ -544,7 +561,7 @@
#define SEC_CARVEOUT_CA3_R_NVJPG BIT(30) #define SEC_CARVEOUT_CA3_R_NVJPG BIT(30)
#define SEC_CARVEOUT_CA3_W_NVJPG BIT(31) #define SEC_CARVEOUT_CA3_W_NVJPG BIT(31)
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS4 */ /*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS4 */
#define SEC_CARVEOUT_CA4_R_SE BIT(0) #define SEC_CARVEOUT_CA4_R_SE BIT(0)
#define SEC_CARVEOUT_CA4_W_SE BIT(1) #define SEC_CARVEOUT_CA4_W_SE BIT(1)
#define SEC_CARVEOUT_CA4_R_AXIAP BIT(2) #define SEC_CARVEOUT_CA4_R_AXIAP BIT(2)

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-2022 CTCaer * Copyright (c) 2019-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -155,13 +155,13 @@ void minerva_sdmmc_la_program(void *table, bool t210b01)
switch (freq) switch (freq)
{ {
case 204000: case 204000:
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 75; la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 50;
break; break;
case 408000: case 408000:
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 37; la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 25;
break; break;
default: default:
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 30; la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 20;
break; break;
} }
} }
@ -206,6 +206,23 @@ void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
mtc_cfg->table_entries++; mtc_cfg->table_entries++;
} }
// Trim table.
int entries = 0;
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
{
// Copy frequencies from 204/408/800 MHz and 1333+ MHz.
int rate = mtc_cfg->mtc_table[i].rate_khz;
if (rate == FREQ_204 ||
rate == FREQ_408 ||
rate == FREQ_800 ||
rate >= FREQ_1333)
{
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
entries++;
}
}
mtc_cfg->table_entries = entries;
// Set init frequency. // Set init frequency.
minerva_change_freq(FREQ_204); minerva_change_freq(FREQ_204);
@ -213,38 +230,21 @@ void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
mtc_cfg->train_mode = OP_TRAIN; mtc_cfg->train_mode = OP_TRAIN;
for (u32 i = 0; i < mtc_cfg->table_entries; i++) for (u32 i = 0; i < mtc_cfg->table_entries; i++)
{ {
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz; // Skip already trained frequencies and OC freq (Arachne handles it).
// Skip already trained frequencies. if (mtc_cfg->mtc_table[i].trained || mtc_cfg->rate_to == oc_freq)
if (mtc_cfg->rate_to == FREQ_204 ||
mtc_cfg->rate_to == FREQ_800 ||
mtc_cfg->rate_to == FREQ_1600 ||
mtc_cfg->rate_to == oc_freq) // Skip OC freq since Arachne handles it.
continue; continue;
// Train frequency. // Train frequency.
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
minerva_cfg(mtc_cfg, NULL); minerva_cfg(mtc_cfg, NULL);
} }
// Do FSP WAR and scale to 800 MHz as boot freq. // Do FSP WAR and scale to 800 MHz as boot freq.
bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0); bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0);
if (fsp_opwr_disabled) if (fsp_opwr_disabled)
minerva_change_freq(FREQ_666); minerva_change_freq(FREQ_1333);
minerva_change_freq(FREQ_800); minerva_change_freq(FREQ_800);
// Trim table.
int entries = 0;
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
{
// Copy freqs from 204 MHz to 800 MHz and 1600 MHz and above.
int rate = mtc_cfg->mtc_table[i].rate_khz;
if ((rate >= FREQ_204 && rate <= FREQ_800) || rate >= FREQ_1600)
{
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
entries++;
}
}
mtc_cfg->table_entries = entries;
// Do not let other mtc ops. // Do not let other mtc ops.
mtc_cfg->init_done = 0; mtc_cfg->init_done = 0;
} }

View file

@ -53,8 +53,9 @@ enum train_mode_t
typedef enum typedef enum
{ {
FREQ_204 = 204000, FREQ_204 = 204000,
FREQ_666 = 665600, FREQ_408 = 408000,
FREQ_800 = 800000, FREQ_800 = 800000,
FREQ_1333 = 1331200,
FREQ_1600 = 1600000 FREQ_1600 = 1600000
} minerva_freq_t; } minerva_freq_t;

View file

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -18,156 +18,228 @@
#include <string.h> #include <string.h>
#include <soc/bpmp.h>
#include <soc/ccplex.h> #include <soc/ccplex.h>
#include <soc/timer.h> #include <soc/timer.h>
#include <soc/t210.h> #include <soc/t210.h>
#include <mem/mc_t210.h> #include <mem/mc_t210.h>
#include <mem/smmu.h> #include <mem/smmu.h>
#include <utils/aarch64_util.h> #include <memory_map.h>
bool smmu_used = false; /*! SMMU register defines */
u8 *_pageheap = (u8 *)SMMU_HEAP_ADDR; #define SMMU_ASID(asid) (((asid) << 24u) | ((asid) << 16u) | ((asid) << 8u) | (asid))
#define SMMU_ENABLE BIT(31)
#define SMMU_TLB_ACTIVE_LINES(l) ((l) << 0u)
#define SMMU_TLB_RR_ARBITRATION BIT(28)
#define SMMU_TLB_HIT_UNDER_MISS BIT(29)
#define SMMU_TLB_STATS_ENABLE BIT(31)
#define SMUU_PTC_INDEX_MAP(m) ((m) << 0u)
#define SMUU_PTC_LINE_MASK(m) ((m) << 8u)
#define SMUU_PTC_REQ_LIMIT(l) ((l) << 24u)
#define SMUU_PTC_CACHE_ENABLE BIT(29)
#define SMUU_PTC_STATS_ENABLE BIT(31)
//Enabling SMMU requires a TZ secure write: MC(MC_SMMU_CONFIG) = 1; /*! Page table defines */
u8 smmu_payload[] __attribute__((aligned(16))) = { #define SMMU_4MB_REGION 0
0x41, 0x01, 0x00, 0x58, // 0x00: LDR X1, =0x70019010 #define SMMU_PAGE_TABLE 1
#define SMMU_PDIR_COUNT 1024
#define SMMU_PTBL_COUNT 1024
#define SMMU_PAGE_SHIFT 12u
#define SMMU_PTN_SHIFT SMMU_PAGE_SHIFT
#define SMMU_PDN_SHIFT 22u
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> SMMU_PAGE_SHIFT)
#define SMMU_ADDR_TO_PTN(addr) ((addr) >> SMMU_PTN_SHIFT)
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> SMMU_PDN_SHIFT)
#define SMMU_PTN_TO_ADDR(ptn) ((ptn) << SMMU_PTN_SHIFT)
#define SMMU_PDN_TO_ADDR(pdn) ((pdn) << SMMU_PDN_SHIFT)
#define SMMU_PTB(page, attr) (((attr) << 29u) | ((page) >> SMMU_PAGE_SHIFT))
static void *smmu_heap = (void *)SMMU_HEAP_ADDR;
// Enabling SMMU requires a TZ (EL3) secure write. MC(MC_SMMU_CONFIG) = 1;
static const u8 smmu_enable_payload[] = {
0xC1, 0x00, 0x00, 0x18, // 0x00: LDR W1, =0x70019010
0x20, 0x00, 0x80, 0xD2, // 0x04: MOV X0, #0x1 0x20, 0x00, 0x80, 0xD2, // 0x04: MOV X0, #0x1
0x20, 0x00, 0x00, 0xB9, // 0x08: STR W0, [X1] 0x20, 0x00, 0x00, 0xB9, // 0x08: STR W0, [X1]
0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC IALLUIS 0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC IALLUIS
0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB ISH 0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB ISH
0xFE, 0xFF, 0xFF, 0x17, // 0x14: B loop 0xFE, 0xFF, 0xFF, 0x17, // 0x14: B loop
0x00, 0x00, 0x80, 0xD2, // 0x18: MOV X0, #0x0 0x10, 0x90, 0x01, 0x70, // 0x18: MC_SMMU_CONFIG
0x20, 0x00, 0x00, 0xB9, // 0x1C: STR W0, [X1]
0x80, 0x00, 0x00, 0x58, // 0x20: LDR X0, =0x4002B000
0x00, 0x00, 0x1F, 0xD6, // 0x28: BR X0
0x10, 0x90, 0x01, 0x70, // 0x28: MC_SMMU_CONFIG
0x00, 0x00, 0x00, 0x00, // 0x2C:
0x00, 0x00, 0x00, 0x00, // 0x30: secmon address
0x00, 0x00, 0x00, 0x00 // 0x34:
}; };
void *page_alloc(u32 num) void *smmu_page_zalloc(u32 num)
{ {
u8 *res = _pageheap; void *page = smmu_heap;
_pageheap += SZ_PAGE * num; memset(page, 0, SZ_PAGE * num);
memset(res, 0, SZ_PAGE * num);
return res; smmu_heap += SZ_PAGE * num;
return page;
} }
u32 *smmu_alloc_pdir() static pde_t *_smmu_pdir_alloc()
{ {
u32 *pdir = (u32 *)page_alloc(1); pde_t *pdir = (pde_t *)smmu_page_zalloc(1);
for (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
pdir[pdn] = _PDE_VACANT(pdn); // Initialize pdes with no permissions.
for (u32 pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
pdir[pdn].huge.page = pdn;
return pdir; return pdir;
} }
void smmu_flush_regs() static void _smmu_flush_regs()
{ {
(void)MC(MC_SMMU_PTB_DATA); (void)MC(MC_SMMU_PTB_DATA);
} }
void smmu_flush_all() void smmu_flush_all()
{ {
MC(MC_SMMU_PTC_FLUSH) = 0;
smmu_flush_regs();
// Flush the entire page table cache.
MC(MC_SMMU_PTC_FLUSH) = 0;
_smmu_flush_regs();
// Flush the entire table.
MC(MC_SMMU_TLB_FLUSH) = 0; MC(MC_SMMU_TLB_FLUSH) = 0;
smmu_flush_regs(); _smmu_flush_regs();
} }
void smmu_init(u32 secmon_base) void smmu_init()
{ {
MC(MC_SMMU_PTB_ASID) = 0; MC(MC_SMMU_PTB_ASID) = 0;
MC(MC_SMMU_PTB_DATA) = 0; MC(MC_SMMU_PTB_DATA) = 0;
MC(MC_SMMU_TLB_CONFIG) = 0x30000030; MC(MC_SMMU_TLB_CONFIG) = SMMU_TLB_HIT_UNDER_MISS | SMMU_TLB_RR_ARBITRATION | SMMU_TLB_ACTIVE_LINES(48);
MC(MC_SMMU_PTC_CONFIG) = 0x28000F3F; MC(MC_SMMU_PTC_CONFIG) = SMUU_PTC_CACHE_ENABLE | SMUU_PTC_REQ_LIMIT(8) | SMUU_PTC_LINE_MASK(0xF) | SMUU_PTC_INDEX_MAP(0x3F);
MC(MC_SMMU_PTC_FLUSH) = 0; MC(MC_SMMU_PTC_FLUSH) = 0;
MC(MC_SMMU_TLB_FLUSH) = 0; MC(MC_SMMU_TLB_FLUSH) = 0;
// Set the secmon address
*(u32 *)(smmu_payload + 0x30) = secmon_base;
} }
void smmu_enable() void smmu_enable()
{ {
if (smmu_used) static bool enabled = false;
if (enabled)
return; return;
ccplex_boot_cpu0((u32)smmu_payload); // Launch payload on CCPLEX in order to set SMMU enable bit.
smmu_used = true; ccplex_boot_cpu0((u32)smmu_enable_payload, false);
msleep(150); msleep(100);
ccplex_powergate_cpu0();
smmu_flush_all(); smmu_flush_all();
enabled = true;
} }
bool smmu_is_used() void smmu_reset_heap()
{ {
return smmu_used; smmu_heap = (void *)SMMU_HEAP_ADDR;
} }
void smmu_exit() void *smmu_init_domain(u32 dev_base, u32 asid)
{ {
*(u32 *)(smmu_payload + 0x14) = _NOP(); void *ptb = _smmu_pdir_alloc();
}
u32 *smmu_init_domain4(u32 dev_base, u32 asid)
{
u32 *pdir = smmu_alloc_pdir();
MC(MC_SMMU_PTB_ASID) = asid; MC(MC_SMMU_PTB_ASID) = asid;
MC(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((u32)pdir, _PDIR_ATTR); MC(MC_SMMU_PTB_DATA) = SMMU_PTB((u32)ptb, SMMU_ATTR_ALL);
smmu_flush_regs(); _smmu_flush_regs();
MC(dev_base) = 0x80000000 | (asid << 24) | (asid << 16) | (asid << 8) | (asid); // Use the same macro for both quad and single domains. Reserved bits are not set anyway.
smmu_flush_regs(); MC(dev_base) = SMMU_ENABLE | SMMU_ASID(asid);
_smmu_flush_regs();
return pdir; return ptb;
} }
u32 *smmu_get_pte(u32 *pdir, u32 iova) void smmu_deinit_domain(u32 dev_base, u32 asid)
{ {
u32 ptn = SMMU_ADDR_TO_PFN(iova); MC(MC_SMMU_PTB_ASID) = asid;
u32 pdn = SMMU_ADDR_TO_PDN(iova); MC(MC_SMMU_PTB_DATA) = 0;
u32 *ptbl; MC(dev_base) = 0;
_smmu_flush_regs();
}
if (pdir[pdn] != _PDE_VACANT(pdn)) void smmu_domain_bypass(u32 dev_base, bool bypass)
ptbl = (u32 *)((pdir[pdn] & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT); {
if (bypass)
{
smmu_flush_all();
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
MC(dev_base) &= ~SMMU_ENABLE;
}
else else
{ {
ptbl = (u32 *)page_alloc(1); bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
MC(dev_base) |= SMMU_ENABLE;
smmu_flush_all();
}
_smmu_flush_regs();
}
static pte_t *_smmu_get_pte(pde_t *pdir, u32 iova)
{
u32 pdn = SMMU_ADDR_TO_PDN(iova);
pte_t *ptbl;
// Get 4MB page table or initialize one.
if (pdir[pdn].tbl.attr)
ptbl = (pte_t *)(SMMU_PTN_TO_ADDR(pdir[pdn].tbl.table));
else
{
// Allocate page table.
ptbl = (pte_t *)smmu_page_zalloc(1);
// Get address.
u32 addr = SMMU_PDN_TO_ADDR(pdn); u32 addr = SMMU_PDN_TO_ADDR(pdn);
for (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE)
ptbl[pn] = _PTE_VACANT(addr); // Initialize page table with no permissions.
pdir[pdn] = SMMU_MK_PDE((u32)ptbl, _PDE_ATTR | _PDE_NEXT); for (u32 pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SZ_PAGE)
ptbl[pn].page = SMMU_ADDR_TO_PFN(addr);
// Set page table to the page directory.
pdir[pdn].tbl.table = SMMU_ADDR_TO_PTN((u32)ptbl);
pdir[pdn].tbl.next = SMMU_PAGE_TABLE;
pdir[pdn].tbl.attr = SMMU_ATTR_ALL;
smmu_flush_all(); smmu_flush_all();
} }
return &ptbl[ptn % SMMU_PTBL_COUNT]; return &ptbl[SMMU_ADDR_TO_PTN(iova) % SMMU_PTBL_COUNT];
} }
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr) void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr)
{ {
for (int i = 0; i < cnt; i++) // Map pages to page table entries. VA/PA should be aligned to 4KB.
for (u32 i = 0; i < pages; i++)
{ {
u32 *pte = smmu_get_pte(pdir, addr); pte_t *pte = _smmu_get_pte((pde_t *)ptb, iova);
*pte = SMMU_ADDR_TO_PFN(page) | attr;
addr += SZ_PAGE; pte->page = SMMU_ADDR_TO_PFN(iopa);
page += SZ_PAGE; pte->attr = attr;
iova += SZ_PAGE;
iopa += SZ_PAGE;
} }
smmu_flush_all(); smmu_flush_all();
} }
u32 *smmu_init_for_tsec() void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr)
{ {
return smmu_init_domain4(MC_SMMU_TSEC_ASID, 1); pde_t *pdir = (pde_t *)ptb;
}
void smmu_deinit_for_tsec() // Map 4MB regions to page directory entries. VA/PA should be aligned to 4MB.
{ for (u32 i = 0; i < regions; i++)
MC(MC_SMMU_PTB_ASID) = 1; {
MC(MC_SMMU_PTB_DATA) = 0; u32 pdn = SMMU_ADDR_TO_PDN(iova);
MC(MC_SMMU_TSEC_ASID) = 0; pdir[pdn].huge.page = SMMU_ADDR_TO_PDN(iopa);
smmu_flush_regs(); pdir[pdn].huge.next = SMMU_4MB_REGION;
} pdir[pdn].huge.attr = attr;
iova += SZ_4M;
iopa += SZ_4M;
}
smmu_flush_all();
}

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -14,70 +15,57 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <assert.h>
#include <utils/types.h> #include <utils/types.h>
#define SMMU_HEAP_ADDR 0xA0000000
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8
#define MC_ERR_ADR 0xc
#define MC_SMMU_CONFIG 0x10
#define MC_SMMU_TLB_CONFIG 0x14
#define MC_SMMU_PTC_CONFIG 0x18
#define MC_SMMU_PTB_ASID 0x1c
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH 0x34
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_AVPC_ASID 0x23C #define MC_SMMU_AVPC_ASID 0x23C
#define MC_SMMU_TSEC_ASID 0x294 #define MC_SMMU_TSEC_ASID 0x294
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
#define SMMU_PDE_NEXT_SHIFT 28 #define SMMU_NS BIT(0)
#define MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29 #define SMMU_WRITE BIT(1)
#define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT 30 #define SMMU_READ BIT(2)
#define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT 31 #define SMMU_ATTR_ALL (SMMU_READ | SMMU_WRITE | SMMU_NS)
#define SMMU_PAGE_SHIFT 12
#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT)
#define SMMU_PDIR_COUNT 1024
#define SMMU_PDIR_SIZE (sizeof(u32) * SMMU_PDIR_COUNT)
#define SMMU_PTBL_COUNT 1024
#define SMMU_PTBL_SIZE (sizeof(u32) * SMMU_PTBL_COUNT)
#define SMMU_PDIR_SHIFT 12
#define SMMU_PDE_SHIFT 12
#define SMMU_PTE_SHIFT 12
#define SMMU_PFN_MASK 0x000FFFFF
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22)
#define _READABLE (1 << MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT)
#define _WRITABLE (1 << MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT)
#define _NONSECURE (1 << MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT)
#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT)
#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)
#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)
#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr))
#define SMMU_MK_PDE(page, attr) (((page) >> SMMU_PDE_SHIFT) | (attr))
void *page_alloc(u32 num); typedef struct _pde_t {
u32 *smmu_alloc_pdir(); union {
void smmu_flush_regs(); union {
void smmu_flush_all(); struct {
void smmu_init(u32 secmon_base); u32 table:22;
void smmu_enable(); u32 rsvd:6;
bool smmu_is_used(); u32 next:1;
void smmu_exit(); u32 attr:3;
u32 *smmu_init_domain4(u32 dev_base, u32 asid); } tbl;
u32 *smmu_get_pte(u32 *pdir, u32 iova);
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr); struct {
u32 *smmu_init_for_tsec(); u32 rsvd_:10;
void smmu_deinit_for_tsec(); u32 page:12;
u32 rsvd:6;
u32 next:1;
u32 attr:3;
} huge;
};
u32 pde;
};
} pde_t;
typedef struct _pte_t {
u32 page:22;
u32 rsvd:7;
u32 attr:3;
} pte_t;
static_assert(sizeof(pde_t) == sizeof(u32), "pde_t size is wrong!");
static_assert(sizeof(pte_t) == sizeof(u32), "pte_t size is wrong!");
void *smmu_page_zalloc(u32 num);
void smmu_flush_all();
void smmu_init();
void smmu_enable();
void smmu_reset_heap();
void *smmu_init_domain(u32 dev_base, u32 asid);
void smmu_deinit_domain(u32 dev_base, u32 asid);
void smmu_domain_bypass(u32 dev_base, bool bypass);
void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr);
void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr);

View file

@ -50,7 +50,9 @@
/* Stack theoretical max: 33MB */ /* Stack theoretical max: 33MB */
#define IPL_STACK_TOP 0x83100000 #define IPL_STACK_TOP 0x83100000
#define IPL_HEAP_START 0x84000000 #define IPL_HEAP_START 0x84000000
#define IPL_HEAP_SZ SZ_512M #define IPL_HEAP_SZ (SZ_512M - SZ_64M)
#define SMMU_HEAP_ADDR 0xA0000000
/* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */ /* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */
// Virtual disk / Chainloader buffers. // Virtual disk / Chainloader buffers.

View file

@ -23,6 +23,8 @@
#include <soc/timer.h> #include <soc/timer.h>
#include <soc/t210.h> #include <soc/t210.h>
int epoch_offset = 0;
void max77620_rtc_prep_read() void max77620_rtc_prep_read()
{ {
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE); i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
@ -154,6 +156,21 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
return epoch; return epoch;
} }
void max77620_rtc_get_time_adjusted(rtc_time_t *time)
{
max77620_rtc_get_time(time);
if (epoch_offset)
{
u32 epoch = (u32)((s64)max77620_rtc_date_to_epoch(time) + epoch_offset);
max77620_rtc_epoch_to_date(epoch, time);
}
}
void max77620_rtc_set_epoch_offset(int offset)
{
epoch_offset = offset;
}
void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr) void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr)
{ {
max77620_rtc_stop_alarm(); max77620_rtc_stop_alarm();

View file

@ -109,6 +109,8 @@ typedef struct _rtc_reboot_reason_t
void max77620_rtc_prep_read(); void max77620_rtc_prep_read();
void max77620_rtc_get_time(rtc_time_t *time); void max77620_rtc_get_time(rtc_time_t *time);
void max77620_rtc_get_time_adjusted(rtc_time_t *time);
void max77620_rtc_set_epoch_offset(int offset);
void max77620_rtc_stop_alarm(); void max77620_rtc_stop_alarm();
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time); void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time); u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -182,7 +182,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
if (!src || !dst) if (!src || !dst)
return 0; return 0;
u8 *block = (u8 *)calloc(1, SE_AES_BLOCK_SIZE); u8 *block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1; SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
@ -657,8 +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 se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
{ {
int res = 0; int res = 0;
u8 *key = (u8 *)calloc(1, SE_KEY_128_SIZE); u8 *key = (u8 *)zalloc(SE_KEY_128_SIZE);
u8 *last_block = (u8 *)calloc(1, SE_AES_BLOCK_SIZE); u8 *last_block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
se_aes_iv_clear(ks); se_aes_iv_clear(ks);
se_aes_iv_updated_clear(ks); se_aes_iv_updated_clear(ks);

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@ -70,8 +70,9 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
int res = 0; int res = 0;
u8 *fwbuf = NULL; u8 *fwbuf = NULL;
u32 type = tsec_ctxt->type; u32 type = tsec_ctxt->type;
u32 *pdir, *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec; u32 *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
u32 *pkg11_magic_off; u32 *pkg11_magic_off;
void *ptb;
bpmp_mmu_disable(); bpmp_mmu_disable();
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL); bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
@ -145,56 +146,56 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
if (type == TSEC_FW_TYPE_EMU) if (type == TSEC_FW_TYPE_EMU)
{ {
// Init SMMU translation for TSEC. // Init SMMU translation for TSEC.
pdir = smmu_init_for_tsec(); ptb = smmu_init_domain(MC_SMMU_TSEC_ASID, 1);
smmu_init(tsec_ctxt->secmon_base); smmu_init();
// Enable SMMU
if (!smmu_is_used()) // Enable SMMU.
smmu_enable(); smmu_enable();
// Clock reset controller. // Clock reset controller.
car = page_alloc(1); car = smmu_page_zalloc(1);
memcpy(car, (void *)CLOCK_BASE, SZ_PAGE); memcpy(car, (void *)CLOCK_BASE, SZ_PAGE);
car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = 2; car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = CLK_SRC_DIV(2);
smmu_map(pdir, CLOCK_BASE, (u32)car, 1, _WRITABLE | _READABLE | _NONSECURE); smmu_map(ptb, CLOCK_BASE, (u32)car, 1, SMMU_WRITE | SMMU_READ | SMMU_NS);
// Fuse driver. // Fuse driver.
fuse = page_alloc(1); fuse = smmu_page_zalloc(1);
memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K); memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K);
fuse[0x82C / 4] = 0; fuse[0x82C / 4] = 0;
fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1; fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1; fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
smmu_map(pdir, (FUSE_BASE - 0x800), (u32)fuse, 1, _READABLE | _NONSECURE); smmu_map(ptb, (FUSE_BASE - 0x800), (u32)fuse, 1, SMMU_READ | SMMU_NS);
// Power management controller. // Power management controller.
pmc = page_alloc(1); pmc = smmu_page_zalloc(1);
smmu_map(pdir, RTC_BASE, (u32)pmc, 1, _READABLE | _NONSECURE); smmu_map(ptb, RTC_BASE, (u32)pmc, 1, SMMU_READ | SMMU_NS);
// Flow control. // Flow control.
flowctrl = page_alloc(1); flowctrl = smmu_page_zalloc(1);
smmu_map(pdir, FLOW_CTLR_BASE, (u32)flowctrl, 1, _WRITABLE | _NONSECURE); smmu_map(ptb, FLOW_CTLR_BASE, (u32)flowctrl, 1, SMMU_WRITE | SMMU_NS);
// Security engine. // Security engine.
se = page_alloc(1); se = smmu_page_zalloc(1);
memcpy(se, (void *)SE_BASE, SZ_PAGE); memcpy(se, (void *)SE_BASE, SZ_PAGE);
smmu_map(pdir, SE_BASE, (u32)se, 1, _READABLE | _WRITABLE | _NONSECURE); smmu_map(ptb, SE_BASE, (u32)se, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
// Memory controller. // Memory controller.
mc = page_alloc(1); mc = smmu_page_zalloc(1);
memcpy(mc, (void *)MC_BASE, SZ_PAGE); memcpy(mc, (void *)MC_BASE, SZ_PAGE);
mc[MC_IRAM_BOM / 4] = 0; mc[MC_IRAM_BOM / 4] = 0;
mc[MC_IRAM_TOM / 4] = DRAM_START; mc[MC_IRAM_TOM / 4] = DRAM_START;
smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE); smmu_map(ptb, MC_BASE, (u32)mc, 1, SMMU_READ | SMMU_NS);
// IRAM // IRAM
iram = page_alloc(0x30); iram = smmu_page_zalloc(0x30);
memcpy(iram, tsec_ctxt->pkg1, 0x30000); memcpy(iram, tsec_ctxt->pkg1, 0x30000);
// PKG1.1 magic offset. // PKG1.1 magic offset.
pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / 4)); pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / sizeof(u32)));
smmu_map(pdir, 0x40010000, (u32)iram, 0x30, _READABLE | _WRITABLE | _NONSECURE); smmu_map(ptb, 0x40010000, (u32)iram, 0x30, SMMU_READ | SMMU_WRITE | SMMU_NS);
// Exception vectors // Exception vectors
evec = page_alloc(1); evec = smmu_page_zalloc(1);
smmu_map(pdir, EXCP_VEC_BASE, (u32)evec, 1, _READABLE | _WRITABLE | _NONSECURE); smmu_map(ptb, EXCP_VEC_BASE, (u32)evec, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
} }
// Execute firmware. // Execute firmware.
@ -229,7 +230,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
if (kidx != 8) if (kidx != 8)
{ {
res = -6; res = -6;
smmu_deinit_for_tsec(); smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
goto out_free; goto out_free;
} }
@ -240,7 +241,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
memcpy(tsec_keys, &key, 0x20); memcpy(tsec_keys, &key, 0x20);
memcpy(tsec_ctxt->pkg1, iram, 0x30000); memcpy(tsec_ctxt->pkg1, iram, 0x30000);
smmu_deinit_for_tsec(); smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
// for (int i = 0; i < kidx; i++) // for (int i = 0; i < kidx; i++)
// gfx_printf("key %08X\n", key[i]); // gfx_printf("key %08X\n", key[i]);

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -35,7 +35,6 @@ typedef struct _tsec_ctxt_t
u32 type; u32 type;
void *pkg1; void *pkg1;
u32 pkg11_off; u32 pkg11_off;
u32 secmon_base;
} tsec_ctxt_t; } tsec_ctxt_t;
int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt); int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt);

View file

@ -287,10 +287,10 @@ void bpmp_usleep(u32 us)
// Each iteration takes 1us. // Each iteration takes 1us.
while (us) while (us)
{ {
delay = (us > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : us; delay = (us > HALT_MAX_CNT) ? HALT_MAX_CNT : us;
us -= delay; us -= delay;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_USEC | delay; FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_USEC | delay;
} }
} }
@ -301,14 +301,14 @@ void bpmp_msleep(u32 ms)
// Iteration time is variable. ~200 - 1000us. // Iteration time is variable. ~200 - 1000us.
while (ms) while (ms)
{ {
delay = (ms > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : ms; delay = (ms > HALT_MAX_CNT) ? HALT_MAX_CNT : ms;
ms -= delay; ms -= delay;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_MSEC | delay; FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_MSEC | delay;
} }
} }
void bpmp_halt() void bpmp_halt()
{ {
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_JTAG; FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_JTAG;
} }

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -27,7 +27,9 @@
#include <power/max77812.h> #include <power/max77812.h>
#include <utils/util.h> #include <utils/util.h>
void _ccplex_enable_power_t210() #define CCPLEX_FLOWCTRL_POWERGATING 0
static void _ccplex_enable_power_t210()
{ {
// Configure GPIO5 and enable output in order to power CPU pmic. // Configure GPIO5 and enable output in order to power CPU pmic.
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_ENABLE); max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_ENABLE);
@ -37,19 +39,31 @@ void _ccplex_enable_power_t210()
// 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL. // 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL.
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_HOS_CFG); max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_HOS_CFG);
// Set voltage and enable cores power. // Set voltage and enable cluster power.
max7762x_regulator_set_voltage(REGULATOR_CPU0, 950000); max7762x_regulator_set_voltage(REGULATOR_CPU0, 950000);
max7762x_regulator_enable(REGULATOR_CPU0, true); max7762x_regulator_enable(REGULATOR_CPU0, true);
} }
void _ccplex_enable_power_t210b01() static void _ccplex_enable_power_t210b01()
{ {
// Set voltage and enable cores power. // Set voltage and enable cluster power.
max7762x_regulator_set_voltage(REGULATOR_CPU1, 800000); max7762x_regulator_set_voltage(REGULATOR_CPU1, 800000);
max7762x_regulator_enable(REGULATOR_CPU1, true); max7762x_regulator_enable(REGULATOR_CPU1, true);
} }
void ccplex_boot_cpu0(u32 entry) static void _ccplex_disable_power()
{
// Disable cluster power.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
{
max7762x_regulator_enable(REGULATOR_CPU0, false);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 0);
}
else
max7762x_regulator_enable(REGULATOR_CPU1, false);
}
void ccplex_boot_cpu0(u32 entry, bool lock)
{ {
// Set ACTIVE_CLUSER to FAST. // Set ACTIVE_CLUSER to FAST.
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW; FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW;
@ -62,12 +76,12 @@ void ccplex_boot_cpu0(u32 entry)
clock_enable_pllx(); clock_enable_pllx();
// Configure MSELECT source and enable clock to 102MHz. // Configure MSELECT source and enable clock to 102MHz.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6; CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (0 << 29) | CLK_SRC_DIV(4);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT);
// Configure initial CPU clock frequency and enable clock. // Configure initial CPU clock frequency and enable clock.
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ. CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ.
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000; CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = BIT(31); // SUPER_CDIV_ENB.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
clock_enable_coresight(); clock_enable_coresight();
@ -90,12 +104,15 @@ void ccplex_boot_cpu0(u32 entry)
EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0; EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;
// Set reset vector. // Set reset vector.
SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN; SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
SB(SB_AA64_RESET_HIGH) = 0; SB(SB_AA64_RESET_HIGH) = 0;
// Non-secure reset vector write disable. // Non-secure reset vector write disable.
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS; if (lock)
(void)SB(SB_CSR); {
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
(void)SB(SB_CSR);
}
// Tighten up the security aperture. // Tighten up the security aperture.
// MC(MC_TZ_SECURITY_CTRL) = 1; // MC(MC_TZ_SECURITY_CTRL) = 1;
@ -103,8 +120,46 @@ void ccplex_boot_cpu0(u32 entry)
// Clear MSELECT reset. // Clear MSELECT reset.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT); CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
// Clear NONCPU reset. // Clear NONCPU reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000; CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(29); // CLR_NONCPURESET.
// Clear CPU0 reset. // Clear CPU0 reset.
// < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset. // < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x41010001; CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
}
void ccplex_powergate_cpu0()
{
#if CCPLEX_FLOWCTRL_POWERGATING
// Halt CPU0.
FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
// Powergate cluster via flow control without waiting for WFI.
FLOW_CTLR(FLOW_CTLR_CPU0_CSR) = CSR_INTR_FLAG | CSR_EVENT_FLAG | CSR_ENABLE_EXT_CPU_RAIL | CSR_WAIT_WFI_NONE | CSR_ENABLE;
// Wait for the rail power off to finish.
while((FLOW_CTLR(FLOW_CTLR_CPU_PWR_CSR) & CPU_PWR_RAIL_STS_MASK) != CPU_PWR_RAIL_OFF);
// Set CPU0 to waitevent.
FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_WAITEVENT;
#endif
// Set CPU0 POR and CORE, CX0, L2, and DBG reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
// Set NONCPU reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(29);
// Set MSELECT reset.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_SET) = BIT(CLK_V_MSELECT);
// Disable CE0.
pmc_enable_partition(POWER_RAIL_CE0, DISABLE);
// Disable cluster 0 non-CPU.
pmc_enable_partition(POWER_RAIL_C0NC, DISABLE);
// Disable CPU rail.
pmc_enable_partition(POWER_RAIL_CRAIL, DISABLE);
clock_disable_coresight();
// Clear out MSELECT and CPU clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_CLR) = BIT(CLK_V_MSELECT) | BIT(CLK_V_CPUG);
_ccplex_disable_power();
} }

View file

@ -19,6 +19,7 @@
#include <utils/types.h> #include <utils/types.h>
void ccplex_boot_cpu0(u32 entry); void ccplex_boot_cpu0(u32 entry, bool lock);
void ccplex_powergate_cpu0();
#endif #endif

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -42,82 +42,82 @@ static const clock_osc_t _clock_osc_cnt[] = {
/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */ /* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
static const clk_rst_t _clock_uart[] = { static const clk_rst_t _clock_uart[] = {
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, 2 } { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, CLK_SRC_DIV(2) }
}; };
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26. //I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
static const clk_rst_t _clock_i2c[] = { static const clk_rst_t _clock_i2c[] = {
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, 19 }, //20.4MHz -> 100KHz { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 4 }, //81.6MHz -> 400KHz { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, 19 }, //20.4MHz -> 100KHz { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, 4 }, //81.6MHz -> 400KHz { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, CLK_SRC_DIV(10.5) } //20.4MHz -> 100KHz
}; };
static clk_rst_t _clock_se = { static clk_rst_t _clock_se = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0 // 408MHz. Default: 408MHz. Max: 627.2 MHz. CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, CLK_SRC_DIV(1) // 408MHz. Default: 408MHz. Max: 627.2 MHz.
}; };
static clk_rst_t _clock_tzram = { static clk_rst_t _clock_tzram = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0 CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_host1x = { static clk_rst_t _clock_host1x = {
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3 // 163.2MHz. Max: 408MHz. CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, CLK_SRC_DIV(2.5) // 163.2MHz. Max: 408MHz.
}; };
static clk_rst_t _clock_tsec = { static clk_rst_t _clock_tsec = {
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2 // 204MHz. Max: 408MHz. CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, CLK_SRC_DIV(2) // 204MHz. Max: 408MHz.
}; };
static clk_rst_t _clock_nvdec = { static clk_rst_t _clock_nvdec = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, 0 // 408 MHz. Max: 716.8/979.2MHz. CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 716.8/979.2MHz.
}; };
static clk_rst_t _clock_nvjpg = { static clk_rst_t _clock_nvjpg = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, 0 // 408 MHz. Max: 627.2/652.8MHz. CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8MHz.
}; };
static clk_rst_t _clock_vic = { static clk_rst_t _clock_vic = {
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, 0 // 408 MHz. Max: 627.2/652.8MHz. CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8MHz.
}; };
static clk_rst_t _clock_sor_safe = { static clk_rst_t _clock_sor_safe = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0 CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_sor0 = { static clk_rst_t _clock_sor0 = {
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, 0 CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_sor1 = { static clk_rst_t _clock_sor1 = {
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2 // 204MHz. CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, CLK_SRC_DIV(2) // 204MHz.
}; };
static clk_rst_t _clock_kfuse = { static clk_rst_t _clock_kfuse = {
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0 CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_cl_dvfs = { static clk_rst_t _clock_cl_dvfs = {
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0 CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_coresight = { static clk_rst_t _clock_coresight = {
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4 // 136MHz. CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, CLK_SRC_DIV(3) // 136MHz.
}; };
static clk_rst_t _clock_pwm = { static clk_rst_t _clock_pwm = {
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, 4 // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz. CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, CLK_SRC_DIV(3) // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
}; };
static clk_rst_t _clock_sdmmc_legacy_tm = { static clk_rst_t _clock_sdmmc_legacy_tm = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, 66 CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, CLK_SRC_DIV(34) // 12MHz.
}; };
static clk_rst_t _clock_apbdma = { static clk_rst_t _clock_apbdma = {
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, 0 // Max: 204MHz. CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, CLK_SRC_DIV(1) // Max: 204MHz.
}; };
static clk_rst_t _clock_ahbdma = { static clk_rst_t _clock_ahbdma = {
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, 0 CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_actmon = { static clk_rst_t _clock_actmon = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, 0 // 19.2MHz. CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, CLK_SRC_DIV(1) // 19.2MHz.
}; };
static clk_rst_t _clock_extperiph1 = { static clk_rst_t _clock_extperiph1 = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, 0 CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_extperiph2 = { static clk_rst_t _clock_extperiph2 = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, 202 // 4.0MHz CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, CLK_SRC_DIV(102) // 4.0MHz
}; };
void clock_enable(const clk_rst_t *clk) void clock_enable(const clk_rst_t *clk)
@ -128,7 +128,7 @@ void clock_enable(const clk_rst_t *clk)
CLOCK(clk->enable) &= ~BIT(clk->index); CLOCK(clk->enable) &= ~BIT(clk->index);
// Configure clock source if required. // Configure clock source if required.
if (clk->source) if (clk->source)
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29); CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29u);
// Enable. // Enable.
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index); CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index);
usleep(2); usleep(2);
@ -168,12 +168,12 @@ int clock_uart_use_src_div(u32 idx, u32 baud)
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000; u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
if (baud == 3000000) if (baud == 3000000)
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 15; CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(8.5);
else if (baud == 1000000) else if (baud == 1000000)
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 49; CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(25.5);
else else
{ {
CLOCK(_clock_uart[idx].source) = clk_src_div | 2; CLOCK(_clock_uart[idx].source) = clk_src_div | CLK_SRC_DIV(2);
return 1; return 1;
} }
@ -401,7 +401,7 @@ void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
// Set DISP1 clock source and parent clock. // Set DISP1 clock source and parent clock.
if (lowpower) if (lowpower)
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT0. CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = (2 << 29u) | CLK_SRC_DIV(1); // PLLD_OUT0.
// Set dividers and enable PLLD. // Set dividers and enable PLLD.
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div; CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
@ -715,38 +715,38 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
{ {
case 25000: case 25000:
*pclock = 24728; *pclock = 24728;
divisor = 31; // 16.5 div. divisor = CLK_SRC_DIV(16.5);
break; break;
case 26000: case 26000:
*pclock = 25500; *pclock = 25500;
divisor = 30; // 16 div. divisor = CLK_SRC_DIV(16);
break; break;
case 50000: case 50000:
*pclock = 48000; *pclock = 48000;
divisor = 15; // 8.5 div. divisor = CLK_SRC_DIV(8.5);
break; break;
case 52000: case 52000:
*pclock = 51000; *pclock = 51000;
divisor = 14; // 8 div. divisor = CLK_SRC_DIV(8);
break; break;
case 82000: case 82000:
*pclock = 81600; *pclock = 81600;
divisor = 8; // 5 div. divisor = CLK_SRC_DIV(5);
break; break;
case 100000: case 100000:
source = SDMMC_CLOCK_SRC_PLLC4_OUT2; source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
*pclock = 99840; *pclock = 99840;
divisor = 2; // 2 div. divisor = CLK_SRC_DIV(2);
break; break;
case 164000: case 164000:
*pclock = 163200; *pclock = 163200;
divisor = 3; // 2.5 div. divisor = CLK_SRC_DIV(2.5);
break; break;
case 200000: case 200000:
@ -762,14 +762,14 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
break; break;
} }
*pclock = 199680; *pclock = 199680;
divisor = 0; // 1 div. divisor = CLK_SRC_DIV(1);
break; break;
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT #ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
case 400000: case 400000:
source = SDMMC_CLOCK_SRC_PLLC4_OUT0; source = SDMMC_CLOCK_SRC_PLLC4_OUT0;
*pclock = 399360; *pclock = 399360;
divisor = 3; // 2.5 div divisor = CLK_SRC_DIV(2.5);
break; break;
#endif #endif
} }
@ -785,7 +785,7 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
_clock_sdmmc_config_legacy_tm(); _clock_sdmmc_config_legacy_tm();
// Set SDMMC clock. // Set SDMMC clock.
u32 src_div = (source << 29) | divisor; u32 src_div = (source << 29u) | divisor;
switch (id) switch (id)
{ {
case SDMMC_1: case SDMMC_1:

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -198,6 +198,9 @@
#define UTMIPLL_LOCK BIT(31) #define UTMIPLL_LOCK BIT(31)
/*! Clock source */
#define CLK_SRC_DIV(d) ((d) ? ((u32)(((d) - 1) * 2)) : 0)
/*! PTO_CLK_CNT */ /*! PTO_CLK_CNT */
#define PTO_REF_CLK_WIN_CFG_MASK 0xF #define PTO_REF_CLK_WIN_CFG_MASK 0xF
#define PTO_REF_CLK_WIN_CFG_16P 0xF #define PTO_REF_CLK_WIN_CFG_16P 0xF

View file

@ -194,7 +194,7 @@ void irq_wait_event(u32 irq)
_irq_enable_source(irq); _irq_enable_source(irq);
// Halt BPMP and wait for the IRQ. No need to use WAIT_EVENT + LIC_IRQ when BPMP serves the IRQ. // Halt BPMP and wait for the IRQ. No need to use WAIT_EVENT + LIC_IRQ when BPMP serves the IRQ.
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_STOP_UNTIL_IRQ; FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
_irq_disable_source(irq); _irq_disable_source(irq);
_irq_ack_source(irq); _irq_ack_source(irq);

View file

@ -308,29 +308,47 @@
#define EMC_HEKA_UPD BIT(30) #define EMC_HEKA_UPD BIT(30)
/*! Flow controller registers. */ /*! Flow controller registers. */
#define FLOW_CTLR_HALT_COP_EVENTS 0x4 #define FLOW_CTLR_HALT_COP_EVENTS 0x4
#define HALT_COP_GIC_IRQ BIT(9) #define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
#define HALT_COP_LIC_IRQ BIT(11) #define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
#define HALT_COP_SEC BIT(23) #define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
#define HALT_COP_MSEC BIT(24) #define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
#define HALT_COP_USEC BIT(25) #define HALT_GIC_IRQ BIT(9)
#define HALT_COP_JTAG BIT(28) #define HALT_LIC_IRQ BIT(11)
#define HALT_COP_WAIT_EVENT BIT(30) #define HALT_SEC BIT(23)
#define HALT_COP_STOP_UNTIL_IRQ BIT(31) #define HALT_MSEC BIT(24)
#define HALT_COP_MAX_CNT 0xFF #define HALT_USEC BIT(25)
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0 #define HALT_JTAG BIT(28)
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14 #define HALT_MODE_NONE (0 << 29u)
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C #define HALT_MODE_RUN_AND_INT (1 << 29u)
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24 #define HALT_MODE_WAITEVENT (2 << 29u)
#define FLOW_CTLR_CPU0_CSR 0x8 #define HALT_MODE_WAITEVENT_AND_INT (3 << 29u)
#define FLOW_CTLR_CPU1_CSR 0x18 #define HALT_MODE_STOP_UNTIL_IRQ (4 << 29u)
#define FLOW_CTLR_CPU2_CSR 0x20 #define HALT_MODE_STOP_UNTIL_IRQ_AND_INT (5 << 29u)
#define FLOW_CTLR_CPU3_CSR 0x28 #define HALT_MODE_STOP_UNTIL_EVENT_AND_IRQ (6 << 29u)
#define FLOW_CTLR_RAM_REPAIR 0x40 #define HALT_MAX_CNT 0xFF
#define RAM_REPAIR_REQ BIT(0) #define FLOW_CTLR_COP_CSR 0xC
#define RAM_REPAIR_STS BIT(1) #define FLOW_CTLR_CPU0_CSR 0x8
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98 #define FLOW_CTLR_CPU1_CSR 0x18
#define CLUSTER_CTRL_ACTIVE_SLOW BIT(0) #define FLOW_CTLR_CPU2_CSR 0x20
#define FLOW_CTLR_CPU3_CSR 0x28
#define CSR_ENABLE BIT(0)
#define CSR_WAIT_WFI_NONE (0 << 8u)
#define CSR_WAIT_WFI_CPU0 (BIT(0) << 8u)
#define CSR_ENABLE_EXT_CPU_ONLY (0 << 12u)
#define CSR_ENABLE_EXT_CPU_NCPU (1 << 12u)
#define CSR_ENABLE_EXT_CPU_RAIL (2 << 12u)
#define CSR_EVENT_FLAG BIT(14)
#define CSR_INTR_FLAG BIT(15)
#define CSR_HALT BIT(22)
#define FLOW_CTLR_CPU_PWR_CSR 0x38
#define CPU_PWR_RAIL_STS_MASK (3 << 1u)
#define CPU_PWR_RAIL_OFF 0
#define FLOW_CTLR_RAM_REPAIR 0x40
#define RAM_REPAIR_REQ BIT(0)
#define RAM_REPAIR_STS BIT(1)
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
#define CLUSTER_CTRL_ACTIVE_SLOW BIT(0)
/* MSelect registers */ /* MSelect registers */
#define MSELECT_CONFIG 0x00 #define MSELECT_CONFIG 0x00

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2019-2022 CTCaer * Copyright (c) 2019-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -135,7 +135,7 @@ int emmc_set_partition(u32 partition) { return sdmmc_storage_set_mmc_partition(&
void emmc_gpt_parse(link_t *gpt) void emmc_gpt_parse(link_t *gpt)
{ {
gpt_t *gpt_buf = (gpt_t *)calloc(GPT_NUM_BLOCKS, EMMC_BLOCKSIZE); gpt_t *gpt_buf = (gpt_t *)zalloc(GPT_NUM_BLOCKS * EMMC_BLOCKSIZE);
#ifdef BDK_EMUMMC_ENABLE #ifdef BDK_EMUMMC_ENABLE
emummc_storage_read(GPT_FIRST_LBA, GPT_NUM_BLOCKS, gpt_buf); emummc_storage_read(GPT_FIRST_LBA, GPT_NUM_BLOCKS, gpt_buf);
@ -149,7 +149,7 @@ void emmc_gpt_parse(link_t *gpt)
for (u32 i = 0; i < gpt_buf->header.num_part_ents; i++) for (u32 i = 0; i < gpt_buf->header.num_part_ents; i++)
{ {
emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1); emmc_part_t *part = (emmc_part_t *)zalloc(sizeof(emmc_part_t));
if (gpt_buf->entries[i].lba_start < gpt_buf->header.first_use_lba) if (gpt_buf->entries[i].lba_start < gpt_buf->header.first_use_lba)
continue; continue;

View file

@ -26,7 +26,7 @@
#define GPT_FIRST_LBA 1 #define GPT_FIRST_LBA 1
#define GPT_NUM_BLOCKS 33 #define GPT_NUM_BLOCKS 33
#define EMMC_BLOCKSIZE 512 #define EMMC_BLOCKSIZE SDMMC_DAT_BLOCKSIZE
enum enum
{ {

View file

@ -22,7 +22,7 @@
#include <storage/sdmmc_driver.h> #include <storage/sdmmc_driver.h>
#include <libs/fatfs/ff.h> #include <libs/fatfs/ff.h>
#define SD_BLOCKSIZE 512 #define SD_BLOCKSIZE SDMMC_DAT_BLOCKSIZE
enum enum
{ {

View file

@ -184,7 +184,7 @@ int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf)
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.blksize = 512; reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.is_write = 0; reqbuf.is_write = 0;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
reqbuf.is_auto_stop_trn = 0; reqbuf.is_auto_stop_trn = 0;
@ -215,7 +215,7 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.num_sectors = num_sectors; reqbuf.num_sectors = num_sectors;
reqbuf.blksize = 512; reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.is_write = is_write; reqbuf.is_write = is_write;
reqbuf.is_multi_block = 1; reqbuf.is_multi_block = 1;
reqbuf.is_auto_stop_trn = 1; reqbuf.is_auto_stop_trn = 1;
@ -326,7 +326,7 @@ reinit_try:
out: out:
sct_off += blkcnt; sct_off += blkcnt;
sct_total -= blkcnt; sct_total -= blkcnt;
bbuf += 512 * blkcnt; bbuf += SDMMC_DAT_BLOCKSIZE * blkcnt;
} }
return 1; return 1;
@ -338,13 +338,13 @@ int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, vo
if (mc_client_has_access(buf) && !((u32)buf % 8)) if (mc_client_has_access(buf) && !((u32)buf % 8))
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0); return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0);
if (num_sectors > (SDMMC_UP_BUF_SZ / 512)) if (num_sectors > (SDMMC_UP_BUF_SZ / SDMMC_DAT_BLOCKSIZE))
return 0; return 0;
u8 *tmp_buf = (u8 *)SDMMC_UPPER_BUFFER; u8 *tmp_buf = (u8 *)SDMMC_UPPER_BUFFER;
if (_sdmmc_storage_readwrite(storage, sector, num_sectors, tmp_buf, 0)) if (_sdmmc_storage_readwrite(storage, sector, num_sectors, tmp_buf, 0))
{ {
memcpy(buf, tmp_buf, 512 * num_sectors); memcpy(buf, tmp_buf, SDMMC_DAT_BLOCKSIZE * num_sectors);
return 1; return 1;
} }
return 0; return 0;
@ -356,11 +356,11 @@ int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, v
if (mc_client_has_access(buf) && !((u32)buf % 8)) if (mc_client_has_access(buf) && !((u32)buf % 8))
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1); return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1);
if (num_sectors > (SDMMC_UP_BUF_SZ / 512)) if (num_sectors > (SDMMC_UP_BUF_SZ / SDMMC_DAT_BLOCKSIZE))
return 0; return 0;
u8 *tmp_buf = (u8 *)SDMMC_UPPER_BUFFER; u8 *tmp_buf = (u8 *)SDMMC_UPPER_BUFFER;
memcpy(tmp_buf, buf, 512 * num_sectors); memcpy(tmp_buf, buf, SDMMC_DAT_BLOCKSIZE * num_sectors);
return _sdmmc_storage_readwrite(storage, sector, num_sectors, tmp_buf, 1); return _sdmmc_storage_readwrite(storage, sector, num_sectors, tmp_buf, 1);
} }
@ -519,7 +519,7 @@ int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf)
sdmmc_req_t reqbuf; sdmmc_req_t reqbuf;
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.blksize = 512; reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.is_write = 0; reqbuf.is_write = 0;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
@ -708,9 +708,9 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_wid
return 0; return 0;
DPRINTF("[MMC] card selected\n"); DPRINTF("[MMC] card selected\n");
if (!_sdmmc_storage_set_blocklen(storage, 512)) if (!_sdmmc_storage_set_blocklen(storage, EMMC_BLOCKSIZE))
return 0; return 0;
DPRINTF("[MMC] set blocklen to 512\n"); DPRINTF("[MMC] set blocklen to EMMC_BLOCKSIZE\n");
// Check system specification version, only version 4.0 and later support below features. // Check system specification version, only version 4.0 and later support below features.
if (storage->csd.mmca_vsn < CSD_SPEC_VER_4) if (storage->csd.mmca_vsn < CSD_SPEC_VER_4)
@ -1089,7 +1089,7 @@ static int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)
sdmmc_req_t reqbuf; sdmmc_req_t reqbuf;
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.blksize = 64; reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.is_write = 0; reqbuf.is_write = 0;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
@ -1113,7 +1113,7 @@ static int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int
sdmmc_req_t reqbuf; sdmmc_req_t reqbuf;
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.blksize = 64; reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.is_write = 0; reqbuf.is_write = 0;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
@ -1526,7 +1526,7 @@ int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf)
sdmmc_req_t reqbuf; sdmmc_req_t reqbuf;
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.blksize = 64; reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.is_write = 0; reqbuf.is_write = 0;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
@ -1545,7 +1545,7 @@ int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf)
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1); sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
// Convert buffer to LE. // Convert buffer to LE.
for (int i = 0; i < 64; i += 4) for (int i = 0; i < SDMMC_CMD_BLOCKSIZE; i += 4)
{ {
storage->raw_ssr[i + 3] = buf[i]; storage->raw_ssr[i + 3] = buf[i];
storage->raw_ssr[i + 2] = buf[i + 1]; storage->raw_ssr[i + 2] = buf[i + 1];
@ -1596,7 +1596,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
{ {
case 0: case 0:
storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2); storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);
storage->csd.capacity <<= unstuff_bits(raw_csd, 80, 4) - 9; // Convert native block size to LBA 512B. storage->csd.capacity <<= unstuff_bits(raw_csd, 80, 4) - 9; // Convert native block size to LBA SDMMC_DAT_BLOCKSIZE.
break; break;
case 1: case 1:
@ -1698,9 +1698,9 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
return 0; return 0;
DPRINTF("[SD] card selected\n"); DPRINTF("[SD] card selected\n");
if (!_sdmmc_storage_set_blocklen(storage, 512)) if (!_sdmmc_storage_set_blocklen(storage, SD_BLOCKSIZE))
return 0; return 0;
DPRINTF("[SD] set blocklen to 512\n"); DPRINTF("[SD] set blocklen to SD_BLOCKSIZE\n");
// Disconnect Card Detect resistor from DAT3. // Disconnect Card Detect resistor from DAT3.
if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN)) if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN))
@ -1775,7 +1775,7 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
sdmmc_req_t reqbuf; sdmmc_req_t reqbuf;
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.blksize = 64; reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.is_write = 1; reqbuf.is_write = 1;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;

View file

@ -22,6 +22,9 @@
#include <storage/sd_def.h> #include <storage/sd_def.h>
#include <storage/sdmmc_driver.h> #include <storage/sdmmc_driver.h>
#define SDMMC_CMD_BLOCKSIZE 64
#define SDMMC_DAT_BLOCKSIZE 512
extern u32 sd_power_cycle_time_start; extern u32 sd_power_cycle_time_start;
typedef enum _sdmmc_type typedef enum _sdmmc_type

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -30,8 +30,8 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
DIR dir; DIR dir;
FILINFO fno; FILINFO fno;
char *dir_entries = (char *)calloc(MAX_ENTRIES, 256); char *dir_entries = (char *)zalloc(MAX_ENTRIES * 256);
char *temp = (char *)calloc(1, 256); char *temp = (char *)zalloc(256);
if (!pattern && !f_opendir(&dir, directory)) if (!pattern && !f_opendir(&dir, directory))
{ {

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -41,7 +41,7 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type
// Calculate total allocation size. // Calculate total allocation size.
u32 len = name ? strlen(name) + 1 : 0; u32 len = name ? strlen(name) + 1 : 0;
char *buf = calloc(sizeof(ini_sec_t) + len, 1); char *buf = zalloc(sizeof(ini_sec_t) + len);
csec = (ini_sec_t *)buf; csec = (ini_sec_t *)buf;
csec->name = strcpy_ns(buf + sizeof(ini_sec_t), name); csec->name = strcpy_ns(buf + sizeof(ini_sec_t), name);
@ -144,7 +144,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
// Calculate total allocation size. // Calculate total allocation size.
u32 klen = strlen(&lbuf[0]) + 1; u32 klen = strlen(&lbuf[0]) + 1;
u32 vlen = strlen(&lbuf[i + 1]) + 1; u32 vlen = strlen(&lbuf[i + 1]) + 1;
char *buf = calloc(sizeof(ini_kv_t) + klen + vlen, 1); char *buf = zalloc(sizeof(ini_kv_t) + klen + vlen);
ini_kv_t *kv = (ini_kv_t *)buf; ini_kv_t *kv = (ini_kv_t *)buf;
buf += sizeof(ini_kv_t); buf += sizeof(ini_kv_t);

View file

@ -211,7 +211,7 @@ u32 crc32_calc(u32 crc, const u8 *buf, u32 len)
// Calculate CRC table. // Calculate CRC table.
if (!table) if (!table)
{ {
table = calloc(256, sizeof(u32)); table = zalloc(256 * sizeof(u32));
for (u32 i = 0; i < 256; i++) for (u32 i = 0; i < 256; i++)
{ {
u32 rem = i; u32 rem = i;

View file

@ -145,7 +145,7 @@ void print_mmc_info()
" Current Rate: %d MB/s\n" " Current Rate: %d MB/s\n"
" Type Support: ", " Type Support: ",
emmc_storage.csd.mmca_vsn, emmc_storage.ext_csd.rev, emmc_storage.ext_csd.dev_version, emmc_storage.csd.cmdclass, emmc_storage.csd.mmca_vsn, emmc_storage.ext_csd.rev, emmc_storage.ext_csd.dev_version, emmc_storage.csd.cmdclass,
emmc_storage.csd.capacity == (4096 * 512) ? "High" : "Low", speed & 0xFFFF, (speed >> 16) & 0xFFFF, emmc_storage.csd.capacity == (4096 * EMMC_BLOCKSIZE) ? "High" : "Low", speed & 0xFFFF, (speed >> 16) & 0xFFFF,
emmc_storage.csd.busspeed); emmc_storage.csd.busspeed);
gfx_con.fntsz = 8; gfx_con.fntsz = 8;
gfx_printf("%s", card_type_support); gfx_printf("%s", card_type_support);
@ -156,13 +156,13 @@ void print_mmc_info()
u32 rpmb_size = emmc_storage.ext_csd.rpmb_mult << 17; u32 rpmb_size = emmc_storage.ext_csd.rpmb_mult << 17;
gfx_printf("%keMMC Partitions:%k\n", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT); gfx_printf("%keMMC Partitions:%k\n", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT);
gfx_printf(" 1: %kBOOT0 %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT, gfx_printf(" 1: %kBOOT0 %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT,
boot_size / 1024, boot_size / 512); boot_size / 1024, boot_size / EMMC_BLOCKSIZE);
gfx_put_small_sep(); gfx_put_small_sep();
gfx_printf(" 2: %kBOOT1 %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT, gfx_printf(" 2: %kBOOT1 %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT,
boot_size / 1024, boot_size / 512); boot_size / 1024, boot_size / EMMC_BLOCKSIZE);
gfx_put_small_sep(); gfx_put_small_sep();
gfx_printf(" 3: %kRPMB %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT, gfx_printf(" 3: %kRPMB %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT,
rpmb_size / 1024, rpmb_size / 512); rpmb_size / 1024, rpmb_size / EMMC_BLOCKSIZE);
gfx_put_small_sep(); gfx_put_small_sep();
gfx_printf(" 0: %kGPP (USER) %k\n Size: %5d MiB (LBA Sectors: 0x%07X)\n\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT, gfx_printf(" 0: %kGPP (USER) %k\n Size: %5d MiB (LBA Sectors: 0x%07X)\n\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT,
emmc_storage.sec_cnt >> SECTORS_TO_MIB_COEFF, emmc_storage.sec_cnt); emmc_storage.sec_cnt >> SECTORS_TO_MIB_COEFF, emmc_storage.sec_cnt);

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 Reisyukaku * Copyright (c) 2018 Reisyukaku
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@ -32,22 +32,14 @@ extern hekate_config h_cfg;
#pragma GCC push_options #pragma GCC push_options
#pragma GCC optimize ("Os") #pragma GCC optimize ("Os")
void _toggle_autorcm(bool enable) static void _toggle_autorcm(bool enable)
{ {
gfx_clear_partial_grey(0x1B, 0, 1256); gfx_clear_partial_grey(0x1B, 0, 1256);
gfx_con_setpos(0, 0); gfx_con_setpos(0, 0);
if (!emmc_initialize(false))
{
EPRINTF("Failed to init eMMC.");
goto out;
}
u8 *tempbuf = (u8 *)malloc(0x200);
emmc_set_partition(EMMC_BOOT0);
int i, sect = 0; int i, sect = 0;
u8 corr_mod0, mod1; u8 corr_mod0, mod1;
u8 *tempbuf = (u8 *)malloc(0x200);
// Get the correct RSA modulus byte masks. // Get the correct RSA modulus byte masks.
nx_emmc_get_autorcm_masks(&corr_mod0, &mod1); nx_emmc_get_autorcm_masks(&corr_mod0, &mod1);
@ -70,7 +62,6 @@ void _toggle_autorcm(bool enable)
} }
free(tempbuf); free(tempbuf);
emmc_end();
if (enable) if (enable)
gfx_printf("%kAutoRCM mode enabled!%k", TXT_CLR_ORANGE, TXT_CLR_DEFAULT); gfx_printf("%kAutoRCM mode enabled!%k", TXT_CLR_ORANGE, TXT_CLR_DEFAULT);
@ -78,12 +69,34 @@ void _toggle_autorcm(bool enable)
gfx_printf("%kAutoRCM mode disabled!%k", TXT_CLR_GREENISH, TXT_CLR_DEFAULT); gfx_printf("%kAutoRCM mode disabled!%k", TXT_CLR_GREENISH, TXT_CLR_DEFAULT);
gfx_printf("\n\nPress any key...\n"); gfx_printf("\n\nPress any key...\n");
out:
btn_wait(); btn_wait();
} }
void _enable_autorcm() { _toggle_autorcm(true); } static void _enable_autorcm() { _toggle_autorcm(true); }
void _disable_autorcm() { _toggle_autorcm(false); } static void _disable_autorcm() { _toggle_autorcm(false); }
bool tools_autorcm_enabled()
{
u8 mod0, mod1;
u8 *tempbuf = (u8 *)malloc(0x200);
// Get the correct RSA modulus byte masks.
nx_emmc_get_autorcm_masks(&mod0, &mod1);
// Get 1st RSA modulus.
emmc_set_partition(EMMC_BOOT0);
sdmmc_storage_read(&emmc_storage, 0x200 / EMMC_BLOCKSIZE, 1, tempbuf);
// Check if 2nd byte of modulus is correct.
bool enabled = false;
if (tempbuf[0x11] == mod1)
if (tempbuf[0x10] != mod0)
enabled = true;
free(tempbuf);
return enabled;
}
void menu_autorcm() void menu_autorcm()
{ {
@ -98,9 +111,6 @@ void menu_autorcm()
return; return;
} }
// Do a simple check on the main BCT.
bool disabled = true;
if (!emmc_initialize(false)) if (!emmc_initialize(false))
{ {
EPRINTF("Failed to init eMMC."); EPRINTF("Failed to init eMMC.");
@ -109,21 +119,8 @@ void menu_autorcm()
return; return;
} }
u8 mod0, mod1; // Do a simple check on the main BCT.
// Get the correct RSA modulus byte masks. bool enabled = tools_autorcm_enabled();
nx_emmc_get_autorcm_masks(&mod0, &mod1);
u8 *tempbuf = (u8 *)malloc(0x200);
emmc_set_partition(EMMC_BOOT0);
sdmmc_storage_read(&emmc_storage, 0x200 / EMMC_BLOCKSIZE, 1, tempbuf);
// Check if 2nd byte of modulus is correct.
if (tempbuf[0x11] == mod1)
if (tempbuf[0x10] != mod0)
disabled = false;
free(tempbuf);
emmc_end();
// Create AutoRCM menu. // Create AutoRCM menu.
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 6); ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 6);
@ -135,7 +132,7 @@ void menu_autorcm()
ments[2].type = MENT_CAPTION; ments[2].type = MENT_CAPTION;
ments[3].type = MENT_CHGLINE; ments[3].type = MENT_CHGLINE;
if (disabled) if (!enabled)
{ {
ments[2].caption = "Status: Disabled!"; ments[2].caption = "Status: Disabled!";
ments[2].color = TXT_CLR_GREENISH; ments[2].color = TXT_CLR_GREENISH;
@ -156,6 +153,8 @@ void menu_autorcm()
menu_t menu = {ments, "This corrupts BOOT0!", 0, 0}; menu_t menu = {ments, "This corrupts BOOT0!", 0, 0};
tui_do_menu(&menu); tui_do_menu(&menu);
emmc_end();
} }
#pragma GCC pop_options #pragma GCC pop_options

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -19,5 +19,6 @@
#define _FE_TOOLS_H_ #define _FE_TOOLS_H_
void menu_autorcm(); void menu_autorcm();
bool tools_autorcm_enabled();
#endif #endif

View file

@ -1,7 +1,7 @@
/* /*
* Atmosphère Fusée Secondary Storage (Package3) parser. * Atmosphère Fusée Secondary Storage (Package3) parser.
* *
* Copyright (c) 2019-2023 CTCaer * Copyright (c) 2019-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -82,34 +82,13 @@ typedef struct _fss_content_t
char name[0x10]; char name[0x10];
} fss_content_t; } fss_content_t;
static void _set_fss_path_and_update_r2p(launch_ctxt_t *ctxt, const char *path) static void _fss_update_r2p()
{ {
char *r2p_path = malloc(256); u8 *r2p_payload = sd_file_read("atmosphere/reboot_payload.bin", NULL);
u32 path_len = strlen(path);
strcpy(r2p_path, path); is_ipl_updated(r2p_payload, "atmosphere/reboot_payload.bin", h_cfg.updater2p ? true : false);
while (path_len) free(r2p_payload);
{
if ((r2p_path[path_len - 1] == '/') || (r2p_path[path_len - 1] == '\\'))
{
r2p_path[path_len] = 0;
strcat(r2p_path, "reboot_payload.bin");
u8 *r2p_payload = sd_file_read(r2p_path, NULL);
is_ipl_updated(r2p_payload, r2p_path, h_cfg.updater2p ? true : false);
free(r2p_payload);
// Save FSS0 parent path.
r2p_path[path_len] = 0;
ctxt->fss0_main_path = r2p_path;
return;
}
path_len--;
}
free(r2p_path);
} }
int parse_fss(launch_ctxt_t *ctxt, const char *path) int parse_fss(launch_ctxt_t *ctxt, const char *path)
@ -230,8 +209,10 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path)
gfx_printf("Done!\n"); gfx_printf("Done!\n");
f_close(&fp); f_close(&fp);
// Set FSS0 path and update r2p if needed. ctxt->fss0 = fss;
_set_fss_path_and_update_r2p(ctxt, path);
// Update r2p if needed.
_fss_update_r2p();
return 1; return 1;
} }

View file

@ -2,7 +2,7 @@
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk * Copyright (c) 2018 st4rk
* Copyright (c) 2018 Ced2911 * Copyright (c) 2018 Ced2911
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@
#include "hos.h" #include "hos.h"
#include "hos_config.h" #include "hos_config.h"
#include "secmon_exo.h" #include "secmon_exo.h"
#include "../frontend/fe_tools.h"
#include "../config.h" #include "../config.h"
#include "../storage/emummc.h" #include "../storage/emummc.h"
@ -121,6 +122,7 @@ static const u8 master_kekseed_t210_tsec_v4[HOS_KB_VERSION_MAX - HOS_KB_VERSION_
{ 0x6E, 0x77, 0x86, 0xAC, 0x83, 0x0A, 0x8D, 0x3E, 0x7D, 0xB7, 0x66, 0xA0, 0x22, 0xB7, 0x6E, 0x67 }, // 15.0.0. { 0x6E, 0x77, 0x86, 0xAC, 0x83, 0x0A, 0x8D, 0x3E, 0x7D, 0xB7, 0x66, 0xA0, 0x22, 0xB7, 0x6E, 0x67 }, // 15.0.0.
{ 0x99, 0x22, 0x09, 0x57, 0xA7, 0xF9, 0x5E, 0x94, 0xFE, 0x78, 0x7F, 0x41, 0xD6, 0xE7, 0x56, 0xE6 }, // 16.0.0. { 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. { 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.
}; };
//!TODO: Update on mkey changes. //!TODO: Update on mkey changes.
@ -137,6 +139,7 @@ static const u8 master_kekseed_t210b01[HOS_KB_VERSION_MAX - HOS_KB_VERSION_600 +
{ 0xEC, 0x61, 0xBC, 0x82, 0x1E, 0x0F, 0x5A, 0xC3, 0x2B, 0x64, 0x3F, 0x9D, 0xD6, 0x19, 0x22, 0x2D }, // 15.0.0. { 0xEC, 0x61, 0xBC, 0x82, 0x1E, 0x0F, 0x5A, 0xC3, 0x2B, 0x64, 0x3F, 0x9D, 0xD6, 0x19, 0x22, 0x2D }, // 15.0.0.
{ 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 }, // 16.0.0. { 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. { 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.
}; };
static const u8 console_keyseed[SE_KEY_128_SIZE] = static const u8 console_keyseed[SE_KEY_128_SIZE] =
@ -218,7 +221,7 @@ static void _hos_eks_get()
if (!h_cfg.eks) if (!h_cfg.eks)
{ {
// Read EKS blob. // Read EKS blob.
u8 *mbr = calloc(512 , 1); u8 *mbr = zalloc(SD_BLOCKSIZE);
if (!hos_eks_rw_try(mbr, false)) if (!hos_eks_rw_try(mbr, false))
goto out; goto out;
@ -248,7 +251,7 @@ static void _hos_eks_save()
bool new_eks = false; bool new_eks = false;
if (!h_cfg.eks) if (!h_cfg.eks)
{ {
h_cfg.eks = calloc(512 , 1); h_cfg.eks = zalloc(SD_BLOCKSIZE);
new_eks = true; new_eks = true;
} }
@ -256,7 +259,7 @@ static void _hos_eks_save()
if (h_cfg.eks->enabled != HOS_EKS_TSEC_VER) if (h_cfg.eks->enabled != HOS_EKS_TSEC_VER)
{ {
// Read EKS blob. // Read EKS blob.
u8 *mbr = calloc(512 , 1); u8 *mbr = zalloc(SD_BLOCKSIZE);
if (!hos_eks_rw_try(mbr, false)) if (!hos_eks_rw_try(mbr, false))
{ {
if (new_eks) if (new_eks)
@ -269,7 +272,7 @@ static void _hos_eks_save()
} }
// Get keys. // Get keys.
u8 *keys = (u8 *)calloc(SZ_4K, 2); u8 *keys = (u8 *)zalloc(SZ_8K);
se_get_aes_keys(keys + SZ_4K, keys, SE_KEY_128_SIZE); se_get_aes_keys(keys + SZ_4K, keys, SE_KEY_128_SIZE);
// Set magic and personalized info. // Set magic and personalized info.
@ -283,7 +286,7 @@ static void _hos_eks_save()
memcpy(h_cfg.eks->troot_dev, keys + 11 * SE_KEY_128_SIZE, SE_KEY_128_SIZE); memcpy(h_cfg.eks->troot_dev, keys + 11 * SE_KEY_128_SIZE, SE_KEY_128_SIZE);
// Encrypt EKS blob. // Encrypt EKS blob.
u8 *eks = calloc(512 , 1); u8 *eks = zalloc(SD_BLOCKSIZE);
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t)); memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t)); se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
@ -310,7 +313,7 @@ void hos_eks_clear(u32 kb)
if (h_cfg.eks->enabled) if (h_cfg.eks->enabled)
{ {
// Read EKS blob. // Read EKS blob.
u8 *mbr = calloc(512 , 1); u8 *mbr = zalloc(SD_BLOCKSIZE);
if (!hos_eks_rw_try(mbr, false)) if (!hos_eks_rw_try(mbr, false))
goto out; goto out;
@ -318,7 +321,7 @@ void hos_eks_clear(u32 kb)
h_cfg.eks->enabled = 0; h_cfg.eks->enabled = 0;
// Encrypt EKS blob. // Encrypt EKS blob.
u8 *eks = calloc(512 , 1); u8 *eks = zalloc(SD_BLOCKSIZE);
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t)); memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t)); se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
@ -392,7 +395,7 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock, bool i
tsec_ctxt->type = TSEC_FW_TYPE_EMU; tsec_ctxt->type = TSEC_FW_TYPE_EMU;
// Prepare smmu tsec page for 6.2.0. // Prepare smmu tsec page for 6.2.0.
u8 *tsec_paged = (u8 *)page_alloc(3); u8 *tsec_paged = (u8 *)smmu_page_zalloc(3);
memcpy(tsec_paged, (void *)tsec_ctxt->fw, tsec_ctxt->size); memcpy(tsec_paged, (void *)tsec_ctxt->fw, tsec_ctxt->size);
tsec_ctxt->fw = tsec_paged; tsec_ctxt->fw = tsec_paged;
} }
@ -646,7 +649,7 @@ try_load:
// Read the correct keyblob for older HOS versions. // Read the correct keyblob for older HOS versions.
if (ctxt->pkg1_id->kb <= HOS_KB_VERSION_600) if (ctxt->pkg1_id->kb <= HOS_KB_VERSION_600)
{ {
ctxt->keyblob = (u8 *)calloc(EMMC_BLOCKSIZE, 1); ctxt->keyblob = (u8 *)zalloc(EMMC_BLOCKSIZE);
emummc_storage_read(PKG1_HOS_KEYBLOBS_OFFSET / EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob); emummc_storage_read(PKG1_HOS_KEYBLOBS_OFFSET / EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
} }
@ -694,12 +697,12 @@ out:
static void _free_launch_components(launch_ctxt_t *ctxt) static void _free_launch_components(launch_ctxt_t *ctxt)
{ {
// Free the malloc'ed guaranteed addresses.
free(ctxt->fss0);
free(ctxt->keyblob); free(ctxt->keyblob);
free(ctxt->pkg1); free(ctxt->pkg1);
free(ctxt->pkg2); free(ctxt->pkg2);
free(ctxt->warmboot); free(ctxt->warmboot);
free(ctxt->secmon);
free(ctxt->kernel);
free(ctxt->kip1_patches); free(ctxt->kip1_patches);
} }
@ -711,7 +714,7 @@ static bool _get_fs_exfat_compatible(link_t *info, u32 *hos_revision)
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link) LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
{ {
if (strncmp((const char*)ki->kip1->name, "FS", sizeof(ki->kip1->name))) if (strcmp((char *)ki->kip1->name, "FS"))
continue; continue;
if (!se_calc_sha256_oneshot(sha_buf, ki->kip1, ki->size)) if (!se_calc_sha256_oneshot(sha_buf, ki->kip1, ki->size))
@ -785,12 +788,6 @@ int hos_launch(ini_sec_t *cfg)
goto error; goto error;
} }
// Read package1 and the correct keyblob.
if (!_read_emmc_pkg1(&ctxt))
goto error;
kb = ctxt.pkg1_id->kb;
// Try to parse config if present. // Try to parse config if present.
if (ctxt.cfg && !parse_boot_config(&ctxt)) if (ctxt.cfg && !parse_boot_config(&ctxt))
{ {
@ -798,6 +795,24 @@ int hos_launch(ini_sec_t *cfg)
goto error; goto error;
} }
// Read package1 and the correct keyblob.
if (!_read_emmc_pkg1(&ctxt))
{
// Check if stock is enabled and device can boot in OFW.
if (ctxt.stock && (h_cfg.t210b01 || !tools_autorcm_enabled()))
{
emmc_end();
WPRINTF("\nRebooting to OFW in 5s...");
msleep(5000);
power_set_state(REBOOT_BYPASS_FUSES);
}
goto error;
}
kb = ctxt.pkg1_id->kb;
bool emummc_enabled = emu_cfg.enabled && !h_cfg.emummc_force_disable; bool emummc_enabled = emu_cfg.enabled && !h_cfg.emummc_force_disable;
// Enable emummc patching. // Enable emummc patching.
@ -849,16 +864,18 @@ int hos_launch(ini_sec_t *cfg)
// Check if secmon is exosphere. // Check if secmon is exosphere.
if (ctxt.secmon) if (ctxt.secmon)
is_exo = !memcmp((void *)((u8 *)ctxt.secmon + ctxt.secmon_size - 4), "LENY", 4); is_exo = !memcmp((void *)((u8 *)ctxt.secmon + ctxt.secmon_size - 4), "LENY", 4);
// Get secmon and warmboot bases.
const pkg1_id_t *pk1_latest = pkg1_get_latest(); const pkg1_id_t *pk1_latest = pkg1_get_latest();
secmon_base = is_exo ? pk1_latest->secmon_base : ctxt.pkg1_id->secmon_base; secmon_base = is_exo ? pk1_latest->secmon_base : ctxt.pkg1_id->secmon_base;
warmboot_base = is_exo ? pk1_latest->warmboot_base : ctxt.pkg1_id->warmboot_base; warmboot_base = is_exo ? pk1_latest->warmboot_base : ctxt.pkg1_id->warmboot_base;
// Generate keys. // Set package1 and tsec fw offsets.
tsec_ctxt.fw = (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off; tsec_ctxt.fw = (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off;
tsec_ctxt.pkg1 = ctxt.pkg1; tsec_ctxt.pkg1 = ctxt.pkg1;
tsec_ctxt.pkg11_off = ctxt.pkg1_id->pkg11_off; tsec_ctxt.pkg11_off = ctxt.pkg1_id->pkg11_off;
tsec_ctxt.secmon_base = secmon_base;
// 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; goto error;
gfx_puts("Generated keys\n"); gfx_puts("Generated keys\n");
@ -903,7 +920,7 @@ int hos_launch(ini_sec_t *cfg)
} }
else else
{ {
_hos_crit_error("No mandatory secmon or warmboot provided!"); _hos_crit_error("No mandatory pkg1 files provided!");
goto error; goto error;
} }
} }
@ -1036,20 +1053,17 @@ int hos_launch(ini_sec_t *cfg)
{ {
_hos_crit_error("SD Card is exFAT but installed HOS driver\nonly supports FAT32!"); _hos_crit_error("SD Card is exFAT but installed HOS driver\nonly supports FAT32!");
_free_launch_components(&ctxt);
goto error; goto error;
} }
} }
// Patch kip1s in memory if needed. // Patch kip1s in memory if needed.
if (ctxt.kip1_patches) const char *failed_patch = pkg2_patch_kips(&kip1_info, ctxt.kip1_patches);
gfx_printf("%kPatching kips%k\n", TXT_CLR_ORANGE, TXT_CLR_DEFAULT); if (failed_patch != NULL)
const char* unappliedPatch = pkg2_patch_kips(&kip1_info, ctxt.kip1_patches);
if (unappliedPatch != NULL)
{ {
EHPRINTFARGS("Failed to apply '%s'!", unappliedPatch); EHPRINTFARGS("Failed to apply '%s'!", failed_patch);
bool emmc_patch_failed = !strcmp(unappliedPatch, "emummc"); bool emmc_patch_failed = !strcmp(failed_patch, "emummc");
if (!emmc_patch_failed) if (!emmc_patch_failed)
{ {
gfx_puts("\nPress POWER to continue.\nPress VOL to go to the menu.\n"); gfx_puts("\nPress POWER to continue.\nPress VOL to go to the menu.\n");
@ -1057,10 +1071,7 @@ int hos_launch(ini_sec_t *cfg)
} }
if (emmc_patch_failed || !(btn_wait() & BTN_POWER)) if (emmc_patch_failed || !(btn_wait() & BTN_POWER))
{
_free_launch_components(&ctxt);
goto error; // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated! goto error; // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated!
}
} }
// Rebuild and encrypt package2. // Rebuild and encrypt package2.
@ -1128,12 +1139,9 @@ int hos_launch(ini_sec_t *cfg)
// Lock SE before starting 'SecureMonitor' if < 6.2.0, otherwise lock bootrom and ipatches. // Lock SE before starting 'SecureMonitor' if < 6.2.0, otherwise lock bootrom and ipatches.
_se_lock(kb <= HOS_KB_VERSION_600 && !is_exo); _se_lock(kb <= HOS_KB_VERSION_600 && !is_exo);
// Reset sysctr0 counters. // Reset sysctr0 counters. Mandatory for 6.2.0 and up.
if (kb >= HOS_KB_VERSION_620) for (u32 i = 0; i < SYSCTR0_COUNTERS; i++)
{ SYSCTR0(SYSCTR0_COUNTERS_BASE + i * sizeof(u32)) = 0;
for (u32 i = 0; i < SYSCTR0_COUNTERS; i += sizeof(u32))
SYSCTR0(SYSCTR0_COUNTERS_BASE + i) = 0;
}
// NX Bootloader locks LP0 Carveout secure scratch registers. // NX Bootloader locks LP0 Carveout secure scratch registers.
//pmc_scratch_lock(PMC_SEC_LOCK_LP0_PARAMS); //pmc_scratch_lock(PMC_SEC_LOCK_LP0_PARAMS);
@ -1152,7 +1160,7 @@ int hos_launch(ini_sec_t *cfg)
} }
// Start directly from PKG2 ready signal and reset outgoing value. // Start directly from PKG2 ready signal and reset outgoing value.
secmon_mailbox->in = pkg1_state_pkg2_ready; secmon_mailbox->in = pkg1_state_pkg2_ready;
secmon_mailbox->out = SECMON_STATE_NOT_READY; secmon_mailbox->out = SECMON_STATE_NOT_READY;
// Disable display. This must be executed before secmon to provide support for all fw versions. // Disable display. This must be executed before secmon to provide support for all fw versions.
@ -1173,16 +1181,14 @@ int hos_launch(ini_sec_t *cfg)
bpmp_clk_rate_set(BPMP_CLK_NORMAL); bpmp_clk_rate_set(BPMP_CLK_NORMAL);
// Launch secmon. // Launch secmon.
if (smmu_is_used()) ccplex_boot_cpu0(secmon_base, true);
smmu_exit();
else
ccplex_boot_cpu0(secmon_base);
// Halt ourselves in wait-event state. // Halt ourselves in wait-event state.
while (true) while (true)
bpmp_halt(); bpmp_halt();
error: error:
_free_launch_components(&ctxt);
emmc_end(); emmc_end();
EPRINTF("\nFailed to launch HOS!"); EPRINTF("\nFailed to launch HOS!");

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -44,7 +44,8 @@ enum {
HOS_KB_VERSION_1500 = 14, HOS_KB_VERSION_1500 = 14,
HOS_KB_VERSION_1600 = 15, HOS_KB_VERSION_1600 = 15,
HOS_KB_VERSION_1700 = 16, HOS_KB_VERSION_1700 = 16,
HOS_KB_VERSION_MAX = HOS_KB_VERSION_1700 HOS_KB_VERSION_1800 = 17,
HOS_KB_VERSION_MAX = HOS_KB_VERSION_1800
}; };
#define HOS_TSEC_VERSION 4 //! TODO: Update on TSEC Root Key changes. #define HOS_TSEC_VERSION 4 //! TODO: Update on TSEC Root Key changes.
@ -109,7 +110,7 @@ typedef struct _launch_ctxt_t
bool stock; bool stock;
bool emummc_forced; bool emummc_forced;
char *fss0_main_path; void *fss0;
u32 fss0_hosver; u32 fss0_hosver;
bool atmosphere; bool atmosphere;

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -122,27 +122,28 @@ int config_kip1patch(launch_ctxt_t *ctxt, const char *value)
if (value == NULL) if (value == NULL)
return 0; return 0;
int valueLen = strlen(value); int len = strlen(value);
if (!valueLen) if (!len)
return 0; return 0;
if (ctxt->kip1_patches == NULL) if (ctxt->kip1_patches == NULL)
{ {
ctxt->kip1_patches = malloc(valueLen + 1); ctxt->kip1_patches = malloc(len + 1);
memcpy(ctxt->kip1_patches, value, valueLen); memcpy(ctxt->kip1_patches, value, len);
ctxt->kip1_patches[valueLen] = 0; ctxt->kip1_patches[len] = 0;
} }
else else
{ {
char *oldAlloc = ctxt->kip1_patches; char *old_addr = ctxt->kip1_patches;
int oldSize = strlen(oldAlloc); int old_len = strlen(old_addr);
ctxt->kip1_patches = malloc(oldSize + 1 + valueLen + 1);
memcpy(ctxt->kip1_patches, oldAlloc, oldSize); ctxt->kip1_patches = malloc(old_len + 1 + len + 1);
free(oldAlloc); memcpy(ctxt->kip1_patches, old_addr, old_len);
oldAlloc = NULL; free(old_addr);
ctxt->kip1_patches[oldSize++] = ',';
memcpy(&ctxt->kip1_patches[oldSize], value, valueLen); ctxt->kip1_patches[old_len++] = ',';
ctxt->kip1_patches[oldSize + valueLen] = 0; memcpy(&ctxt->kip1_patches[old_len], value, len);
ctxt->kip1_patches[old_len + len] = 0;
} }
return 1; return 1;
} }
@ -220,7 +221,7 @@ static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value)
static int _config_exo_usb3_force(launch_ctxt_t *ctxt, const char *value) static int _config_exo_usb3_force(launch_ctxt_t *ctxt, const char *value)
{ {
// Override key found. // Override key found.
ctxt->exo_ctx.usb3_force = calloc(sizeof(bool), 1); ctxt->exo_ctx.usb3_force = zalloc(sizeof(bool));
if (*value == '1') if (*value == '1')
{ {
@ -233,7 +234,7 @@ static int _config_exo_usb3_force(launch_ctxt_t *ctxt, const char *value)
static int _config_exo_cal0_blanking(launch_ctxt_t *ctxt, const char *value) static int _config_exo_cal0_blanking(launch_ctxt_t *ctxt, const char *value)
{ {
// Override key found. // Override key found.
ctxt->exo_ctx.cal0_blank = calloc(sizeof(bool), 1); ctxt->exo_ctx.cal0_blank = zalloc(sizeof(bool));
if (*value == '1') if (*value == '1')
{ {
@ -246,7 +247,7 @@ static int _config_exo_cal0_blanking(launch_ctxt_t *ctxt, const char *value)
static int _config_exo_cal0_writes_enable(launch_ctxt_t *ctxt, const char *value) static int _config_exo_cal0_writes_enable(launch_ctxt_t *ctxt, const char *value)
{ {
// Override key found. // Override key found.
ctxt->exo_ctx.cal0_allow_writes_sys = calloc(sizeof(bool), 1); ctxt->exo_ctx.cal0_allow_writes_sys = zalloc(sizeof(bool));
if (*value == '1') if (*value == '1')
{ {

View file

@ -169,7 +169,8 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20220209", 13, 16, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 14.0.0 - 14.1.2. { "20220209", 13, 16, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 14.0.0 - 14.1.2.
{ "20220801", 14, 17, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 15.0.0 - 15.0.1. { "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. { "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+ { "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+
}; };
const pkg1_id_t *pkg1_get_latest() const pkg1_id_t *pkg1_get_latest()
@ -436,7 +437,7 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base, u32 fuses_fw, u8 kb)
void pkg1_warmboot_rsa_mod(u32 warmboot_base) void pkg1_warmboot_rsa_mod(u32 warmboot_base)
{ {
// Set warmboot binary rsa modulus. // Set warmboot binary rsa modulus.
u8 *rsa_mod = (u8 *)malloc(512); u8 *rsa_mod = (u8 *)malloc(EMMC_BLOCKSIZE);
emmc_set_partition(EMMC_BOOT0); emmc_set_partition(EMMC_BOOT0);

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -77,93 +77,93 @@ static void parse_external_kip_patches()
if (ini_patch_parse(&ini_kip_sections, "bootloader/patches.ini")) if (ini_patch_parse(&ini_kip_sections, "bootloader/patches.ini"))
{ {
// Copy ids into a new patchset. // Copy ids into a new patchset.
_kip_id_sets = calloc(sizeof(kip1_id_t), 256); // Max 256 kip ids. _kip_id_sets = zalloc(sizeof(kip1_id_t) * 256); // Max 256 kip ids.
memcpy(_kip_id_sets, _kip_ids, sizeof(_kip_ids)); memcpy(_kip_id_sets, _kip_ids, sizeof(_kip_ids));
// Parse patchsets and glue them together. // Parse patchsets and glue them together.
LIST_FOREACH_ENTRY(ini_kip_sec_t, ini_psec, &ini_kip_sections, link) LIST_FOREACH_ENTRY(ini_kip_sec_t, ini_psec, &ini_kip_sections, link)
{ {
kip1_id_t* curr_kip = NULL; kip1_id_t *kip = NULL;
bool found = false; bool found = false;
for (u32 curr_kip_idx = 0; curr_kip_idx < _kip_id_sets_cnt + 1; curr_kip_idx++) for (u32 kip_idx = 0; kip_idx < _kip_id_sets_cnt + 1; kip_idx++)
{ {
curr_kip = &_kip_id_sets[curr_kip_idx]; kip = &_kip_id_sets[kip_idx];
// Check if reached the end of predefined list. // Check if reached the end of predefined list.
if (!curr_kip->name) if (!kip->name)
break; break;
// Check if name and hash match. // Check if name and hash match.
if (!strcmp(curr_kip->name, ini_psec->name) && !memcmp(curr_kip->hash, ini_psec->hash, 8)) if (!strcmp(kip->name, ini_psec->name) && !memcmp(kip->hash, ini_psec->hash, 8))
{ {
found = true; found = true;
break; break;
} }
} }
if (!curr_kip) if (!kip)
continue; continue;
// If not found, create a new empty entry. // If not found, create a new empty entry.
if (!found) if (!found)
{ {
curr_kip->name = ini_psec->name; kip->name = ini_psec->name;
memcpy(curr_kip->hash, ini_psec->hash, 8); memcpy(kip->hash, ini_psec->hash, 8);
curr_kip->patchset = calloc(sizeof(kip1_patchset_t), 1); kip->patchset = zalloc(sizeof(kip1_patchset_t));
_kip_id_sets_cnt++; _kip_id_sets_cnt++;
} }
kip1_patchset_t *patchsets = (kip1_patchset_t *)calloc(sizeof(kip1_patchset_t), 16); // Max 16 patchsets per kip. kip1_patchset_t *patchsets = (kip1_patchset_t *)zalloc(sizeof(kip1_patchset_t) * 16); // Max 16 patchsets per kip.
u32 curr_patchset_idx; u32 patchset_idx;
for (curr_patchset_idx = 0; curr_kip->patchset[curr_patchset_idx].name != NULL; curr_patchset_idx++) for (patchset_idx = 0; kip->patchset[patchset_idx].name != NULL; patchset_idx++)
{ {
patchsets[curr_patchset_idx].name = curr_kip->patchset[curr_patchset_idx].name; patchsets[patchset_idx].name = kip->patchset[patchset_idx].name;
patchsets[curr_patchset_idx].patches = curr_kip->patchset[curr_patchset_idx].patches; patchsets[patchset_idx].patches = kip->patchset[patchset_idx].patches;
} }
curr_kip->patchset = patchsets; kip->patchset = patchsets;
bool first_ext_patch = true; bool first_ext_patch = true;
u32 curr_patch_idx = 0; u32 patch_idx = 0;
// Parse patches and glue them together to a patchset. // Parse patches and glue them together to a patchset.
kip1_patch_t *patches = calloc(sizeof(kip1_patch_t), 32); // Max 32 patches per set. kip1_patch_t *patches = zalloc(sizeof(kip1_patch_t) * 32); // Max 32 patches per set.
LIST_FOREACH_ENTRY(ini_patchset_t, pt, &ini_psec->pts, link) LIST_FOREACH_ENTRY(ini_patchset_t, pt, &ini_psec->pts, link)
{ {
if (first_ext_patch) if (first_ext_patch)
{ {
first_ext_patch = false; first_ext_patch = false;
patchsets[curr_patchset_idx].name = pt->name; patchsets[patchset_idx].name = pt->name;
patchsets[curr_patchset_idx].patches = patches; patchsets[patchset_idx].patches = patches;
} }
else if (strcmp(pt->name, patchsets[curr_patchset_idx].name)) else if (strcmp(pt->name, patchsets[patchset_idx].name))
{ {
// New patchset name found, create a new set. // New patchset name found, create a new set.
curr_patchset_idx++; patchset_idx++;
curr_patch_idx = 0; patch_idx = 0;
patches = calloc(sizeof(kip1_patch_t), 32); // Max 32 patches per set. patches = zalloc(sizeof(kip1_patch_t) * 32); // Max 32 patches per set.
patchsets[curr_patchset_idx].name = pt->name; patchsets[patchset_idx].name = pt->name;
patchsets[curr_patchset_idx].patches = patches; patchsets[patchset_idx].patches = patches;
} }
if (pt->length) if (pt->length)
{ {
patches[curr_patch_idx].offset = pt->offset; patches[patch_idx].offset = pt->offset;
patches[curr_patch_idx].length = pt->length; patches[patch_idx].length = pt->length;
patches[curr_patch_idx].srcData = (char *)pt->srcData; patches[patch_idx].src_data = (char *)pt->src_data;
patches[curr_patch_idx].dstData = (char *)pt->dstData; patches[patch_idx].dst_data = (char *)pt->dst_data;
} }
else else
patches[curr_patch_idx].srcData = malloc(1); // Empty patches check. Keep everything else as 0. patches[patch_idx].src_data = malloc(1); // Empty patches check. Keep everything else as 0.
curr_patch_idx++; patch_idx++;
} }
curr_patchset_idx++; patchset_idx++;
patchsets[curr_patchset_idx].name = NULL; patchsets[patchset_idx].name = NULL;
patchsets[curr_patchset_idx].patches = NULL; patchsets[patchset_idx].patches = NULL;
} }
} }
@ -307,7 +307,7 @@ void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1)
pkg2_add_kip(info, kip1); pkg2_add_kip(info, kip1);
} }
int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp) static int _decompress_kip(pkg2_kip1_info_t *ki, u32 sectsToDecomp)
{ {
u32 compClearMask = ~sectsToDecomp; u32 compClearMask = ~sectsToDecomp;
if ((ki->kip1->flags & compClearMask) == ki->kip1->flags) if ((ki->kip1->flags & compClearMask) == ki->kip1->flags)
@ -316,70 +316,70 @@ int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp)
pkg2_kip1_t hdr; pkg2_kip1_t hdr;
memcpy(&hdr, ki->kip1, sizeof(hdr)); memcpy(&hdr, ki->kip1, sizeof(hdr));
unsigned int newKipSize = sizeof(hdr); u32 new_kip_size = sizeof(hdr);
for (u32 sectIdx = 0; sectIdx < KIP1_NUM_SECTIONS; sectIdx++) for (u32 sect_idx = 0; sect_idx < KIP1_NUM_SECTIONS; sect_idx++)
{ {
u32 sectCompBit = BIT(sectIdx); u32 comp_bit_mask = BIT(sect_idx);
// For compressed, cant get actual decompressed size without doing it, so use safe "output size". // For compressed, cant get actual decompressed size without doing it, so use safe "output size".
if (sectIdx < 3 && (sectsToDecomp & sectCompBit) && (hdr.flags & sectCompBit)) if (sect_idx < 3 && (sectsToDecomp & comp_bit_mask) && (hdr.flags & comp_bit_mask))
newKipSize += hdr.sections[sectIdx].size_decomp; new_kip_size += hdr.sections[sect_idx].size_decomp;
else else
newKipSize += hdr.sections[sectIdx].size_comp; new_kip_size += hdr.sections[sect_idx].size_comp;
} }
pkg2_kip1_t* newKip = malloc(newKipSize); pkg2_kip1_t *new_kip = malloc(new_kip_size);
unsigned char* dstDataPtr = newKip->data; u8 *dst_data = new_kip->data;
const unsigned char* srcDataPtr = ki->kip1->data; const u8 *src_data = ki->kip1->data;
for (u32 sectIdx = 0; sectIdx < KIP1_NUM_SECTIONS; sectIdx++) for (u32 sect_idx = 0; sect_idx < KIP1_NUM_SECTIONS; sect_idx++)
{ {
u32 sectCompBit = BIT(sectIdx); u32 comp_bit_mask = BIT(sect_idx);
// Easy copy path for uncompressed or ones we dont want to uncompress. // Easy copy path for uncompressed or ones we dont want to uncompress.
if (sectIdx >= 3 || !(sectsToDecomp & sectCompBit) || !(hdr.flags & sectCompBit)) if (sect_idx >= 3 || !(sectsToDecomp & comp_bit_mask) || !(hdr.flags & comp_bit_mask))
{ {
unsigned int dataSize = hdr.sections[sectIdx].size_comp; u32 dataSize = hdr.sections[sect_idx].size_comp;
if (dataSize == 0) if (dataSize == 0)
continue; continue;
memcpy(dstDataPtr, srcDataPtr, dataSize); memcpy(dst_data, src_data, dataSize);
srcDataPtr += dataSize; src_data += dataSize;
dstDataPtr += dataSize; dst_data += dataSize;
continue; continue;
} }
unsigned int compSize = hdr.sections[sectIdx].size_comp; u32 comp_size = hdr.sections[sect_idx].size_comp;
unsigned int outputSize = hdr.sections[sectIdx].size_decomp; u32 output_size = hdr.sections[sect_idx].size_decomp;
gfx_printf("Decomping '%s', sect %d, size %d..\n", (const char*)hdr.name, sectIdx, compSize); gfx_printf("Decomping '%s', sect %d, size %d..\n", (char *)hdr.name, sect_idx, comp_size);
if (blz_uncompress_srcdest(srcDataPtr, compSize, dstDataPtr, outputSize) == 0) if (blz_uncompress_srcdest(src_data, comp_size, dst_data, output_size) == 0)
{ {
gfx_con.mute = false; gfx_con.mute = false;
gfx_printf("%kERROR decomping sect %d of '%s'!%k\n", TXT_CLR_ERROR, sectIdx, (char*)hdr.name, TXT_CLR_DEFAULT); gfx_printf("%kERROR decomping sect %d of '%s'!%k\n", TXT_CLR_ERROR, sect_idx, (char *)hdr.name, TXT_CLR_DEFAULT);
free(newKip); free(new_kip);
return 1; return 1;
} }
else else
{ {
DPRINTF("Done! Decompressed size is %d!\n", outputSize); DPRINTF("Done! Decompressed size is %d!\n", output_size);
} }
hdr.sections[sectIdx].size_comp = outputSize; hdr.sections[sect_idx].size_comp = output_size;
srcDataPtr += compSize; src_data += comp_size;
dstDataPtr += outputSize; dst_data += output_size;
} }
hdr.flags &= compClearMask; hdr.flags &= compClearMask;
memcpy(newKip, &hdr, sizeof(hdr)); memcpy(new_kip, &hdr, sizeof(hdr));
newKipSize = dstDataPtr-(unsigned char*)(newKip); new_kip_size = dst_data - (u8 *)(new_kip);
free(ki->kip1); free(ki->kip1);
ki->kip1 = newKip; ki->kip1 = new_kip;
ki->size = newKipSize; ki->size = new_kip_size;
return 0; return 0;
} }
static int _kipm_inject(const char *kipm_path, char *target_name, pkg2_kip1_info_t* ki) static int _kipm_inject(const char *kipm_path, char *target_name, pkg2_kip1_info_t *ki)
{ {
if (!strncmp((const char *)ki->kip1->name, target_name, sizeof(ki->kip1->name))) if (!strcmp((char *)ki->kip1->name, target_name))
{ {
u32 size = 0; u32 size = 0;
u8 *kipm_data = (u8 *)sd_file_read(kipm_path, &size); u8 *kipm_data = (u8 *)sd_file_read(kipm_path, &size);
@ -403,9 +403,9 @@ static int _kipm_inject(const char *kipm_path, char *target_name, pkg2_kip1_info
u32 new_offset = 0; u32 new_offset = 0;
for (u32 currSectIdx = 0; currSectIdx < KIP1_NUM_SECTIONS - 2; currSectIdx++) for (u32 section_idx = 0; section_idx < KIP1_NUM_SECTIONS - 2; section_idx++)
{ {
if (!currSectIdx) // .text. if (!section_idx) // .text.
{ {
memcpy(ki->kip1->data + inject_size, fs_kip->data, fs_kip->sections[0].size_comp); memcpy(ki->kip1->data + inject_size, fs_kip->data, fs_kip->sections[0].size_comp);
ki->kip1->sections[0].size_decomp += inject_size; ki->kip1->sections[0].size_decomp += inject_size;
@ -413,11 +413,11 @@ static int _kipm_inject(const char *kipm_path, char *target_name, pkg2_kip1_info
} }
else // Others. else // Others.
{ {
if (currSectIdx < 3) if (section_idx < 3)
memcpy(ki->kip1->data + new_offset + inject_size, fs_kip->data + new_offset, fs_kip->sections[currSectIdx].size_comp); memcpy(ki->kip1->data + new_offset + inject_size, fs_kip->data + new_offset, fs_kip->sections[section_idx].size_comp);
ki->kip1->sections[currSectIdx].offset += inject_size; ki->kip1->sections[section_idx].offset += inject_size;
} }
new_offset += fs_kip->sections[currSectIdx].size_comp; new_offset += fs_kip->sections[section_idx].size_comp;
} }
// Patch PMC capabilities for 1.0.0. // Patch PMC capabilities for 1.0.0.
@ -440,24 +440,28 @@ static int _kipm_inject(const char *kipm_path, char *target_name, pkg2_kip1_info
return 1; return 1;
} }
const char* pkg2_patch_kips(link_t *info, char* patchNames) const char *pkg2_patch_kips(link_t *info, char *patch_names)
{ {
if (patchNames == NULL || patchNames[0] == 0) bool emummc_patch_selected = false;
if (patch_names == NULL || patch_names[0] == 0)
return NULL; return NULL;
static const u32 MAX_NUM_PATCHES_REQUESTED = sizeof(u32) * 8; gfx_printf("%kPatching kips%k\n", TXT_CLR_ORANGE, TXT_CLR_DEFAULT);
char* patches[MAX_NUM_PATCHES_REQUESTED];
u32 numPatches = 1; static const u32 MAX_NUM_PATCHES_REQUESTED = sizeof(u32) * 8;
patches[0] = patchNames; char *patches[MAX_NUM_PATCHES_REQUESTED];
u32 patches_num = 1;
patches[0] = patch_names;
{ {
for (char* p = patchNames; *p != 0; p++) for (char *p = patch_names; *p != 0; p++)
{ {
if (*p == ',') if (*p == ',')
{ {
*p = 0; *p = 0;
patches[numPatches++] = p + 1; patches[patches_num++] = p + 1;
if (numPatches >= MAX_NUM_PATCHES_REQUESTED) if (patches_num >= MAX_NUM_PATCHES_REQUESTED)
return "too_many_patches"; return "too_many_patches";
} }
else if (*p >= 'A' && *p <= 'Z') // Convert to lowercase. else if (*p >= 'A' && *p <= 'Z') // Convert to lowercase.
@ -465,198 +469,220 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
} }
} }
u32 patchesApplied = 0; // Bitset over patches. u32 patches_applied = 0; // Bitset over patches.
for (u32 i = 0; i < numPatches; i++) for (u32 i = 0; i < patches_num; i++)
{ {
// Eliminate leading spaces. // Eliminate leading spaces.
for (const char* p = patches[i]; *p != 0; p++) for (const char *p = patches[i]; *p != 0; p++)
{ {
if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
patches[i]++; patches[i]++;
else else
break; break;
} }
int valueLen = strlen(patches[i]);
if (valueLen == 0) int patch_len = strlen(patches[i]);
if (patch_len == 0)
continue; continue;
// Eliminate trailing spaces. // Eliminate trailing spaces.
for (int chIdx = valueLen - 1; chIdx >= 0; chIdx--) for (int chIdx = patch_len - 1; chIdx >= 0; chIdx--)
{ {
const char* p = patches[i] + chIdx; const char *p = patches[i] + chIdx;
if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
valueLen = chIdx; patch_len = chIdx;
else else
break; break;
} }
patches[i][valueLen] = 0; patches[i][patch_len] = 0;
DPRINTF("Requested patch: '%s'\n", patches[i]); DPRINTF("Requested patch: '%s'\n", patches[i]);
} }
// Parse external patches if needed. // Parse external patches if needed.
for (u32 i = 0; i < numPatches; i++) for (u32 i = 0; i < patches_num; i++)
{ {
if (strcmp(patches[i], "emummc") && strcmp(patches[i], "nogc")) if (!strcmp(patches[i], "emummc"))
{
// emuMMC patch is managed on its own.
emummc_patch_selected = true;
patches_applied |= BIT(i);
continue;
}
if (strcmp(patches[i], "nogc"))
{ {
parse_external_kip_patches(); parse_external_kip_patches();
break; break;
} }
} }
u32 shaBuf[SE_SHA_256_SIZE / sizeof(u32)]; u32 kip_hash[SE_SHA_256_SIZE / sizeof(u32)];
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link) LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
{ {
shaBuf[0] = 0; // sha256 for this kip not yet calculated. // Reset hash so it can be calculated for the new kip.
for (u32 currKipIdx = 0; currKipIdx < _kip_id_sets_cnt; currKipIdx++) kip_hash[0] = 0;
bool emummc_patch_apply = emummc_patch_selected && !strcmp((char *)ki->kip1->name, "FS");
// Check all SHA256 ID sets. (IDs are grouped per KIP. IDs are still unique.)
for (u32 kip_id_idx = 0; kip_id_idx < _kip_id_sets_cnt; kip_id_idx++)
{ {
if (strncmp((const char*)ki->kip1->name, _kip_id_sets[currKipIdx].name, sizeof(ki->kip1->name)) != 0) // Check if KIP name macthes ID's KIP name.
if (strcmp((char *)ki->kip1->name, _kip_id_sets[kip_id_idx].name) != 0)
continue; continue;
u32 bitsAffected = 0; // Check if there are patches to apply.
kip1_patchset_t* currPatchset = _kip_id_sets[currKipIdx].patchset; bool patches_found = false;
while (currPatchset != NULL && currPatchset->name != NULL) kip1_patchset_t *patchset = _kip_id_sets[kip_id_idx].patchset;
while (patchset != NULL && patchset->name != NULL && !patches_found)
{ {
for (u32 i = 0; i < numPatches; i++) for (u32 i = 0; i < patches_num; i++)
{ {
// Continue if patch name does not match. // Continue if patch name does not match.
if (strcmp(currPatchset->name, patches[i]) != 0) if (strcmp(patchset->name, patches[i]) != 0)
continue; continue;
bitsAffected = i + 1; patches_found = true;
break; break;
} }
currPatchset++; patchset++;
} }
// Dont bother even hashing this KIP if we dont have any patches enabled for it. // Don't bother hashing this KIP if no patches are enabled for it.
if (bitsAffected == 0) if (!patches_found && !emummc_patch_apply)
continue; continue;
if (shaBuf[0] == 0) // Check if current KIP not hashed and hash it.
{ if (kip_hash[0] == 0)
if (!se_calc_sha256_oneshot(shaBuf, ki->kip1, ki->size)) if (!se_calc_sha256_oneshot(kip_hash, ki->kip1, ki->size))
memset(shaBuf, 0, sizeof(shaBuf)); memset(kip_hash, 0, sizeof(kip_hash));
}
if (memcmp(shaBuf, _kip_id_sets[currKipIdx].hash, sizeof(_kip_id_sets[0].hash)) != 0) // Check if kip is the expected version.
if (memcmp(kip_hash, _kip_id_sets[kip_id_idx].hash, sizeof(_kip_id_sets[0].hash)) != 0)
continue; continue;
// Find out which sections are affected by the enabled patches, to know which to decompress. // Find out which sections are affected by the enabled patches, in order to decompress them.
bitsAffected = 0; u32 sections_affected = 0;
currPatchset = _kip_id_sets[currKipIdx].patchset; patchset = _kip_id_sets[kip_id_idx].patchset;
while (currPatchset != NULL && currPatchset->name != NULL) while (patchset != NULL && patchset->name != NULL)
{ {
if (currPatchset->patches != NULL) if (patchset->patches != NULL)
{ {
for (u32 currEnabIdx = 0; currEnabIdx < numPatches; currEnabIdx++) for (u32 patch_idx = 0; patch_idx < patches_num; patch_idx++)
{ {
if (strcmp(currPatchset->name, patches[currEnabIdx])) if (strcmp(patchset->name, patches[patch_idx]))
continue; continue;
if (!strcmp(currPatchset->name, "emummc")) for (const kip1_patch_t *patch = patchset->patches; patch != NULL && (patch->length != 0); patch++)
bitsAffected |= BIT(GET_KIP_PATCH_SECTION(currPatchset->patches->offset)); sections_affected |= BIT(GET_KIP_PATCH_SECTION(patch->offset));
for (const kip1_patch_t* currPatch=currPatchset->patches; currPatch != NULL && (currPatch->length != 0); currPatch++)
bitsAffected |= BIT(GET_KIP_PATCH_SECTION(currPatch->offset));
} }
} }
currPatchset++; patchset++;
} }
// Got patches to apply to this kip, have to decompress it. // If emuMMC is enabled, set its affected section.
if (pkg2_decompress_kip(ki, bitsAffected)) if (emummc_patch_apply)
return (const char*)ki->kip1->name; // Failed to decompress. sections_affected |= BIT(KIP_TEXT);
currPatchset = _kip_id_sets[currKipIdx].patchset; // Got patches to apply to this kip, have to decompress it.
bool emummc_patch_selected = false; if (_decompress_kip(ki, sections_affected))
while (currPatchset != NULL && currPatchset->name != NULL) return (char *)ki->kip1->name; // Failed to decompress.
// Apply all patches for matched ID.
patchset = _kip_id_sets[kip_id_idx].patchset;
while (patchset != NULL && patchset->name != NULL)
{ {
for (u32 currEnabIdx = 0; currEnabIdx < numPatches; currEnabIdx++) for (u32 patch_idx = 0; patch_idx < patches_num; patch_idx++)
{ {
if (strcmp(currPatchset->name, patches[currEnabIdx])) // Check if patchset name matches requested patch.
if (strcmp(patchset->name, patches[patch_idx]))
continue; continue;
u32 appliedMask = BIT(currEnabIdx); u32 applied_mask = BIT(patch_idx);
if (!strcmp(currPatchset->name, "emummc")) // Check if patchset is empty.
if (patchset->patches == NULL)
{ {
emummc_patch_selected = true; DPRINTF("Patch '%s' not necessary for %s\n", patchset->name, (char *)ki->kip1->name);
patchesApplied |= appliedMask; patches_applied |= applied_mask;
continue; // Patching is done later.
}
if (currPatchset->patches == NULL)
{
DPRINTF("Patch '%s' not necessary for %s\n", currPatchset->name, (const char*)ki->kip1->name);
patchesApplied |= appliedMask;
continue; // Continue in case it's double defined. continue; // Continue in case it's double defined.
} }
unsigned char* kipSectData = ki->kip1->data; // Apply patches per section.
for (u32 currSectIdx = 0; currSectIdx < KIP1_NUM_SECTIONS; currSectIdx++) u8 *kip_sect_data = ki->kip1->data;
for (u32 section_idx = 0; section_idx < KIP1_NUM_SECTIONS; section_idx++)
{ {
if (bitsAffected & BIT(currSectIdx)) if (sections_affected & BIT(section_idx))
{ {
gfx_printf("Applying '%s' on %s, sect %d\n", currPatchset->name, (const char*)ki->kip1->name, currSectIdx); gfx_printf("Applying '%s' on %s, sect %d\n", patchset->name, (char *)ki->kip1->name, section_idx);
for (const kip1_patch_t* currPatch = currPatchset->patches; currPatch != NULL && currPatch->srcData != NULL; currPatch++) for (const kip1_patch_t *patch = patchset->patches; patch != NULL && patch->src_data != NULL; patch++)
{ {
if (GET_KIP_PATCH_SECTION(currPatch->offset) != currSectIdx) // Check if patch is in current section.
if (GET_KIP_PATCH_SECTION(patch->offset) != section_idx)
continue; continue;
if (!currPatch->length) // Check if patch is empty.
if (!patch->length)
{ {
gfx_con.mute = false; gfx_con.mute = false;
gfx_printf("%kPatch empty!%k\n", TXT_CLR_ERROR, TXT_CLR_DEFAULT); gfx_printf("%kPatch empty!%k\n", TXT_CLR_ERROR, TXT_CLR_DEFAULT);
return currPatchset->name; // MUST stop here as it's not probably intended. return patchset->name; // MUST stop here as it's not probably intended.
} }
u32 currOffset = GET_KIP_PATCH_OFFSET(currPatch->offset);
// If source does not match and is not already patched, throw an error. // If source does not match and is not already patched, throw an error.
if ((memcmp(&kipSectData[currOffset], currPatch->srcData, currPatch->length) != 0) && u32 patch_offset = GET_KIP_PATCH_OFFSET(patch->offset);
(memcmp(&kipSectData[currOffset], currPatch->dstData, currPatch->length) != 0)) if (patch->src_data != KIP1_PATCH_SRC_NO_CHECK &&
(memcmp(&kip_sect_data[patch_offset], patch->src_data, patch->length) != 0) &&
(memcmp(&kip_sect_data[patch_offset], patch->dst_data, patch->length) != 0))
{ {
gfx_con.mute = false; gfx_con.mute = false;
gfx_printf("%kPatch mismatch at 0x%x!%k\n", TXT_CLR_ERROR, currOffset, TXT_CLR_DEFAULT); gfx_printf("%kPatch mismatch at 0x%x!%k\n", TXT_CLR_ERROR, patch_offset, TXT_CLR_DEFAULT);
return currPatchset->name; // MUST stop here as kip is likely corrupt. return patchset->name; // MUST stop here as kip is likely corrupt.
} }
else else
{ {
DPRINTF("Patching %d bytes at offset 0x%x\n", currPatch->length, currOffset); DPRINTF("Patching %d bytes at offset 0x%x\n", patch->length, patch_offset);
memcpy(&kipSectData[currOffset], currPatch->dstData, currPatch->length); memcpy(&kip_sect_data[patch_offset], patch->dst_data, patch->length);
} }
} }
} }
kipSectData += ki->kip1->sections[currSectIdx].size_comp; kip_sect_data += ki->kip1->sections[section_idx].size_comp;
} }
patchesApplied |= appliedMask; patches_applied |= applied_mask;
continue; // Continue in case it's double defined.
} }
currPatchset++;
patchset++;
} }
if (emummc_patch_selected && !strncmp(_kip_id_sets[currKipIdx].name, "FS", sizeof(ki->kip1->name))) // emuMMC must be applied after all other patches, since it affects TEXT offset.
if (emummc_patch_apply)
{ {
emummc_patch_selected = false; // Encode ID.
emu_cfg.fs_ver = currKipIdx; emu_cfg.fs_ver = kip_id_idx;
if (currKipIdx) if (kip_id_idx)
emu_cfg.fs_ver--; emu_cfg.fs_ver--;
if (currKipIdx > 17) if (kip_id_idx > 17)
emu_cfg.fs_ver -= 2; emu_cfg.fs_ver -= 2;
// Inject emuMMC code.
gfx_printf("Injecting emuMMC. FS ID: %d\n", emu_cfg.fs_ver); gfx_printf("Injecting emuMMC. FS ID: %d\n", emu_cfg.fs_ver);
if (_kipm_inject("/bootloader/sys/emummc.kipm", "FS", ki)) if (_kipm_inject("bootloader/sys/emummc.kipm", "FS", ki))
return "emummc"; return "emummc";
// Skip checking again.
emummc_patch_selected = false;
emummc_patch_apply = false;
} }
} }
} }
for (u32 i = 0; i < numPatches; i++) // Check if all patches were applied.
for (u32 i = 0; i < patches_num; i++)
{ {
if ((patchesApplied & BIT(i)) == 0) if ((patches_applied & BIT(i)) == 0)
return patches[i]; return patches[i];
} }
@ -746,7 +772,7 @@ static u32 _pkg2_ini1_build(u8 *pdst, u8 *psec, pkg2_hdr_t *hdr, link_t *kips_in
// Merge KIPs into INI1. // Merge KIPs into INI1.
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link) LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link)
{ {
DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->size); DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", (char *)ki->kip1->name, (u32)ki->kip1, ki->size);
memcpy(pdst, ki->kip1, ki->size); memcpy(pdst, ki->kip1, ki->size);
pdst += ki->size; pdst += ki->size;
ini1->num_procs++; ini1->num_procs++;
@ -770,7 +796,7 @@ DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->s
void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info, bool is_exo) void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info, bool is_exo)
{ {
launch_ctxt_t * ctxt = (launch_ctxt_t *)hos_ctxt; launch_ctxt_t *ctxt = (launch_ctxt_t *)hos_ctxt;
u32 meso_magic = *(u32 *)(ctxt->kernel + 4); u32 meso_magic = *(u32 *)(ctxt->kernel + 4);
u32 kernel_size = ctxt->kernel_size; u32 kernel_size = ctxt->kernel_size;
u8 kb = ctxt->pkg1_id->kb; u8 kb = ctxt->pkg1_id->kb;

View file

@ -40,9 +40,9 @@ extern u32 pkg2_newkern_ini1_end;
typedef struct _kernel_patch_t typedef struct _kernel_patch_t
{ {
u32 id; u32 id;
u32 off; u32 off;
u32 val; u32 val;
u32 *ptr; u32 *ptr;
} kernel_patch_t; } kernel_patch_t;
@ -67,8 +67,8 @@ enum
typedef struct _pkg2_hdr_t typedef struct _pkg2_hdr_t
{ {
u8 ctr[0x10]; u8 ctr[0x10];
u8 sec_ctr[0x40]; u8 sec_ctr[0x40];
u32 magic; u32 magic;
u32 base; u32 base;
u32 pad0; u32 pad0;
@ -77,8 +77,8 @@ typedef struct _pkg2_hdr_t
u16 pad1; u16 pad1;
u32 sec_size[4]; u32 sec_size[4];
u32 sec_off[4]; u32 sec_off[4];
u8 sec_sha256[0x80]; u8 sec_sha256[0x80];
u8 data[]; u8 data[];
} pkg2_hdr_t; } pkg2_hdr_t;
typedef struct _pkg2_ini1_t typedef struct _pkg2_ini1_t
@ -127,25 +127,27 @@ typedef struct _pkg2_kernel_id_t
kernel_patch_t *kernel_patchset; kernel_patch_t *kernel_patchset;
} pkg2_kernel_id_t; } pkg2_kernel_id_t;
#define KIP1_PATCH_SRC_NO_CHECK (char *)(-1)
typedef struct _kip1_patch_t typedef struct _kip1_patch_t
{ {
u32 offset; // section+offset of patch to apply. u32 offset; // section+offset of patch to apply.
u32 length; // In bytes, 0 means last patch. u32 length; // In bytes, 0 means last patch.
char* srcData; // That must match. char *src_data; // That must match.
char* dstData; // That it gets replaced by. char *dst_data; // That it gets replaced by.
} kip1_patch_t; } kip1_patch_t;
typedef struct _kip1_patchset_t typedef struct _kip1_patchset_t
{ {
char* name; // NULL means end. char *name; // NULL means end.
kip1_patch_t* patches; // NULL means not necessary. kip1_patch_t *patches; // NULL means not necessary.
} kip1_patchset_t; } kip1_patchset_t;
typedef struct _kip1_id_t typedef struct _kip1_id_t
{ {
const char* name; const char *name;
u8 hash[8]; u8 hash[8];
kip1_patchset_t* patchset; kip1_patchset_t *patchset;
} kip1_id_t; } kip1_id_t;
void pkg2_get_newkern_info(u8 *kern_data); void pkg2_get_newkern_info(u8 *kern_data);
@ -155,7 +157,7 @@ void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1);
void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1); void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1);
void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1); void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1);
void pkg2_get_ids(kip1_id_t **ids, u32 *entries); void pkg2_get_ids(kip1_id_t **ids, u32 *entries);
const char* pkg2_patch_kips(link_t *info, char* patchNames); const char *pkg2_patch_kips(link_t *info, char *patch_names);
const pkg2_kernel_id_t *pkg2_identify(u8 *hash); const pkg2_kernel_id_t *pkg2_identify(u8 *hash);
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb, bool is_exo); pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb, bool is_exo);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-2022 CTCaer * Copyright (c) 2019-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -80,7 +80,7 @@ static ini_kip_sec_t *_ini_create_kip_section(link_t *dst, ini_kip_sec_t *ksec,
// Calculate total allocation size. // Calculate total allocation size.
u32 len = strlen(name); u32 len = strlen(name);
char *buf = calloc(sizeof(ini_kip_sec_t) + len + 1, 1); char *buf = zalloc(sizeof(ini_kip_sec_t) + len + 1);
ksec = (ini_kip_sec_t *)buf; ksec = (ini_kip_sec_t *)buf;
u32 i = _find_patch_section_name(name, len, ':') + 1; u32 i = _find_patch_section_name(name, len, ':') + 1;
@ -132,7 +132,7 @@ int ini_patch_parse(link_t *dst, char *ini_path)
u32 pos = _find_patch_section_name(lbuf, lblen, '='); u32 pos = _find_patch_section_name(lbuf, lblen, '=');
// Calculate total allocation size. // Calculate total allocation size.
char *buf = calloc(sizeof(ini_patchset_t) + strlen(&lbuf[1]) + 1, 1); char *buf = zalloc(sizeof(ini_patchset_t) + strlen(&lbuf[1]) + 1);
ini_patchset_t *pt = (ini_patchset_t *)buf; ini_patchset_t *pt = (ini_patchset_t *)buf;
// Set patch name. // Set patch name.
@ -158,11 +158,11 @@ int ini_patch_parse(link_t *dst, char *ini_path)
// Set patch source data. // Set patch source data.
str_start = _find_patch_section_name(&lbuf[pos], lblen - pos, ','); str_start = _find_patch_section_name(&lbuf[pos], lblen - pos, ',');
pt->srcData = _htoa(NULL, &lbuf[pos], pt->length, buf); pt->src_data = _htoa(NULL, &lbuf[pos], pt->length, buf);
pos += str_start + 1; pos += str_start + 1;
// Set patch destination data. // Set patch destination data.
pt->dstData = _htoa(NULL, &lbuf[pos], pt->length, buf + pt->length); pt->dst_data = _htoa(NULL, &lbuf[pos], pt->length, buf + pt->length);
} }
list_append(&ksec->pts, &pt->link); list_append(&ksec->pts, &pt->link);

View file

@ -22,10 +22,10 @@
typedef struct _ini_patchset_t typedef struct _ini_patchset_t
{ {
char *name; char *name;
u32 offset; // section + offset of patch to apply. u32 offset; // section + offset of patch to apply.
u32 length; // In bytes, 0 means last patch. u32 length; // In bytes, 0 means last patch.
u8 *srcData; // That must match. u8 *src_data; // That must match.
u8 *dstData; // Gets replaced with. u8 *dst_data; // Gets replaced with.
link_t link; link_t link;
} ini_patchset_t; } ini_patchset_t;

View file

@ -448,362 +448,349 @@ static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
}; };
// All kip patch offsets are without the 0x100-sized header. // All kip patch offsets are without the 0x100-sized header.
static kip1_patch_t _fs_emummc[] = {
{ KPS(KIP_TEXT) | 1, 0, "", "" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_100[] = { static kip1_patchset_t _fs_patches_100[] = {
{ "nogc", NULL }, { "nogc", NULL },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_40x[] = { static kip1_patch_t _fs_nogc_40x[] = {
{ KPS(KIP_TEXT) | 0xA3458, 4, "\x14\x40\x80\x72", "\x14\x80\x80\x72" }, { KPS(KIP_TEXT) | 0xA3458, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x72" },
{ KPS(KIP_TEXT) | 0xAAB44, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0xAAB44, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_40x[] = { static kip1_patchset_t _fs_patches_40x[] = {
{ "nogc", _fs_nogc_40x }, { "nogc", _fs_nogc_40x },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_410[] = { static kip1_patch_t _fs_nogc_410[] = {
{ KPS(KIP_TEXT) | 0xA34BC, 4, "\x14\x40\x80\x72", "\x14\x80\x80\x72" }, { KPS(KIP_TEXT) | 0xA34BC, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x72" },
{ KPS(KIP_TEXT) | 0xAABA8, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0xAABA8, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_410[] = { static kip1_patchset_t _fs_patches_410[] = {
{ "nogc", _fs_nogc_410 }, { "nogc", _fs_nogc_410 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_50x[] = { static kip1_patch_t _fs_nogc_50x[] = {
{ KPS(KIP_TEXT) | 0xCF3C4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0xCF3C4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ KPS(KIP_TEXT) | 0xD73A0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0xD73A0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_50x[] = { static kip1_patchset_t _fs_patches_50x[] = {
{ "nogc", _fs_nogc_50x }, { "nogc", _fs_nogc_50x },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_510[] = { static kip1_patch_t _fs_nogc_510[] = {
{ KPS(KIP_TEXT) | 0xCF794, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0xCF794, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ KPS(KIP_TEXT) | 0xD7770, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0xD7770, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_510[] = { static kip1_patchset_t _fs_patches_510[] = {
{ "nogc", _fs_nogc_510 }, { "nogc", _fs_nogc_510 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_600[] = { static kip1_patch_t _fs_nogc_600[] = {
{ KPS(KIP_TEXT) | 0x12CC20, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x12CC20, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x1538F4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x1538F4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_600_exfat[] = { static kip1_patch_t _fs_nogc_600_exfat[] = {
{ KPS(KIP_TEXT) | 0x138320, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x138320, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x15EFF4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x15EFF4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_600[] = { static kip1_patchset_t _fs_patches_600[] = {
{ "nogc", _fs_nogc_600 }, { "nogc", _fs_nogc_600 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_600_exfat[] = { static kip1_patchset_t _fs_patches_600_exfat[] = {
{ "nogc", _fs_nogc_600_exfat }, { "nogc", _fs_nogc_600_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_700[] = { static kip1_patch_t _fs_nogc_700[] = {
{ KPS(KIP_TEXT) | 0x134160, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x134160, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x15BF04, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x15BF04, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_700_exfat[] = { static kip1_patch_t _fs_nogc_700_exfat[] = {
{ KPS(KIP_TEXT) | 0x13F710, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x13F710, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x1674B4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x1674B4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_700[] = { static kip1_patchset_t _fs_patches_700[] = {
{ "nogc", _fs_nogc_700 }, { "nogc", _fs_nogc_700 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_700_exfat[] = { static kip1_patchset_t _fs_patches_700_exfat[] = {
{ "nogc", _fs_nogc_700_exfat }, { "nogc", _fs_nogc_700_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_800[] = { static kip1_patch_t _fs_nogc_800[] = {
{ KPS(KIP_TEXT) | 0x136800, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x136800, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x15EB94, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x15EB94, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_800_exfat[] = { static kip1_patch_t _fs_nogc_800_exfat[] = {
{ KPS(KIP_TEXT) | 0x141DB0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x141DB0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x16A144, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x16A144, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_800[] = { static kip1_patchset_t _fs_patches_800[] = {
{ "nogc", _fs_nogc_800 }, { "nogc", _fs_nogc_800 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_800_exfat[] = { static kip1_patchset_t _fs_patches_800_exfat[] = {
{ "nogc", _fs_nogc_800_exfat }, { "nogc", _fs_nogc_800_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_900[] = { static kip1_patch_t _fs_nogc_900[] = {
{ KPS(KIP_TEXT) | 0x129420, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x129420, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x143268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x143268, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_900[] = { static kip1_patchset_t _fs_patches_900[] = {
{ "nogc", _fs_nogc_900 }, { "nogc", _fs_nogc_900 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_910[] = { static kip1_patch_t _fs_nogc_910[] = {
{ KPS(KIP_TEXT) | 0x129430, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x129430, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x143278, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x143278, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_910[] = { static kip1_patchset_t _fs_patches_910[] = {
{ "nogc", _fs_nogc_910 }, { "nogc", _fs_nogc_910 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1000[] = { static kip1_patch_t _fs_nogc_1000[] = {
{ KPS(KIP_TEXT) | 0x13BE90, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x13BE90, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x14DE08, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x14DE08, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1000[] = { static kip1_patchset_t _fs_patches_1000[] = {
{ "nogc", _fs_nogc_1000 }, { "nogc", _fs_nogc_1000 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1020[] = { static kip1_patch_t _fs_nogc_1020[] = {
{ KPS(KIP_TEXT) | 0x13C2F0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x13C2F0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x14E268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x14E268, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1020[] = { static kip1_patchset_t _fs_patches_1020[] = {
{ "nogc", _fs_nogc_1020 }, { "nogc", _fs_nogc_1020 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1100[] = { static kip1_patch_t _fs_nogc_1100[] = {
{ KPS(KIP_TEXT) | 0x1398B4, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x1398B4, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x156EB8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x156EB8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1100[] = { static kip1_patchset_t _fs_patches_1100[] = {
{ "nogc", _fs_nogc_1100 }, { "nogc", _fs_nogc_1100 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1200[] = { static kip1_patch_t _fs_nogc_1200[] = {
{ KPS(KIP_TEXT) | 0x13EA24, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x13EA24, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x155368, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x155368, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1200[] = { static kip1_patchset_t _fs_patches_1200[] = {
{ "nogc", _fs_nogc_1200 }, { "nogc", _fs_nogc_1200 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1203[] = { static kip1_patch_t _fs_nogc_1203[] = {
{ KPS(KIP_TEXT) | 0x13EB34, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x13EB34, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x155478, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x155478, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1203[] = { static kip1_patchset_t _fs_patches_1203[] = {
{ "nogc", _fs_nogc_1203 }, { "nogc", _fs_nogc_1203 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1300[] = { static kip1_patch_t _fs_nogc_1300[] = {
{ KPS(KIP_TEXT) | 0x1425D0, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x1425D0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x159018, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x159018, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1300[] = { static kip1_patchset_t _fs_patches_1300[] = {
{ "nogc", _fs_nogc_1300 }, { "nogc", _fs_nogc_1300 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1310[] = { static kip1_patch_t _fs_nogc_1310[] = {
{ KPS(KIP_TEXT) | 0x142570, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x142570, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x158FB8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x158FB8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1310[] = { static kip1_patchset_t _fs_patches_1310[] = {
{ "nogc", _fs_nogc_1310 }, { "nogc", _fs_nogc_1310 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1400[] = { static kip1_patch_t _fs_nogc_1400[] = {
{ KPS(KIP_TEXT) | 0x164230, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x164230, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x18A2E8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x18A2E8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1400[] = { static kip1_patchset_t _fs_patches_1400[] = {
{ "nogc", _fs_nogc_1400 }, { "nogc", _fs_nogc_1400 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1400_exfat[] = { static kip1_patch_t _fs_nogc_1400_exfat[] = {
{ KPS(KIP_TEXT) | 0x16F5B0, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x16F5B0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x195668, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x195668, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1400_exfat[] = { static kip1_patchset_t _fs_patches_1400_exfat[] = {
{ "nogc", _fs_nogc_1400_exfat }, { "nogc", _fs_nogc_1400_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1500[] = { static kip1_patch_t _fs_nogc_1500[] = {
{ KPS(KIP_TEXT) | 0x15ECE4, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x15ECE4, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x184158, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x184158, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1500[] = { static kip1_patchset_t _fs_patches_1500[] = {
{ "nogc", _fs_nogc_1500 }, { "nogc", _fs_nogc_1500 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1500_exfat[] = { static kip1_patch_t _fs_nogc_1500_exfat[] = {
{ KPS(KIP_TEXT) | 0x169C74, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x169C74, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x18F0E8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x18F0E8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1500_exfat[] = { static kip1_patchset_t _fs_patches_1500_exfat[] = {
{ "nogc", _fs_nogc_1500_exfat }, { "nogc", _fs_nogc_1500_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1600[] = { static kip1_patch_t _fs_nogc_1600[] = {
{ KPS(KIP_TEXT) | 0x160B70, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x160B70, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x1865D8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x1865D8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1600[] = { static kip1_patchset_t _fs_patches_1600[] = {
{ "nogc", _fs_nogc_1600 }, { "nogc", _fs_nogc_1600 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1600_exfat[] = { static kip1_patch_t _fs_nogc_1600_exfat[] = {
{ KPS(KIP_TEXT) | 0x16B850, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x16B850, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x1912B8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x1912B8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1600_exfat[] = { static kip1_patchset_t _fs_patches_1600_exfat[] = {
{ "nogc", _fs_nogc_1600_exfat }, { "nogc", _fs_nogc_1600_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1603[] = { static kip1_patch_t _fs_nogc_1603[] = {
{ KPS(KIP_TEXT) | 0x160BC0, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x160BC0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x186628, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x186628, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1603[] = { static kip1_patchset_t _fs_patches_1603[] = {
{ "nogc", _fs_nogc_1603 }, { "nogc", _fs_nogc_1603 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1603_exfat[] = { static kip1_patch_t _fs_nogc_1603_exfat[] = {
{ KPS(KIP_TEXT) | 0x16B8A0, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x16B8A0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x191308, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x191308, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1603_exfat[] = { static kip1_patchset_t _fs_patches_1603_exfat[] = {
{ "nogc", _fs_nogc_1603_exfat }, { "nogc", _fs_nogc_1603_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1700[] = { static kip1_patch_t _fs_nogc_1700[] = {
{ KPS(KIP_TEXT) | 0x165100, 8, "\xFD\x7B\xBD\xA9\xF5\x0B\x00\xF9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x165100, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x18B048, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x18B048, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1700[] = { static kip1_patchset_t _fs_patches_1700[] = {
{ "nogc", _fs_nogc_1700 }, { "nogc", _fs_nogc_1700 },
{ "emummc", _fs_emummc },
{ NULL, NULL } { NULL, NULL }
}; };
static kip1_patch_t _fs_nogc_1700_exfat[] = { static kip1_patch_t _fs_nogc_1700_exfat[] = {
{ KPS(KIP_TEXT) | 0x16FF60, 8, "\xFD\x7B\xBD\xA9\xF5\x0B\x00\xF9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, { KPS(KIP_TEXT) | 0x16FF60, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x195EA8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, { KPS(KIP_TEXT) | 0x195EA8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static kip1_patchset_t _fs_patches_1700_exfat[] = { static kip1_patchset_t _fs_patches_1700_exfat[] = {
{ "nogc", _fs_nogc_1700_exfat }, { "nogc", _fs_nogc_1700_exfat },
{ "emummc", _fs_emummc }, { NULL, NULL }
};
static kip1_patch_t _fs_nogc_1800[] = {
{ KPS(KIP_TEXT) | 0x164A50, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x18AE48, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1800[] = {
{ "nogc", _fs_nogc_1800 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1800_exfat[] = {
{ KPS(KIP_TEXT) | 0x16FAE0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x195ED8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1800_exfat[] = {
{ "nogc", _fs_nogc_1800_exfat },
{ NULL, NULL } { NULL, NULL }
}; };
@ -866,4 +853,6 @@ static kip1_id_t _kip_ids[] =
{ "FS", "\x62\xC6\x5E\xFD\x9A\xBF\x7C\x43", _fs_patches_1603_exfat }, // FS 16.0.3 exFAT { "FS", "\x62\xC6\x5E\xFD\x9A\xBF\x7C\x43", _fs_patches_1603_exfat }, // FS 16.0.3 exFAT
{ "FS", "\x27\x07\x3B\xF0\xA1\xB8\xCE\x61", _fs_patches_1700 }, // FS 17.0.0 { "FS", "\x27\x07\x3B\xF0\xA1\xB8\xCE\x61", _fs_patches_1700 }, // FS 17.0.0
{ "FS", "\xEE\x0F\x4B\xAC\x6D\x1F\xFC\x4B", _fs_patches_1700_exfat }, // FS 17.0.0 exFAT { "FS", "\xEE\x0F\x4B\xAC\x6D\x1F\xFC\x4B", _fs_patches_1700_exfat }, // FS 17.0.0 exFAT
{ "FS", "\x79\x5F\x5A\x5E\xB0\xC6\x77\x9E", _fs_patches_1800 }, // FS 18.0.0
{ "FS", "\x1E\x2C\x64\xB1\xCC\xE2\x78\x24", _fs_patches_1800_exfat }, // FS 18.0.0 exFAT
}; };

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2019 Atmosphère-NX * Copyright (c) 2019 Atmosphère-NX
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@ -156,28 +156,24 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
//! TODO: Replace current HOS version decoding (as it's bound to break in the future). //! TODO: Replace current HOS version decoding (as it's bound to break in the future).
// Old exosphere target versioning. Use fuses for a simpler decoding. // Old exosphere target versioning.
if (ctxt->pkg1_id->fuses <= 3 || ctxt->pkg1_id->fuses >= 10) // 1.0.0 - 3.0.0, 8.1.0+. if (ctxt->pkg1_id->kb >= HOS_KB_VERSION_1210) // 12.1.0+
exo_fw_no = ctxt->pkg1_id->kb + 4;
else if (ctxt->pkg1_id->fuses <= 3 || ctxt->pkg1_id->fuses >= 10) // 1.0.0 - 3.0.0, 8.1.0 - 12.0.3.
exo_fw_no = ctxt->pkg1_id->fuses; exo_fw_no = ctxt->pkg1_id->fuses;
else else
exo_fw_no = ctxt->pkg1_id->fuses - 1; // 3.0.1 - 7.0.1, 8.0.x. exo_fw_no = ctxt->pkg1_id->fuses - 1; // 3.0.1 - 7.0.1, 8.0.x.
// Handle versions that change API and do not burn new fuse.
if (!memcmp(ctxt->pkg1_id->id, "20190314", 8) || // 8.0.x, same fuses with 7.0.1.
!memcmp(ctxt->pkg1_id->id, "20210129", 8) // 12.0.0, same fuses with 11.0.0.
)
exo_fw_no++;
// Set 12.1.0 specific revision. // Set 12.1.0 specific revision.
if (ctxt->pkg1_id->kb == HOS_KB_VERSION_1210) if (ctxt->pkg1_id->kb == HOS_KB_VERSION_1210)
ctxt->exo_ctx.hos_revision = 1; ctxt->exo_ctx.hos_revision = 1;
// Handle 15.0.0+.
if (ctxt->pkg1_id->fuses >= 17)
exo_fw_no++;
// Handle versions that change API and do not burn new fuse.
if (!memcmp(ctxt->pkg1_id->id, "20190314", 8) || // 8.0.x, same fuses with 7.0.1.
!memcmp(ctxt->pkg1_id->id, "20210129", 8) || // 12.0.0, same fuses with 11.0.0.
!memcmp(ctxt->pkg1_id->id, "20210805", 8) || // 13.0.0, same fuses with 12.1.0.
!memcmp(ctxt->pkg1_id->id, "20220209", 8) // 14.0.0, same fuses with 13.2.1.
)
exo_fw_no++;
// Feed old exosphere target versioning to new. // Feed old exosphere target versioning to new.
switch (exo_fw_no) switch (exo_fw_no)
{ {
@ -203,7 +199,7 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
case 12: case 12:
exo_fw_no = EXO_FW_VER(9, 1); exo_fw_no = EXO_FW_VER(9, 1);
break; break;
case 13 ... 20: //!TODO: Update on API changes. 20: 17.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); exo_fw_no = EXO_FW_VER(exo_fw_no - 3, ctxt->exo_ctx.hos_revision);
break; break;
} }
@ -245,32 +241,29 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
} }
break; break;
} }
}
// Parse usb mtim settings. Avoid parsing if it's overridden. // Parse usb mtim settings. Avoid parsing if it's overridden.
if (ctxt->fss0_main_path && !ctxt->exo_ctx.usb3_force) if (!ctxt->exo_ctx.usb3_force)
{
char settings_path[256];
strcpy(settings_path, ctxt->fss0_main_path);
strcat(settings_path, "config/system_settings.ini");
LIST_INIT(sys_settings);
if (ini_parse(&ini_sections, settings_path, false))
{ {
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) LIST_INIT(ini_sections);
if (ini_parse(&ini_sections, "atmosphere/config/system_settings.ini", false))
{ {
// Only parse usb section. LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
if (!(ini_sec->type == INI_CHOICE) || strcmp(ini_sec->name, "usb"))
continue;
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{ {
if (!strcmp("usb30_force_enabled", kv->key)) // Only parse usb section.
if (!(ini_sec->type == INI_CHOICE) || strcmp(ini_sec->name, "usb"))
continue;
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{ {
usb3_force = !strcmp("u8!0x1", kv->val); if (!strcmp("usb30_force_enabled", kv->key))
break; // Only parse usb30_force_enabled key. {
usb3_force = !strcmp("u8!0x1", kv->val);
break; // Only parse usb30_force_enabled key.
}
} }
break;
} }
break;
} }
} }
} }
@ -416,7 +409,7 @@ void secmon_exo_check_panic()
// Save context to the SD card. // Save context to the SD card.
char filepath[0x40]; char filepath[0x40];
f_mkdir("atmosphere/fatal_errors"); f_mkdir("atmosphere/fatal_errors");
strcpy(filepath, "/atmosphere/fatal_errors/report_"); strcpy(filepath, "atmosphere/fatal_errors/report_");
itoa((u32)((u64)rpt->report_identifier >> 32), filepath + strlen(filepath), 16); itoa((u32)((u64)rpt->report_identifier >> 32), filepath + strlen(filepath), 16);
itoa((u32)(rpt->report_identifier), filepath + strlen(filepath), 16); itoa((u32)(rpt->report_identifier), filepath + strlen(filepath), 16);
strcat(filepath, ".bin"); strcat(filepath, ".bin");

View file

@ -33,9 +33,12 @@
* 1: SDMMC1 LA programming for SDMMC1 UHS DDR200. * 1: SDMMC1 LA programming for SDMMC1 UHS DDR200.
* 2: Arachne Register Cell v1. * 2: Arachne Register Cell v1.
* 3: Arachne Register Cell v2. PTSA Rework support. * 3: Arachne Register Cell v2. PTSA Rework support.
* 4: Arachne Register Cell v3. DRAM OPT and DDR200 changes.
* 5: Arachne Register Cell v4. DRAM FREQ and DDR200 changes.
*/ */
#define L4T_LOADER_API_REV 4
#define L4T_FIRMWARE_REV 0x34524556 // REV4. #define L4T_LOADER_API_REV 5
#define L4T_FIRMWARE_REV 0x35524556 // REV5.
#ifdef DEBUG_UART_PORT #ifdef DEBUG_UART_PORT
#include <soc/uart.h> #include <soc/uart.h>
@ -1156,7 +1159,7 @@ void launch_l4t(const ini_sec_t *ini_sec, int entry_idx, int is_list, bool t210b
if (t210b01) if (t210b01)
{ {
// Launch BL31. // Launch BL31.
ccplex_boot_cpu0(TZDRAM_COLD_ENTRY); ccplex_boot_cpu0(TZDRAM_COLD_ENTRY, true);
// Enable Wrap burst for BPMP, GPU and PCIE. // Enable Wrap burst for BPMP, GPU and PCIE.
MSELECT(MSELECT_CONFIG) = (MSELECT(MSELECT_CONFIG) & (~(MSELECT_CFG_ERR_RESP_EN_GPU | MSELECT_CFG_ERR_RESP_EN_PCIE))) | MSELECT(MSELECT_CONFIG) = (MSELECT(MSELECT_CONFIG) & (~(MSELECT_CFG_ERR_RESP_EN_GPU | MSELECT_CFG_ERR_RESP_EN_PCIE))) |

View file

@ -1,35 +0,0 @@
/*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs */
/* (C) ChaN, 2018 */
/* (C) CTCaer, 2018 */
/*------------------------------------------------------------------------*/
#include <bdk.h>
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/*------------------------------------------------------------------------*/
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
UINT msize /* Number of bytes to allocate */
)
{
return malloc(msize); /* Allocate a new memory block with POSIX API */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree (
void* mblock /* Pointer to the memory block to free (nothing to do if null) */
)
{
free(mblock); /* Free the memory block with POSIX API */
}
#endif

View file

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* *
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -767,7 +767,7 @@ static void _check_for_updated_bootloader()
_launch_payload("bootloader/update.bin", true, false); _launch_payload("bootloader/update.bin", true, false);
else else
{ {
u8 *buf = calloc(0x200, 1); u8 *buf = zalloc(0x200);
is_ipl_updated(buf, "bootloader/update.bin", true); is_ipl_updated(buf, "bootloader/update.bin", true);
free(buf); free(buf);
} }
@ -1236,7 +1236,7 @@ static void _check_low_battery()
u8 *battery_icon = malloc(0x95A); // 21x38x3 u8 *battery_icon = malloc(0x95A); // 21x38x3
u8 *charging_icon = malloc(0x2F4); // 21x12x3 u8 *charging_icon = malloc(0x2F4); // 21x12x3
u8 *no_charging_icon = calloc(0x2F4, 1); u8 *no_charging_icon = zalloc(0x2F4);
memcpy(charging_icon, battery_res, 0x2F4); memcpy(charging_icon, battery_res, 0x2F4);
memcpy(battery_icon, battery_res + 0x2F4, 0x95A); memcpy(battery_icon, battery_res + 0x2F4, 0x95A);
@ -1478,7 +1478,7 @@ ment_t ment_top[] = {
MDEF_END() MDEF_END()
}; };
menu_t menu_top = { ment_top, "hekate v6.1.0", 0, 0 }; menu_t menu_top = { ment_top, "hekate v6.1.1", 0, 0 };
extern void pivot_stack(u32 stack_top); extern void pivot_stack(u32 stack_top);

View file

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 Rajko Stojadinovic * Copyright (c) 2018 Rajko Stojadinovic
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -40,7 +40,7 @@ extern char *emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_s
static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_idx, bool backup) static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_idx, bool backup)
{ {
sd_mount(); sd_mount();
mbr_t *mbr = (mbr_t *)calloc(sizeof(mbr_t), 1); mbr_t *mbr = (mbr_t *)zalloc(sizeof(mbr_t));
sdmmc_storage_read(&sd_storage, 0, 1, mbr); sdmmc_storage_read(&sd_storage, 0, 1, mbr);
*part_idx = 0; *part_idx = 0;
@ -57,7 +57,7 @@ static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_
{ {
if (backup) if (backup)
{ {
u8 gpt_check[512] = { 0 }; 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)) if (!memcmp(gpt_check, "EFI PART", 8))
{ {
@ -90,7 +90,7 @@ static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_
// Get emuMMC GPP size. // Get emuMMC GPP size.
if (backup && *part_idx && *sector_size) if (backup && *part_idx && *sector_size)
{ {
gpt_t *gpt = (gpt_t *)calloc(sizeof(gpt_t), 1); 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; u32 new_size = gpt->header.alt_lba + 1;

View file

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 Rajko Stojadinovic * Copyright (c) 2018 Rajko Stojadinovic
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -705,7 +705,7 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
// Read MBR, GPT and backup GPT. // Read MBR, GPT and backup GPT.
mbr_t mbr; mbr_t mbr;
gpt_t *gpt = calloc(1, sizeof(gpt_t)); gpt_t *gpt = zalloc(sizeof(gpt_t));
gpt_header_t gpt_hdr_backup; gpt_header_t gpt_hdr_backup;
sdmmc_storage_read(&emmc_storage, 0, 1, &mbr); sdmmc_storage_read(&emmc_storage, 0, 1, &mbr);
sdmmc_storage_read(&emmc_storage, 1, sizeof(gpt_t) >> 9, gpt); sdmmc_storage_read(&emmc_storage, 1, sizeof(gpt_t) >> 9, gpt);

View file

@ -282,12 +282,7 @@ static void _save_fb_to_bmp()
// Create date/time name. // Create date/time name.
char fname[32]; char fname[32];
rtc_time_t time; rtc_time_t time;
max77620_rtc_get_time(&time); max77620_rtc_get_time_adjusted(&time);
if (n_cfg.timeoff)
{
u32 epoch = max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff;
max77620_rtc_epoch_to_date(epoch, &time);
}
s_printf(fname, "%04d%02d%02d_%02d%02d%02d", time.year, time.month, time.day, time.hour, time.min, time.sec); s_printf(fname, "%04d%02d%02d_%02d%02d%02d", time.year, time.month, time.day, time.hour, time.min, time.sec);
s_printf(path + strlen(path), "/nyx%s.bmp", fname); s_printf(path + strlen(path), "/nyx%s.bmp", fname);
@ -1318,12 +1313,7 @@ static void _update_status_bar(void *params)
rtc_time_t time; rtc_time_t time;
// Get sensor data. // Get sensor data.
max77620_rtc_get_time(&time); max77620_rtc_get_time_adjusted(&time);
if (n_cfg.timeoff)
{
u32 epoch = max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff;
max77620_rtc_epoch_to_date(epoch, &time);
}
soc_temp = tmp451_get_soc_temp(false); soc_temp = tmp451_get_soc_temp(false);
bq24193_get_property(BQ24193_ChargeStatus, &charge_status); bq24193_get_property(BQ24193_ChargeStatus, &charge_status);
max17050_get_property(MAX17050_RepSOC, (int *)&batt_percent); max17050_get_property(MAX17050_RepSOC, (int *)&batt_percent);

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@ -858,6 +858,9 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
case PANEL_SAM_AMS699VC01: case PANEL_SAM_AMS699VC01:
strcat(txt_buf, "Samsung AMS699VC01"); strcat(txt_buf, "Samsung AMS699VC01");
break; break;
case PANEL_OEM_CLONE_6_2:
strcat(txt_buf, "#FFDD00 OEM Clone 6.2\"#");
break;
case PANEL_OEM_CLONE_5_5: case PANEL_OEM_CLONE_5_5:
strcat(txt_buf, "#FFDD00 OEM Clone 5.5\"#"); strcat(txt_buf, "#FFDD00 OEM Clone 5.5\"#");
break; break;
@ -1107,7 +1110,7 @@ static lv_res_t _create_mbox_emmc_sandisk_report(lv_obj_t * btn)
lv_mbox_set_text(mbox, "#C7EA46 Sandisk Device Report#"); lv_mbox_set_text(mbox, "#C7EA46 Sandisk Device Report#");
u8 *buf = calloc(512, 1); u8 *buf = zalloc(EMMC_BLOCKSIZE);
char *txt_buf = (char *)malloc(SZ_32K); char *txt_buf = (char *)malloc(SZ_32K);
char *txt_buf2 = (char *)malloc(SZ_32K); char *txt_buf2 = (char *)malloc(SZ_32K);
txt_buf[0] = 0; txt_buf[0] = 0;
@ -1619,6 +1622,9 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
case 0x90: case 0x90:
strcat(txt_buf, "SK Hynix "); strcat(txt_buf, "SK Hynix ");
break; break;
default:
strcat(txt_buf, "Unknown ");
break;
} }
s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c%c\n%d.%d\n%04X\n%02d/%04d\n\n", s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c%c\n%d.%d\n%04X\n%02d/%04d\n\n",
@ -1694,7 +1700,7 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
emmc_storage.csd.cmdclass, speed & 0xFFFF, (speed >> 16) & 0xFFFF, emmc_storage.csd.cmdclass, speed & 0xFFFF, (speed >> 16) & 0xFFFF,
emmc_storage.csd.busspeed, card_type_support, emmc_storage.csd.busspeed, card_type_support,
!(cache % 1024) ? (cache / 1024) : cache, !(cache % 1024) ? "MiB" : "KiB", !(cache % 1024) ? (cache / 1024) : cache, !(cache % 1024) ? "MiB" : "KiB",
emmc_storage.ext_csd.max_enh_mult * 512 / 1024, emmc_storage.ext_csd.max_enh_mult * EMMC_BLOCKSIZE / 1024,
life_a_txt, life_b_txt, rsvd_blocks); life_a_txt, life_b_txt, rsvd_blocks);
lv_label_set_static_text(lb_desc, lv_label_set_static_text(lb_desc,
@ -1735,9 +1741,9 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
u32 boot_size = emmc_storage.ext_csd.boot_mult << 17; u32 boot_size = emmc_storage.ext_csd.boot_mult << 17;
u32 rpmb_size = emmc_storage.ext_csd.rpmb_mult << 17; u32 rpmb_size = emmc_storage.ext_csd.rpmb_mult << 17;
strcpy(txt_buf, "#00DDFF eMMC Physical Partitions:#\n"); strcpy(txt_buf, "#00DDFF eMMC Physical Partitions:#\n");
s_printf(txt_buf + strlen(txt_buf), "1: #96FF00 BOOT0# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / 512); s_printf(txt_buf + strlen(txt_buf), "1: #96FF00 BOOT0# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / EMMC_BLOCKSIZE);
s_printf(txt_buf + strlen(txt_buf), "2: #96FF00 BOOT1# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / 512); s_printf(txt_buf + strlen(txt_buf), "2: #96FF00 BOOT1# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / EMMC_BLOCKSIZE);
s_printf(txt_buf + strlen(txt_buf), "3: #96FF00 RPMB# Size: %6d KiB (Sect: 0x%08X)\n", rpmb_size / 1024, rpmb_size / 512); s_printf(txt_buf + strlen(txt_buf), "3: #96FF00 RPMB# Size: %6d KiB (Sect: 0x%08X)\n", rpmb_size / 1024, rpmb_size / EMMC_BLOCKSIZE);
s_printf(txt_buf + strlen(txt_buf), "0: #96FF00 GPP# Size: %6d MiB (Sect: 0x%08X)\n", emmc_storage.sec_cnt >> SECTORS_TO_MIB_COEFF, emmc_storage.sec_cnt); s_printf(txt_buf + strlen(txt_buf), "0: #96FF00 GPP# Size: %6d MiB (Sect: 0x%08X)\n", emmc_storage.sec_cnt >> SECTORS_TO_MIB_COEFF, emmc_storage.sec_cnt);
strcat(txt_buf, "\n#00DDFF GPP (eMMC USER) Partition Table:#\n"); strcat(txt_buf, "\n#00DDFF GPP (eMMC USER) Partition Table:#\n");
@ -2119,7 +2125,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
s_printf(txt_buf, "\n%s\n%d %s\n%d/%d MiB", 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.fs_type == FS_EXFAT ? ("exFAT "SYMBOL_SHRK) : ("FAT32"),
(sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512, (sd_fs.csize > 1) ? (sd_fs.csize >> 1) : SD_BLOCKSIZE,
(sd_fs.csize > 1) ? "KiB" : "B", (sd_fs.csize > 1) ? "KiB" : "B",
(u32)(sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF), (u32)(sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF),
(u32)(sd_fs.n_fatent * sd_fs.csize >> SECTORS_TO_MIB_COEFF)); (u32)(sd_fs.n_fatent * sd_fs.csize >> SECTORS_TO_MIB_COEFF));

View file

@ -706,9 +706,14 @@ static lv_res_t _action_clock_edit(lv_obj_t *btns, const char * txt)
u32 new_epoch = max77620_rtc_date_to_epoch(&time); u32 new_epoch = max77620_rtc_date_to_epoch(&time);
// Stored in u32 and allow overflow for integer offset casting.
n_cfg.timeoff = new_epoch - epoch; n_cfg.timeoff = new_epoch - epoch;
// If canceled set 1 for invalidating first boot clock edit.
if (!n_cfg.timeoff) if (!n_cfg.timeoff)
n_cfg.timeoff = 1; n_cfg.timeoff = 1;
else
max77620_rtc_set_epoch_offset((int)n_cfg.timeoff);
nyx_changes_made = true; nyx_changes_made = true;
} }
@ -744,12 +749,7 @@ static lv_res_t _create_mbox_clock_edit(lv_obj_t *btn)
// Get current time. // Get current time.
rtc_time_t time; rtc_time_t time;
max77620_rtc_get_time(&time); max77620_rtc_get_time_adjusted(&time);
if (n_cfg.timeoff)
{
u32 epoch = max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff;
max77620_rtc_epoch_to_date(epoch, &time);
}
// Normalize year if out of range. // Normalize year if out of range.
if (time.year < CLOCK_MIN_YEAR) if (time.year < CLOCK_MIN_YEAR)
@ -842,6 +842,7 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
{ {
FIL fp; FIL fp;
int error = 0; int error = 0;
int cal_error = 0;
bool is_l_hos = false; bool is_l_hos = false;
bool is_r_hos = false; bool is_r_hos = false;
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG; bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
@ -853,8 +854,17 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
if (!nx_hoag && !jc_pad) if (!nx_hoag && !jc_pad)
error = 255; error = 255;
if (!error) // Try 2 times to get factory calibration data.
error = hos_dump_cal0(); for (u32 i = 0; i < 2; i++)
{
if (!error)
cal_error = hos_dump_cal0();
if (!cal_error)
break;
}
if (cal_error && nx_hoag)
error = cal_error;
if (error) if (error)
goto disabled_or_cal0_issue; goto disabled_or_cal0_issue;
@ -919,35 +929,38 @@ save_data:
f_mkdir("switchroot"); f_mkdir("switchroot");
// Save IMU Calibration data. // Save IMU Calibration data.
s_printf(data, if (!error && !cal_error)
"imu_type=%d\n\n"
"acc_cal_off_x=0x%X\n"
"acc_cal_off_y=0x%X\n"
"acc_cal_off_z=0x%X\n"
"acc_cal_scl_x=0x%X\n"
"acc_cal_scl_y=0x%X\n"
"acc_cal_scl_z=0x%X\n\n"
"gyr_cal_off_x=0x%X\n"
"gyr_cal_off_y=0x%X\n"
"gyr_cal_off_z=0x%X\n"
"gyr_cal_scl_x=0x%X\n"
"gyr_cal_scl_y=0x%X\n"
"gyr_cal_scl_z=0x%X\n\n"
"device_bt_mac=%02X:%02X:%02X:%02X:%02X:%02X\n",
cal0->console_6axis_sensor_type,
cal0->acc_offset[0], cal0->acc_offset[1], cal0->acc_offset[2],
cal0->acc_scale[0], cal0->acc_scale[1], cal0->acc_scale[2],
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)
{ {
f_puts(data, &fp); s_printf(data,
f_close(&fp); "imu_type=%d\n\n"
"acc_cal_off_x=0x%X\n"
"acc_cal_off_y=0x%X\n"
"acc_cal_off_z=0x%X\n"
"acc_cal_scl_x=0x%X\n"
"acc_cal_scl_y=0x%X\n"
"acc_cal_scl_z=0x%X\n\n"
"gyr_cal_off_x=0x%X\n"
"gyr_cal_off_y=0x%X\n"
"gyr_cal_off_z=0x%X\n"
"gyr_cal_scl_x=0x%X\n"
"gyr_cal_scl_y=0x%X\n"
"gyr_cal_scl_z=0x%X\n\n"
"device_bt_mac=%02X:%02X:%02X:%02X:%02X:%02X\n",
cal0->console_6axis_sensor_type,
cal0->acc_offset[0], cal0->acc_offset[1], cal0->acc_offset[2],
cal0->acc_scale[0], cal0->acc_scale[1], cal0->acc_scale[2],
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)
{
f_puts(data, &fp);
f_close(&fp);
}
} }
} }
else else
@ -1066,6 +1079,9 @@ disabled_or_cal0_issue:;
strcat(txt_buf, strcat(txt_buf,
"\n\n#FFDD00 Make sure that both Joy-Con are connected,#\n" "\n\n#FFDD00 Make sure that both Joy-Con are connected,#\n"
"#FFDD00 and that you paired them in HOS!#"); "#FFDD00 and that you paired them in HOS!#");
if (cal_error)
s_printf(txt_buf + strlen(txt_buf), "\n\n#FF8000 Warning: Failed (%d) to get IMU calibration!#", cal_error);
} }
else else
{ {

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -595,7 +595,7 @@ static lv_res_t _action_ums_emuemmc_gpp(lv_obj_t *btn)
error = 1; error = 1;
usbs.offset = emu_info.sector + 0x4000; usbs.offset = emu_info.sector + 0x4000;
u8 *gpt = malloc(512); u8 *gpt = malloc(SD_BLOCKSIZE);
if (sdmmc_storage_read(&sd_storage, usbs.offset + 1, 1, gpt)) if (sdmmc_storage_read(&sd_storage, usbs.offset + 1, 1, gpt))
{ {
if (!memcmp(gpt, "EFI PART", 8)) if (!memcmp(gpt, "EFI PART", 8))
@ -1145,10 +1145,10 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
char path[128]; char path[128];
u8 kb = 0; u8 kb = 0;
u8 *pkg1 = (u8 *)calloc(1, SZ_256K); u8 *pkg1 = (u8 *)zalloc(SZ_256K);
u8 *warmboot = (u8 *)calloc(1, SZ_256K); u8 *warmboot = (u8 *)zalloc(SZ_256K);
u8 *secmon = (u8 *)calloc(1, SZ_256K); u8 *secmon = (u8 *)zalloc(SZ_256K);
u8 *loader = (u8 *)calloc(1, SZ_256K); u8 *loader = (u8 *)zalloc(SZ_256K);
u8 *pkg2 = NULL; u8 *pkg2 = NULL;
char *txt_buf = (char *)malloc(SZ_16K); char *txt_buf = (char *)malloc(SZ_16K);
@ -1205,10 +1205,9 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
tsec_ctxt.fw = (void *)(pkg1 + pkg1_id->tsec_off); tsec_ctxt.fw = (void *)(pkg1 + pkg1_id->tsec_off);
tsec_ctxt.pkg1 = (void *)pkg1; tsec_ctxt.pkg1 = (void *)pkg1;
tsec_ctxt.pkg11_off = pkg1_id->pkg11_off; tsec_ctxt.pkg11_off = pkg1_id->pkg11_off;
tsec_ctxt.secmon_base = pkg1_id->secmon_base;
// Read keyblob. // Read keyblob.
u8 *keyblob = (u8 *)calloc(EMMC_BLOCKSIZE, 1); u8 *keyblob = (u8 *)zalloc(EMMC_BLOCKSIZE);
sdmmc_storage_read(&emmc_storage, HOS_KEYBLOBS_OFFSET / EMMC_BLOCKSIZE + kb, 1, keyblob); sdmmc_storage_read(&emmc_storage, HOS_KEYBLOBS_OFFSET / EMMC_BLOCKSIZE + kb, 1, keyblob);
// Decrypt. // Decrypt.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-2022 CTCaer * Copyright (c) 2019-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -345,7 +345,7 @@ static void _prepare_and_flash_mbr_gpt()
if (part_info.and_size) if (part_info.and_size)
{ {
gpt_t *gpt = calloc(1, sizeof(gpt_t)); gpt_t *gpt = zalloc(sizeof(gpt_t));
gpt_header_t gpt_hdr_backup = { 0 }; gpt_header_t gpt_hdr_backup = { 0 };
// Set GPT protective partition in MBR. // Set GPT protective partition in MBR.
@ -768,7 +768,7 @@ exit:
static u32 _get_available_l4t_partition() static u32 _get_available_l4t_partition()
{ {
mbr_t mbr = { 0 }; mbr_t mbr = { 0 };
gpt_t *gpt = calloc(1, sizeof(gpt_t)); gpt_t *gpt = zalloc(sizeof(gpt_t));
memset(&l4t_flash_ctxt, 0, sizeof(l4t_flasher_ctxt_t)); memset(&l4t_flash_ctxt, 0, sizeof(l4t_flasher_ctxt_t));
@ -815,7 +815,7 @@ static u32 _get_available_l4t_partition()
static bool _get_available_android_partition() static bool _get_available_android_partition()
{ {
gpt_t *gpt = calloc(1, sizeof(gpt_t)); gpt_t *gpt = zalloc(sizeof(gpt_t));
// Read main GPT. // Read main GPT.
sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, gpt); sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, gpt);
@ -926,8 +926,8 @@ static lv_res_t _action_check_flash_linux(lv_obj_t *btn)
goto error; goto error;
} }
// Last part. Align size to LBA (512 bytes). // Last part. Align size to LBA (SD_BLOCKSIZE).
fno.fsize = ALIGN((u64)fno.fsize, 512); fno.fsize = ALIGN((u64)fno.fsize, SD_BLOCKSIZE);
idx--; idx--;
} }
l4t_flash_ctxt.image_size_sct += (u64)fno.fsize >> 9; l4t_flash_ctxt.image_size_sct += (u64)fno.fsize >> 9;
@ -1007,7 +1007,7 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
// Flash Android components. // Flash Android components.
char path[128]; char path[128];
gpt_t *gpt = calloc(1, sizeof(gpt_t)); gpt_t *gpt = zalloc(sizeof(gpt_t));
char *txt_buf = malloc(SZ_4K); char *txt_buf = malloc(SZ_4K);
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
@ -1077,7 +1077,7 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
if (file_size % 0x200) if (file_size % 0x200)
{ {
file_size = ALIGN(file_size, 0x200); file_size = ALIGN(file_size, 0x200);
u8 *buf_tmp = calloc(file_size, 1); u8 *buf_tmp = zalloc(file_size);
memcpy(buf_tmp, buf, file_size); memcpy(buf_tmp, buf, file_size);
free(buf); free(buf);
buf = buf_tmp; buf = buf_tmp;
@ -1141,7 +1141,7 @@ boot_img_not_found:
if (file_size % 0x200) if (file_size % 0x200)
{ {
file_size = ALIGN(file_size, 0x200); file_size = ALIGN(file_size, 0x200);
u8 *buf_tmp = calloc(file_size, 1); u8 *buf_tmp = zalloc(file_size);
memcpy(buf_tmp, buf, file_size); memcpy(buf_tmp, buf, file_size);
free(buf); free(buf);
buf = buf_tmp; buf = buf_tmp;
@ -1203,7 +1203,7 @@ recovery_not_found:
if (file_size % 0x200) if (file_size % 0x200)
{ {
file_size = ALIGN(file_size, 0x200); file_size = ALIGN(file_size, 0x200);
u8 *buf_tmp = calloc(file_size, 1); u8 *buf_tmp = zalloc(file_size);
memcpy(buf_tmp, buf, file_size); memcpy(buf_tmp, buf, file_size);
free(buf); free(buf);
buf = buf_tmp; buf = buf_tmp;
@ -1231,7 +1231,7 @@ dtb_not_found:
{ {
if (!memcmp(gpt->entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6) || !memcmp(gpt->entries[i].name, (char[]) { 'r', 0, 'e', 0, 'c', 0, 'o', 0, 'v', 0, 'e', 0, 'r', 0, 'y', 0 }, 16)) if (!memcmp(gpt->entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6) || !memcmp(gpt->entries[i].name, (char[]) { 'r', 0, 'e', 0, 'c', 0, 'o', 0, 'v', 0, 'e', 0, 'r', 0, 'y', 0 }, 16))
{ {
u8 *buf = malloc(512); u8 *buf = malloc(SD_BLOCKSIZE);
sdmmc_storage_read(&sd_storage, gpt->entries[i].lba_start, 1, buf); sdmmc_storage_read(&sd_storage, gpt->entries[i].lba_start, 1, buf);
if (!memcmp(buf, "ANDROID", 7)) if (!memcmp(buf, "ANDROID", 7))
boot_recovery = true; boot_recovery = true;
@ -2228,7 +2228,7 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
lv_label_set_recolor(lbl_status, true); lv_label_set_recolor(lbl_status, true);
mbr_t mbr[2] = { 0 }; mbr_t mbr[2] = { 0 };
gpt_t *gpt = calloc(1, sizeof(gpt_t)); gpt_t *gpt = zalloc(sizeof(gpt_t));
gpt_header_t gpt_hdr_backup = { 0 }; gpt_header_t gpt_hdr_backup = { 0 };
bool has_mbr_attributes = false; bool has_mbr_attributes = false;
@ -2279,7 +2279,7 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
LIST_INIT(gpt_parsed); LIST_INIT(gpt_parsed);
for (u32 i = 0; i < gpt->header.num_part_ents; i++) for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{ {
emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1); emmc_part_t *part = (emmc_part_t *)zalloc(sizeof(emmc_part_t));
if (gpt->entries[i].lba_start < gpt->header.first_use_lba) if (gpt->entries[i].lba_start < gpt->header.first_use_lba)
continue; continue;
@ -2429,7 +2429,7 @@ check_changes:
gpt_hdr_backup.crc32 = crc32_calc(0, (const u8 *)&gpt_hdr_backup, gpt_hdr_backup.size); gpt_hdr_backup.crc32 = crc32_calc(0, (const u8 *)&gpt_hdr_backup, gpt_hdr_backup.size);
// Write main GPT. // Write main GPT.
u32 aligned_entries_size = ALIGN(entries_size, 512); u32 aligned_entries_size = ALIGN(entries_size, SD_BLOCKSIZE);
sdmmc_storage_write(&sd_storage, gpt->header.my_lba, (sizeof(gpt_header_t) + aligned_entries_size) >> 9, gpt); sdmmc_storage_write(&sd_storage, gpt->header.my_lba, (sizeof(gpt_header_t) + aligned_entries_size) >> 9, gpt);
// Write backup GPT partition table. // Write backup GPT partition table.

View file

@ -2,7 +2,7 @@
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk * Copyright (c) 2018 st4rk
* Copyright (c) 2018 Ced2911 * Copyright (c) 2018 Ced2911
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* *
* This program is free software; you can redistribute it and/or modify it * 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. //!TODO: Update on mkey changes.
static const u8 master_kekseed_t210_max[SE_KEY_128_SIZE] = static const u8 master_kekseed_t210_max[SE_KEY_128_SIZE] =
{ 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.
//!TODO: Update on mkey changes. //!TODO: Update on mkey changes.
static const u8 master_kekseed_t210b01[HOS_KB_VERSION_MAX - HOS_KB_VERSION_600 + 1][SE_KEY_128_SIZE] = { static const u8 master_kekseed_t210b01[HOS_KB_VERSION_MAX - HOS_KB_VERSION_600 + 1][SE_KEY_128_SIZE] = {
@ -92,6 +92,7 @@ static const u8 master_kekseed_t210b01[HOS_KB_VERSION_MAX - HOS_KB_VERSION_600 +
{ 0xEC, 0x61, 0xBC, 0x82, 0x1E, 0x0F, 0x5A, 0xC3, 0x2B, 0x64, 0x3F, 0x9D, 0xD6, 0x19, 0x22, 0x2D }, // 15.0.0. { 0xEC, 0x61, 0xBC, 0x82, 0x1E, 0x0F, 0x5A, 0xC3, 0x2B, 0x64, 0x3F, 0x9D, 0xD6, 0x19, 0x22, 0x2D }, // 15.0.0.
{ 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 }, // 16.0.0. { 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. { 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.
}; };
static const u8 console_keyseed[SE_KEY_128_SIZE] = static const u8 console_keyseed[SE_KEY_128_SIZE] =
@ -122,6 +123,7 @@ static const u8 mkey_vectors[HOS_KB_VERSION_MAX + 1][SE_KEY_128_SIZE] = {
{ 0xB1, 0x81, 0xA6, 0x0D, 0x72, 0xC7, 0xEE, 0x15, 0x21, 0xF3, 0xC0, 0xB5, 0x6B, 0x61, 0x6D, 0xE7 }, // Mkey 13 encrypted with mkey 14. { 0xB1, 0x81, 0xA6, 0x0D, 0x72, 0xC7, 0xEE, 0x15, 0x21, 0xF3, 0xC0, 0xB5, 0x6B, 0x61, 0x6D, 0xE7 }, // Mkey 13 encrypted with mkey 14.
{ 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 }, // Mkey 14 encrypted with mkey 15. { 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. { 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.
}; };
//!TODO: Update on mkey changes. //!TODO: Update on mkey changes.
@ -140,6 +142,7 @@ static const u8 new_console_keyseed[HOS_KB_VERSION_MAX - HOS_KB_VERSION_400 + 1]
{ 0x5E, 0xC9, 0xC5, 0x0A, 0xD0, 0x5F, 0x8B, 0x7B, 0xA7, 0x39, 0xEA, 0xBC, 0x60, 0x0F, 0x74, 0xE6 }, // 15.0.0 New Device Key Source. { 0x5E, 0xC9, 0xC5, 0x0A, 0xD0, 0x5F, 0x8B, 0x7B, 0xA7, 0x39, 0xEA, 0xBC, 0x60, 0x0F, 0x74, 0xE6 }, // 15.0.0 New Device Key Source.
{ 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C }, // 16.0.0 New Device Key Source. { 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. { 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.
}; };
//!TODO: Update on mkey changes. //!TODO: Update on mkey changes.
@ -158,6 +161,7 @@ static const u8 new_console_kekseed[HOS_KB_VERSION_MAX - HOS_KB_VERSION_400 + 1]
{ 0x7C, 0x30, 0xED, 0x8B, 0x39, 0x25, 0x2C, 0x08, 0x8F, 0x48, 0xDC, 0x28, 0xE6, 0x1A, 0x6B, 0x49 }, // 15.0.0 New Device Keygen Source. { 0x7C, 0x30, 0xED, 0x8B, 0x39, 0x25, 0x2C, 0x08, 0x8F, 0x48, 0xDC, 0x28, 0xE6, 0x1A, 0x6B, 0x49 }, // 15.0.0 New Device Keygen Source.
{ 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F }, // 16.0.0 New Device Keygen Source. { 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. { 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.
}; };
static const u8 gen_keyseed[SE_KEY_128_SIZE] = static const u8 gen_keyseed[SE_KEY_128_SIZE] =
@ -210,7 +214,7 @@ static void _hos_eks_get()
if (!h_cfg.eks) if (!h_cfg.eks)
{ {
// Read EKS blob. // Read EKS blob.
u8 *mbr = calloc(512 , 1); u8 *mbr = zalloc(SD_BLOCKSIZE);
if (!hos_eks_rw_try(mbr, false)) if (!hos_eks_rw_try(mbr, false))
goto out; goto out;
@ -240,7 +244,7 @@ static void _hos_eks_save()
bool new_eks = false; bool new_eks = false;
if (!h_cfg.eks) if (!h_cfg.eks)
{ {
h_cfg.eks = calloc(512 , 1); h_cfg.eks = zalloc(SD_BLOCKSIZE);
new_eks = true; new_eks = true;
} }
@ -248,7 +252,7 @@ static void _hos_eks_save()
if (h_cfg.eks->enabled != HOS_EKS_TSEC_VER) if (h_cfg.eks->enabled != HOS_EKS_TSEC_VER)
{ {
// Read EKS blob. // Read EKS blob.
u8 *mbr = calloc(512 , 1); u8 *mbr = zalloc(SD_BLOCKSIZE);
if (!hos_eks_rw_try(mbr, false)) if (!hos_eks_rw_try(mbr, false))
{ {
if (new_eks) if (new_eks)
@ -261,7 +265,7 @@ static void _hos_eks_save()
} }
// Get keys. // Get keys.
u8 *keys = (u8 *)calloc(SZ_4K, 2); u8 *keys = (u8 *)calloc(2, SZ_4K);
se_get_aes_keys(keys + SZ_4K, keys, SE_KEY_128_SIZE); se_get_aes_keys(keys + SZ_4K, keys, SE_KEY_128_SIZE);
// Set magic and personalized info. // Set magic and personalized info.
@ -275,7 +279,7 @@ static void _hos_eks_save()
memcpy(h_cfg.eks->troot_dev, keys + 11 * SE_KEY_128_SIZE, SE_KEY_128_SIZE); memcpy(h_cfg.eks->troot_dev, keys + 11 * SE_KEY_128_SIZE, SE_KEY_128_SIZE);
// Encrypt EKS blob. // Encrypt EKS blob.
u8 *eks = calloc(512 , 1); u8 *eks = zalloc(SD_BLOCKSIZE);
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t)); memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t)); se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
@ -302,7 +306,7 @@ void hos_eks_clear(u32 kb)
if (h_cfg.eks->enabled) if (h_cfg.eks->enabled)
{ {
// Read EKS blob. // Read EKS blob.
u8 *mbr = calloc(512 , 1); u8 *mbr = zalloc(SD_BLOCKSIZE);
if (!hos_eks_rw_try(mbr, false)) if (!hos_eks_rw_try(mbr, false))
goto out; goto out;
@ -310,7 +314,7 @@ void hos_eks_clear(u32 kb)
h_cfg.eks->enabled = 0; h_cfg.eks->enabled = 0;
// Encrypt EKS blob. // Encrypt EKS blob.
u8 *eks = calloc(512 , 1); u8 *eks = zalloc(SD_BLOCKSIZE);
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t)); memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t)); se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
@ -373,7 +377,7 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
tsec_ctxt->type = TSEC_FW_TYPE_EMU; tsec_ctxt->type = TSEC_FW_TYPE_EMU;
// Prepare smmu tsec page for 6.2.0. // Prepare smmu tsec page for 6.2.0.
u8 *tsec_paged = (u8 *)page_alloc(3); u8 *tsec_paged = (u8 *)smmu_page_zalloc(3);
memcpy(tsec_paged, (void *)tsec_ctxt->fw, tsec_ctxt->size); memcpy(tsec_paged, (void *)tsec_ctxt->fw, tsec_ctxt->size);
tsec_ctxt->fw = tsec_paged; tsec_ctxt->fw = tsec_paged;
} }

View file

@ -44,7 +44,8 @@ enum {
HOS_KB_VERSION_1500 = 14, HOS_KB_VERSION_1500 = 14,
HOS_KB_VERSION_1600 = 15, HOS_KB_VERSION_1600 = 15,
HOS_KB_VERSION_1700 = 16, HOS_KB_VERSION_1700 = 16,
HOS_KB_VERSION_MAX = HOS_KB_VERSION_1700 HOS_KB_VERSION_1800 = 17,
HOS_KB_VERSION_MAX = HOS_KB_VERSION_1800
}; };
#define HOS_TSEC_VERSION 4 //! TODO: Update on TSEC Root Key changes. #define HOS_TSEC_VERSION 4 //! TODO: Update on TSEC Root Key changes.

View file

@ -65,7 +65,8 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20220209", 13, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 14.0.0 - 14.1.2. { "20220209", 13, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 14.0.0 - 14.1.2.
{ "20220801", 14, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 15.0.0 - 15.0.1. { "20220801", 14, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 15.0.0 - 15.0.1.
{ "20230111", 15, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 16.0.0 - 16.1.0. { "20230111", 15, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 16.0.0 - 16.1.0.
{ "20230906", 16, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 17.0.0+ { "20230906", 16, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 17.0.0 - 17.0.1.
{ "20240207", 17, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 18.0.0+
}; };
const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date) const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date)

View file

@ -111,6 +111,8 @@ static const u8 mkey_vector_7xx[HOS_KB_VERSION_MAX - HOS_KB_VERSION_810 + 1][SE_
{ 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 }, { 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 },
// Master key 15 encrypted with 16. (16.0.0 with 17.0.0) // Master key 15 encrypted with 16. (16.0.0 with 17.0.0)
{ 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD }, { 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 },
}; };
static bool _pkg2_key_unwrap_validate(pkg2_hdr_t *tmp_test, pkg2_hdr_t *hdr, u8 src_slot, u8 *mkey, const u8 *key_seed) static bool _pkg2_key_unwrap_validate(pkg2_hdr_t *tmp_test, pkg2_hdr_t *hdr, u8 src_slot, u8 *mkey, const u8 *key_seed)

View file

@ -269,7 +269,11 @@ skip_main_cfg_parse:
else if (!strcmp("entries5col", kv->key)) else if (!strcmp("entries5col", kv->key))
n_cfg.entries_5_col = atoi(kv->val) == 1; n_cfg.entries_5_col = atoi(kv->val) == 1;
else if (!strcmp("timeoff", kv->key)) else if (!strcmp("timeoff", kv->key))
{
n_cfg.timeoff = strtol(kv->val, NULL, 16); n_cfg.timeoff = strtol(kv->val, NULL, 16);
if (n_cfg.timeoff != 1)
max77620_rtc_set_epoch_offset((int)n_cfg.timeoff);
}
else if (!strcmp("homescreen", kv->key)) else if (!strcmp("homescreen", kv->key))
n_cfg.home_screen = atoi(kv->val); n_cfg.home_screen = atoi(kv->val);
else if (!strcmp("verification", kv->key)) else if (!strcmp("verification", kv->key))

View file

@ -21,132 +21,3 @@
.nosigchk=0:0x194A0:0x4:BA090094,E0031F2A .nosigchk=0:0x194A0:0x4:BA090094,E0031F2A
.nosigchk=0:0x3A79C:0x4:E0060036,1F2003D5 .nosigchk=0:0x3A79C:0x4:E0060036,1F2003D5
#FS Patches for 2.0.0
[FS:cd7bbe18d6130b28]
.nosigchk=0:0x15DF4:0x4:BC0A0094,E0031F2A
.nosigchk=0:0x3F720:0x4:00060036,1F2003D5
#FS Patches for 2.0.0 exfat
[FS:e76692dfaa0420e9]
.nosigchk=0:0x15DF4:0x4:BC0A0094,E0031F2A
.nosigchk=0:0x3F720:0x4:00060036,1F2003D5
#FS Patches for 2.1.0
[FS:0d7005627b07767c]
.nosigchk=0:0x15F64:0x4:DF0A0094,E0031F2A
.nosigchk=0:0x3FAF8:0x4:00060036,1F2003D5
#FS Patches for 2.1.0 exfat
[FS:dbd85fcacc193da8]
.nosigchk=0:0x15F64:0x4:DF0A0094,E0031F2A
.nosigchk=0:0x3FAF8:0x4:00060036,1F2003D5
#FS Patches for 3.0.0
[FS:a86da5e87ef1097b]
.nosigchk=0:0x18E24:0x4:520C0094,E0031F2A
.nosigchk=0:0x49EC8:0x4:40040036,1F2003D5
#FS Patches for 3.0.0 exfat
[FS:981c57e7f02f70f7]
.nosigchk=0:0x18E24:0x4:520C0094,E0031F2A
.nosigchk=0:0x49EC8:0x4:40040036,1F2003D5
#FS Patches for 3.0.1
[FS:57397c063f10b631]
.nosigchk=0:0x18E90:0x4:520C0094,E0031F2A
.nosigchk=0:0x49F34:0x4:E0030036,1F2003D5
#FS Patches for 3.0.1 exfat
[FS:073099d7c6ad7d89]
.nosigchk=0:0x18E90:0x4:520C0094,E0031F2A
.nosigchk=0:0x49F34:0x4:E0030036,1F2003D5
#FS Patches for 4.0.0
[FS:06e90719595a010c]
.nosigchk=0:0x1C4FC:0x4:3C2F0094,E0031F2A
.nosigchk=0:0x57934:0x4:E0020036,1F2003D5
#FS Patches for 4.0.0 exfat
[FS:549b0f8d6f72c4e9]
.nosigchk=0:0x1C4FC:0x4:3C2F0094,E0031F2A
.nosigchk=0:0x57934:0x4:E0020036,1F2003D5
#FS Patches for 4.1.0
[FS:8096af7c6a35aa82]
.nosigchk=0:0x1C4FC:0x4:3C2F0094,E0031F2A
.nosigchk=0:0x57934:0x4:E0020036,1F2003D5
#FS Patches for 4.1.0 exfat
[FS:02d5abaafd20c8b0]
.nosigchk=0:0x1C4FC:0x4:3C2F0094,E0031F2A
.nosigchk=0:0x57934:0x4:E0020036,1F2003D5
#FS Patches for 5.0.0
[FS:a6f27ad9ac7c73ad]
.nosigchk=0:0x22DDC:0x4:7D3E0094,E0031F2A
.nosigchk=0:0x7D490:0x4:40030036,1F2003D5
#FS Patches for 5.0.0 exfat
[FS:ce3ecba2f2f062f5]
.nosigchk=0:0x22DDC:0x4:7D3E0094,E0031F2A
.nosigchk=0:0x7D490:0x4:40030036,1F2003D5
#FS Patches for 5.1.0
[FS:76f87402c9387c0f]
.nosigchk=0:0x22E0C:0x4:853E0094,E0031F2A
.nosigchk=0:0x7D860:0x4:40030036,1F2003D5
#FS Patches for 5.1.0 exfat
[FS:10b2d81605488599]
.nosigchk=0:0x22E0C:0x4:853E0094,E0031F2A
.nosigchk=0:0x7D860:0x4:40030036,1F2003D5
#FS Patches for 6.0.0 - 4
[FS:1b82cb221867cb52]
.nosigchk=0:0x712A8:0x4:8E3E0094,E0031F2A
.nosigchk=0:0xEB08C:0x4:C0030036,1F2003D5
#FS Patches for 6.0.0 - 4 exfat
[FS:966add3d20b62713]
.nosigchk=0:0x7C9A8:0x4:8E3E0094,E0031F2A
.nosigchk=0:0xF678C:0x4:C0030036,1F2003D5
#FS Patches for 6.0.0 - 5
[FS:3a574d436186191d]
.nosigchk=0:0x712A8:0x4:8E3E0094,E0031F2A
.nosigchk=0:0xEB08C:0x4:C0030036,1F2003D5
#FS Patches for 6.0.0 - 5 exfat
[FS:330553f6b5fb55c4]
.nosigchk=0:0x7C9A8:0x4:8E3E0094,E0031F2A
.nosigchk=0:0xF678C:0x4:C0030036,1F2003D5
#FS Patches for 7.0.0
[FS:2ADBE97E9B5F4177]
.nosigchk=0:0x74A2C:0x4:31430094,E0031F2A
.nosigchk=0:0xF25E4:0x4:C0030036,1F2003D5
#FS Patches for 7.0.0 exfat
[FS:2CCE659CEC536A8E]
.nosigchk=0:0x7FFDC:0x4:31430094,E0031F2A
.nosigchk=0:0xFDB94:0x4:C0030036,1F2003D5
#FS Patches for 8.0.0
[FS:B2F5176B3548364D]
.nosigchk=0:0x7630C:0x4:51440094,E0031F2A
.nosigchk=0:0xF49A4:0x4:C0030036,1F2003D5
#FS Patches for 8.0.0 exfat
[FS:DBD941C0C53C52CC]
.nosigchk=0:0x818BC:0x4:51440094,E0031F2A
.nosigchk=0:0xFFF54:0x4:C0030036,1F2003D5
#FS Patches for 8.1.0
[FS:6B09B67B29C02024]
.nosigchk=0:0x7630C:0x4:51440094,E0031F2A
.nosigchk=0:0xF49A4:0x4:C0030036,1F2003D5
#FS Patches for 8.1.0 exfat
[FS:B4CAE1F24965D92E]
.nosigchk=0:0x818BC:0x4:51440094,E0031F2A
.nosigchk=0:0xFFF54:0x4:C0030036,1F2003D5