mirror of
https://github.com/CTCaer/hekate
synced 2025-01-25 01:14:16 +00:00
Compare commits
36 commits
29d1e4a809
...
9e1b2ee573
Author | SHA1 | Date | |
---|---|---|---|
|
9e1b2ee573 | ||
|
9cfe1d2162 | ||
|
cfbbafe72f | ||
|
5607fd18ea | ||
|
d71903abf2 | ||
|
547cfca0c9 | ||
|
dca350bfe9 | ||
|
06b7a38d47 | ||
|
9567ba19c8 | ||
|
c9ff5179f9 | ||
|
f764bf04b1 | ||
|
8b1486c74b | ||
|
471b99366d | ||
|
368ca21316 | ||
|
c021aef9b0 | ||
|
622f7124ac | ||
|
e846f4576e | ||
|
42c02e97e8 | ||
|
4b3014bc18 | ||
|
4effaab241 | ||
|
d687b53249 | ||
|
9e41aa7759 | ||
|
0100c11757 | ||
|
9ba7c44b89 | ||
|
cdf0f30b17 | ||
|
9a520d63a6 | ||
|
20e661fc01 | ||
|
e341cf39f2 | ||
|
3a4fa12f42 | ||
|
fb31cb2926 | ||
|
82925845e3 | ||
|
f126486266 | ||
|
25b7ffecd1 | ||
|
7d1600b85c | ||
|
b1e6661a7a | ||
|
83ac40c4b9 |
63 changed files with 1127 additions and 1083 deletions
|
@ -1,11 +1,11 @@
|
|||
# IPL Version.
|
||||
BLVERSION_MAJOR := 6
|
||||
BLVERSION_MINOR := 1
|
||||
BLVERSION_HOTFX := 0
|
||||
BLVERSION_HOTFX := 1
|
||||
BLVERSION_RSVD := 0
|
||||
|
||||
# Nyx Version.
|
||||
NYXVERSION_MAJOR := 1
|
||||
NYXVERSION_MINOR := 6
|
||||
NYXVERSION_HOTFX := 0
|
||||
NYXVERSION_HOTFX := 1
|
||||
NYXVERSION_RSVD := 0
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* 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_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_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.
|
||||
PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||
|
|
|
@ -789,10 +789,12 @@ enum
|
|||
PANEL_SHP_LQ055T1SW10 = 0x1040,
|
||||
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.
|
||||
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.
|
||||
PANEL_OEM_CLONE = 0
|
||||
PANEL_OEM_CLONE = 0x0000
|
||||
};
|
||||
|
||||
void display_init();
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
**************************************/
|
||||
#include <mem/heap.h> /* malloc, calloc, free */
|
||||
#define ALLOC(s) malloc(s)
|
||||
#define ALLOC_AND_ZERO(s) calloc(1,s)
|
||||
#define ALLOC_AND_ZERO(s) zalloc(s)
|
||||
#define FREEMEM free
|
||||
#include <string.h> /* memset, memcpy */
|
||||
#define MEM_INIT memset
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
/*------------------------------------------------------------------------*/
|
||||
/* Sample Code of OS Dependent Functions for FatFs */
|
||||
/* (C) ChaN, 2018 */
|
||||
/* (C) CTCaer, 2018 */
|
||||
/* (C) ChaN, 2018 */
|
||||
/* (C) CTCaer, 2018-2024 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include <bdk.h>
|
||||
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include "../../config.h"
|
||||
|
||||
extern nyx_config n_cfg;
|
||||
|
||||
#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 */
|
||||
)
|
||||
{
|
||||
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;
|
||||
|
||||
max77620_rtc_get_time(&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);
|
||||
}
|
||||
max77620_rtc_get_time_adjusted(&time);
|
||||
|
||||
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));
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -159,6 +159,13 @@ void *calloc(u32 num, u32 size)
|
|||
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)
|
||||
{
|
||||
if (buf >= _heap.start)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* 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 *malloc(u32 size);
|
||||
void *calloc(u32 num, u32 size);
|
||||
void *zalloc(u32 size);
|
||||
void free(void *buf);
|
||||
void heap_monitor(heap_monitor_t *mon, bool print_node_stats);
|
||||
|
||||
|
|
|
@ -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
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
|
@ -14,6 +15,22 @@
|
|||
#ifndef _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_INTMASK 0x4
|
||||
#define MC_ERR_STATUS 0x8
|
||||
|
@ -464,7 +481,7 @@
|
|||
#define MC_UNTRANSLATED_REGION_CHECK 0x948
|
||||
#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_DISPLAY0A BIT(1)
|
||||
#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_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_VDEMBE BIT(3)
|
||||
#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_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_VDETPM BIT(1)
|
||||
#define SEC_CARVEOUT_CA2_R_ISPRA BIT(4)
|
||||
|
@ -524,7 +541,7 @@
|
|||
#define SEC_CARVEOUT_CA2_W_GPU BIT(25)
|
||||
#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_SDMMCAA BIT(1)
|
||||
#define SEC_CARVEOUT_CA3_R_SDMMC BIT(2)
|
||||
|
@ -544,7 +561,7 @@
|
|||
#define SEC_CARVEOUT_CA3_R_NVJPG BIT(30)
|
||||
#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_W_SE BIT(1)
|
||||
#define SEC_CARVEOUT_CA4_R_AXIAP BIT(2)
|
||||
|
|
|
@ -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
|
||||
* 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)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -206,6 +206,23 @@ void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
|
|||
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.
|
||||
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;
|
||||
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.
|
||||
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.
|
||||
// Skip already trained frequencies and OC freq (Arachne handles it).
|
||||
if (mtc_cfg->mtc_table[i].trained || mtc_cfg->rate_to == oc_freq)
|
||||
continue;
|
||||
|
||||
// Train frequency.
|
||||
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
}
|
||||
|
||||
// Do FSP WAR and scale to 800 MHz as boot freq.
|
||||
bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0);
|
||||
if (fsp_opwr_disabled)
|
||||
minerva_change_freq(FREQ_666);
|
||||
minerva_change_freq(FREQ_1333);
|
||||
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.
|
||||
mtc_cfg->init_done = 0;
|
||||
}
|
||||
|
|
|
@ -53,8 +53,9 @@ enum train_mode_t
|
|||
typedef enum
|
||||
{
|
||||
FREQ_204 = 204000,
|
||||
FREQ_666 = 665600,
|
||||
FREQ_408 = 408000,
|
||||
FREQ_800 = 800000,
|
||||
FREQ_1333 = 1331200,
|
||||
FREQ_1600 = 1600000
|
||||
} minerva_freq_t;
|
||||
|
||||
|
|
230
bdk/mem/smmu.c
230
bdk/mem/smmu.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* 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
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,156 +18,228 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/ccplex.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <mem/mc_t210.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <utils/aarch64_util.h>
|
||||
#include <memory_map.h>
|
||||
|
||||
bool smmu_used = false;
|
||||
u8 *_pageheap = (u8 *)SMMU_HEAP_ADDR;
|
||||
/*! SMMU register defines */
|
||||
#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;
|
||||
u8 smmu_payload[] __attribute__((aligned(16))) = {
|
||||
0x41, 0x01, 0x00, 0x58, // 0x00: LDR X1, =0x70019010
|
||||
/*! Page table defines */
|
||||
#define SMMU_4MB_REGION 0
|
||||
#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, 0x00, 0xB9, // 0x08: STR W0, [X1]
|
||||
0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC IALLUIS
|
||||
0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB ISH
|
||||
0xFE, 0xFF, 0xFF, 0x17, // 0x14: B loop
|
||||
0x00, 0x00, 0x80, 0xD2, // 0x18: MOV X0, #0x0
|
||||
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:
|
||||
0x10, 0x90, 0x01, 0x70, // 0x18: MC_SMMU_CONFIG
|
||||
};
|
||||
|
||||
void *page_alloc(u32 num)
|
||||
void *smmu_page_zalloc(u32 num)
|
||||
{
|
||||
u8 *res = _pageheap;
|
||||
_pageheap += SZ_PAGE * num;
|
||||
memset(res, 0, SZ_PAGE * num);
|
||||
return res;
|
||||
void *page = smmu_heap;
|
||||
memset(page, 0, SZ_PAGE * num);
|
||||
|
||||
smmu_heap += SZ_PAGE * num;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
u32 *smmu_alloc_pdir()
|
||||
static pde_t *_smmu_pdir_alloc()
|
||||
{
|
||||
u32 *pdir = (u32 *)page_alloc(1);
|
||||
for (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
|
||||
pdir[pdn] = _PDE_VACANT(pdn);
|
||||
pde_t *pdir = (pde_t *)smmu_page_zalloc(1);
|
||||
|
||||
// Initialize pdes with no permissions.
|
||||
for (u32 pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
|
||||
pdir[pdn].huge.page = pdn;
|
||||
|
||||
return pdir;
|
||||
}
|
||||
|
||||
void smmu_flush_regs()
|
||||
static void _smmu_flush_regs()
|
||||
{
|
||||
(void)MC(MC_SMMU_PTB_DATA);
|
||||
}
|
||||
|
||||
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;
|
||||
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_DATA) = 0;
|
||||
MC(MC_SMMU_TLB_CONFIG) = 0x30000030;
|
||||
MC(MC_SMMU_PTC_CONFIG) = 0x28000F3F;
|
||||
MC(MC_SMMU_TLB_CONFIG) = SMMU_TLB_HIT_UNDER_MISS | SMMU_TLB_RR_ARBITRATION | SMMU_TLB_ACTIVE_LINES(48);
|
||||
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_TLB_FLUSH) = 0;
|
||||
|
||||
// Set the secmon address
|
||||
*(u32 *)(smmu_payload + 0x30) = secmon_base;
|
||||
}
|
||||
|
||||
void smmu_enable()
|
||||
{
|
||||
if (smmu_used)
|
||||
static bool enabled = false;
|
||||
|
||||
if (enabled)
|
||||
return;
|
||||
|
||||
ccplex_boot_cpu0((u32)smmu_payload);
|
||||
smmu_used = true;
|
||||
msleep(150);
|
||||
// Launch payload on CCPLEX in order to set SMMU enable bit.
|
||||
ccplex_boot_cpu0((u32)smmu_enable_payload, false);
|
||||
msleep(100);
|
||||
ccplex_powergate_cpu0();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
u32 *smmu_init_domain4(u32 dev_base, u32 asid)
|
||||
{
|
||||
u32 *pdir = smmu_alloc_pdir();
|
||||
void *ptb = _smmu_pdir_alloc();
|
||||
|
||||
MC(MC_SMMU_PTB_ASID) = asid;
|
||||
MC(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((u32)pdir, _PDIR_ATTR);
|
||||
smmu_flush_regs();
|
||||
MC(MC_SMMU_PTB_DATA) = SMMU_PTB((u32)ptb, SMMU_ATTR_ALL);
|
||||
_smmu_flush_regs();
|
||||
|
||||
MC(dev_base) = 0x80000000 | (asid << 24) | (asid << 16) | (asid << 8) | (asid);
|
||||
smmu_flush_regs();
|
||||
// Use the same macro for both quad and single domains. Reserved bits are not set anyway.
|
||||
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);
|
||||
u32 pdn = SMMU_ADDR_TO_PDN(iova);
|
||||
u32 *ptbl;
|
||||
MC(MC_SMMU_PTB_ASID) = asid;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
MC(dev_base) = 0;
|
||||
_smmu_flush_regs();
|
||||
}
|
||||
|
||||
if (pdir[pdn] != _PDE_VACANT(pdn))
|
||||
ptbl = (u32 *)((pdir[pdn] & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT);
|
||||
void smmu_domain_bypass(u32 dev_base, bool bypass)
|
||||
{
|
||||
if (bypass)
|
||||
{
|
||||
smmu_flush_all();
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
MC(dev_base) &= ~SMMU_ENABLE;
|
||||
}
|
||||
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);
|
||||
for (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE)
|
||||
ptbl[pn] = _PTE_VACANT(addr);
|
||||
pdir[pdn] = SMMU_MK_PDE((u32)ptbl, _PDE_ATTR | _PDE_NEXT);
|
||||
|
||||
// Initialize page table with no permissions.
|
||||
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();
|
||||
}
|
||||
|
||||
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 = SMMU_ADDR_TO_PFN(page) | attr;
|
||||
addr += SZ_PAGE;
|
||||
page += SZ_PAGE;
|
||||
pte_t *pte = _smmu_get_pte((pde_t *)ptb, iova);
|
||||
|
||||
pte->page = SMMU_ADDR_TO_PFN(iopa);
|
||||
pte->attr = attr;
|
||||
|
||||
iova += SZ_PAGE;
|
||||
iopa += SZ_PAGE;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
MC(MC_SMMU_PTB_ASID) = 1;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
MC(MC_SMMU_TSEC_ASID) = 0;
|
||||
smmu_flush_regs();
|
||||
}
|
||||
// Map 4MB regions to page directory entries. VA/PA should be aligned to 4MB.
|
||||
for (u32 i = 0; i < regions; i++)
|
||||
{
|
||||
u32 pdn = SMMU_ADDR_TO_PDN(iova);
|
||||
pdir[pdn].huge.page = SMMU_ADDR_TO_PDN(iopa);
|
||||
pdir[pdn].huge.next = SMMU_4MB_REGION;
|
||||
pdir[pdn].huge.attr = attr;
|
||||
|
||||
iova += SZ_4M;
|
||||
iopa += SZ_4M;
|
||||
}
|
||||
|
||||
smmu_flush_all();
|
||||
}
|
||||
|
|
110
bdk/mem/smmu.h
110
bdk/mem/smmu.h
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -14,70 +15,57 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.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_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 MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29
|
||||
#define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT 30
|
||||
#define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT 31
|
||||
#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))
|
||||
#define SMMU_NS BIT(0)
|
||||
#define SMMU_WRITE BIT(1)
|
||||
#define SMMU_READ BIT(2)
|
||||
#define SMMU_ATTR_ALL (SMMU_READ | SMMU_WRITE | SMMU_NS)
|
||||
|
||||
void *page_alloc(u32 num);
|
||||
u32 *smmu_alloc_pdir();
|
||||
void smmu_flush_regs();
|
||||
void smmu_flush_all();
|
||||
void smmu_init(u32 secmon_base);
|
||||
void smmu_enable();
|
||||
bool smmu_is_used();
|
||||
void smmu_exit();
|
||||
u32 *smmu_init_domain4(u32 dev_base, u32 asid);
|
||||
u32 *smmu_get_pte(u32 *pdir, u32 iova);
|
||||
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr);
|
||||
u32 *smmu_init_for_tsec();
|
||||
void smmu_deinit_for_tsec();
|
||||
typedef struct _pde_t {
|
||||
union {
|
||||
union {
|
||||
struct {
|
||||
u32 table:22;
|
||||
u32 rsvd:6;
|
||||
u32 next:1;
|
||||
u32 attr:3;
|
||||
} tbl;
|
||||
|
||||
struct {
|
||||
u32 rsvd_:10;
|
||||
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);
|
||||
|
|
|
@ -50,7 +50,9 @@
|
|||
/* Stack theoretical max: 33MB */
|
||||
#define IPL_STACK_TOP 0x83100000
|
||||
#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 --- */
|
||||
|
||||
// Virtual disk / Chainloader buffers.
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
|
||||
int epoch_offset = 0;
|
||||
|
||||
void max77620_rtc_prep_read()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
max77620_rtc_stop_alarm();
|
||||
|
|
|
@ -109,6 +109,8 @@ typedef struct _rtc_reboot_reason_t
|
|||
|
||||
void max77620_rtc_prep_read();
|
||||
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_epoch_to_date(u32 epoch, rtc_time_t *time);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* 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)
|
||||
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;
|
||||
|
||||
|
@ -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 res = 0;
|
||||
u8 *key = (u8 *)calloc(1, SE_KEY_128_SIZE);
|
||||
u8 *last_block = (u8 *)calloc(1, SE_AES_BLOCK_SIZE);
|
||||
u8 *key = (u8 *)zalloc(SE_KEY_128_SIZE);
|
||||
u8 *last_block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
|
||||
|
||||
se_aes_iv_clear(ks);
|
||||
se_aes_iv_updated_clear(ks);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* 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;
|
||||
u8 *fwbuf = NULL;
|
||||
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;
|
||||
void *ptb;
|
||||
|
||||
bpmp_mmu_disable();
|
||||
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)
|
||||
{
|
||||
// Init SMMU translation for TSEC.
|
||||
pdir = smmu_init_for_tsec();
|
||||
smmu_init(tsec_ctxt->secmon_base);
|
||||
// Enable SMMU
|
||||
if (!smmu_is_used())
|
||||
smmu_enable();
|
||||
ptb = smmu_init_domain(MC_SMMU_TSEC_ASID, 1);
|
||||
smmu_init();
|
||||
|
||||
// Enable SMMU.
|
||||
smmu_enable();
|
||||
|
||||
// Clock reset controller.
|
||||
car = page_alloc(1);
|
||||
car = smmu_page_zalloc(1);
|
||||
memcpy(car, (void *)CLOCK_BASE, SZ_PAGE);
|
||||
car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = 2;
|
||||
smmu_map(pdir, CLOCK_BASE, (u32)car, 1, _WRITABLE | _READABLE | _NONSECURE);
|
||||
car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = CLK_SRC_DIV(2);
|
||||
smmu_map(ptb, CLOCK_BASE, (u32)car, 1, SMMU_WRITE | SMMU_READ | SMMU_NS);
|
||||
|
||||
// Fuse driver.
|
||||
fuse = page_alloc(1);
|
||||
fuse = smmu_page_zalloc(1);
|
||||
memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K);
|
||||
fuse[0x82C / 4] = 0;
|
||||
fuse[0x9E0 / 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.
|
||||
pmc = page_alloc(1);
|
||||
smmu_map(pdir, RTC_BASE, (u32)pmc, 1, _READABLE | _NONSECURE);
|
||||
pmc = smmu_page_zalloc(1);
|
||||
smmu_map(ptb, RTC_BASE, (u32)pmc, 1, SMMU_READ | SMMU_NS);
|
||||
|
||||
// Flow control.
|
||||
flowctrl = page_alloc(1);
|
||||
smmu_map(pdir, FLOW_CTLR_BASE, (u32)flowctrl, 1, _WRITABLE | _NONSECURE);
|
||||
flowctrl = smmu_page_zalloc(1);
|
||||
smmu_map(ptb, FLOW_CTLR_BASE, (u32)flowctrl, 1, SMMU_WRITE | SMMU_NS);
|
||||
|
||||
// Security engine.
|
||||
se = page_alloc(1);
|
||||
se = smmu_page_zalloc(1);
|
||||
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.
|
||||
mc = page_alloc(1);
|
||||
mc = smmu_page_zalloc(1);
|
||||
memcpy(mc, (void *)MC_BASE, SZ_PAGE);
|
||||
mc[MC_IRAM_BOM / 4] = 0;
|
||||
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 = page_alloc(0x30);
|
||||
iram = smmu_page_zalloc(0x30);
|
||||
memcpy(iram, tsec_ctxt->pkg1, 0x30000);
|
||||
// PKG1.1 magic offset.
|
||||
pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / 4));
|
||||
smmu_map(pdir, 0x40010000, (u32)iram, 0x30, _READABLE | _WRITABLE | _NONSECURE);
|
||||
pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / sizeof(u32)));
|
||||
smmu_map(ptb, 0x40010000, (u32)iram, 0x30, SMMU_READ | SMMU_WRITE | SMMU_NS);
|
||||
|
||||
// Exception vectors
|
||||
evec = page_alloc(1);
|
||||
smmu_map(pdir, EXCP_VEC_BASE, (u32)evec, 1, _READABLE | _WRITABLE | _NONSECURE);
|
||||
evec = smmu_page_zalloc(1);
|
||||
smmu_map(ptb, EXCP_VEC_BASE, (u32)evec, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
|
||||
}
|
||||
|
||||
// Execute firmware.
|
||||
|
@ -229,7 +230,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||
if (kidx != 8)
|
||||
{
|
||||
res = -6;
|
||||
smmu_deinit_for_tsec();
|
||||
smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
|
||||
|
||||
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_ctxt->pkg1, iram, 0x30000);
|
||||
|
||||
smmu_deinit_for_tsec();
|
||||
smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
|
||||
|
||||
// for (int i = 0; i < kidx; i++)
|
||||
// gfx_printf("key %08X\n", key[i]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -35,7 +35,6 @@ typedef struct _tsec_ctxt_t
|
|||
u32 type;
|
||||
void *pkg1;
|
||||
u32 pkg11_off;
|
||||
u32 secmon_base;
|
||||
} tsec_ctxt_t;
|
||||
|
||||
int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt);
|
||||
|
|
|
@ -287,10 +287,10 @@ void bpmp_usleep(u32 us)
|
|||
// Each iteration takes 1us.
|
||||
while (us)
|
||||
{
|
||||
delay = (us > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : us;
|
||||
delay = (us > HALT_MAX_CNT) ? HALT_MAX_CNT : us;
|
||||
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.
|
||||
while (ms)
|
||||
{
|
||||
delay = (ms > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : ms;
|
||||
delay = (ms > HALT_MAX_CNT) ? HALT_MAX_CNT : ms;
|
||||
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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -27,7 +27,9 @@
|
|||
#include <power/max77812.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.
|
||||
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.
|
||||
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_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_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.
|
||||
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW;
|
||||
|
@ -62,12 +76,12 @@ void ccplex_boot_cpu0(u32 entry)
|
|||
clock_enable_pllx();
|
||||
|
||||
// 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);
|
||||
|
||||
// Configure initial CPU clock frequency and enable clock.
|
||||
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_enable_coresight();
|
||||
|
@ -90,12 +104,15 @@ void ccplex_boot_cpu0(u32 entry)
|
|||
EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;
|
||||
|
||||
// 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;
|
||||
|
||||
// Non-secure reset vector write disable.
|
||||
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
|
||||
(void)SB(SB_CSR);
|
||||
if (lock)
|
||||
{
|
||||
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
|
||||
(void)SB(SB_CSR);
|
||||
}
|
||||
|
||||
// Tighten up the security aperture.
|
||||
// MC(MC_TZ_SECURITY_CTRL) = 1;
|
||||
|
@ -103,8 +120,46 @@ void ccplex_boot_cpu0(u32 entry)
|
|||
// Clear MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
|
||||
// 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.
|
||||
// < 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();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <utils/types.h>
|
||||
|
||||
void ccplex_boot_cpu0(u32 entry);
|
||||
void ccplex_boot_cpu0(u32 entry, bool lock);
|
||||
void ccplex_powergate_cpu0();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* 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 */
|
||||
|
||||
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_UARTB, CLK_L_UARTB, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, 2 }
|
||||
{ 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, 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, 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, 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, CLK_SRC_DIV(2) }
|
||||
};
|
||||
|
||||
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
|
||||
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_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, 19 }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz
|
||||
{ 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, 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, 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, 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, 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, CLK_SRC_DIV(10.5) } //20.4MHz -> 100KHz
|
||||
};
|
||||
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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)
|
||||
|
@ -128,7 +128,7 @@ void clock_enable(const clk_rst_t *clk)
|
|||
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||
// Configure clock source if required.
|
||||
if (clk->source)
|
||||
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
|
||||
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29u);
|
||||
// Enable.
|
||||
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
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;
|
||||
|
||||
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)
|
||||
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
|
||||
{
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | 2;
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | CLK_SRC_DIV(2);
|
||||
|
||||
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.
|
||||
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.
|
||||
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:
|
||||
*pclock = 24728;
|
||||
divisor = 31; // 16.5 div.
|
||||
divisor = CLK_SRC_DIV(16.5);
|
||||
break;
|
||||
|
||||
case 26000:
|
||||
*pclock = 25500;
|
||||
divisor = 30; // 16 div.
|
||||
divisor = CLK_SRC_DIV(16);
|
||||
break;
|
||||
|
||||
case 50000:
|
||||
*pclock = 48000;
|
||||
divisor = 15; // 8.5 div.
|
||||
divisor = CLK_SRC_DIV(8.5);
|
||||
break;
|
||||
|
||||
case 52000:
|
||||
*pclock = 51000;
|
||||
divisor = 14; // 8 div.
|
||||
divisor = CLK_SRC_DIV(8);
|
||||
break;
|
||||
|
||||
case 82000:
|
||||
*pclock = 81600;
|
||||
divisor = 8; // 5 div.
|
||||
divisor = CLK_SRC_DIV(5);
|
||||
break;
|
||||
|
||||
case 100000:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
*pclock = 99840;
|
||||
divisor = 2; // 2 div.
|
||||
divisor = CLK_SRC_DIV(2);
|
||||
break;
|
||||
|
||||
case 164000:
|
||||
*pclock = 163200;
|
||||
divisor = 3; // 2.5 div.
|
||||
divisor = CLK_SRC_DIV(2.5);
|
||||
break;
|
||||
|
||||
case 200000:
|
||||
|
@ -762,14 +762,14 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
|||
break;
|
||||
}
|
||||
*pclock = 199680;
|
||||
divisor = 0; // 1 div.
|
||||
divisor = CLK_SRC_DIV(1);
|
||||
break;
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
case 400000:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT0;
|
||||
*pclock = 399360;
|
||||
divisor = 3; // 2.5 div
|
||||
divisor = CLK_SRC_DIV(2.5);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
@ -785,7 +785,7 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
|||
_clock_sdmmc_config_legacy_tm();
|
||||
|
||||
// Set SDMMC clock.
|
||||
u32 src_div = (source << 29) | divisor;
|
||||
u32 src_div = (source << 29u) | divisor;
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -198,6 +198,9 @@
|
|||
|
||||
#define UTMIPLL_LOCK BIT(31)
|
||||
|
||||
/*! Clock source */
|
||||
#define CLK_SRC_DIV(d) ((d) ? ((u32)(((d) - 1) * 2)) : 0)
|
||||
|
||||
/*! PTO_CLK_CNT */
|
||||
#define PTO_REF_CLK_WIN_CFG_MASK 0xF
|
||||
#define PTO_REF_CLK_WIN_CFG_16P 0xF
|
||||
|
|
|
@ -194,7 +194,7 @@ void irq_wait_event(u32 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.
|
||||
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_ack_source(irq);
|
||||
|
|
|
@ -308,29 +308,47 @@
|
|||
#define EMC_HEKA_UPD BIT(30)
|
||||
|
||||
/*! Flow controller registers. */
|
||||
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
|
||||
#define HALT_COP_GIC_IRQ BIT(9)
|
||||
#define HALT_COP_LIC_IRQ BIT(11)
|
||||
#define HALT_COP_SEC BIT(23)
|
||||
#define HALT_COP_MSEC BIT(24)
|
||||
#define HALT_COP_USEC BIT(25)
|
||||
#define HALT_COP_JTAG BIT(28)
|
||||
#define HALT_COP_WAIT_EVENT BIT(30)
|
||||
#define HALT_COP_STOP_UNTIL_IRQ BIT(31)
|
||||
#define HALT_COP_MAX_CNT 0xFF
|
||||
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
|
||||
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
|
||||
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
|
||||
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
|
||||
#define FLOW_CTLR_CPU0_CSR 0x8
|
||||
#define FLOW_CTLR_CPU1_CSR 0x18
|
||||
#define FLOW_CTLR_CPU2_CSR 0x20
|
||||
#define FLOW_CTLR_CPU3_CSR 0x28
|
||||
#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)
|
||||
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
|
||||
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
|
||||
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
|
||||
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
|
||||
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
|
||||
#define HALT_GIC_IRQ BIT(9)
|
||||
#define HALT_LIC_IRQ BIT(11)
|
||||
#define HALT_SEC BIT(23)
|
||||
#define HALT_MSEC BIT(24)
|
||||
#define HALT_USEC BIT(25)
|
||||
#define HALT_JTAG BIT(28)
|
||||
#define HALT_MODE_NONE (0 << 29u)
|
||||
#define HALT_MODE_RUN_AND_INT (1 << 29u)
|
||||
#define HALT_MODE_WAITEVENT (2 << 29u)
|
||||
#define HALT_MODE_WAITEVENT_AND_INT (3 << 29u)
|
||||
#define HALT_MODE_STOP_UNTIL_IRQ (4 << 29u)
|
||||
#define HALT_MODE_STOP_UNTIL_IRQ_AND_INT (5 << 29u)
|
||||
#define HALT_MODE_STOP_UNTIL_EVENT_AND_IRQ (6 << 29u)
|
||||
#define HALT_MAX_CNT 0xFF
|
||||
#define FLOW_CTLR_COP_CSR 0xC
|
||||
#define FLOW_CTLR_CPU0_CSR 0x8
|
||||
#define FLOW_CTLR_CPU1_CSR 0x18
|
||||
#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 */
|
||||
#define MSELECT_CONFIG 0x00
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* 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)
|
||||
{
|
||||
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
|
||||
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++)
|
||||
{
|
||||
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)
|
||||
continue;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#define GPT_FIRST_LBA 1
|
||||
#define GPT_NUM_BLOCKS 33
|
||||
#define EMMC_BLOCKSIZE 512
|
||||
#define EMMC_BLOCKSIZE SDMMC_DAT_BLOCKSIZE
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <storage/sdmmc_driver.h>
|
||||
#include <libs/fatfs/ff.h>
|
||||
|
||||
#define SD_BLOCKSIZE 512
|
||||
#define SD_BLOCKSIZE SDMMC_DAT_BLOCKSIZE
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -184,7 +184,7 @@ int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf)
|
|||
|
||||
reqbuf.buf = buf;
|
||||
reqbuf.num_sectors = 1;
|
||||
reqbuf.blksize = 512;
|
||||
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
|
||||
reqbuf.is_write = 0;
|
||||
reqbuf.is_multi_block = 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.num_sectors = num_sectors;
|
||||
reqbuf.blksize = 512;
|
||||
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
|
||||
reqbuf.is_write = is_write;
|
||||
reqbuf.is_multi_block = 1;
|
||||
reqbuf.is_auto_stop_trn = 1;
|
||||
|
@ -326,7 +326,7 @@ reinit_try:
|
|||
out:
|
||||
sct_off += blkcnt;
|
||||
sct_total -= blkcnt;
|
||||
bbuf += 512 * blkcnt;
|
||||
bbuf += SDMMC_DAT_BLOCKSIZE * blkcnt;
|
||||
}
|
||||
|
||||
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))
|
||||
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;
|
||||
|
||||
u8 *tmp_buf = (u8 *)SDMMC_UPPER_BUFFER;
|
||||
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 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))
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -519,7 +519,7 @@ int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf)
|
|||
|
||||
sdmmc_req_t reqbuf;
|
||||
reqbuf.buf = buf;
|
||||
reqbuf.blksize = 512;
|
||||
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
|
||||
reqbuf.num_sectors = 1;
|
||||
reqbuf.is_write = 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;
|
||||
DPRINTF("[MMC] card selected\n");
|
||||
|
||||
if (!_sdmmc_storage_set_blocklen(storage, 512))
|
||||
if (!_sdmmc_storage_set_blocklen(storage, EMMC_BLOCKSIZE))
|
||||
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.
|
||||
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;
|
||||
reqbuf.buf = buf;
|
||||
reqbuf.blksize = 64;
|
||||
reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
|
||||
reqbuf.num_sectors = 1;
|
||||
reqbuf.is_write = 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;
|
||||
reqbuf.buf = buf;
|
||||
reqbuf.blksize = 64;
|
||||
reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
|
||||
reqbuf.num_sectors = 1;
|
||||
reqbuf.is_write = 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;
|
||||
reqbuf.buf = buf;
|
||||
reqbuf.blksize = 64;
|
||||
reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
|
||||
reqbuf.num_sectors = 1;
|
||||
reqbuf.is_write = 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);
|
||||
|
||||
// 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 + 2] = buf[i + 1];
|
||||
|
@ -1596,7 +1596,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
|
|||
{
|
||||
case 0:
|
||||
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;
|
||||
|
||||
case 1:
|
||||
|
@ -1698,9 +1698,9 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
|
|||
return 0;
|
||||
DPRINTF("[SD] card selected\n");
|
||||
|
||||
if (!_sdmmc_storage_set_blocklen(storage, 512))
|
||||
if (!_sdmmc_storage_set_blocklen(storage, SD_BLOCKSIZE))
|
||||
return 0;
|
||||
DPRINTF("[SD] set blocklen to 512\n");
|
||||
DPRINTF("[SD] set blocklen to SD_BLOCKSIZE\n");
|
||||
|
||||
// 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))
|
||||
|
@ -1775,7 +1775,7 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
|
|||
|
||||
sdmmc_req_t reqbuf;
|
||||
reqbuf.buf = buf;
|
||||
reqbuf.blksize = 64;
|
||||
reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
|
||||
reqbuf.num_sectors = 1;
|
||||
reqbuf.is_write = 1;
|
||||
reqbuf.is_multi_block = 0;
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include <storage/sd_def.h>
|
||||
#include <storage/sdmmc_driver.h>
|
||||
|
||||
#define SDMMC_CMD_BLOCKSIZE 64
|
||||
#define SDMMC_DAT_BLOCKSIZE 512
|
||||
|
||||
extern u32 sd_power_cycle_time_start;
|
||||
|
||||
typedef enum _sdmmc_type
|
||||
|
|
|
@ -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
|
||||
* 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;
|
||||
FILINFO fno;
|
||||
|
||||
char *dir_entries = (char *)calloc(MAX_ENTRIES, 256);
|
||||
char *temp = (char *)calloc(1, 256);
|
||||
char *dir_entries = (char *)zalloc(MAX_ENTRIES * 256);
|
||||
char *temp = (char *)zalloc(256);
|
||||
|
||||
if (!pattern && !f_opendir(&dir, directory))
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.
|
||||
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->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.
|
||||
u32 klen = strlen(&lbuf[0]) + 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;
|
||||
buf += sizeof(ini_kv_t);
|
||||
|
|
|
@ -211,7 +211,7 @@ u32 crc32_calc(u32 crc, const u8 *buf, u32 len)
|
|||
// Calculate CRC table.
|
||||
if (!table)
|
||||
{
|
||||
table = calloc(256, sizeof(u32));
|
||||
table = zalloc(256 * sizeof(u32));
|
||||
for (u32 i = 0; i < 256; i++)
|
||||
{
|
||||
u32 rem = i;
|
||||
|
|
|
@ -145,7 +145,7 @@ void print_mmc_info()
|
|||
" Current Rate: %d MB/s\n"
|
||||
" 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.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);
|
||||
gfx_con.fntsz = 8;
|
||||
gfx_printf("%s", card_type_support);
|
||||
|
@ -156,13 +156,13 @@ void print_mmc_info()
|
|||
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(" 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_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_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_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);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 Reisyukaku
|
||||
*
|
||||
* 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 optimize ("Os")
|
||||
|
||||
void _toggle_autorcm(bool enable)
|
||||
static void _toggle_autorcm(bool enable)
|
||||
{
|
||||
gfx_clear_partial_grey(0x1B, 0, 1256);
|
||||
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;
|
||||
u8 corr_mod0, mod1;
|
||||
u8 *tempbuf = (u8 *)malloc(0x200);
|
||||
|
||||
// Get the correct RSA modulus byte masks.
|
||||
nx_emmc_get_autorcm_masks(&corr_mod0, &mod1);
|
||||
|
@ -70,7 +62,6 @@ void _toggle_autorcm(bool enable)
|
|||
}
|
||||
|
||||
free(tempbuf);
|
||||
emmc_end();
|
||||
|
||||
if (enable)
|
||||
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("\n\nPress any key...\n");
|
||||
|
||||
out:
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void _enable_autorcm() { _toggle_autorcm(true); }
|
||||
void _disable_autorcm() { _toggle_autorcm(false); }
|
||||
static void _enable_autorcm() { _toggle_autorcm(true); }
|
||||
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()
|
||||
{
|
||||
|
@ -98,9 +111,6 @@ void menu_autorcm()
|
|||
return;
|
||||
}
|
||||
|
||||
// Do a simple check on the main BCT.
|
||||
bool disabled = true;
|
||||
|
||||
if (!emmc_initialize(false))
|
||||
{
|
||||
EPRINTF("Failed to init eMMC.");
|
||||
|
@ -109,21 +119,8 @@ void menu_autorcm()
|
|||
return;
|
||||
}
|
||||
|
||||
u8 mod0, mod1;
|
||||
// Get the correct RSA modulus byte masks.
|
||||
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();
|
||||
// Do a simple check on the main BCT.
|
||||
bool enabled = tools_autorcm_enabled();
|
||||
|
||||
// Create AutoRCM menu.
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 6);
|
||||
|
@ -135,7 +132,7 @@ void menu_autorcm()
|
|||
|
||||
ments[2].type = MENT_CAPTION;
|
||||
ments[3].type = MENT_CHGLINE;
|
||||
if (disabled)
|
||||
if (!enabled)
|
||||
{
|
||||
ments[2].caption = "Status: Disabled!";
|
||||
ments[2].color = TXT_CLR_GREENISH;
|
||||
|
@ -156,6 +153,8 @@ void menu_autorcm()
|
|||
menu_t menu = {ments, "This corrupts BOOT0!", 0, 0};
|
||||
|
||||
tui_do_menu(&menu);
|
||||
|
||||
emmc_end();
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -19,5 +19,6 @@
|
|||
#define _FE_TOOLS_H_
|
||||
|
||||
void menu_autorcm();
|
||||
bool tools_autorcm_enabled();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -82,34 +82,13 @@ typedef struct _fss_content_t
|
|||
char name[0x10];
|
||||
} 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);
|
||||
u32 path_len = strlen(path);
|
||||
u8 *r2p_payload = sd_file_read("atmosphere/reboot_payload.bin", NULL);
|
||||
|
||||
strcpy(r2p_path, path);
|
||||
is_ipl_updated(r2p_payload, "atmosphere/reboot_payload.bin", h_cfg.updater2p ? true : false);
|
||||
|
||||
while (path_len)
|
||||
{
|
||||
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);
|
||||
free(r2p_payload);
|
||||
}
|
||||
|
||||
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");
|
||||
f_close(&fp);
|
||||
|
||||
// Set FSS0 path and update r2p if needed.
|
||||
_set_fss_path_and_update_r2p(ctxt, path);
|
||||
ctxt->fss0 = fss;
|
||||
|
||||
// Update r2p if needed.
|
||||
_fss_update_r2p();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018 Ced2911
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -25,6 +25,7 @@
|
|||
#include "hos.h"
|
||||
#include "hos_config.h"
|
||||
#include "secmon_exo.h"
|
||||
#include "../frontend/fe_tools.h"
|
||||
#include "../config.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.
|
||||
{ 0x99, 0x22, 0x09, 0x57, 0xA7, 0xF9, 0x5E, 0x94, 0xFE, 0x78, 0x7F, 0x41, 0xD6, 0xE7, 0x56, 0xE6 }, // 16.0.0.
|
||||
{ 0x71, 0xB9, 0xA6, 0xC0, 0xFF, 0x97, 0x6B, 0x0C, 0xB4, 0x40, 0xB9, 0xD5, 0x81, 0x5D, 0x81, 0x90 }, // 17.0.0.
|
||||
{ 0x00, 0x04, 0x5D, 0xF0, 0x4D, 0xCD, 0x14, 0xA3, 0x1C, 0xBF, 0xDE, 0x48, 0x55, 0xBA, 0x35, 0xC1 }, // 18.0.0.
|
||||
};
|
||||
|
||||
//!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.
|
||||
{ 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 }, // 16.0.0.
|
||||
{ 0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80 }, // 17.0.0.
|
||||
{ 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 }, // 18.0.0.
|
||||
};
|
||||
|
||||
static const u8 console_keyseed[SE_KEY_128_SIZE] =
|
||||
|
@ -218,7 +221,7 @@ static void _hos_eks_get()
|
|||
if (!h_cfg.eks)
|
||||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
u8 *mbr = zalloc(SD_BLOCKSIZE);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
goto out;
|
||||
|
||||
|
@ -248,7 +251,7 @@ static void _hos_eks_save()
|
|||
bool new_eks = false;
|
||||
if (!h_cfg.eks)
|
||||
{
|
||||
h_cfg.eks = calloc(512 , 1);
|
||||
h_cfg.eks = zalloc(SD_BLOCKSIZE);
|
||||
new_eks = true;
|
||||
}
|
||||
|
||||
|
@ -256,7 +259,7 @@ static void _hos_eks_save()
|
|||
if (h_cfg.eks->enabled != HOS_EKS_TSEC_VER)
|
||||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
u8 *mbr = zalloc(SD_BLOCKSIZE);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
{
|
||||
if (new_eks)
|
||||
|
@ -269,7 +272,7 @@ static void _hos_eks_save()
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = calloc(512 , 1);
|
||||
u8 *eks = zalloc(SD_BLOCKSIZE);
|
||||
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));
|
||||
|
||||
|
@ -310,7 +313,7 @@ void hos_eks_clear(u32 kb)
|
|||
if (h_cfg.eks->enabled)
|
||||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
u8 *mbr = zalloc(SD_BLOCKSIZE);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
goto out;
|
||||
|
||||
|
@ -318,7 +321,7 @@ void hos_eks_clear(u32 kb)
|
|||
h_cfg.eks->enabled = 0;
|
||||
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = calloc(512 , 1);
|
||||
u8 *eks = zalloc(SD_BLOCKSIZE);
|
||||
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));
|
||||
|
||||
|
@ -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;
|
||||
|
||||
// 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);
|
||||
tsec_ctxt->fw = tsec_paged;
|
||||
}
|
||||
|
@ -646,7 +649,7 @@ try_load:
|
|||
// Read the correct keyblob for older HOS versions.
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -694,12 +697,12 @@ out:
|
|||
|
||||
static void _free_launch_components(launch_ctxt_t *ctxt)
|
||||
{
|
||||
// Free the malloc'ed guaranteed addresses.
|
||||
free(ctxt->fss0);
|
||||
free(ctxt->keyblob);
|
||||
free(ctxt->pkg1);
|
||||
free(ctxt->pkg2);
|
||||
free(ctxt->warmboot);
|
||||
free(ctxt->secmon);
|
||||
free(ctxt->kernel);
|
||||
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)
|
||||
{
|
||||
if (strncmp((const char*)ki->kip1->name, "FS", sizeof(ki->kip1->name)))
|
||||
if (strcmp((char *)ki->kip1->name, "FS"))
|
||||
continue;
|
||||
|
||||
if (!se_calc_sha256_oneshot(sha_buf, ki->kip1, ki->size))
|
||||
|
@ -785,12 +788,6 @@ int hos_launch(ini_sec_t *cfg)
|
|||
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.
|
||||
if (ctxt.cfg && !parse_boot_config(&ctxt))
|
||||
{
|
||||
|
@ -798,6 +795,24 @@ int hos_launch(ini_sec_t *cfg)
|
|||
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;
|
||||
|
||||
// Enable emummc patching.
|
||||
|
@ -849,16 +864,18 @@ int hos_launch(ini_sec_t *cfg)
|
|||
// Check if secmon is exosphere.
|
||||
if (ctxt.secmon)
|
||||
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();
|
||||
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;
|
||||
|
||||
// Generate keys.
|
||||
tsec_ctxt.fw = (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off;
|
||||
tsec_ctxt.pkg1 = ctxt.pkg1;
|
||||
// Set package1 and tsec fw offsets.
|
||||
tsec_ctxt.fw = (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off;
|
||||
tsec_ctxt.pkg1 = ctxt.pkg1;
|
||||
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))
|
||||
goto error;
|
||||
gfx_puts("Generated keys\n");
|
||||
|
@ -903,7 +920,7 @@ int hos_launch(ini_sec_t *cfg)
|
|||
}
|
||||
else
|
||||
{
|
||||
_hos_crit_error("No mandatory secmon or warmboot provided!");
|
||||
_hos_crit_error("No mandatory pkg1 files provided!");
|
||||
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!");
|
||||
|
||||
_free_launch_components(&ctxt);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
// Patch kip1s in memory if needed.
|
||||
if (ctxt.kip1_patches)
|
||||
gfx_printf("%kPatching kips%k\n", TXT_CLR_ORANGE, TXT_CLR_DEFAULT);
|
||||
const char* unappliedPatch = pkg2_patch_kips(&kip1_info, ctxt.kip1_patches);
|
||||
if (unappliedPatch != NULL)
|
||||
const char *failed_patch = pkg2_patch_kips(&kip1_info, ctxt.kip1_patches);
|
||||
if (failed_patch != 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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
_free_launch_components(&ctxt);
|
||||
goto error; // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated!
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
_se_lock(kb <= HOS_KB_VERSION_600 && !is_exo);
|
||||
|
||||
// Reset sysctr0 counters.
|
||||
if (kb >= HOS_KB_VERSION_620)
|
||||
{
|
||||
for (u32 i = 0; i < SYSCTR0_COUNTERS; i += sizeof(u32))
|
||||
SYSCTR0(SYSCTR0_COUNTERS_BASE + i) = 0;
|
||||
}
|
||||
// Reset sysctr0 counters. Mandatory for 6.2.0 and up.
|
||||
for (u32 i = 0; i < SYSCTR0_COUNTERS; i++)
|
||||
SYSCTR0(SYSCTR0_COUNTERS_BASE + i * sizeof(u32)) = 0;
|
||||
|
||||
// NX Bootloader locks LP0 Carveout secure scratch registers.
|
||||
//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.
|
||||
secmon_mailbox->in = pkg1_state_pkg2_ready;
|
||||
secmon_mailbox->in = pkg1_state_pkg2_ready;
|
||||
secmon_mailbox->out = SECMON_STATE_NOT_READY;
|
||||
|
||||
// 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);
|
||||
|
||||
// Launch secmon.
|
||||
if (smmu_is_used())
|
||||
smmu_exit();
|
||||
else
|
||||
ccplex_boot_cpu0(secmon_base);
|
||||
ccplex_boot_cpu0(secmon_base, true);
|
||||
|
||||
// Halt ourselves in wait-event state.
|
||||
while (true)
|
||||
bpmp_halt();
|
||||
|
||||
error:
|
||||
_free_launch_components(&ctxt);
|
||||
emmc_end();
|
||||
|
||||
EPRINTF("\nFailed to launch HOS!");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -44,7 +44,8 @@ enum {
|
|||
HOS_KB_VERSION_1500 = 14,
|
||||
HOS_KB_VERSION_1600 = 15,
|
||||
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.
|
||||
|
@ -109,7 +110,7 @@ typedef struct _launch_ctxt_t
|
|||
bool stock;
|
||||
bool emummc_forced;
|
||||
|
||||
char *fss0_main_path;
|
||||
void *fss0;
|
||||
u32 fss0_hosver;
|
||||
bool atmosphere;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* 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)
|
||||
return 0;
|
||||
|
||||
int valueLen = strlen(value);
|
||||
if (!valueLen)
|
||||
int len = strlen(value);
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (ctxt->kip1_patches == NULL)
|
||||
{
|
||||
ctxt->kip1_patches = malloc(valueLen + 1);
|
||||
memcpy(ctxt->kip1_patches, value, valueLen);
|
||||
ctxt->kip1_patches[valueLen] = 0;
|
||||
ctxt->kip1_patches = malloc(len + 1);
|
||||
memcpy(ctxt->kip1_patches, value, len);
|
||||
ctxt->kip1_patches[len] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *oldAlloc = ctxt->kip1_patches;
|
||||
int oldSize = strlen(oldAlloc);
|
||||
ctxt->kip1_patches = malloc(oldSize + 1 + valueLen + 1);
|
||||
memcpy(ctxt->kip1_patches, oldAlloc, oldSize);
|
||||
free(oldAlloc);
|
||||
oldAlloc = NULL;
|
||||
ctxt->kip1_patches[oldSize++] = ',';
|
||||
memcpy(&ctxt->kip1_patches[oldSize], value, valueLen);
|
||||
ctxt->kip1_patches[oldSize + valueLen] = 0;
|
||||
char *old_addr = ctxt->kip1_patches;
|
||||
int old_len = strlen(old_addr);
|
||||
|
||||
ctxt->kip1_patches = malloc(old_len + 1 + len + 1);
|
||||
memcpy(ctxt->kip1_patches, old_addr, old_len);
|
||||
free(old_addr);
|
||||
|
||||
ctxt->kip1_patches[old_len++] = ',';
|
||||
memcpy(&ctxt->kip1_patches[old_len], value, len);
|
||||
ctxt->kip1_patches[old_len + len] = 0;
|
||||
}
|
||||
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)
|
||||
{
|
||||
// Override key found.
|
||||
ctxt->exo_ctx.usb3_force = calloc(sizeof(bool), 1);
|
||||
ctxt->exo_ctx.usb3_force = zalloc(sizeof(bool));
|
||||
|
||||
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)
|
||||
{
|
||||
// Override key found.
|
||||
ctxt->exo_ctx.cal0_blank = calloc(sizeof(bool), 1);
|
||||
ctxt->exo_ctx.cal0_blank = zalloc(sizeof(bool));
|
||||
|
||||
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)
|
||||
{
|
||||
// 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')
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
{ "20220801", 14, 17, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 15.0.0 - 15.0.1.
|
||||
{ "20230111", 15, 18, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 16.0.0 - 16.1.0.
|
||||
{ "20230906", 16, 19, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 17.0.0+
|
||||
{ "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()
|
||||
|
@ -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)
|
||||
{
|
||||
// Set warmboot binary rsa modulus.
|
||||
u8 *rsa_mod = (u8 *)malloc(512);
|
||||
u8 *rsa_mod = (u8 *)malloc(EMMC_BLOCKSIZE);
|
||||
|
||||
emmc_set_partition(EMMC_BOOT0);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* 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"))
|
||||
{
|
||||
// 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));
|
||||
|
||||
// Parse patchsets and glue them together.
|
||||
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;
|
||||
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.
|
||||
if (!curr_kip->name)
|
||||
if (!kip->name)
|
||||
break;
|
||||
|
||||
// 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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!curr_kip)
|
||||
if (!kip)
|
||||
continue;
|
||||
|
||||
// If not found, create a new empty entry.
|
||||
if (!found)
|
||||
{
|
||||
curr_kip->name = ini_psec->name;
|
||||
memcpy(curr_kip->hash, ini_psec->hash, 8);
|
||||
curr_kip->patchset = calloc(sizeof(kip1_patchset_t), 1);
|
||||
kip->name = ini_psec->name;
|
||||
memcpy(kip->hash, ini_psec->hash, 8);
|
||||
kip->patchset = zalloc(sizeof(kip1_patchset_t));
|
||||
|
||||
_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;
|
||||
for (curr_patchset_idx = 0; curr_kip->patchset[curr_patchset_idx].name != NULL; curr_patchset_idx++)
|
||||
u32 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[curr_patchset_idx].patches = curr_kip->patchset[curr_patchset_idx].patches;
|
||||
patchsets[patchset_idx].name = kip->patchset[patchset_idx].name;
|
||||
patchsets[patchset_idx].patches = kip->patchset[patchset_idx].patches;
|
||||
}
|
||||
|
||||
curr_kip->patchset = patchsets;
|
||||
kip->patchset = patchsets;
|
||||
bool first_ext_patch = true;
|
||||
u32 curr_patch_idx = 0;
|
||||
u32 patch_idx = 0;
|
||||
|
||||
// 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)
|
||||
{
|
||||
if (first_ext_patch)
|
||||
{
|
||||
first_ext_patch = false;
|
||||
patchsets[curr_patchset_idx].name = pt->name;
|
||||
patchsets[curr_patchset_idx].patches = patches;
|
||||
patchsets[patchset_idx].name = pt->name;
|
||||
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.
|
||||
curr_patchset_idx++;
|
||||
curr_patch_idx = 0;
|
||||
patches = calloc(sizeof(kip1_patch_t), 32); // Max 32 patches per set.
|
||||
patchset_idx++;
|
||||
patch_idx = 0;
|
||||
patches = zalloc(sizeof(kip1_patch_t) * 32); // Max 32 patches per set.
|
||||
|
||||
patchsets[curr_patchset_idx].name = pt->name;
|
||||
patchsets[curr_patchset_idx].patches = patches;
|
||||
patchsets[patchset_idx].name = pt->name;
|
||||
patchsets[patchset_idx].patches = patches;
|
||||
}
|
||||
|
||||
if (pt->length)
|
||||
{
|
||||
patches[curr_patch_idx].offset = pt->offset;
|
||||
patches[curr_patch_idx].length = pt->length;
|
||||
patches[patch_idx].offset = pt->offset;
|
||||
patches[patch_idx].length = pt->length;
|
||||
|
||||
patches[curr_patch_idx].srcData = (char *)pt->srcData;
|
||||
patches[curr_patch_idx].dstData = (char *)pt->dstData;
|
||||
patches[patch_idx].src_data = (char *)pt->src_data;
|
||||
patches[patch_idx].dst_data = (char *)pt->dst_data;
|
||||
}
|
||||
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++;
|
||||
patchsets[curr_patchset_idx].name = NULL;
|
||||
patchsets[curr_patchset_idx].patches = NULL;
|
||||
patchset_idx++;
|
||||
patchsets[patchset_idx].name = 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);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
memcpy(&hdr, ki->kip1, sizeof(hdr));
|
||||
|
||||
unsigned int newKipSize = sizeof(hdr);
|
||||
for (u32 sectIdx = 0; sectIdx < KIP1_NUM_SECTIONS; sectIdx++)
|
||||
u32 new_kip_size = sizeof(hdr);
|
||||
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".
|
||||
if (sectIdx < 3 && (sectsToDecomp & sectCompBit) && (hdr.flags & sectCompBit))
|
||||
newKipSize += hdr.sections[sectIdx].size_decomp;
|
||||
if (sect_idx < 3 && (sectsToDecomp & comp_bit_mask) && (hdr.flags & comp_bit_mask))
|
||||
new_kip_size += hdr.sections[sect_idx].size_decomp;
|
||||
else
|
||||
newKipSize += hdr.sections[sectIdx].size_comp;
|
||||
new_kip_size += hdr.sections[sect_idx].size_comp;
|
||||
}
|
||||
|
||||
pkg2_kip1_t* newKip = malloc(newKipSize);
|
||||
unsigned char* dstDataPtr = newKip->data;
|
||||
const unsigned char* srcDataPtr = ki->kip1->data;
|
||||
for (u32 sectIdx = 0; sectIdx < KIP1_NUM_SECTIONS; sectIdx++)
|
||||
pkg2_kip1_t *new_kip = malloc(new_kip_size);
|
||||
u8 *dst_data = new_kip->data;
|
||||
const u8 *src_data = ki->kip1->data;
|
||||
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.
|
||||
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)
|
||||
continue;
|
||||
|
||||
memcpy(dstDataPtr, srcDataPtr, dataSize);
|
||||
srcDataPtr += dataSize;
|
||||
dstDataPtr += dataSize;
|
||||
memcpy(dst_data, src_data, dataSize);
|
||||
src_data += dataSize;
|
||||
dst_data += dataSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned int compSize = hdr.sections[sectIdx].size_comp;
|
||||
unsigned int outputSize = hdr.sections[sectIdx].size_decomp;
|
||||
gfx_printf("Decomping '%s', sect %d, size %d..\n", (const char*)hdr.name, sectIdx, compSize);
|
||||
if (blz_uncompress_srcdest(srcDataPtr, compSize, dstDataPtr, outputSize) == 0)
|
||||
u32 comp_size = hdr.sections[sect_idx].size_comp;
|
||||
u32 output_size = hdr.sections[sect_idx].size_decomp;
|
||||
gfx_printf("Decomping '%s', sect %d, size %d..\n", (char *)hdr.name, sect_idx, comp_size);
|
||||
if (blz_uncompress_srcdest(src_data, comp_size, dst_data, output_size) == 0)
|
||||
{
|
||||
gfx_con.mute = false;
|
||||
gfx_printf("%kERROR decomping sect %d of '%s'!%k\n", TXT_CLR_ERROR, sectIdx, (char*)hdr.name, TXT_CLR_DEFAULT);
|
||||
free(newKip);
|
||||
gfx_printf("%kERROR decomping sect %d of '%s'!%k\n", TXT_CLR_ERROR, sect_idx, (char *)hdr.name, TXT_CLR_DEFAULT);
|
||||
free(new_kip);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF("Done! Decompressed size is %d!\n", outputSize);
|
||||
DPRINTF("Done! Decompressed size is %d!\n", output_size);
|
||||
}
|
||||
hdr.sections[sectIdx].size_comp = outputSize;
|
||||
srcDataPtr += compSize;
|
||||
dstDataPtr += outputSize;
|
||||
hdr.sections[sect_idx].size_comp = output_size;
|
||||
src_data += comp_size;
|
||||
dst_data += output_size;
|
||||
}
|
||||
|
||||
hdr.flags &= compClearMask;
|
||||
memcpy(newKip, &hdr, sizeof(hdr));
|
||||
newKipSize = dstDataPtr-(unsigned char*)(newKip);
|
||||
memcpy(new_kip, &hdr, sizeof(hdr));
|
||||
new_kip_size = dst_data - (u8 *)(new_kip);
|
||||
|
||||
free(ki->kip1);
|
||||
ki->kip1 = newKip;
|
||||
ki->size = newKipSize;
|
||||
ki->kip1 = new_kip;
|
||||
ki->size = new_kip_size;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
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);
|
||||
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.
|
||||
{
|
||||
if (currSectIdx < 3)
|
||||
memcpy(ki->kip1->data + new_offset + inject_size, fs_kip->data + new_offset, fs_kip->sections[currSectIdx].size_comp);
|
||||
ki->kip1->sections[currSectIdx].offset += inject_size;
|
||||
if (section_idx < 3)
|
||||
memcpy(ki->kip1->data + new_offset + inject_size, fs_kip->data + new_offset, fs_kip->sections[section_idx].size_comp);
|
||||
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.
|
||||
|
@ -440,24 +440,28 @@ static int _kipm_inject(const char *kipm_path, char *target_name, pkg2_kip1_info
|
|||
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;
|
||||
|
||||
static const u32 MAX_NUM_PATCHES_REQUESTED = sizeof(u32) * 8;
|
||||
char* patches[MAX_NUM_PATCHES_REQUESTED];
|
||||
gfx_printf("%kPatching kips%k\n", TXT_CLR_ORANGE, TXT_CLR_DEFAULT);
|
||||
|
||||
u32 numPatches = 1;
|
||||
patches[0] = patchNames;
|
||||
static const u32 MAX_NUM_PATCHES_REQUESTED = sizeof(u32) * 8;
|
||||
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 == ',')
|
||||
{
|
||||
*p = 0;
|
||||
patches[numPatches++] = p + 1;
|
||||
if (numPatches >= MAX_NUM_PATCHES_REQUESTED)
|
||||
patches[patches_num++] = p + 1;
|
||||
if (patches_num >= MAX_NUM_PATCHES_REQUESTED)
|
||||
return "too_many_patches";
|
||||
}
|
||||
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.
|
||||
for (u32 i = 0; i < numPatches; i++)
|
||||
u32 patches_applied = 0; // Bitset over patches.
|
||||
for (u32 i = 0; i < patches_num; i++)
|
||||
{
|
||||
// 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')
|
||||
patches[i]++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
int valueLen = strlen(patches[i]);
|
||||
if (valueLen == 0)
|
||||
|
||||
int patch_len = strlen(patches[i]);
|
||||
if (patch_len == 0)
|
||||
continue;
|
||||
|
||||
// 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')
|
||||
valueLen = chIdx;
|
||||
patch_len = chIdx;
|
||||
else
|
||||
break;
|
||||
}
|
||||
patches[i][valueLen] = 0;
|
||||
patches[i][patch_len] = 0;
|
||||
|
||||
DPRINTF("Requested patch: '%s'\n", patches[i]);
|
||||
}
|
||||
|
||||
// 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();
|
||||
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)
|
||||
{
|
||||
shaBuf[0] = 0; // sha256 for this kip not yet calculated.
|
||||
for (u32 currKipIdx = 0; currKipIdx < _kip_id_sets_cnt; currKipIdx++)
|
||||
// Reset hash so it can be calculated for the new kip.
|
||||
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;
|
||||
|
||||
u32 bitsAffected = 0;
|
||||
kip1_patchset_t* currPatchset = _kip_id_sets[currKipIdx].patchset;
|
||||
while (currPatchset != NULL && currPatchset->name != NULL)
|
||||
// Check if there are patches to apply.
|
||||
bool patches_found = false;
|
||||
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.
|
||||
if (strcmp(currPatchset->name, patches[i]) != 0)
|
||||
if (strcmp(patchset->name, patches[i]) != 0)
|
||||
continue;
|
||||
|
||||
bitsAffected = i + 1;
|
||||
patches_found = true;
|
||||
break;
|
||||
}
|
||||
currPatchset++;
|
||||
patchset++;
|
||||
}
|
||||
|
||||
// Dont bother even hashing this KIP if we dont have any patches enabled for it.
|
||||
if (bitsAffected == 0)
|
||||
// Don't bother hashing this KIP if no patches are enabled for it.
|
||||
if (!patches_found && !emummc_patch_apply)
|
||||
continue;
|
||||
|
||||
if (shaBuf[0] == 0)
|
||||
{
|
||||
if (!se_calc_sha256_oneshot(shaBuf, ki->kip1, ki->size))
|
||||
memset(shaBuf, 0, sizeof(shaBuf));
|
||||
}
|
||||
// Check if current KIP not hashed and hash it.
|
||||
if (kip_hash[0] == 0)
|
||||
if (!se_calc_sha256_oneshot(kip_hash, ki->kip1, ki->size))
|
||||
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;
|
||||
|
||||
// Find out which sections are affected by the enabled patches, to know which to decompress.
|
||||
bitsAffected = 0;
|
||||
currPatchset = _kip_id_sets[currKipIdx].patchset;
|
||||
while (currPatchset != NULL && currPatchset->name != NULL)
|
||||
// Find out which sections are affected by the enabled patches, in order to decompress them.
|
||||
u32 sections_affected = 0;
|
||||
patchset = _kip_id_sets[kip_id_idx].patchset;
|
||||
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;
|
||||
|
||||
if (!strcmp(currPatchset->name, "emummc"))
|
||||
bitsAffected |= BIT(GET_KIP_PATCH_SECTION(currPatchset->patches->offset));
|
||||
|
||||
for (const kip1_patch_t* currPatch=currPatchset->patches; currPatch != NULL && (currPatch->length != 0); currPatch++)
|
||||
bitsAffected |= BIT(GET_KIP_PATCH_SECTION(currPatch->offset));
|
||||
for (const kip1_patch_t *patch = patchset->patches; patch != NULL && (patch->length != 0); patch++)
|
||||
sections_affected |= BIT(GET_KIP_PATCH_SECTION(patch->offset));
|
||||
}
|
||||
}
|
||||
currPatchset++;
|
||||
patchset++;
|
||||
}
|
||||
|
||||
// Got patches to apply to this kip, have to decompress it.
|
||||
if (pkg2_decompress_kip(ki, bitsAffected))
|
||||
return (const char*)ki->kip1->name; // Failed to decompress.
|
||||
// If emuMMC is enabled, set its affected section.
|
||||
if (emummc_patch_apply)
|
||||
sections_affected |= BIT(KIP_TEXT);
|
||||
|
||||
currPatchset = _kip_id_sets[currKipIdx].patchset;
|
||||
bool emummc_patch_selected = false;
|
||||
while (currPatchset != NULL && currPatchset->name != NULL)
|
||||
// Got patches to apply to this kip, have to decompress it.
|
||||
if (_decompress_kip(ki, sections_affected))
|
||||
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;
|
||||
|
||||
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;
|
||||
patchesApplied |= appliedMask;
|
||||
|
||||
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;
|
||||
DPRINTF("Patch '%s' not necessary for %s\n", patchset->name, (char *)ki->kip1->name);
|
||||
patches_applied |= applied_mask;
|
||||
|
||||
continue; // Continue in case it's double defined.
|
||||
}
|
||||
|
||||
unsigned char* kipSectData = ki->kip1->data;
|
||||
for (u32 currSectIdx = 0; currSectIdx < KIP1_NUM_SECTIONS; currSectIdx++)
|
||||
// Apply patches per section.
|
||||
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);
|
||||
for (const kip1_patch_t* currPatch = currPatchset->patches; currPatch != NULL && currPatch->srcData != NULL; currPatch++)
|
||||
gfx_printf("Applying '%s' on %s, sect %d\n", patchset->name, (char *)ki->kip1->name, section_idx);
|
||||
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;
|
||||
|
||||
if (!currPatch->length)
|
||||
// Check if patch is empty.
|
||||
if (!patch->length)
|
||||
{
|
||||
gfx_con.mute = false;
|
||||
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 ((memcmp(&kipSectData[currOffset], currPatch->srcData, currPatch->length) != 0) &&
|
||||
(memcmp(&kipSectData[currOffset], currPatch->dstData, currPatch->length) != 0))
|
||||
u32 patch_offset = GET_KIP_PATCH_OFFSET(patch->offset);
|
||||
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_printf("%kPatch mismatch at 0x%x!%k\n", TXT_CLR_ERROR, currOffset, TXT_CLR_DEFAULT);
|
||||
return currPatchset->name; // MUST stop here as kip is likely corrupt.
|
||||
gfx_printf("%kPatch mismatch at 0x%x!%k\n", TXT_CLR_ERROR, patch_offset, TXT_CLR_DEFAULT);
|
||||
return patchset->name; // MUST stop here as kip is likely corrupt.
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF("Patching %d bytes at offset 0x%x\n", currPatch->length, currOffset);
|
||||
memcpy(&kipSectData[currOffset], currPatch->dstData, currPatch->length);
|
||||
DPRINTF("Patching %d bytes at offset 0x%x\n", patch->length, patch_offset);
|
||||
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;
|
||||
continue; // Continue in case it's double defined.
|
||||
patches_applied |= applied_mask;
|
||||
}
|
||||
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;
|
||||
emu_cfg.fs_ver = currKipIdx;
|
||||
if (currKipIdx)
|
||||
// Encode ID.
|
||||
emu_cfg.fs_ver = kip_id_idx;
|
||||
if (kip_id_idx)
|
||||
emu_cfg.fs_ver--;
|
||||
if (currKipIdx > 17)
|
||||
if (kip_id_idx > 17)
|
||||
emu_cfg.fs_ver -= 2;
|
||||
|
||||
// Inject emuMMC code.
|
||||
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";
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
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);
|
||||
pdst += ki->size;
|
||||
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)
|
||||
{
|
||||
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 kernel_size = ctxt->kernel_size;
|
||||
u8 kb = ctxt->pkg1_id->kb;
|
||||
|
|
|
@ -40,9 +40,9 @@ extern u32 pkg2_newkern_ini1_end;
|
|||
|
||||
typedef struct _kernel_patch_t
|
||||
{
|
||||
u32 id;
|
||||
u32 off;
|
||||
u32 val;
|
||||
u32 id;
|
||||
u32 off;
|
||||
u32 val;
|
||||
u32 *ptr;
|
||||
} kernel_patch_t;
|
||||
|
||||
|
@ -67,8 +67,8 @@ enum
|
|||
|
||||
typedef struct _pkg2_hdr_t
|
||||
{
|
||||
u8 ctr[0x10];
|
||||
u8 sec_ctr[0x40];
|
||||
u8 ctr[0x10];
|
||||
u8 sec_ctr[0x40];
|
||||
u32 magic;
|
||||
u32 base;
|
||||
u32 pad0;
|
||||
|
@ -77,8 +77,8 @@ typedef struct _pkg2_hdr_t
|
|||
u16 pad1;
|
||||
u32 sec_size[4];
|
||||
u32 sec_off[4];
|
||||
u8 sec_sha256[0x80];
|
||||
u8 data[];
|
||||
u8 sec_sha256[0x80];
|
||||
u8 data[];
|
||||
} pkg2_hdr_t;
|
||||
|
||||
typedef struct _pkg2_ini1_t
|
||||
|
@ -102,7 +102,7 @@ typedef struct _pkg2_kip1_sec_t
|
|||
typedef struct _pkg2_kip1_t
|
||||
{
|
||||
/* 0x000 */ u32 magic;
|
||||
/* 0x004*/ u8 name[12];
|
||||
/* 0x004*/ u8 name[12];
|
||||
/* 0x010 */ u64 tid;
|
||||
/* 0x018 */ u32 proc_cat;
|
||||
/* 0x01C */ u8 main_thrd_prio;
|
||||
|
@ -127,25 +127,27 @@ typedef struct _pkg2_kernel_id_t
|
|||
kernel_patch_t *kernel_patchset;
|
||||
} pkg2_kernel_id_t;
|
||||
|
||||
#define KIP1_PATCH_SRC_NO_CHECK (char *)(-1)
|
||||
|
||||
typedef struct _kip1_patch_t
|
||||
{
|
||||
u32 offset; // section+offset of patch to apply.
|
||||
u32 length; // In bytes, 0 means last patch.
|
||||
char* srcData; // That must match.
|
||||
char* dstData; // That it gets replaced by.
|
||||
u32 offset; // section+offset of patch to apply.
|
||||
u32 length; // In bytes, 0 means last patch.
|
||||
char *src_data; // That must match.
|
||||
char *dst_data; // That it gets replaced by.
|
||||
} kip1_patch_t;
|
||||
|
||||
typedef struct _kip1_patchset_t
|
||||
{
|
||||
char* name; // NULL means end.
|
||||
kip1_patch_t* patches; // NULL means not necessary.
|
||||
char *name; // NULL means end.
|
||||
kip1_patch_t *patches; // NULL means not necessary.
|
||||
} kip1_patchset_t;
|
||||
|
||||
typedef struct _kip1_id_t
|
||||
{
|
||||
const char* name;
|
||||
const char *name;
|
||||
u8 hash[8];
|
||||
kip1_patchset_t* patchset;
|
||||
kip1_patchset_t *patchset;
|
||||
} kip1_id_t;
|
||||
|
||||
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_merge_kip(link_t *info, pkg2_kip1_t *kip1);
|
||||
void pkg2_get_ids(kip1_id_t **ids, u32 *entries);
|
||||
const char* pkg2_patch_kips(link_t *info, char* patchNames);
|
||||
const char *pkg2_patch_kips(link_t *info, char *patch_names);
|
||||
|
||||
const pkg2_kernel_id_t *pkg2_identify(u8 *hash);
|
||||
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb, bool is_exo);
|
||||
|
|
|
@ -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
|
||||
* 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.
|
||||
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;
|
||||
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, '=');
|
||||
|
||||
// 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;
|
||||
|
||||
// Set patch name.
|
||||
|
@ -158,11 +158,11 @@ int ini_patch_parse(link_t *dst, char *ini_path)
|
|||
|
||||
// Set patch source data.
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
typedef struct _ini_patchset_t
|
||||
{
|
||||
char *name;
|
||||
u32 offset; // section + offset of patch to apply.
|
||||
u32 length; // In bytes, 0 means last patch.
|
||||
u8 *srcData; // That must match.
|
||||
u8 *dstData; // Gets replaced with.
|
||||
u32 offset; // section + offset of patch to apply.
|
||||
u32 length; // In bytes, 0 means last patch.
|
||||
u8 *src_data; // That must match.
|
||||
u8 *dst_data; // Gets replaced with.
|
||||
link_t link;
|
||||
} ini_patchset_t;
|
||||
|
||||
|
|
|
@ -448,362 +448,349 @@ static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
|
|||
};
|
||||
|
||||
// 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[] = {
|
||||
{ "nogc", NULL },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_40x[] = {
|
||||
{ KPS(KIP_TEXT) | 0xA3458, 4, "\x14\x40\x80\x72", "\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) | 0xA3458, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x72" },
|
||||
{ KPS(KIP_TEXT) | 0xAAB44, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_40x[] = {
|
||||
{ "nogc", _fs_nogc_40x },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_410[] = {
|
||||
{ KPS(KIP_TEXT) | 0xA34BC, 4, "\x14\x40\x80\x72", "\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) | 0xA34BC, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x72" },
|
||||
{ KPS(KIP_TEXT) | 0xAABA8, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_410[] = {
|
||||
{ "nogc", _fs_nogc_410 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_50x[] = {
|
||||
{ KPS(KIP_TEXT) | 0xCF3C4, 4, "\x14\x40\x80\x52", "\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) | 0xCF3C4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0xD73A0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_50x[] = {
|
||||
{ "nogc", _fs_nogc_50x },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_510[] = {
|
||||
{ KPS(KIP_TEXT) | 0xCF794, 4, "\x14\x40\x80\x52", "\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) | 0xCF794, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0xD7770, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_510[] = {
|
||||
{ "nogc", _fs_nogc_510 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x1538F4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x12CC20, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x1538F4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x15EFF4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x138320, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x15EFF4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_600[] = {
|
||||
{ "nogc", _fs_nogc_600 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_600_exfat[] = {
|
||||
{ "nogc", _fs_nogc_600_exfat },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x15BF04, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x134160, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x15BF04, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x1674B4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x13F710, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x1674B4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_700[] = {
|
||||
{ "nogc", _fs_nogc_700 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_700_exfat[] = {
|
||||
{ "nogc", _fs_nogc_700_exfat },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x15EB94, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x136800, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x15EB94, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x16A144, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x141DB0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x16A144, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_800[] = {
|
||||
{ "nogc", _fs_nogc_800 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_800_exfat[] = {
|
||||
{ "nogc", _fs_nogc_800_exfat },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x143268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x129420, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x143268, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_900[] = {
|
||||
{ "nogc", _fs_nogc_900 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x143278, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x129430, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x143278, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_910[] = {
|
||||
{ "nogc", _fs_nogc_910 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x14DE08, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x13BE90, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x14DE08, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1000[] = {
|
||||
{ "nogc", _fs_nogc_1000 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_1020[] = {
|
||||
{ KPS(KIP_TEXT) | 0x13C2F0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x14E268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x13C2F0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x14E268, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1020[] = {
|
||||
{ "nogc", _fs_nogc_1020 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x156EB8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x1398B4, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x156EB8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1100[] = {
|
||||
{ "nogc", _fs_nogc_1100 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x155368, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x13EA24, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x155368, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1200[] = {
|
||||
{ "nogc", _fs_nogc_1200 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x155478, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x13EB34, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x155478, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1203[] = {
|
||||
{ "nogc", _fs_nogc_1203 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x159018, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x1425D0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x159018, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1300[] = {
|
||||
{ "nogc", _fs_nogc_1300 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x158FB8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x142570, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x158FB8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1310[] = {
|
||||
{ "nogc", _fs_nogc_1310 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x18A2E8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x164230, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x18A2E8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1400[] = {
|
||||
{ "nogc", _fs_nogc_1400 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x195668, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x16F5B0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x195668, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1400_exfat[] = {
|
||||
{ "nogc", _fs_nogc_1400_exfat },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x184158, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x15ECE4, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x184158, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1500[] = {
|
||||
{ "nogc", _fs_nogc_1500 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x18F0E8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x169C74, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x18F0E8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1500_exfat[] = {
|
||||
{ "nogc", _fs_nogc_1500_exfat },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x1865D8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x160B70, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x1865D8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1600[] = {
|
||||
{ "nogc", _fs_nogc_1600 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x1912B8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x16B850, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x1912B8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1600_exfat[] = {
|
||||
{ "nogc", _fs_nogc_1600_exfat },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x186628, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x160BC0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x186628, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1603[] = {
|
||||
{ "nogc", _fs_nogc_1603 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x191308, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x16B8A0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x191308, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1603_exfat[] = {
|
||||
{ "nogc", _fs_nogc_1603_exfat },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x18B048, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x165100, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x18B048, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1700[] = {
|
||||
{ "nogc", _fs_nogc_1700 },
|
||||
{ "emummc", _fs_emummc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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) | 0x195EA8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0x16FF60, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x195EA8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_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 }
|
||||
};
|
||||
|
||||
|
@ -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", "\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", "\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
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2019 Atmosphère-NX
|
||||
*
|
||||
* 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).
|
||||
|
||||
// Old exosphere target versioning. Use fuses for a simpler decoding.
|
||||
if (ctxt->pkg1_id->fuses <= 3 || ctxt->pkg1_id->fuses >= 10) // 1.0.0 - 3.0.0, 8.1.0+.
|
||||
// Old exosphere target versioning.
|
||||
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;
|
||||
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.
|
||||
if (ctxt->pkg1_id->kb == HOS_KB_VERSION_1210)
|
||||
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.
|
||||
switch (exo_fw_no)
|
||||
{
|
||||
|
@ -203,7 +199,7 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
|
|||
case 12:
|
||||
exo_fw_no = EXO_FW_VER(9, 1);
|
||||
break;
|
||||
case 13 ... 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);
|
||||
break;
|
||||
}
|
||||
|
@ -245,32 +241,29 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
|
|||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse usb mtim settings. Avoid parsing if it's overridden.
|
||||
if (ctxt->fss0_main_path && !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))
|
||||
// Parse usb mtim settings. Avoid parsing if it's overridden.
|
||||
if (!ctxt->exo_ctx.usb3_force)
|
||||
{
|
||||
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.
|
||||
if (!(ini_sec->type == INI_CHOICE) || strcmp(ini_sec->name, "usb"))
|
||||
continue;
|
||||
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, 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);
|
||||
break; // Only parse usb30_force_enabled key.
|
||||
if (!strcmp("usb30_force_enabled", kv->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.
|
||||
char filepath[0x40];
|
||||
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)(rpt->report_identifier), filepath + strlen(filepath), 16);
|
||||
strcat(filepath, ".bin");
|
||||
|
|
|
@ -33,9 +33,12 @@
|
|||
* 1: SDMMC1 LA programming for SDMMC1 UHS DDR200.
|
||||
* 2: Arachne Register Cell v1.
|
||||
* 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
|
||||
#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)
|
||||
{
|
||||
// Launch BL31.
|
||||
ccplex_boot_cpu0(TZDRAM_COLD_ENTRY);
|
||||
ccplex_boot_cpu0(TZDRAM_COLD_ENTRY, true);
|
||||
|
||||
// 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))) |
|
||||
|
|
|
@ -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
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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);
|
||||
else
|
||||
{
|
||||
u8 *buf = calloc(0x200, 1);
|
||||
u8 *buf = zalloc(0x200);
|
||||
is_ipl_updated(buf, "bootloader/update.bin", true);
|
||||
free(buf);
|
||||
}
|
||||
|
@ -1236,7 +1236,7 @@ static void _check_low_battery()
|
|||
|
||||
u8 *battery_icon = malloc(0x95A); // 21x38x3
|
||||
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(battery_icon, battery_res + 0x2F4, 0x95A);
|
||||
|
@ -1478,7 +1478,7 @@ ment_t ment_top[] = {
|
|||
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);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* 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
|
||||
* 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)
|
||||
{
|
||||
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);
|
||||
|
||||
*part_idx = 0;
|
||||
|
@ -57,7 +57,7 @@ static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_
|
|||
{
|
||||
if (backup)
|
||||
{
|
||||
u8 gpt_check[512] = { 0 };
|
||||
u8 gpt_check[SD_BLOCKSIZE] = { 0 };
|
||||
sdmmc_storage_read(&sd_storage, *sector_start + 0xC001, 1, gpt_check);
|
||||
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.
|
||||
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);
|
||||
|
||||
u32 new_size = gpt->header.alt_lba + 1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* 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
|
||||
* 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.
|
||||
mbr_t mbr;
|
||||
gpt_t *gpt = calloc(1, sizeof(gpt_t));
|
||||
gpt_t *gpt = zalloc(sizeof(gpt_t));
|
||||
gpt_header_t gpt_hdr_backup;
|
||||
sdmmc_storage_read(&emmc_storage, 0, 1, &mbr);
|
||||
sdmmc_storage_read(&emmc_storage, 1, sizeof(gpt_t) >> 9, gpt);
|
||||
|
|
|
@ -282,12 +282,7 @@ static void _save_fb_to_bmp()
|
|||
// Create date/time name.
|
||||
char fname[32];
|
||||
rtc_time_t time;
|
||||
max77620_rtc_get_time(&time);
|
||||
if (n_cfg.timeoff)
|
||||
{
|
||||
u32 epoch = max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff;
|
||||
max77620_rtc_epoch_to_date(epoch, &time);
|
||||
}
|
||||
max77620_rtc_get_time_adjusted(&time);
|
||||
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);
|
||||
|
||||
|
@ -1318,12 +1313,7 @@ static void _update_status_bar(void *params)
|
|||
rtc_time_t time;
|
||||
|
||||
// Get sensor data.
|
||||
max77620_rtc_get_time(&time);
|
||||
if (n_cfg.timeoff)
|
||||
{
|
||||
u32 epoch = max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff;
|
||||
max77620_rtc_epoch_to_date(epoch, &time);
|
||||
}
|
||||
max77620_rtc_get_time_adjusted(&time);
|
||||
soc_temp = tmp451_get_soc_temp(false);
|
||||
bq24193_get_property(BQ24193_ChargeStatus, &charge_status);
|
||||
max17050_get_property(MAX17050_RepSOC, (int *)&batt_percent);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* 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:
|
||||
strcat(txt_buf, "Samsung AMS699VC01");
|
||||
break;
|
||||
case PANEL_OEM_CLONE_6_2:
|
||||
strcat(txt_buf, "#FFDD00 OEM Clone 6.2\"#");
|
||||
break;
|
||||
case PANEL_OEM_CLONE_5_5:
|
||||
strcat(txt_buf, "#FFDD00 OEM Clone 5.5\"#");
|
||||
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#");
|
||||
|
||||
u8 *buf = calloc(512, 1);
|
||||
u8 *buf = zalloc(EMMC_BLOCKSIZE);
|
||||
char *txt_buf = (char *)malloc(SZ_32K);
|
||||
char *txt_buf2 = (char *)malloc(SZ_32K);
|
||||
txt_buf[0] = 0;
|
||||
|
@ -1619,6 +1622,9 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
|
|||
case 0x90:
|
||||
strcat(txt_buf, "SK Hynix ");
|
||||
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",
|
||||
|
@ -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.busspeed, card_type_support,
|
||||
!(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);
|
||||
|
||||
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 rpmb_size = emmc_storage.ext_csd.rpmb_mult << 17;
|
||||
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), "2: #96FF00 BOOT1# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / 512);
|
||||
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), "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 / EMMC_BLOCKSIZE);
|
||||
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);
|
||||
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",
|
||||
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",
|
||||
(u32)(sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF),
|
||||
(u32)(sd_fs.n_fatent * sd_fs.csize >> SECTORS_TO_MIB_COEFF));
|
||||
|
|
|
@ -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);
|
||||
|
||||
// Stored in u32 and allow overflow for integer offset casting.
|
||||
n_cfg.timeoff = new_epoch - epoch;
|
||||
|
||||
// If canceled set 1 for invalidating first boot clock edit.
|
||||
if (!n_cfg.timeoff)
|
||||
n_cfg.timeoff = 1;
|
||||
else
|
||||
max77620_rtc_set_epoch_offset((int)n_cfg.timeoff);
|
||||
|
||||
nyx_changes_made = true;
|
||||
}
|
||||
|
@ -744,12 +749,7 @@ static lv_res_t _create_mbox_clock_edit(lv_obj_t *btn)
|
|||
|
||||
// Get current time.
|
||||
rtc_time_t time;
|
||||
max77620_rtc_get_time(&time);
|
||||
if (n_cfg.timeoff)
|
||||
{
|
||||
u32 epoch = max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff;
|
||||
max77620_rtc_epoch_to_date(epoch, &time);
|
||||
}
|
||||
max77620_rtc_get_time_adjusted(&time);
|
||||
|
||||
// Normalize year if out of range.
|
||||
if (time.year < CLOCK_MIN_YEAR)
|
||||
|
@ -842,6 +842,7 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
|
|||
{
|
||||
FIL fp;
|
||||
int error = 0;
|
||||
int cal_error = 0;
|
||||
bool is_l_hos = false;
|
||||
bool is_r_hos = false;
|
||||
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)
|
||||
error = 255;
|
||||
|
||||
if (!error)
|
||||
error = hos_dump_cal0();
|
||||
// Try 2 times to get factory calibration data.
|
||||
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)
|
||||
goto disabled_or_cal0_issue;
|
||||
|
@ -919,35 +929,38 @@ save_data:
|
|||
f_mkdir("switchroot");
|
||||
|
||||
// Save IMU Calibration data.
|
||||
s_printf(data,
|
||||
"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)
|
||||
if (!error && !cal_error)
|
||||
{
|
||||
f_puts(data, &fp);
|
||||
f_close(&fp);
|
||||
s_printf(data,
|
||||
"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
|
||||
|
@ -1066,6 +1079,9 @@ disabled_or_cal0_issue:;
|
|||
strcat(txt_buf,
|
||||
"\n\n#FFDD00 Make sure that both Joy-Con are connected,#\n"
|
||||
"#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
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* 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;
|
||||
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 (!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];
|
||||
|
||||
u8 kb = 0;
|
||||
u8 *pkg1 = (u8 *)calloc(1, SZ_256K);
|
||||
u8 *warmboot = (u8 *)calloc(1, SZ_256K);
|
||||
u8 *secmon = (u8 *)calloc(1, SZ_256K);
|
||||
u8 *loader = (u8 *)calloc(1, SZ_256K);
|
||||
u8 *pkg1 = (u8 *)zalloc(SZ_256K);
|
||||
u8 *warmboot = (u8 *)zalloc(SZ_256K);
|
||||
u8 *secmon = (u8 *)zalloc(SZ_256K);
|
||||
u8 *loader = (u8 *)zalloc(SZ_256K);
|
||||
u8 *pkg2 = NULL;
|
||||
|
||||
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.pkg1 = (void *)pkg1;
|
||||
tsec_ctxt.pkg11_off = pkg1_id->pkg11_off;
|
||||
tsec_ctxt.secmon_base = pkg1_id->secmon_base;
|
||||
|
||||
// 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);
|
||||
|
||||
// Decrypt.
|
||||
|
|
|
@ -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
|
||||
* 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)
|
||||
{
|
||||
gpt_t *gpt = calloc(1, sizeof(gpt_t));
|
||||
gpt_t *gpt = zalloc(sizeof(gpt_t));
|
||||
gpt_header_t gpt_hdr_backup = { 0 };
|
||||
|
||||
// Set GPT protective partition in MBR.
|
||||
|
@ -768,7 +768,7 @@ exit:
|
|||
static u32 _get_available_l4t_partition()
|
||||
{
|
||||
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));
|
||||
|
||||
|
@ -815,7 +815,7 @@ static u32 _get_available_l4t_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.
|
||||
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;
|
||||
}
|
||||
|
||||
// Last part. Align size to LBA (512 bytes).
|
||||
fno.fsize = ALIGN((u64)fno.fsize, 512);
|
||||
// Last part. Align size to LBA (SD_BLOCKSIZE).
|
||||
fno.fsize = ALIGN((u64)fno.fsize, SD_BLOCKSIZE);
|
||||
idx--;
|
||||
}
|
||||
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.
|
||||
char path[128];
|
||||
gpt_t *gpt = calloc(1, sizeof(gpt_t));
|
||||
gpt_t *gpt = zalloc(sizeof(gpt_t));
|
||||
char *txt_buf = malloc(SZ_4K);
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
free(buf);
|
||||
buf = buf_tmp;
|
||||
|
@ -1141,7 +1141,7 @@ boot_img_not_found:
|
|||
if (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);
|
||||
free(buf);
|
||||
buf = buf_tmp;
|
||||
|
@ -1203,7 +1203,7 @@ recovery_not_found:
|
|||
if (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);
|
||||
free(buf);
|
||||
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))
|
||||
{
|
||||
u8 *buf = malloc(512);
|
||||
u8 *buf = malloc(SD_BLOCKSIZE);
|
||||
sdmmc_storage_read(&sd_storage, gpt->entries[i].lba_start, 1, buf);
|
||||
if (!memcmp(buf, "ANDROID", 7))
|
||||
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);
|
||||
|
||||
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 };
|
||||
|
||||
bool has_mbr_attributes = false;
|
||||
|
@ -2279,7 +2279,7 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
|
|||
LIST_INIT(gpt_parsed);
|
||||
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)
|
||||
continue;
|
||||
|
@ -2429,7 +2429,7 @@ check_changes:
|
|||
gpt_hdr_backup.crc32 = crc32_calc(0, (const u8 *)&gpt_hdr_backup, gpt_hdr_backup.size);
|
||||
|
||||
// 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);
|
||||
|
||||
// Write backup GPT partition table.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018 Ced2911
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -76,7 +76,7 @@ static const u8 master_kekseed_620[SE_KEY_128_SIZE] =
|
|||
|
||||
//!TODO: Update on mkey changes.
|
||||
static const u8 master_kekseed_t210_max[SE_KEY_128_SIZE] =
|
||||
{ 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.
|
||||
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.
|
||||
{ 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 }, // 16.0.0.
|
||||
{ 0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80 }, // 17.0.0.
|
||||
{ 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 }, // 18.0.0.
|
||||
};
|
||||
|
||||
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.
|
||||
{ 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 }, // Mkey 14 encrypted with mkey 15.
|
||||
{ 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD }, // Mkey 15 encrypted with mkey 16.
|
||||
{ 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 }, // Mkey 16 encrypted with mkey 17.
|
||||
};
|
||||
|
||||
//!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.
|
||||
{ 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C }, // 16.0.0 New Device Key Source.
|
||||
{ 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 }, // 17.0.0 New Device Key Source.
|
||||
{ 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 }, // 18.0.0 New Device Key Source.
|
||||
};
|
||||
|
||||
//!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.
|
||||
{ 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F }, // 16.0.0 New Device Keygen Source.
|
||||
{ 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E }, // 17.0.0 New Device Keygen Source.
|
||||
{ 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B }, // 18.0.0 New Device Keygen Source.
|
||||
};
|
||||
|
||||
static const u8 gen_keyseed[SE_KEY_128_SIZE] =
|
||||
|
@ -210,7 +214,7 @@ static void _hos_eks_get()
|
|||
if (!h_cfg.eks)
|
||||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
u8 *mbr = zalloc(SD_BLOCKSIZE);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
goto out;
|
||||
|
||||
|
@ -240,7 +244,7 @@ static void _hos_eks_save()
|
|||
bool new_eks = false;
|
||||
if (!h_cfg.eks)
|
||||
{
|
||||
h_cfg.eks = calloc(512 , 1);
|
||||
h_cfg.eks = zalloc(SD_BLOCKSIZE);
|
||||
new_eks = true;
|
||||
}
|
||||
|
||||
|
@ -248,7 +252,7 @@ static void _hos_eks_save()
|
|||
if (h_cfg.eks->enabled != HOS_EKS_TSEC_VER)
|
||||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
u8 *mbr = zalloc(SD_BLOCKSIZE);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
{
|
||||
if (new_eks)
|
||||
|
@ -261,7 +265,7 @@ static void _hos_eks_save()
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = calloc(512 , 1);
|
||||
u8 *eks = zalloc(SD_BLOCKSIZE);
|
||||
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));
|
||||
|
||||
|
@ -302,7 +306,7 @@ void hos_eks_clear(u32 kb)
|
|||
if (h_cfg.eks->enabled)
|
||||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
u8 *mbr = zalloc(SD_BLOCKSIZE);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
goto out;
|
||||
|
||||
|
@ -310,7 +314,7 @@ void hos_eks_clear(u32 kb)
|
|||
h_cfg.eks->enabled = 0;
|
||||
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = calloc(512 , 1);
|
||||
u8 *eks = zalloc(SD_BLOCKSIZE);
|
||||
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));
|
||||
|
||||
|
@ -373,7 +377,7 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
tsec_ctxt->type = TSEC_FW_TYPE_EMU;
|
||||
|
||||
// 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);
|
||||
tsec_ctxt->fw = tsec_paged;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ enum {
|
|||
HOS_KB_VERSION_1500 = 14,
|
||||
HOS_KB_VERSION_1600 = 15,
|
||||
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.
|
||||
|
|
|
@ -65,7 +65,8 @@ static const pkg1_id_t _pkg1_ids[] = {
|
|||
{ "20220209", 13, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 14.0.0 - 14.1.2.
|
||||
{ "20220801", 14, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 15.0.0 - 15.0.1.
|
||||
{ "20230111", 15, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 16.0.0 - 16.1.0.
|
||||
{ "20230906", 16, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 17.0.0+
|
||||
{ "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)
|
||||
|
|
|
@ -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 },
|
||||
// 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 },
|
||||
// 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)
|
||||
|
|
|
@ -269,7 +269,11 @@ skip_main_cfg_parse:
|
|||
else if (!strcmp("entries5col", kv->key))
|
||||
n_cfg.entries_5_col = atoi(kv->val) == 1;
|
||||
else if (!strcmp("timeoff", kv->key))
|
||||
{
|
||||
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))
|
||||
n_cfg.home_screen = atoi(kv->val);
|
||||
else if (!strcmp("verification", kv->key))
|
||||
|
|
|
@ -21,132 +21,3 @@
|
|||
.nosigchk=0:0x194A0:0x4:BA090094,E0031F2A
|
||||
.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
|
||||
|
|
Loading…
Reference in a new issue