Compare commits

...

92 Commits

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

Partitions:
- boot
- recovery
- dtb
- misc
- cache
- super
- userdata
2024-02-16 17:17:12 +02:00
CTCaer feb5b11f66 minerva: do not reread mrr for channel b
Just in case the mrr fifo is not empty.
2024-02-16 16:34:30 +02:00
CTCaer e96e74c72a nyx: finer control of fan when temp is high 2024-02-16 16:07:27 +02:00
CTCaer 6e6f5f8eed hekate: reduce binary size
By using the same message everywhere.
2024-02-16 16:05:42 +02:00
CTCaer 35c36908a1 hekate/nyx: change fs/clock year to 2024 2024-02-16 16:03:54 +02:00
CTCaer 6d69ef3cf6 bdk: sprintf: allow padding > 9 2024-02-16 16:01:54 +02:00
CTCaer abeafb9a67 l4t: allow exFAT as boot drive
Allow exFAT support of boot partition.
For newer bl33 (U-Boot >= 2024-NX02).
Old ones will just fail to load the boot script in such cases.
2024-02-16 15:59:30 +02:00
CTCaer be3297ae1f l4t: raise T210 vdd2 limit to 1237.5mV 2024-02-16 15:57:22 +02:00
CTCaer f05563579e bdk: max77620: raise sd1 max voltage
For T210.
2024-02-16 15:55:40 +02:00
CTCaer 644747230c bdk: dram: add FPGA code for 3rd gen micron 2024-02-16 15:54:22 +02:00
CTCaer 05f4c42a2d l4t: add custom options
That's a special flag config that controls ARC.
2024-02-16 15:53:04 +02:00
CTCaer 1f30b8deb7 bdk: minerva: add custom option in table 2024-02-16 15:51:02 +02:00
CTCaer 6c518435ec nyx: add info about 3rd gen micron lpddr4x 2024-02-14 02:18:01 +02:00
CTCaer 25e48472c8 nyx: add info about oem 5.5" panel 2024-02-14 02:17:45 +02:00
CTCaer bfc6069b2d bdk: display: add OEM panel id 2024-02-14 00:08:06 +02:00
CTCaer 38a792e564 nyx: add penel rev and change some labels 2024-02-12 04:14:14 +02:00
CTCaer 8c5fdf52d4 nyx: correct dram info
Parse per module info on channel A, rank 0.
It was channel info on chip 0, rank0 before.
2024-02-12 04:13:39 +02:00
CTCaer 4576ed81ef sdram: acquire per chip mrr info 2024-02-12 04:08:39 +02:00
CTCaer e9d2bdb124 l4t: remove more redundant carveout cfg 2024-01-07 12:40:28 +02:00
CTCaer b37430dc1d bdk: update copyright year 2024-01-07 12:38:10 +02:00
CTCaer 75543875e2 bdk: mc: remove some redundant carveout cfg 2024-01-07 12:33:29 +02:00
CTCaer cc50ed2051 l4t: remove redundant wpr cfg
It's now done in dram cfg.
2024-01-06 22:09:18 +02:00
CTCaer d1bae553ec nyx: info: use the updated define for micron wtc 2024-01-06 22:06:21 +02:00
CTCaer 30c320d6e7 bdk: sdram: update all ram info comments 2024-01-06 22:05:24 +02:00
CTCaer eff27d92f2 bdk: sdram: update default wpr overrides
Since it's only used in L4T set them to the correct latest reg tool values.

HOS overrides them anyway.
2024-01-06 22:03:54 +02:00
CTCaer 3874840d77 bdk: sdram: update cfg for 8GB erista 2024-01-06 21:59:18 +02:00
CTCaer 74e252aaf2 bdk: sdram: update latest reg tool vpr overrides
Set them to default config and remove them from patching.
2024-01-06 21:58:51 +02:00
CTCaer c7333e710c bdk: strtol: support unsigned 32bit hex
If base is 16 and input is not negative allow unsigned 32bit parsing.

This allows parsing numbers of up to 4294967295 in that case.
2024-01-06 21:55:21 +02:00
CTCaer dab5eb9aa0 bdk: sprintf: do not accept null chars
Skip NULL chars on putc since they break the resulted string.
2024-01-06 21:52:48 +02:00
CTCaer 92093ff08e bdk: se: deduplicate sha hash extraction 2023-12-27 21:07:52 +02:00
CTCaer 2cc6cd45d9 bdk: dram: small refactor 2023-12-27 21:06:09 +02:00
CTCaer a6ec41744b bdk: sdram: refactor patching offsets 2023-12-27 21:04:04 +02:00
CTCaer bb6e4deb4c bdk: remove unused lp0 cfg from bdk 2023-12-27 21:02:33 +02:00
CTCaer 1522f1ee92 nyx: info: add max bus speed info for sd 2023-12-27 15:02:00 +02:00
CTCaer 41d3565353 bdk: sdmmc: deduplicate function modes get
And parse the whole info
2023-12-27 15:01:20 +02:00
CTCaer e23d469f06 nyx: revamp jc/sio cal info dumping
Hoag:
- Add stick types
- Add imu type

All the rest:
- Add imu calibration info
- Add BT mac
2023-12-25 04:17:59 +02:00
CTCaer bd1733c4fa minerva: use min 2 divm
Adhere to software based imposed limits for T210.
2023-12-25 04:11:55 +02:00
CTCaer db214f2865 l4t: correct debug print 2023-12-25 04:09:46 +02:00
CTCaer b584a3f53a bdk: add several defines 2023-12-25 04:08:34 +02:00
CTCaer 7f98fb736a bdk: hwinit: reorder sdmmc1 reg disable 2023-12-25 04:07:26 +02:00
CTCaer 87c50732c0 bdk: fuse: simplify idle wait 2023-12-25 03:47:26 +02:00
CTCaer 504659a39b bdk: actmon: switch to averaged sampling 2023-12-25 03:46:05 +02:00
CTCaer e47a819948 bdk: se: add more useful functions
- aes cmac 128bit
- aes hashing
- option to clear updated aes iv
2023-12-25 03:44:52 +02:00
CTCaer 39abeb9a28 nyx: improve fuses info
Correct the Chip ID Revision and also add actual (derived) iddq values.
2023-12-25 03:33:37 +02:00
CTCaer 80a32304cb nyx: rename 3rd gen hynix ram chips 2023-12-25 03:21:17 +02:00
CTCaer 913cdee8e8 bdk: sdram: rename 3rd gen t210b01 hynix ram
Confirmed to be a Hynix H54G46CYRBX267 and not a H9HCNNNBKMMLXR-NEI
2023-12-25 03:02:11 +02:00
CTCaer eff55ff378 bdk: touch: rename samsung touch panel
BH2109 is the board model and not the touch panel.
2023-12-25 02:41:42 +02:00
CTCaer 09dfcfc57d bdk: display: deduplicate interrupt code 2023-12-25 02:40:38 +02:00
CTCaer 239c48c790 bdk: usb: hid: improve stick calibration
Wait a bit before calibrating stick centers, in order to avoid bad values.
2023-12-25 02:37:40 +02:00
CTCaer 2e1a773a08 nyx: relax joycon calibration init
Wait a bit before actually doing stick calibration in order to avoid bad values.
2023-12-25 02:36:27 +02:00
CTCaer d1ee0e35fd hos: pkg2: fix validation check for nogc 17.0.0 2023-10-13 07:58:56 +03:00
88 changed files with 2004 additions and 5088 deletions

View File

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

View File

@ -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,6 +42,26 @@ static bool _nx_aula = false;
static void _display_panel_and_hw_end(bool no_panel_deinit);
void display_enable_interrupt(u32 intr)
{
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) |= intr;
}
void display_disable_interrupt(u32 intr)
{
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) &= ~intr;
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = intr;
}
void display_wait_interrupt(u32 intr)
{
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = intr;
// Interrupts are masked. Poll status register for checking if fired.
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & intr))
;
}
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
{
u32 end = get_tmr_us() + timeout;
@ -64,22 +84,18 @@ static void _display_dsi_wait_vblank(bool enable)
if (enable)
{
// Enable vblank interrupt.
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT;
display_enable_interrupt(DC_CMD_INT_FRAME_END_INT);
// Use the 4th line to transmit the host cmd packet.
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
// Wait for vblank before starting the transfer.
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
;
display_wait_interrupt(DC_CMD_INT_FRAME_END_INT);
}
else
{
// Wait for vblank before resetting sync points.
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
;
display_wait_interrupt(DC_CMD_INT_FRAME_END_INT);
usleep(14);
// Reset all states of syncpt block.
@ -94,8 +110,7 @@ static void _display_dsi_wait_vblank(bool enable)
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
// Disable and clear vblank interrupt.
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0;
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT;
display_disable_interrupt(DC_CMD_INT_FRAME_END_INT);
}
}
@ -383,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;

View File

@ -732,9 +732,10 @@
* [10] 96 [09]: JDI LAM062M109A
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
* [20] 96 [0F]: InnoLux P062CCA-AZ3 (Rev XX) [UNCONFIRMED MODEL+REV]
* [20] 96 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
* [20] 97 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
* [20] 98 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
* [20] 99 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
* [30] 93 [0F]: AUO A062TAN00 (59.06A33.000)
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
@ -786,13 +787,25 @@ enum
PANEL_INL_2J055IA_27A = 0x1020,
PANEL_AUO_A055TAN01 = 0x1030,
PANEL_SHP_LQ055T1SW10 = 0x1040,
PANEL_SAM_AMS699VC01 = 0x2050
PANEL_SAM_AMS699VC01 = 0x2050,
// Found on 6/2" clones. Unknown markings. Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F].
PANEL_OEM_CLONE_6_2 = 0x0F83,
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
PANEL_OEM_CLONE_5_5 = 0x00B3,
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
PANEL_OEM_CLONE = 0x0000
};
void display_init();
void display_backlight_pwm_init();
void display_end();
/*! Interrupt management. */
void display_enable_interrupt(u32 intr);
void display_disable_interrupt(u32 intr);
void display_wait_interrupt(u32 intr);
/*! Get/Set Display panel ID. */
u16 display_get_decoded_panel_id();
void display_set_decoded_panel_id(u32 id);

View File

@ -39,7 +39,7 @@ static touch_panel_info_t _panels[] =
{ 1, 0, 1, 1, "GiS GGM6 B2X" },// 1.
{ 2, 0, 0, 0, "NISSHA NBF-K9A" },// 3.
{ 3, 1, 0, 0, "GiS 5.5\"" },// 4.
{ 4, 0, 0, 1, "Samsung BH2109" },// 5?
{ 4, 0, 0, 1, "Samsung TSP" },// 5?
{ -1, 1, 0, 1, "GiS VA 6.2\"" } // 2.
};

View File

@ -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

View File

@ -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));

View File

@ -712,7 +712,7 @@ enum
EMC_CHAN1 = 1
};
typedef struct _emc_mr_data_t
typedef struct _emc_mr_chip_data_t
{
// Device 0.
u8 rank0_ch0;
@ -721,6 +721,12 @@ typedef struct _emc_mr_data_t
// Device 1.
u8 rank1_ch0;
u8 rank1_ch1;
} emc_mr_chip_data_t;
typedef struct _emc_mr_data_t
{
emc_mr_chip_data_t chip0;
emc_mr_chip_data_t chip1;
} emc_mr_data_t;
#endif

View File

@ -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)

View File

@ -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);

View File

@ -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,
@ -21,7 +21,7 @@
#include <soc/t210.h>
#include <soc/clock.h>
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)
void mc_config_tzdram_carveout(u32 bom, u32 size1mb, bool lock)
{
MC(MC_SEC_CARVEOUT_BOM) = bom;
MC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
@ -31,96 +31,47 @@ void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)
void mc_config_carveout()
{
// Enable ACR GSR3.
*(vu32 *)0x8005FFFC = 0xC0EDBBCC;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
MC(MC_VIDEO_PROTECT_BOM) = 0;
MC(MC_VIDEO_PROTECT_SIZE_MB) = 0;
MC(MC_VIDEO_PROTECT_REG_CTRL) = 1;
MC(MC_VIDEO_PROTECT_REG_CTRL) = VPR_CTRL_LOCKED;
// Configure TSEC carveout @ 0x90000000, 1MB.
//mc_config_tsec_carveout(0x90000000, 1, false);
mc_config_tsec_carveout(0, 0, true);
// Configure TZDRAM carveout @ 0x90000000, 1MB.
//mc_config_tzdram_carveout(0x90000000, 1, false);
mc_config_tzdram_carveout(0, 0, true);
MC(MC_MTS_CARVEOUT_BOM) = 0;
MC(MC_MTS_CARVEOUT_SIZE_MB) = 0;
MC(MC_MTS_CARVEOUT_ADR_HI) = 0;
MC(MC_MTS_CARVEOUT_REG_CTRL) = 1;
MC(MC_SECURITY_CARVEOUT1_BOM) = 0;
MC(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
MC(MC_SECURITY_CARVEOUT1_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
SEC_CARVEOUT_CFG_APERTURE_ID(0) |
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
MC(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
MC(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = 0x3100000;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = 0x300;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU | SEC_CARVEOUT_CA2_R_TSEC;
MC(MC_SECURITY_CARVEOUT3_BOM) = 0;
MC(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = 0x3000000;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = 0x300;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
MC(MC_SECURITY_CARVEOUT4_BOM) = 0;
MC(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
MC(MC_SECURITY_CARVEOUT4_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
SEC_CARVEOUT_CFG_LOCKED |
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
SEC_CARVEOUT_CFG_RD_NS |
SEC_CARVEOUT_CFG_WR_NS;
MC(MC_SECURITY_CARVEOUT5_BOM) = 0;
MC(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
MC(MC_SECURITY_CARVEOUT5_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
SEC_CARVEOUT_CFG_LOCKED |
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
SEC_CARVEOUT_CFG_RD_NS |
SEC_CARVEOUT_CFG_WR_NS;
}
void mc_enable_ahb_redirect()
@ -157,12 +108,10 @@ bool mc_client_has_access(void *address)
void mc_enable()
{
// Reset EMC source to PLLP.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29);
// Enable memory clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MEM);
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29u);
// Enable and clear reset for memory clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
// Clear clock resets for memory.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
usleep(5);

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
* Copyright (c) 2014, NVIDIA Corporation.
* Copyright (c) 2018-2023, CTCaer
*
* This software is licensed under the terms of the GNU General Public
* 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)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2022 CTCaer
* Copyright (c) 2019-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -27,10 +27,10 @@
#include <soc/t210.h>
#include <utils/util.h>
#define LA_REGS_OFFSET_T210 0x1284
#define LA_REGS_OFFSET_T210B01 0xFA4
#define TABLE_FREQ_KHZ_OFFSET 0x40
#define TABLE_LA_REGS_T210_OFFSET 0x1284
#define TABLE_LA_REGS_T210B01_OFFSET 0xFA4
#define LA_SDMMC1_INDEX 6
#define LA_SDMMC4_INDEX 9
extern volatile nyx_storage_t *nyx_str;
@ -148,10 +148,22 @@ void minerva_change_freq(minerva_freq_t freq)
void minerva_sdmmc_la_program(void *table, bool t210b01)
{
u32 *la_scale_regs = (u32 *)(table + (t210b01 ? LA_REGS_OFFSET_T210B01 : LA_REGS_OFFSET_T210));
u32 freq = *(u32 *)(table + TABLE_FREQ_KHZ_OFFSET);
u32 *la_scale_regs = (u32 *)(table + (t210b01 ? TABLE_LA_REGS_T210B01_OFFSET : TABLE_LA_REGS_T210_OFFSET));
// Promote SDMMC1 latency allowance to SDMMC4 (SD to eMMC).
la_scale_regs[LA_SDMMC1_INDEX] = la_scale_regs[LA_SDMMC4_INDEX];
// Adjust SDMMC1 latency allowance.
switch (freq)
{
case 204000:
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) | 25;
break;
default:
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 20;
break;
}
}
void minerva_prep_boot_freq()
@ -171,7 +183,7 @@ void minerva_prep_boot_freq()
minerva_change_freq(FREQ_800);
}
void minerva_prep_boot_l4t(u32 oc_freq)
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
{
if (!minerva_cfg)
return;
@ -188,10 +200,29 @@ void minerva_prep_boot_l4t(u32 oc_freq)
memcpy(&mtc_cfg->mtc_table[mtc_cfg->table_entries],
&mtc_cfg->mtc_table[mtc_cfg->table_entries - 1],
sizeof(emc_table_t));
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
mtc_cfg->mtc_table[mtc_cfg->table_entries].opt_custom = opt_custom;
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
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);
@ -199,38 +230,21 @@ void minerva_prep_boot_l4t(u32 oc_freq)
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;
}

View File

@ -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;
@ -63,7 +64,7 @@ u32 minerva_init();
void minerva_change_freq(minerva_freq_t freq);
void minerva_sdmmc_la_program(void *table, bool t210b01);
void minerva_prep_boot_freq();
void minerva_prep_boot_l4t(u32 oc_freq);
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom);
void minerva_periodic_training();
emc_table_t *minerva_get_mtc_table();
int minerva_get_mtc_table_entries();

View File

@ -481,7 +481,8 @@ typedef struct
u32 rate_khz;
u32 min_volt;
u32 gpu_min_volt;
char clock_src[32];
char clock_src[28];
u32 opt_custom;
u32 clk_src_emc;
u32 needs_training;
u32 training_pattern;

View File

@ -42,8 +42,8 @@
typedef struct _sdram_vendor_patch_t
{
u32 val;
u32 offset:16;
u32 dramcf:16;
u32 offset:16;
} sdram_vendor_patch_t;
static const u8 dram_encoding_t210b01[] = {
@ -76,9 +76,9 @@ static const u8 dram_encoding_t210b01[] = {
/* 26 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
/* 27 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
/* 28 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
/* 29 */ LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI,
/* 30 */ LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI,
/* 31 */ LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI,
/* 29 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
/* 30 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
/* 31 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
/* 32 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
/* 33 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
/* 34 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
@ -127,15 +127,19 @@ static void _sdram_req_mrr_data(u32 data, bool dual_channel)
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
{
emc_mr_data_t data;
u32 dual_channel = (EMC(EMC_FBIO_CFG7) >> 2) & 1;
u32 mrr;
bool dual_rank = EMC(EMC_ADR_CFG) & 1;
bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 2) & 1; // Each EMC channel is a RAM chip module.
// Clear left overs.
for (u32 i = 0; i < 32; i++)
for (u32 i = 0; i < 16; i++)
{
(void)EMC(EMC_MRR);
usleep(1);
}
memset(&data, 0xFF, sizeof(emc_mr_data_t));
/*
* When a dram chip has only one rank, then the info from the 2 ranks differs.
* Info not matching is only allowed on different channels.
@ -143,21 +147,38 @@ emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
// Get Device 0 (Rank 0) info from both dram chips (channels).
_sdram_req_mrr_data((2u << 30) | (mrx << 16), dual_channel);
data.rank0_ch0 = EMC(EMC_MRR) & 0xFF;
data.rank0_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
// Ram module 0 info.
mrr = EMC_CH0(EMC_MRR);
data.chip0.rank0_ch0 = mrr & 0xFF;
data.chip0.rank0_ch1 = (mrr & 0xFF00 >> 8);
// Ram module 1 info.
if (dual_channel)
{
mrr = EMC_CH1(EMC_MRR);
data.chip1.rank0_ch0 = mrr & 0xFF;
data.chip1.rank0_ch1 = (mrr & 0xFF00 >> 8);
}
// If Rank 1 exists, get info.
if (EMC(EMC_ADR_CFG) & 1)
if (dual_rank)
{
// Get Device 1 (Rank 1) info from both dram chips (channels).
_sdram_req_mrr_data((1u << 30) | (mrx << 16), dual_channel);
data.rank1_ch0 = EMC(EMC_MRR) & 0xFF;
data.rank1_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
}
else
{
data.rank1_ch0 = 0xFF;
data.rank1_ch1 = 0xFF;
// Ram module 0 info.
mrr = EMC_CH0(EMC_MRR);
data.chip0.rank1_ch0 = mrr & 0xFF;
data.chip0.rank1_ch1 = (mrr & 0xFF00 >> 8);
// Ram module 1 info.
if (dual_channel)
{
mrr = EMC_CH1(EMC_MRR);
data.chip1.rank1_ch0 = mrr & 0xFF;
data.chip1.rank1_ch1 = (mrr & 0xFF00 >> 8);
}
}
return data;
@ -167,12 +188,12 @@ static void _sdram_config_t210(const sdram_params_t210_t *params)
{
// Program DPD3/DPD4 regs (coldboot path).
// Enable sel_dpd on unused pins.
u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x80000000;
u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | (2 << 30u);
PMC(APBDEV_PMC_IO_DPD3_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF;
usleep(params->pmc_io_dpd3_req_wait);
// Disable e_dpd_vttgen.
dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | 0x80000000;
dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | (2 << 30u);
PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req & 0xFFFF0000) ^ 0x3FFF0000;
usleep(params->pmc_io_dpd4_req_wait);
@ -209,7 +230,7 @@ break_nosleep:
if (params->emc_clock_source_dll)
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
if (params->clear_clock2_mc1)
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000; // Clear Reset to MC1.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_MC1); // Clear Reset to MC1.
// Enable and clear reset for memory clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
@ -233,7 +254,7 @@ break_nosleep:
// Program CMD mapping. Required before brick mapping, else
// we can't guarantee CK will be differential at all times.
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
EMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;
@ -246,7 +267,7 @@ break_nosleep:
EMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
// Program brick mapping.
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
@ -289,13 +310,13 @@ break_nosleep:
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
@ -328,7 +349,7 @@ break_nosleep:
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
EMC(EMC_CFG_3) = params->emc_cfg3;
EMC(EMC_CFG_3) = params->emc_cfg3;
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
@ -561,9 +582,11 @@ break_nosleep:
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
EMC(EMC_DBG) = params->emc_dbg;
EMC(EMC_QRST) = params->emc_qrst;
EMC(EMC_ISSUE_QRST) = 1;
EMC(EMC_ISSUE_QRST) = 0;
EMC(EMC_QSAFE) = params->emc_qsafe;
EMC(EMC_RDV) = params->emc_rdv;
EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
@ -616,7 +639,7 @@ break_nosleep:
}
// Release SEL_DPD_CMD.
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000;
PMC(APBDEV_PMC_IO_DPD3_REQ) = (params->emc_pmc_scratch1 & 0xFFF0000) | (1 << 30u);
usleep(params->pmc_io_dpd3_req_wait);
// Set autocal interval if not configured.
@ -707,7 +730,7 @@ break_nosleep:
EMC(EMC_REF) = (((1 << params->emc_extra_refresh_num) - 1) << 8) | (params->emc_dev_select << 30) | 3;
// Enable refresh.
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
EMC(EMC_REFCTRL) = params->emc_dev_select | BIT(31);
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
@ -717,7 +740,7 @@ break_nosleep:
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
// Write addr swizzle lock bit.
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | BIT(1);
EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
@ -751,15 +774,15 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
// Program DPD3/DPD4 regs (coldboot path).
// Enable sel_dpd on unused pins.
PMC(APBDEV_PMC_WEAK_BIAS) = (pmc_scratch1 & 0x1000) << 19 | (pmc_scratch1 & 0xFFF) << 18 | (pmc_scratch1 & 0x8000) << 15;
PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) + 0x80000000;
PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) | (2 << 30u);
usleep(params->pmc_io_dpd3_req_wait);
// Disable e_dpd_vttgen.
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x3FFF0000) | 0x80000000;
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x3FFF0000) | (2 << 30u);
usleep(params->pmc_io_dpd4_req_wait);
// Disable e_dpd_bg.
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x1FFF) | 0x80000000;
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x1FFF) | (2 << 30u);
usleep(1);
// Program CMD mapping. Required before brick mapping, else
@ -1155,9 +1178,11 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
EMC(EMC_DBG) = params->emc_dbg;
EMC(EMC_QRST) = params->emc_qrst;
EMC(EMC_ISSUE_QRST) = 1;
EMC(EMC_ISSUE_QRST) = 0;
EMC(EMC_QSAFE) = params->emc_qsafe;
EMC(EMC_RDV) = params->emc_rdv;
EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
@ -1219,7 +1244,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
*(vu32 *)params->emc_bct_spare_secure16 = params->emc_bct_spare_secure17;
// Release SEL_DPD_CMD.
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000;
PMC(APBDEV_PMC_IO_DPD3_REQ) = (params->emc_pmc_scratch1 & 0xFFF0000) | (1 << 30u);
usleep(params->pmc_io_dpd3_req_wait);
// Set transmission pad control parameters.
@ -1315,7 +1340,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 253) | (params->emc_dev_select << 30);
// Enable refresh.
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
EMC(EMC_REFCTRL) = params->emc_dev_select | BIT(31);
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
EMC(EMC_CFG) = params->emc_cfg;
@ -1324,7 +1349,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
// Write addr swizzle lock bit.
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | BIT(1);
EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2020-2023 CTCaer
* Copyright (c) 2020-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -42,58 +42,67 @@
enum sdram_ids_erista
{
// LPDDR4 3200Mbps.
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0,
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1,
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2, // WT:C.
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, // Die-B. (2y-01).
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, // Die-M. (2y-01).
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2, // Die-C. (2y-01).
LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4,
LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4, // Die-C. (2y-01).
LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7, // Custom 8GB. XX: CH/CJ/CL. 7 since it can be easily applied in fuses.
// Custom hekate/L4T supported 8GB. 7 dram id can be easily applied in fuses.
LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7, // XX: CH/CJ/CL.
};
enum sdram_ids_mariko
{
/*
* Nintendo Switch LPDRR4X generations:
* - 1x nm are 1st-gen
* - 1y nm are 2nd-gen
* - 1z/a nm are 3rd-gen
*/
// LPDDR4X 4266Mbps.
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Replaced from Copper. Die-M. (1y-01).
LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Replaced from Copper. Die-M. (1y-01).
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Replaced from Copper. Die-M. (1y-01).
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Die-M. (1y-01).
LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Die-M. (1y-01).
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Die-M. (1y-01).
// LPDDR4X 3733Mbps.
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. 1st gen. 3733Mbps.
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M.
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M.
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // 4266Mbps. Die-E. D9WGB.
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. (1x-03).
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M. (1x-03).
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M. (1x-03).
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // Die-E. (1x-03). D9WGB. 4266Mbps.
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. 1st gen. 3733Mbps.
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M.
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M.
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // 4266Mbps. Die-E. D9WGB.
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. (1x-03).
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M. (1x-03).
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M. (1x-03).
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // Die-E. (1x-03). D9WGB. 4266Mbps.
// LPDDR4X 4266Mbps.
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. (1y-X03). 2nd gen. 4266Mbps.
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. (1y-X03).
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A. (1y-X03).
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. (1y-X03). 2nd gen. 4266Mbps.
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. (1y-X03).
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 20, // Die-B. 1z nm. 40% lower power usage. (1z-01).
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 21, // Die-B. 1z nm. 40% lower power usage. (1z-01).
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 22, // Die-B. 1z nm. 40% lower power usage. (1z-01).
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 20, // Die-B. (1z-01). 40% lp.
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 21, // Die-B. (1z-01). 40% lp.
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 22, // Die-B. (1z-01). 40% lp.
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. (1y-X03).
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. (1y-X03). 2nd gen. 4266Mbps.
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. (1y-X03).
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // Die-F. (1y-01). D9XRR.
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // Die-F. (1y-01). D9XRR.
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // Die-F. (1y-01). D9XRR.
LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A.
LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A. (1y-X03). 2nd gen.
LPDDR4X_UNK0_4GB_HYNIX_H9HCNNNBKMMLXR_NEI = 29, // Die-M. 1a nm. 61% lower power usage. (1a-01).
LPDDR4X_UNK1_4GB_HYNIX_H9HCNNNBKMMLXR_NEI = 30, // Die-M. 1a nm. 61% lower power usage. (1a-01).
LPDDR4X_UNK2_4GB_HYNIX_H9HCNNNBKMMLXR_NEI = 31, // Die-M. 1a nm. 61% lower power usage. (1a-01).
// Old naming scheme: H9HCNNNBKMCLXR-NEE
LPDDR4X_IOWA_4GB_HYNIX_H54G46CYRBX267 = 29, // Die-C. (1a-01). 61% lp.
LPDDR4X_HOAG_4GB_HYNIX_H54G46CYRBX267 = 30, // Die-C. (1a-01). 61% lp.
LPDDR4X_AULA_4GB_HYNIX_H54G46CYRBX267 = 31, // Die-C. (1a-01). 61% lp.
LPDDR4X_UNK0_4GB_MICRON_MT53E512M32D1NP_046_WTB = 32, // 1a nm. 61% lower power usage. (1a-01).
LPDDR4X_UNK1_4GB_MICRON_MT53E512M32D1NP_046_WTB = 33, // 1a nm. 61% lower power usage. (1a-01).
LPDDR4X_UNK2_4GB_MICRON_MT53E512M32D1NP_046_WTB = 34, // 1a nm. 61% lower power usage. (1a-01).
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 32, // Die-B. (1a-01). D8BQM. 61% lp.
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D1NP_046_WTB = 33, // Die-B. (1a-01). D8BQM. 61% lp.
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 34, // Die-B. (1a-01). D8BQM. 61% lp.
};
enum sdram_codes_mariko
@ -111,7 +120,7 @@ enum sdram_codes_mariko
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 5, // DRAM IDs: 20, 21, 22.
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF = 6, // DRAM IDs: 25, 26, 27.
LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 7, // DRAM IDs: 03, 05, 06.
LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI = 8, // DRAM IDs: 29, 30, 31.
LPDDR4X_4GB_HYNIX_H54G46CYRBX267 = 8, // DRAM IDs: 29, 30, 31.
LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB = 9, // DRAM IDs: 32, 33, 34.
};

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2020-2022 CTCaer
* Copyright (c) 2020-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -434,9 +434,9 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.emc_dll_cfg0 = 0x1F13412F,
.emc_dll_cfg1 = 0x00010014,
.emc_pmc_scratch1 = 0x4FAFFFFF,
.emc_pmc_scratch1 = 0x4FAFFFFF, // APBDEV_PMC_IO_DPD3_REQ.
.emc_pmc_scratch2 = 0x7FFFFFFF,
.emc_pmc_scratch3 = 0x4006D70B,
.emc_pmc_scratch3 = 0x4006D70B, // APBDEV_PMC_DDR_CNTRL.
.emc_pmacro_pad_cfg_ctrl = 0x00020000,
.emc_pmacro_vttgen_ctrl0 = 0x00030808,
@ -499,7 +499,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
* Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes)
*/
.mc_emem_cfg = 0x00001000, // 4GB total density.
.mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
/* MC arbitration configuration */
.mc_emem_arb_cfg = 0x08000001,
@ -542,16 +542,18 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.mc_video_protect_bom_adr_hi = 0x00000000,
.mc_video_protect_size_mb = 0x00000000,
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A.
.mc_video_protect_vpr_override = 0xE4BAC343,
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR.
.mc_video_protect_vpr_override1 = 0x00001ED3,
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. Plus TSEC, NVENC.
.mc_video_protect_vpr_override = 0xE4FACB43, // Default: 0xE4BAC343. New: 0xE4FACB43. + TSEC, NVENC.
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus TSECB, TSEC1, TSECB1.
.mc_video_protect_vpr_override1 = 0x0000FED3, // Default: 0x00001ED3. New: 0x0000FED3. + TSECB, TSEC1, TSECB1.
.mc_video_protect_gpu_override0 = 0x2A800000, // Default: 0x00000000. Forced to 1 by HOS Secmon.
.mc_video_protect_gpu_override1 = 0x00000002, // Default: 0x00000000. Forced to 0 by HOS Secmon.
.mc_video_protect_gpu_override0 = 0x00000000,
.mc_video_protect_gpu_override1 = 0x00000000,
.mc_sec_carveout_bom = 0xFFF00000,
.mc_sec_carveout_adr_hi = 0x00000000,
.mc_sec_carveout_size_mb = 0x00000000,
.mc_video_protect_write_access = 0x00000000,
.mc_sec_carveout_protect_write_access = 0x00000000,
@ -646,26 +648,27 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.mc_mts_carveout_reg_ctrl = 0x00000000
};
#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210_t, m) / 4)
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = {
// Hynix timing config.
{ 0x0000000D, 0x10C / 4, DRAM_ID(1) }, // emc_r2w.
{ 0x00000001, 0x16C / 4, DRAM_ID(1) }, // emc_puterm_extra.
{ 0x80000000, 0x170 / 4, DRAM_ID(1) }, // emc_puterm_width.
{ 0x00000210, 0x4F4 / 4, DRAM_ID(1) }, // emc_pmacro_data_rx_term_mode.
{ 0x00000005, 0x5C0 / 4, DRAM_ID(1) }, // mc_emem_arb_timing_r2w.
{ 0x0000000D, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_r2w) },
{ 0x00000001, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_extra) },
{ 0x80000000, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_width) },
{ 0x00000210, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_pmacro_data_rx_term_mode) },
{ 0x00000005, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(mc_emem_arb_timing_r2w) },
// Samsung 6GB density config.
{ 0x000C0302, 0x56C / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB Chip 0 density.
{ 0x000C0302, 0x570 / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB Chip 1 density.
{ 0x00001800, 0x584 / 4, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density.
{ 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 768MB Chip 0 density.
{ 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 768MB Chip 1 density.
{ 0x00001800, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_cfg) }, // 6GB total density. Max 8GB.
// Samsung 8GB density config.
{ 0x0000003A, 0xEC / 4, DRAM_ID(7) }, // emc_rfc.
{ 0x0000001D, 0xF0 / 4, DRAM_ID(7) }, // emc_rfc_pb.
{ 0x0000003B, 0x1C0 / 4, DRAM_ID(7) }, // emc_txsr.
{ 0x0000003B, 0x1C4 / 4, DRAM_ID(7) }, // emc_txsr_dll.
{ 0x00000713, 0x2B4 / 4, DRAM_ID(7) }, // emc_dyn_self_ref_control.
{ 0x00080302, 0x56C / 4, DRAM_ID(7) }, // mc_emem_adr_cfg_dev0. 1024MB Chip 0 density.
{ 0x00080302, 0x570 / 4, DRAM_ID(7) }, // mc_emem_adr_cfg_dev1. 1024MB Chip 1 density.
{ 0x00002000, 0x584 / 4, DRAM_ID(7) }, // mc_emem_cfg. 8GB total density.
{ 0x0000003A, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc) },
{ 0x0000001D, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc_pb) },
{ 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr) },
{ 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr_dll) },
{ 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 1024MB Chip 0 density.
{ 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 1024MB Chip 1 density.
{ 0x00002000, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
};
#undef DCFG_OFFSET_OF

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 CTCaer
* Copyright (c) 2020-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -552,7 +552,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
* Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes)
*/
.mc_emem_cfg = 0x00001000, // 4GB total density.
.mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
/* MC arbitration configuration */
.mc_emem_arb_cfg = 0x08000001,
@ -595,17 +595,18 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
.mc_video_protect_bom_adr_hi = 0x00000000,
.mc_video_protect_size_mb = 0x00000000,
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A.
.mc_video_protect_vpr_override = 0xE4BAC343,
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B.
.mc_video_protect_vpr_override1 = 0x06001ED3,
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. Plus TSEC, NVENC.
.mc_video_protect_vpr_override = 0xE4FACB43, // Default: 0xE4BAC343.
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B and TSECB, TSEC1, TSECB1.
.mc_video_protect_vpr_override1 = 0x0600FED3, // Default: 0x06001ED3.
.mc_video_protect_gpu_override0 = 0x00000000,
.mc_video_protect_gpu_override1 = 0x00000000,
.mc_video_protect_gpu_override0 = 0x2A800000, // Default: 0x00000000. Forced to 1 by HOS Secmon.
.mc_video_protect_gpu_override1 = 0x00000002, // Default: 0x00000000. Forced to 0 by HOS Secmon.
.mc_sec_carveout_bom = 0xFFF00000,
.mc_sec_carveout_adr_hi = 0x00000000,
.mc_sec_carveout_size_mb = 0x00000000,
.mc_video_protect_write_access = 0x00000000,
.mc_sec_carveout_protect_write_access = 0x00000000,
@ -708,30 +709,30 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
#define DRAM_CC_LPDDR4X_PMACRO_IB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ))
#define DRAM_CC_LPDDR4X_AUTOCAL_VPR (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
#define DRAM_CC_LPDDR4X_PUPD_VPR (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_DYN_SELF_CTRL (DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
#define DRAM_CC_LPDDR4X_DSR (DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_QUSE_EINPUT (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
#define DRAM_CC_LPDDR4X_QUSE (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
@ -741,67 +742,71 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB))
#define DRAM_CC_LPDDR4X_VPR (DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_8GB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL))
#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210b01_t, m) / 4)
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = {
// Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ Die-M for SDEV Iowa and Hoag.
{ 0x35353535, 0x350 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_0.
{ 0x35353535, 0x354 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_1.
{ 0x00100010, 0x3FC / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
{ 0x00100010, 0x400 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
{ 0x00100010, 0x404 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
{ 0x00100010, 0x408 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
{ 0x00100010, 0x40C / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
{ 0x00100010, 0x410 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
{ 0x00100010, 0x414 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
{ 0x00100010, 0x418 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
{ 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_0) },
{ 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_1) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_0) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_1) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_2) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_3) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_0) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_1) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_2) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_3) },
/*! Shared patched between DRAM Codes. */
{ 0x05500000, 0x0D4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_config2.
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_vref_sel0.
{ 0x2A800000, 0x6DC / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // mc_video_protect_gpu_override0.
{ 0x00000002, 0x6E0 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // mc_video_protect_gpu_override1.
//!TODO Find out what mc_video_protect_gpu_override0 and mc_video_protect_gpu_override1 new bits are.
{ 0x05500000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_config2) },
{ 0xC9AFBCBC, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_vref_sel0) },
{ 0x88161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_mrw14.
{ 0x80000713, 0x32C / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_dyn_self_ref_control.
// Moved to default config.
// { 0x2A800000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override0) },
// { 0x00000002, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override1) },
{ 0x00000006, 0x1CC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse.
{ 0x00000005, 0x1D0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse_width.
{ 0x00000003, 0x1DC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput.
{ 0x0000000C, 0x1E0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput_duration.
{ 0x88161414, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_mrw14) },
{ 0x80000713, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_dyn_self_ref_control) },
{ 0x00000008, 0x24C / 4, DRAM_CC_LPDDR4X_FAW }, // emc_tfaw.
{ 0x00000001, 0x670 / 4, DRAM_CC_LPDDR4X_FAW }, // mc_emem_arb_timing_faw.
{ 0x00000006, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse) },
{ 0x00000005, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse_width) },
{ 0x00000003, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput) },
{ 0x0000000C, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput_duration) },
{ 0xE4FACB43, 0x6D4 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override. + TSEC, NVENC.
{ 0x0600FED3, 0x6D8 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1.
{ 0x00000008, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(emc_tfaw) },
{ 0x00000001, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(mc_emem_arb_timing_faw) },
{ 0x00000001, 0x134 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_adr_cfg. 2 Ranks.
{ 0x08010004, 0x2B8 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw1.
{ 0x08020000, 0x2BC / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw2.
{ 0x080D0000, 0x2C0 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw3.
{ 0x08033131, 0x2C8 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw6.
{ 0x080B0000, 0x2CC / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw8.
{ 0x0C0E5D5D, 0x2D0 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw9.
{ 0x080C5D5D, 0x2D4 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw10.
{ 0x0C0D0808, 0x2D8 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw12.
{ 0x0C0D0000, 0x2DC / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw13.
{ 0x08161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw14.
{ 0x08010004, 0x2E4 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw_extra.
{ 0x00000000, 0x340 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_dev_select. Both devices.
{ 0x0051004F, 0x450 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_zcal_mrw_cmd.
{ 0x40000001, 0x45C / 4, DRAM_CC_LPDDR4X_8GB }, // emc_zcal_init_dev1.
{ 0x00000000, 0x594 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_pmacro_tx_pwrd4.
{ 0x00001000, 0x598 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_pmacro_tx_pwrd5.
{ 0x00000001, 0x630 / 4, DRAM_CC_LPDDR4X_8GB }, // mc_emem_adr_cfg. 2 Ranks.
{ 0x00002000, 0x64C / 4, DRAM_CC_LPDDR4X_8GB }, // mc_emem_cfg. 8GB total density.
{ 0x00000002, 0x680 / 4, DRAM_CC_LPDDR4X_8GB }, // mc_emem_arb_timing_r2r.
{ 0x02020001, 0x694 / 4, DRAM_CC_LPDDR4X_8GB }, // mc_emem_arb_da_turns.
// Moved to default config.
// { 0xE4FACB43, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override) }, // + TSEC, NVENC.
// { 0x0600FED3, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override1) }, // + TSECB, TSEC1, TSECB1.
{ 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_adr_cfg) }, // 2 Ranks.
{ 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw1) },
{ 0x08020000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw2) },
{ 0x080D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw3) },
{ 0x08033131, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw6) },
{ 0x080B0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw8) },
{ 0x0C0E5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw9) },
{ 0x080C5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw10) },
{ 0x0C0D0808, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw12) },
{ 0x0C0D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw13) },
{ 0x08161414, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw14) },
{ 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw_extra) },
{ 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_dev_select) }, // Both devices.
{ 0x0051004F, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_mrw_cmd) },
{ 0x40000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_init_dev1) },
{ 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd4) },
{ 0x00001000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd5) },
{ 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_adr_cfg) }, // 2 Ranks.
{ 0x00002000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
{ 0x00000002, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_timing_r2r) },
{ 0x02020001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_da_turns) },
};
#undef DCFG_OFFSET_OF

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -225,7 +225,6 @@ typedef struct _sdram_params_t210b01_t
u32 emc_r2p;
/* Specifies the value for EMC_W2P */
u32 emc_w2p;
/* Specifies the value for EMC_RD_RCD */
u32 emc_tppd;
u32 emc_trtm;
@ -235,6 +234,7 @@ typedef struct _sdram_params_t210b01_t
u32 emc_tr2ref;
u32 emc_ccdmw;
/* Specifies the value for EMC_RD_RCD */
u32 emc_rd_rcd;
/* Specifies the value for EMC_WR_RCD */
u32 emc_wr_rcd;

View File

@ -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();
}

View File

@ -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);

View File

@ -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.

View File

@ -75,7 +75,7 @@ typedef struct _max77620_regulator_t
static const max77620_regulator_t _pmic_regulators[] = {
{ "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} },
{ "sd1", 12500, 600000, 1125000, 1175000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
{ "sd1", 12500, 600000, 1125000, 1237500, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
{ "sd2", 12500, 600000, 1325000, 1350000, REGULATOR_SD, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD2, 1, 5, 2 }} },
{ "sd3", 12500, 600000, 1800000, 1800000, REGULATOR_SD, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD3, 0, 3, 3 }} },
{ "ldo0", 25000, 800000, 1200000, 1200000, REGULATOR_LDO, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO0, 3, 7, 0 }} },

View File

@ -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();

View File

@ -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);

View File

@ -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;
@ -281,6 +281,14 @@ void se_aes_iv_clear(u32 ks)
}
}
void se_aes_iv_updated_clear(u32 ks)
{
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
{
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(UPDATED_IV) | SE_KEYTABLE_PKT(i);
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
}
}
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
{
@ -292,6 +300,26 @@ int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE);
}
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
{
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP) |
SE_CRYPTO_HASH(HASH_ENABLE);
}
else
{
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) |
SE_CRYPTO_HASH(HASH_ENABLE);
}
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
}
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
@ -459,6 +487,23 @@ int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, vo
return 1;
}
static void se_calc_sha256_get_hash(void *hash, u32 *msg_left)
{
u32 hash32[SE_SHA_256_SIZE / 4];
// Backup message left.
if (msg_left)
{
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
}
// Copy output hash.
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
memcpy(hash, hash32, SE_SHA_256_SIZE);
}
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot)
{
int res;
@ -468,6 +513,17 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
return 0;
// Src size of 0 is not supported, so return null string sha256.
// if (!src_size)
// {
// const u8 null_hash[SE_SHA_256_SIZE] = {
// 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
// 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
// };
// memcpy(hash, null_hash, SE_SHA_256_SIZE);
// return 1;
// }
// Setup config for SHA256.
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_SHA_CONFIG_REG) = sha_cfg;
@ -506,19 +562,7 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
res = _se_execute(SE_OP_START, NULL, 0, src, src_size, is_oneshot);
if (is_oneshot)
{
// Backup message left.
if (msg_left)
{
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
}
// Copy output hash.
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
memcpy(hash, hash32, SE_SHA_256_SIZE);
}
se_calc_sha256_get_hash(hash, msg_left);
return res;
}
@ -530,20 +574,9 @@ int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size)
int se_calc_sha256_finalize(void *hash, u32 *msg_left)
{
u32 hash32[SE_SHA_256_SIZE / 4];
int res = _se_execute_finalize();
// Backup message left.
if (msg_left)
{
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
}
// Copy output hash.
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
memcpy(hash, hash32, SE_SHA_256_SIZE);
se_calc_sha256_get_hash(hash, msg_left);
return res;
}
@ -620,3 +653,62 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
se_aes_crypt_cbc(3, DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize);
se_aes_key_clear(3);
}
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
{
int res = 0;
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);
// Generate sub key
if (!se_aes_crypt_hash(ks, ENCRYPT, key, SE_KEY_128_SIZE, key, SE_KEY_128_SIZE))
goto out;
_gf256_mul_x(key);
if (src_size & 0xF)
_gf256_mul_x(key);
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) |
SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
se_aes_iv_clear(ks);
se_aes_iv_updated_clear(ks);
u32 num_blocks = (src_size + 0xf) >> 4;
if (num_blocks > 1)
{
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2;
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size))
goto out;
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
}
if (src_size & 0xf)
{
memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf);
last_block[src_size & 0xf] = 0x80;
}
else if (src_size >= SE_AES_BLOCK_SIZE)
{
memcpy(last_block, src + src_size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE);
}
for (u32 i = 0; i < SE_KEY_128_SIZE; i++)
last_block[i] ^= key[i];
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, SE_AES_BLOCK_SIZE);
u32 *dst32 = (u32 *)dst;
for (u32 i = 0; i < (SE_KEY_128_SIZE / 4); i++)
dst32[i] = SE(SE_HASH_RESULT_REG + (i * 4));
out:;
free(key);
free(last_block);
return res;
}

View File

@ -30,7 +30,9 @@ void se_aes_iv_set(u32 ks, void *iv);
void se_aes_key_get(u32 ks, void *key, u32 size);
void se_aes_key_clear(u32 ks);
void se_aes_iv_clear(u32 ks);
void se_aes_iv_updated_clear(u32 ks);
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
@ -42,5 +44,6 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u6
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
int se_calc_sha256_finalize(void *hash, u32 *msg_left);
int se_gen_prng128(void *dst);
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size);
#endif

View File

@ -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]);

View File

@ -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);

View File

@ -76,7 +76,9 @@
#define ACTMON_HISTOGRAM_DATA_BASE 0x380
#define ACTMON_HISTOGRAM_DATA_NUM 32
#define ACTMON_FREQ 19200000
#define ACTMON_FREQ 19200000
#define ACTMON_PERIOD_MS 20
#define DEV_COUNT_WEIGHT 5
typedef struct _actmon_dev_reg_t
{
@ -91,11 +93,9 @@ typedef struct _actmon_dev_reg_t
vu32 avg_count;
vu32 intr_status;
vu32 ctrl2;
vu32 unk[5];
vu32 rsvd[5];
} actmon_dev_reg_t;
u32 sample_period = 0;
void actmon_hist_enable(actmon_hist_src_t src)
{
ACTMON(ACTMON_HISTOGRAM_CONFIG) = ACTMON_HIST_CFG_SOURCE(src) | ACTMON_HIST_CFG_ACTIVE;
@ -120,10 +120,10 @@ void actmon_dev_enable(actmon_dev_t dev)
{
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
regs->init_avg = 0;
regs->count_weight = 5;
regs->init_avg = ACTMON_FREQ * ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT / 100;
regs->count_weight = DEV_COUNT_WEIGHT;
regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC;
regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC | ACTMON_DEV_CTRL_K_VAL(7); // 128 samples average.
}
void actmon_dev_disable(actmon_dev_t dev)
@ -138,7 +138,7 @@ u32 actmon_dev_get_load(actmon_dev_t dev)
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
// Get load-based sampling. 1 decimal point precision.
u32 load = regs->count / (ACTMON_FREQ / 1000);
u32 load = regs->count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
return load;
}
@ -148,7 +148,7 @@ u32 actmon_dev_get_load_avg(actmon_dev_t dev)
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
// Get load-based sampling. 1 decimal point precision.
u32 avg_load = regs->avg_count / (ACTMON_FREQ / 1000);
u32 avg_load = regs->avg_count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
return avg_load;
}
@ -162,9 +162,8 @@ void actmon_init()
{
clock_enable_actmon();
// Set period to 200ms.
ACTMON(ACTMON_GLB_PERIOD_CTRL) &= ~ACTMON_GLB_PERIOD_USEC;
ACTMON(ACTMON_GLB_PERIOD_CTRL) |= ACTMON_GLB_PERIOD_SAMPLE(200);
// Set period.
ACTMON(ACTMON_GLB_PERIOD_CTRL) = ACTMON_GLB_PERIOD_SAMPLE(ACTMON_PERIOD_MS);
}
void actmon_end()

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -167,11 +167,8 @@ int fuse_set_sbk()
void fuse_wait_idle()
{
u32 ctrl;
do
{
ctrl = FUSE(FUSE_CTRL);
} while (((ctrl >> 16) & 0x1f) != 4);
while (((FUSE(FUSE_CTRL) >> 16) & 0x1F) != FUSE_STATUS_IDLE)
;
}
u32 fuse_read(u32 addr)

View File

@ -255,11 +255,32 @@
#define FUSE_SPARE_BIT_31 0x3FC
/*! Fuse commands. */
#define FUSE_IDLE 0x0
#define FUSE_READ 0x1
#define FUSE_WRITE 0x2
#define FUSE_SENSE 0x3
#define FUSE_CMD_MASK 0x3
/*! Fuse status. */
#define FUSE_STATUS_RESET 0
#define FUSE_STATUS_POST_RESET 1
#define FUSE_STATUS_LOAD_ROW0 2
#define FUSE_STATUS_LOAD_ROW1 3
#define FUSE_STATUS_IDLE 4
#define FUSE_STATUS_READ_SETUP 5
#define FUSE_STATUS_READ_STROBE 6
#define FUSE_STATUS_SAMPLE_FUSES 7
#define FUSE_STATUS_READ_HOLD 8
#define FUSE_STATUS_FUSE_SRC_SETUP 9
#define FUSE_STATUS_WRITE_SETUP 10
#define FUSE_STATUS_WRITE_ADDR_SETUP 11
#define FUSE_STATUS_WRITE_PROGRAM 12
#define FUSE_STATUS_WRITE_ADDR_HOLD 13
#define FUSE_STATUS_FUSE_SRC_HOLD 14
#define FUSE_STATUS_LOAD_RIR 15
#define FUSE_STATUS_READ_BEFORE_WRITE_SETUP 16
#define FUSE_STATUS_READ_DEASSERT_PD 17
/*! Fuse cache registers. */
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))

View File

@ -277,12 +277,12 @@ static void _config_regulators(bool tegra_t210)
// Disable low battery shutdown monitor.
max77620_low_battery_monitor_config(false);
// Disable SDMMC1 IO power.
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
// Disable SDMMC1 IO/Core power.
max7762x_regulator_enable(REGULATOR_LDO2, false);
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
sd_power_cycle_time_start = get_tmr_ms();
// Disable LCD DVDD.
// Disable LCD DVDD to make sure it's in a reset state.
max7762x_regulator_enable(REGULATOR_LDO0, false);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);

View File

@ -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);

View File

@ -180,6 +180,7 @@
#define IRQ_EVENT_GPIO_A 162
#define IRQ_EVENT_GPIO_B 163
#define IRQ_EVENT_GPIO_C 164
#define IRQ_EVENT_GPIO_D_T210B01 165
#define IRQ_FLOW_RSM_CPU 168
#define IRQ_FLOW_RSM_COP 169
#define IRQ_TMR_SHARED 170

View File

@ -132,6 +132,9 @@
#define PMC_CNTRL2_SYSCLK_ORRIDE BIT(10)
#define PMC_CNTRL2_HOLD_CKE_LOW_EN BIT(12)
#define PMC_CNTRL2_ALLOW_PULSE_WAKE BIT(14)
#define APBDEV_PMC_FUSE_CONTROL 0x450
#define PMC_FUSE_CONTROL_PS18_LATCH_SET BIT(8)
#define PMC_FUSE_CONTROL_PS18_LATCH_CLR BIT(9)
#define APBDEV_PMC_IO_DPD3_REQ 0x45C
#define APBDEV_PMC_IO_DPD4_REQ 0x464
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
@ -177,6 +180,12 @@
#define PMC_LED_BREATHING_COUNTER_HZ 32768
#define APBDEV_PMC_LED_BREATHING_STATUS 0xB5C
#define PMC_LED_BREATHING_FSM_STATUS_MASK 0x7
#define PMC_LED_BREATHING_FSM_STS_IDLE 0
#define PMC_LED_BREATHING_FSM_STS_UP_RAMP 1
#define PMC_LED_BREATHING_FSM_STS_PLATEAU 2
#define PMC_LED_BREATHING_FSM_STS_DOWN_RAMP 3
#define PMC_LED_BREATHING_FSM_STS_SHORT_LOW_PERIOD 4
#define PMC_LED_BREATHING_FSM_STS_LONG_LOW_PERIOD 5
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
#define PMC_TZRAM_PWR_CNTRL_SD BIT(0)
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC

View File

@ -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

View File

@ -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;

View File

@ -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
{

View File

@ -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
{

View File

@ -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;
@ -1292,21 +1292,36 @@ static int _sd_storage_set_card_bus_speed(sdmmc_storage_t *storage, u32 hs_type,
return 0;
}
static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)
int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *fmodes)
{
if (sdmmc_get_bus_width(storage->sdmmc) != SDMMC_BUS_WIDTH_4)
return 0;
if (!buf)
buf = (u8 *)SDMMC_UPPER_BUFFER;
if (!_sd_storage_switch_get(storage, buf))
return 0;
u8 access_mode = buf[13];
u16 power_limit = buf[7] | (buf[6] << 8);
fmodes->access_mode = buf[13] | (buf[12] << 8);
fmodes->cmd_system = buf[11] | (buf[10] << 8);
fmodes->driver_strength = buf[9] | (buf[8] << 8);
fmodes->power_limit = buf[7] | (buf[6] << 8);
return 1;
}
static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)
{
sd_func_modes_t fmodes;
if (sdmmc_get_bus_width(storage->sdmmc) != SDMMC_BUS_WIDTH_4)
return 0;
if (!sd_storage_get_fmodes(storage, buf, &fmodes))
return 0;
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
u16 cmd_system = buf[11] | (buf[10] << 8);
DPRINTF("[SD] access: %02X, power: %02X, cmd: %02X\n", access_mode, power_limit, cmd_system);
DPRINTF("[SD] access: %02X, power: %02X, cmd: %02X\n", fmodes.access_mode, fmodes.power_limit, fmodes.cmd_system);
#else
DPRINTF("[SD] access: %02X, power: %02X\n", access_mode, power_limit);
DPRINTF("[SD] access: %02X, power: %02X\n", fmodes.access_mode, fmodes.power_limit);
#endif
u32 hs_type = 0;
@ -1315,11 +1330,11 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
case SDHCI_TIMING_UHS_DDR200:
// Fall through if DDR200 is not supported.
if (cmd_system & SD_MODE_UHS_DDR200)
if (fmodes.cmd_system & SD_MODE_UHS_DDR200)
{
DPRINTF("[SD] setting bus speed to DDR200\n");
storage->csd.busspeed = 200;
_sd_storage_set_power_limit(storage, power_limit, buf);
_sd_storage_set_power_limit(storage, fmodes.power_limit, buf);
return _sd_storage_enable_DDR200(storage, buf);
}
#endif
@ -1327,7 +1342,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
case SDHCI_TIMING_UHS_SDR104:
case SDHCI_TIMING_UHS_SDR82:
// Fall through if not supported.
if (access_mode & SD_MODE_UHS_SDR104)
if (fmodes.access_mode & SD_MODE_UHS_SDR104)
{
type = SDHCI_TIMING_UHS_SDR104;
hs_type = UHS_SDR104_BUS_SPEED;
@ -1345,7 +1360,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
}
case SDHCI_TIMING_UHS_SDR50:
if (access_mode & SD_MODE_UHS_SDR50)
if (fmodes.access_mode & SD_MODE_UHS_SDR50)
{
type = SDHCI_TIMING_UHS_SDR50;
hs_type = UHS_SDR50_BUS_SPEED;
@ -1355,7 +1370,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
}
/*
case SDHCI_TIMING_UHS_DDR50:
if (access_mode & SD_MODE_UHS_DDR50)
if (fmodes.access_mode & SD_MODE_UHS_DDR50)
{
type = SDHCI_TIMING_UHS_DDR50;
hs_type = UHS_DDR50_BUS_SPEED;
@ -1365,7 +1380,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
}
*/
case SDHCI_TIMING_UHS_SDR25:
if (access_mode & SD_MODE_UHS_SDR25)
if (fmodes.access_mode & SD_MODE_UHS_SDR25)
{
type = SDHCI_TIMING_UHS_SDR25;
hs_type = UHS_SDR25_BUS_SPEED;
@ -1382,7 +1397,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
// Try to raise the power limit to let the card perform better.
if (hs_type != UHS_SDR25_BUS_SPEED)
_sd_storage_set_power_limit(storage, power_limit, buf);
_sd_storage_set_power_limit(storage, fmodes.power_limit, buf);
// Setup and set selected card and bus speed.
if (!_sd_storage_set_card_bus_speed(storage, hs_type, buf))
@ -1402,17 +1417,17 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf)
{
if (!_sd_storage_switch_get(storage, buf))
sd_func_modes_t fmodes;
if (!sd_storage_get_fmodes(storage, buf, &fmodes))
return 0;
u8 access_mode = buf[13];
u16 power_limit = buf[7] | buf[6] << 8;
DPRINTF("[SD] access: %02X, power: %02X\n", access_mode, power_limit);
DPRINTF("[SD] access: %02X, power: %02X\n", fmodes.access_mode, fmodes.power_limit);
// Try to raise the power limit to let the card perform better.
_sd_storage_set_power_limit(storage, power_limit, buf);
_sd_storage_set_power_limit(storage, fmodes.power_limit, buf);
if (!(access_mode & SD_MODE_HIGH_SPEED))
if (!(fmodes.access_mode & SD_MODE_HIGH_SPEED))
return 1;
if (!_sd_storage_set_card_bus_speed(storage, HIGH_SPEED_BUS_SPEED, buf))
@ -1511,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;
@ -1530,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];
@ -1581,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:
@ -1683,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))
@ -1760,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;

View File

@ -19,8 +19,12 @@
#define _SDMMC_H_
#include <utils/types.h>
#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
@ -195,6 +199,14 @@ typedef struct _sdmmc_storage_t
sd_ssr_t ssr;
} sdmmc_storage_t;
typedef struct _sd_func_modes_t
{
u16 access_mode;
u16 cmd_system;
u16 driver_strength;
u16 power_limit;
} sd_func_modes_t;
int sdmmc_storage_end(sdmmc_storage_t *storage);
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
@ -209,6 +221,7 @@ int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf);
int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf);
int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *functions);
int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf);
int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf);
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage);

View File

@ -56,16 +56,19 @@ typedef struct _gamepad_report_t
typedef struct _jc_cal_t
{
bool cl_done;
bool cr_done;
u16 clx_max;
u16 clx_min;
u16 cly_max;
u16 cly_min;
u16 crx_max;
u16 crx_min;
u16 cry_max;
u16 cry_min;
// 15ms * JC_CAL_MAX_STEPS = 240 ms.
#define JC_CAL_MAX_STEPS 16
u32 cl_step;
u32 cr_step;
u16 clx_max;
u16 clx_min;
u16 cly_max;
u16 cly_min;
u16 crx_max;
u16 crx_min;
u16 cry_max;
u16 cry_min;
} jc_cal_t;
static jc_cal_t jc_cal_ctx;
@ -74,34 +77,40 @@ static usb_ops_t usb_ops;
static bool _jc_calibration(jc_gamepad_rpt_t *jc_pad)
{
// Calibrate left stick.
if (!jc_cal_ctx.cl_done)
if (jc_cal_ctx.cl_step != JC_CAL_MAX_STEPS)
{
if (jc_pad->conn_l
&& jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400
&& jc_pad->lstick_x < 0xC00 && jc_pad->lstick_y < 0xC00)
{
jc_cal_ctx.cl_step++;
jc_cal_ctx.clx_max = jc_pad->lstick_x + 0x72;
jc_cal_ctx.clx_min = jc_pad->lstick_x - 0x72;
jc_cal_ctx.cly_max = jc_pad->lstick_y + 0x72;
jc_cal_ctx.cly_min = jc_pad->lstick_y - 0x72;
jc_cal_ctx.cl_done = true;
if (jc_cal_ctx.cl_step != JC_CAL_MAX_STEPS)
return false;
}
else
return false;
}
// Calibrate right stick.
if (!jc_cal_ctx.cr_done)
if (jc_cal_ctx.cr_step != JC_CAL_MAX_STEPS)
{
if (jc_pad->conn_r
&& jc_pad->rstick_x > 0x400 && jc_pad->rstick_y > 0x400
&& jc_pad->rstick_x < 0xC00 && jc_pad->rstick_y < 0xC00)
{
jc_cal_ctx.cr_step++;
jc_cal_ctx.crx_max = jc_pad->rstick_x + 0x72;
jc_cal_ctx.crx_min = jc_pad->rstick_x - 0x72;
jc_cal_ctx.cry_max = jc_pad->rstick_y + 0x72;
jc_cal_ctx.cry_min = jc_pad->rstick_y - 0x72;
jc_cal_ctx.cr_done = true;
if (jc_cal_ctx.cr_step != JC_CAL_MAX_STEPS)
return false;
}
else
return false;
@ -122,7 +131,7 @@ static bool _jc_poll(gamepad_report_t *rpt)
if (jc_pad->l3 && jc_pad->home)
return true;
if (!jc_cal_ctx.cl_done || !jc_cal_ctx.cr_done)
if (jc_cal_ctx.cl_step != JC_CAL_MAX_STEPS || jc_cal_ctx.cr_step != JC_CAL_MAX_STEPS)
{
if (!_jc_calibration(jc_pad))
return false;
@ -130,9 +139,9 @@ static bool _jc_poll(gamepad_report_t *rpt)
// Re-calibrate on disconnection.
if (!jc_pad->conn_l)
jc_cal_ctx.cl_done = false;
jc_cal_ctx.cl_step = 0;
if (!jc_pad->conn_r)
jc_cal_ctx.cr_done = false;
jc_cal_ctx.cr_step = 0;
// Calculate left analog stick.
if (jc_pad->lstick_x <= jc_cal_ctx.clx_max && jc_pad->lstick_x >= jc_cal_ctx.clx_min)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* 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))
{

View File

@ -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);

View File

@ -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,
@ -39,7 +39,7 @@ static void _s_putn(u32 v, int base, char fill, int fcnt)
static const char digits[] = "0123456789ABCDEF";
char *p;
char buf[65];
char buf[65]; // Number char size + leftover for padding.
int c = fcnt;
bool negative = false;
@ -93,44 +93,66 @@ void s_printf(char *out_buf, const char *fmt, ...)
fmt++;
fill = 0;
fcnt = 0;
// Check for padding. Number or space based.
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
{
fcnt = *fmt;
fcnt = *fmt; // Padding size or padding type.
fmt++;
if (*fmt >= '0' && *fmt <= '9')
{
// Padding size exists. Previous char was type.
fill = fcnt;
fcnt = *fmt - '0';
fmt++;
parse_padding_dec:
// Parse padding size extra digits.
if (*fmt >= '0' && *fmt <= '9')
{
fcnt = fcnt * 10 + *fmt - '0';
fmt++;
goto parse_padding_dec;
}
}
else
{
// No padding type, use space. (Max padding size is 9).
fill = ' ';
fcnt -= '0';
}
}
switch (*fmt)
{
case 'c':
_s_putc(va_arg(ap, u32));
char c = va_arg(ap, u32);
if (c != '\0')
_s_putc(c);
break;
case 's':
_s_puts(va_arg(ap, char *));
break;
case 'd':
_s_putn(va_arg(ap, u32), 10, fill, fcnt);
break;
case 'p':
case 'P':
case 'x':
case 'X':
_s_putn(va_arg(ap, u32), 16, fill, fcnt);
break;
case '%':
_s_putc('%');
break;
case '\0':
goto out;
default:
_s_putc('%');
_s_putc(*fmt);
@ -160,44 +182,66 @@ void s_vprintf(char *out_buf, const char *fmt, va_list ap)
fmt++;
fill = 0;
fcnt = 0;
// Check for padding. Number or space based.
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
{
fcnt = *fmt;
fcnt = *fmt; // Padding size or padding type.
fmt++;
if (*fmt >= '0' && *fmt <= '9')
{
// Padding size exists. Previous char was type.
fill = fcnt;
fcnt = *fmt - '0';
fmt++;
parse_padding_dec:
// Parse padding size extra digits.
if (*fmt >= '0' && *fmt <= '9')
{
fcnt = fcnt * 10 + *fmt - '0';
fmt++;
goto parse_padding_dec;
}
}
else
{
// No padding type, use space. (Max padding size is 9).
fill = ' ';
fcnt -= '0';
}
}
switch(*fmt)
switch (*fmt)
{
case 'c':
_s_putc(va_arg(ap, u32));
char c = va_arg(ap, u32);
if (c != '\0')
_s_putc(c);
break;
case 's':
_s_puts(va_arg(ap, char *));
break;
case 'd':
_s_putn(va_arg(ap, u32), 10, fill, fcnt);
break;
case 'p':
case 'P':
case 'x':
case 'X':
_s_putn(va_arg(ap, u32), 16, fill, fcnt);
break;
case '%':
_s_putc('%');
break;
case '\0':
goto out;
default:
_s_putc('%');
_s_putc(*fmt);

View File

@ -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,
@ -102,8 +102,9 @@ u64 sqrt64(u64 num)
return square_root;
}
#define TLONG_MAX ((long)(((unsigned long)(~0L)) >> 1))
#define TLONG_MIN ((long)(~TLONG_MAX))
#define TULONG_MAX ((unsigned long)((unsigned long)(~0L)))
#define TLONG_MAX ((long)(((unsigned long)(~0L)) >> 1))
#define TLONG_MIN ((long)(~TLONG_MAX))
#define ISSPACE(ch) ((ch >= '\t' && ch <= '\r') || (ch == ' '))
#define ISDIGIT(ch) ( ch >= '0' && ch <= '9' )
#define ISALPHA(ch) ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
@ -162,7 +163,7 @@ long strtol(const char *nptr, char **endptr, register int base)
* Set any if any `digits' consumed; make it negative to indicate
* overflow.
*/
cutoff = neg ? -(unsigned long)TLONG_MIN : TLONG_MAX;
cutoff = neg ? -(unsigned long)TLONG_MIN : (base == 16 ? TULONG_MAX : TLONG_MAX);
cutlim = cutoff % (unsigned long)base;
cutoff /= (unsigned long)base;
for (acc = 0, any = 0;; c = *s++) {
@ -210,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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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!");

View File

@ -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;

View File

@ -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')
{

View File

@ -169,7 +169,8 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20220209", 13, 16, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 14.0.0 - 14.1.2.
{ "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);

View File

@ -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;

View File

@ -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);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2022 CTCaer
* Copyright (c) 2019-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* 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);

View File

@ -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;

View File

@ -448,362 +448,349 @@ static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
};
// All kip patch offsets are without the 0x100-sized header.
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\xBE\xA9\xF4\x4F\x01\xA9", "\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\xBE\xA9\xF4\x4F\x01\xA9", "\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
};

View File

@ -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");

View File

@ -1,7 +1,7 @@
/*
* L4T Loader for Tegra X1
*
* Copyright (c) 2020-2023 CTCaer
* Copyright (c) 2020-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -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 3
#define L4T_FIRMWARE_REV 0x33524556 // REV3.
#define L4T_LOADER_API_REV 5
#define L4T_FIRMWARE_REV 0x35524556 // REV5.
#ifdef DEBUG_UART_PORT
#include <soc/uart.h>
@ -109,13 +112,11 @@
#define BPMPFW_B01_DTB_EMC_ENABLE_OFF 0x20
#define BPMPFW_B01_DTB_EMC_VALUES_OFF 0x4C
#define BPMPFW_B01_DTB_EMC_FREQ_VAL 0x8C
#define BPMPFW_B01_DTB_EMC_SCC_OFF 0x108C
#define BPMPFW_B01_DTB_EMC_PLLM_DIVM_VAL 0x10A4
#define BPMPFW_B01_DTB_EMC_PLLM_DIVN_VAL 0x10A8
#define BPMPFW_B01_DTB_EMC_PLLM_DIVP_VAL 0x10AC
#define BPMPFW_B01_DTB_EMC_OPT_VAL 0xEDC
#define BPMPFW_B01_DTB_EMC_TBL_START(idx) (BPMPFW_B01_DTB_EMC_TBL_OFF + BPMPFW_B01_DTB_EMC_TBL_SZ * (idx))
#define BPMPFW_B01_DTB_EMC_TBL_SET_VAL(idx, off, val) (*(u32 *)(BPMPFW_B01_DTB_EMC_TBL_START(idx) + (off)) = (val))
#define BPMPFW_B01_DTB_EMC_TBL_SET_FREQ(idx, freq) (*(u32 *)(BPMPFW_B01_DTB_EMC_TBL_START(idx) + BPMPFW_B01_DTB_EMC_FREQ_VAL) = (freq))
#define BPMPFW_B01_DTB_EMC_TBL_SET_OPTC(idx, opt) (*(u32 *)(BPMPFW_B01_DTB_EMC_TBL_START(idx) + BPMPFW_B01_DTB_EMC_OPT_VAL) = (opt))
#define BPMPFW_B01_DTB_EMC_TBL_SET_NAME(idx, name) (strcpy((char *)(BPMPFW_B01_DTB_EMC_TBL_START(idx) + BPMPFW_B01_DTB_EMC_NAME_VAL), (name)))
#define BPMPFW_B01_DTB_EMC_TBL_ENABLE(idx) (*(char *)(BPMPFW_B01_DTB_EMC_TBL_START(idx) + BPMPFW_B01_DTB_EMC_ENABLE_OFF) = 'n')
#define BPMPFW_B01_DTB_EMC_TBL_OFFSET(idx) ((void *)(BPMPFW_B01_DTB_EMC_TBL_START(idx) + BPMPFW_B01_DTB_EMC_VALUES_OFF))
@ -258,6 +259,7 @@ typedef struct _l4t_ctxt_t
int ram_oc_freq;
int ram_oc_vdd2;
int ram_oc_vddq;
int ram_oc_opt;
u32 serial_port;
u32 sc7entry_size;
@ -265,10 +267,11 @@ typedef struct _l4t_ctxt_t
emc_table_t *mtc_table;
} l4t_ctxt_t;
#define DRAM_VDD2_OC_MIN_VOLTAGE 1050
#define DRAM_VDD2_OC_MAX_VOLTAGE 1175
#define DRAM_VDDQ_OC_MIN_VOLTAGE 550
#define DRAM_VDDQ_OC_MAX_VOLTAGE 650
#define DRAM_VDD2_OC_MIN_VOLTAGE 1050
#define DRAM_VDD2_OC_MAX_VOLTAGE 1175
#define DRAM_VDD2Q_OC_MAX_VOLTAGE 1237
#define DRAM_VDDQ_OC_MIN_VOLTAGE 550
#define DRAM_VDDQ_OC_MAX_VOLTAGE 650
#define DRAM_T210B01_TBL_MAX_FREQ 1600000
//! TODO: Update on dram config changes.
@ -362,8 +365,6 @@ static void _l4t_sdram_lp0_save_params(bool t210b01)
} else {
s(MC_VIDEO_PROTECT_REG_CTRL, 1:0, secure_scratch14, 31:30);
}
s32(MC_VIDEO_PROTECT_GPU_OVERRIDE_0, secure_scratch12);
s(MC_VIDEO_PROTECT_GPU_OVERRIDE_1, 15:0, secure_scratch49, 15:0);
// TZD.
s(MC_SEC_CARVEOUT_BOM, 31:20, secure_scratch53, 23:12);
@ -471,14 +472,6 @@ static void _l4t_mc_config_carveout(bool t210b01)
// Disabled VPR carveout. DT decides if enabled or not.
MC(MC_VIDEO_PROTECT_BOM) = 0xFFF00000;
MC(MC_VIDEO_PROTECT_SIZE_MB) = 0;
if (!t210b01)
{
// For T210 force the following values for Falcon to configure WPR access.
// For T210B01 use default, already set from dram config.
// HOS forces 1 and 0.
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 0x2A800000;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 2;
}
MC(MC_VIDEO_PROTECT_REG_CTRL) = VPR_CTRL_TZ_SECURE | VPR_CTRL_LOCKED;
// Temporarily disable TZDRAM carveout. For launching coldboot TZ.
@ -486,11 +479,6 @@ static void _l4t_mc_config_carveout(bool t210b01)
MC(MC_SEC_CARVEOUT_SIZE_MB) = 0;
MC(MC_SEC_CARVEOUT_REG_CTRL) = 0;
// Disable MTS carveout. Only CCPLEX has access.
MC(MC_SEC_CARVEOUT_BOM) = 0xFFF00000;
MC(MC_SEC_CARVEOUT_SIZE_MB) = 0;
MC(MC_SEC_CARVEOUT_REG_CTRL) = 0;
// Print real one, not temp disabled.
UPRINTF("TZD: TZDRAM Carveout: %08X - %08X\n", TZDRAM_BASE, TZDRAM_BASE - 1 + TZDRAM_SIZE);
@ -657,18 +645,7 @@ static void _l4t_mc_config_carveout(bool t210b01)
*/
carveout_base -= CARVEOUT_NVDEC_TSEC_ENABLE ? ALIGN(CARVEOUT_TSEC_SIZE, SZ_1M) : 0;
MC(MC_SECURITY_CARVEOUT4_BOM) = CARVEOUT_NVDEC_TSEC_ENABLE ? carveout_base : 0;
MC(MC_SECURITY_CARVEOUT4_BOM_HI) = 0x0;
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = CARVEOUT_NVDEC_TSEC_ENABLE ? CARVEOUT_TSEC_SIZE / SZ_128K : 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_TSEC | SEC_CARVEOUT_CA2_W_TSEC;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = SEC_CARVEOUT_CA4_R_TSECB | SEC_CARVEOUT_CA4_W_TSECB;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT4_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
SEC_CARVEOUT_CFG_RD_FALCON_HS |
SEC_CARVEOUT_CFG_WR_FALCON_HS |
@ -681,18 +658,7 @@ static void _l4t_mc_config_carveout(bool t210b01)
// Set TSECA carveout. Only for NVDEC bl/prod and TSEC. Otherwise disabled.
carveout_base -= CARVEOUT_NVDEC_TSEC_ENABLE ? ALIGN(CARVEOUT_TSEC_SIZE, SZ_1M) : 0;
MC(MC_SECURITY_CARVEOUT5_BOM) = CARVEOUT_NVDEC_TSEC_ENABLE ? carveout_base : 0;
MC(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = CARVEOUT_NVDEC_TSEC_ENABLE ? CARVEOUT_TSEC_SIZE / SZ_128K : 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_TSEC | SEC_CARVEOUT_CA2_W_TSEC;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT5_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
SEC_CARVEOUT_CFG_RD_FALCON_HS |
SEC_CARVEOUT_CFG_WR_FALCON_HS |
@ -757,6 +723,7 @@ static void _l4t_bpmpfw_b01_config(l4t_ctxt_t *ctxt)
{
char *ram_oc_txt = ctxt->ram_oc_txt;
u32 ram_oc_freq = ctxt->ram_oc_freq;
u32 ram_oc_opt = ctxt->ram_oc_opt;
u32 ram_id = fuse_read_dramid(true);
// Set default parameters.
@ -815,11 +782,12 @@ static void _l4t_bpmpfw_b01_config(l4t_ctxt_t *ctxt)
BPMPFW_B01_DTB_EMC_TBL_SET_NAME(tbl_idx, ram_oc_txt);
BPMPFW_B01_DTB_EMC_TBL_SET_FREQ(tbl_idx, ram_oc_freq);
BPMPFW_B01_DTB_EMC_TBL_SET_OPTC(tbl_idx, ram_oc_opt);
// Enable table.
BPMPFW_B01_DTB_EMC_TBL_ENABLE(tbl_idx);
UPRINTF("RAM Frequency set to: %d KHz. Voltage: %d mV\n", ram_oc_freq, ram_oc_volt);
UPRINTF("RAM Frequency set to: %d KHz. Voltage: %d mV\n", ram_oc_freq, ctxt->ram_oc_vdd2);
}
// Save BPMP-FW entrypoint for TZ.
@ -876,7 +844,7 @@ static void _l4t_bl33_cfg_set_key(char *env, char *key, char *val)
strcat(env, "\n");
}
static void _l4t_set_config(l4t_ctxt_t *ctxt, const ini_sec_t *ini_sec, int entry_idx, int is_list)
static void _l4t_set_config(l4t_ctxt_t *ctxt, const ini_sec_t *ini_sec, int entry_idx, int is_list, bool t210b01)
{
char *bl33_env = (char *)BL33_ENV_BASE;
bl33_env[0] = '\0';
@ -895,10 +863,13 @@ static void _l4t_set_config(l4t_ctxt_t *ctxt, const ini_sec_t *ini_sec, int entr
else if (!strcmp("ram_oc_vdd2", kv->key))
{
ctxt->ram_oc_vdd2 = atoi(kv->val);
if (ctxt->ram_oc_vdd2 > DRAM_VDD2_OC_MAX_VOLTAGE)
if (t210b01 && ctxt->ram_oc_vdd2 > DRAM_VDD2_OC_MAX_VOLTAGE)
ctxt->ram_oc_vdd2 = DRAM_VDD2_OC_MAX_VOLTAGE;
else if (!t210b01 && ctxt->ram_oc_vdd2 > DRAM_VDD2Q_OC_MAX_VOLTAGE)
ctxt->ram_oc_vdd2 = DRAM_VDD2Q_OC_MAX_VOLTAGE;
else if (ctxt->ram_oc_vdd2 < DRAM_VDD2_OC_MIN_VOLTAGE)
ctxt->ram_oc_vdd2 = 0;
ctxt->ram_oc_vdd2 = DRAM_VDD2_OC_MIN_VOLTAGE;
}
else if (!strcmp("ram_oc_vddq", kv->key))
{
@ -908,6 +879,8 @@ static void _l4t_set_config(l4t_ctxt_t *ctxt, const ini_sec_t *ini_sec, int entr
else if (ctxt->ram_oc_vddq < DRAM_VDDQ_OC_MIN_VOLTAGE)
ctxt->ram_oc_vddq = 0;
}
else if (!strcmp("ram_oc_opt", kv->key))
ctxt->ram_oc_opt = atoi(kv->val);
else if (!strcmp("uart_port", kv->key))
ctxt->serial_port = atoi(kv->val);
@ -958,7 +931,7 @@ void launch_l4t(const ini_sec_t *ini_sec, int entry_idx, int is_list, bool t210b
gfx_con_setpos(0, 0);
// Parse config.
_l4t_set_config(&ctxt, ini_sec, entry_idx, is_list);
_l4t_set_config(&ctxt, ini_sec, entry_idx, is_list, t210b01);
if (!ctxt.path)
{
@ -974,13 +947,6 @@ void launch_l4t(const ini_sec_t *ini_sec, int entry_idx, int is_list, bool t210b
return;
}
// U-BOOT does not support exfat.
if (sd_fs.fs_type == FS_EXFAT)
{
_l4t_crit_error("exFAT not supported", false);
return;
}
// Load BL31 (ATF/TrustZone fw).
if (!_l4t_sd_load(BL31_FW))
{
@ -1146,7 +1112,7 @@ void launch_l4t(const ini_sec_t *ini_sec, int entry_idx, int is_list, bool t210b
max7762x_regulator_set_voltage(REGULATOR_SD1, ctxt.ram_oc_vdd2 * 1000);
// Train the rest of the table, apply FSP WAR, set RAM to 800 MHz.
minerva_prep_boot_l4t(ctxt.ram_oc_freq);
minerva_prep_boot_l4t(ctxt.ram_oc_freq, ctxt.ram_oc_opt);
// Set emc table parameters and copy it.
int table_entries = minerva_get_mtc_table_entries();
@ -1193,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))) |

View File

@ -256,7 +256,7 @@
#define FF_FS_NORTC 1
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2023
#define FF_NORTC_YEAR 2024
/* The option FF_FS_NORTC switches timestamp function. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp

View File

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

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
*
* Copyright (c) 2018-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,
@ -665,7 +665,7 @@ static void _nyx_load_run()
gfx_con_setpos(0, 0);
WPRINTF("Old Nyx GUI found! There will be dragons!\n");
WPRINTF("\nUpdate the bootloader folder!\n\n");
WPRINTF("\nUpdate bootloader folder!\n\n");
WPRINTF("Press any key...");
msleep(1000);
@ -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.0.7", 0, 0 };
menu_t menu_top = { ment_top, "hekate v6.1.1", 0, 0 };
extern void pivot_stack(u32 stack_top);

View File

@ -91,9 +91,9 @@ static pllm_clk_config_t pllm_clk_config_table[] =
{38400, 2099200, 164, 3, 0}, // Custom. Normalized 2100 MHz.
{38400, 2131200, 111, 2, 0}, // JEDEC Standard. (T210B01 official max).
{38400, 2163200, 169, 3, 0}, // Custom. Normalized 2166 MHz.
{38400, 2188800, 57, 1, 0}, // Custom. Normalized 2200 MHz.
{38400, 2227200, 58, 1, 0}, // Custom. Normalized 2233 MHz.
{38400, 2265600, 59, 1, 0}, // Custom. Normalized 2266 MHz.
{38400, 2188800, 114, 2, 0}, // Custom. Normalized 2200 MHz.
{38400, 2227200, 116, 2, 0}, // Custom. Normalized 2233 MHz.
{38400, 2265600, 118, 2, 0}, // Custom. Normalized 2266 MHz.
{38400, 2291200, 179, 3, 0}, // Custom. Normalized 2300 MHz.
{38400, 2329600, 182, 3, 0}, // Custom. Normalized 2333 MHz.
{38400, 2361600, 123, 2, 0}, // Custom. Normalized 2366 MHz.
@ -1168,7 +1168,7 @@ static u32 _get_dram_temperature()
if (channel1_enabled)
{
_request_mmr_data(0x40040000, EMC_CHANNEL1);
mr4_1 = EMC(EMC_MRR);
mr4_1 = EMC(EMC_MRR) & 0xFFFF;
if (mr4_1 < 0xF001)
mr4_1 &= 0x7;
@ -1549,21 +1549,25 @@ static u32 _minerva_update_clock_tree_delay(emc_table_t *src_emc_entry, emc_tabl
if (upd_type_bits & 0x5400)
{
_request_mmr_data(0x80130000, channel1_enabled); // Dev0 MRR 19.
temp_ch0_0 = (EMC(EMC_MRR) & 0xFF) << 8;
temp_ch0_1 = EMC(EMC_MRR) & 0xFF00;
u32 mrr = EMC(EMC_MRR);
temp_ch0_0 = (mrr & 0xFF) << 8;
temp_ch0_1 = mrr & 0xFF00;
if (channel1_enabled)
{
temp_ch1_0 = (EMC_CH1(EMC_MRR) & 0xFF) << 8;
temp_ch1_1 = EMC_CH1(EMC_MRR) & 0xFF00;
mrr = EMC_CH1(EMC_MRR);
temp_ch1_0 = (mrr & 0xFF) << 8;
temp_ch1_1 = mrr & 0xFF00;
}
_request_mmr_data(0x80120000, channel1_enabled); // Dev0 MRR 18.
temp_ch0_0 |= EMC(EMC_MRR) & 0xFF;
temp_ch0_1 |= (EMC(EMC_MRR) & 0xFF00) >> 8;
mrr = EMC(EMC_MRR);
temp_ch0_0 |= mrr & 0xFF;
temp_ch0_1 |= (mrr & 0xFF00) >> 8;
if (channel1_enabled)
{
temp_ch1_0 |= EMC_CH1(EMC_MRR) & 0xFF;
temp_ch1_1 |= (EMC_CH1(EMC_MRR) & 0xFF00) >> 8;
mrr = EMC_CH1(EMC_MRR);
temp_ch1_0 |= mrr & 0xFF;
temp_ch1_1 |= (mrr & 0xFF00) >> 8;
}
}
@ -1723,21 +1727,25 @@ calc_dev2:
if (update_type <= PERIODIC_TRAINING_UPDATE && upd_type_bits & 0x5400)
{
_request_mmr_data(0x40130000, channel1_enabled); // Dev1 MRR 19.
temp_ch0_0 = (EMC(EMC_MRR) & 0xFF) << 8;
temp_ch0_1 = EMC(EMC_MRR) & 0xFF00;
u32 mrr = EMC(EMC_MRR);
temp_ch0_0 = (mrr& 0xFF) << 8;
temp_ch0_1 = mrr & 0xFF00;
if (channel1_enabled)
{
temp_ch1_0 = (EMC_CH1(EMC_MRR) & 0xFF) << 8;
temp_ch1_1 = EMC_CH1(EMC_MRR) & 0xFF00;
mrr = EMC_CH1(EMC_MRR);
temp_ch1_0 = (mrr & 0xFF) << 8;
temp_ch1_1 = mrr & 0xFF00;
}
_request_mmr_data(0x40120000, channel1_enabled); // Dev1 MRR 18
temp_ch0_0 |= EMC(EMC_MRR) & 0xFF;
temp_ch0_1 |= ((EMC(EMC_MRR) & 0xFF00) >> 8);
mrr = EMC(EMC_MRR);
temp_ch0_0 |= mrr & 0xFF;
temp_ch0_1 |= ((mrr & 0xFF00) >> 8);
if (channel1_enabled)
{
temp_ch1_0 |= EMC_CH1(EMC_MRR) & 0xFF;
temp_ch1_1 |= (EMC_CH1(EMC_MRR) & 0xFF00) >> 8;
mrr = EMC_CH1(EMC_MRR);
temp_ch1_0 |= mrr & 0xFF;
temp_ch1_1 |= (mrr & 0xFF00) >> 8;
}
}
@ -3280,7 +3288,7 @@ static u32 _minerva_set_clock(emc_table_t *src_emc_entry, emc_table_t *dst_emc_e
if (needs_wr_training)
training_command |= (1 << 3); // WR: Initiates WR Training.
if (needs_wr_vref_training)
training_command |= (1 << 6); // WR_VREF: Initiates OB (wrire) DRAM_VREF Training.
training_command |= (1 << 6); // WR_VREF: Initiates OB (write) DRAM_VREF Training.
if (needs_rd_training)
training_command |= (1 << 2); // RD: Initiates RD Training.
if (needs_rd_vref_training)
@ -3614,9 +3622,9 @@ void _minerva_do_over_temp_compensation(mtc_config_t *mtc_cfg)
if (dram_type != DRAM_TYPE_LPDDR4)
return;
u32 dram_temp = _get_dram_temperature();
s32 dram_temp = _get_dram_temperature();
if (mtc_cfg->prev_temp == dram_temp || dram_temp == (u32)-1)
if (dram_temp < 0 || mtc_cfg->prev_temp == (u32)dram_temp)
return;
u32 refr = mtc_cfg->current_emc_table->burst_regs.emc_refresh;
@ -3632,7 +3640,7 @@ void _minerva_do_over_temp_compensation(mtc_config_t *mtc_cfg)
case 3:
if (mtc_cfg->prev_temp < 4)
{
mtc_cfg->prev_temp = dram_temp;
mtc_cfg->prev_temp = (u32)dram_temp;
return;
}
break;

View File

@ -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;

View File

@ -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);

View File

@ -1,5 +1,5 @@
/*
* 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,
@ -65,7 +65,9 @@ char *text_color;
typedef struct _jc_lv_driver_t
{
lv_indev_t *indev;
bool centering_done;
// LV_INDEV_READ_PERIOD * JC_CAL_MAX_STEPS = 264 ms.
#define JC_CAL_MAX_STEPS 8
u32 calibration_step;
u16 cx_max;
u16 cx_min;
u16 cy_max;
@ -280,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);
@ -412,7 +409,7 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
}
// Calibrate left stick.
if (!jc_drv_ctx.centering_done)
if (jc_drv_ctx.calibration_step != JC_CAL_MAX_STEPS)
{
if (n_cfg.jc_force_right)
{
@ -420,11 +417,11 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
&& jc_pad->rstick_x > 0x400 && jc_pad->rstick_y > 0x400
&& jc_pad->rstick_x < 0xC00 && jc_pad->rstick_y < 0xC00)
{
jc_drv_ctx.calibration_step++;
jc_drv_ctx.cx_max = jc_pad->rstick_x + 0x96;
jc_drv_ctx.cx_min = jc_pad->rstick_x - 0x96;
jc_drv_ctx.cy_max = jc_pad->rstick_y + 0x96;
jc_drv_ctx.cy_min = jc_pad->rstick_y - 0x96;
jc_drv_ctx.centering_done = true;
jc_drv_ctx.cursor_timeout = 0;
}
}
@ -432,14 +429,15 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
&& jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400
&& jc_pad->lstick_x < 0xC00 && jc_pad->lstick_y < 0xC00)
{
jc_drv_ctx.calibration_step++;
jc_drv_ctx.cx_max = jc_pad->lstick_x + 0x96;
jc_drv_ctx.cx_min = jc_pad->lstick_x - 0x96;
jc_drv_ctx.cy_max = jc_pad->lstick_y + 0x96;
jc_drv_ctx.cy_min = jc_pad->lstick_y - 0x96;
jc_drv_ctx.centering_done = true;
jc_drv_ctx.cursor_timeout = 0;
}
else
if (jc_drv_ctx.calibration_step != JC_CAL_MAX_STEPS)
{
data->state = LV_INDEV_STATE_REL;
return false;
@ -447,13 +445,10 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
}
// Re-calibrate on disconnection.
if (n_cfg.jc_force_right)
{
if (!jc_pad->conn_r)
jc_drv_ctx.centering_done = 0;
}
else if (!jc_pad->conn_l)
jc_drv_ctx.centering_done = 0;
if (n_cfg.jc_force_right && !jc_pad->conn_r)
jc_drv_ctx.calibration_step = 0;
else if (!n_cfg.jc_force_right && !jc_pad->conn_l)
jc_drv_ctx.calibration_step = 0;
// Set button presses.
if (jc_pad->a || jc_pad->zl || jc_pad->zr)
@ -1318,23 +1313,20 @@ 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);
max17050_get_property(MAX17050_VCELL, &batt_volt);
max17050_get_property(MAX17050_Current, &batt_curr);
// Enable fan if more than 46 oC.
// Enable fan if more than 41 oC.
u32 soc_temp_dec = (soc_temp >> 8);
if (soc_temp_dec > 51)
set_fan_duty(102);
else if (soc_temp_dec > 46)
set_fan_duty(76);
else if (soc_temp_dec > 41)
set_fan_duty(51);
else if (soc_temp_dec < 40)
set_fan_duty(0);

View File

@ -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
@ -405,7 +405,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
// Decode fuses.
char *sku;
char dram_man[32];
char dram_man[64];
char fuses_hos_version[64];
u8 dram_id = fuse_read_dramid(true);
@ -440,7 +440,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
case LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE:
strcpy(dram_man, "Hynix H9HCNNNBPUMLHR-NLE 4GB");
break;
case LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT:
case LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC:
strcpy(dram_man, "Micron MT53B512M32D2NP-062 WT:C");
break;
case LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH:
@ -502,19 +502,15 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
case LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE: // Replaced from Copper.
strcpy(dram_man, "Hynix H9HCNNNBKMMLXR-NEE 4GB");
break;
case LPDDR4X_UNK0_4GB_HYNIX_H9HCNNNBKMMLXR_NEI:
case LPDDR4X_UNK1_4GB_HYNIX_H9HCNNNBKMMLXR_NEI:
case LPDDR4X_UNK2_4GB_HYNIX_H9HCNNNBKMMLXR_NEI:
//strcpy(dram_man, "Hynix H9HCNNNBKMMLXR-NEI 4GB");
strcpy(dram_man, "Hynix 1a 4GB #FF8000 Contact me!#");
case LPDDR4X_IOWA_4GB_HYNIX_H54G46CYRBX267:
case LPDDR4X_HOAG_4GB_HYNIX_H54G46CYRBX267:
case LPDDR4X_AULA_4GB_HYNIX_H54G46CYRBX267:
strcpy(dram_man, "Hynix H54G46CYRBX267 4GB");
break;
case LPDDR4X_UNK0_4GB_MICRON_MT53E512M32D1NP_046_WTB:
case LPDDR4X_UNK1_4GB_MICRON_MT53E512M32D1NP_046_WTB:
case LPDDR4X_UNK2_4GB_MICRON_MT53E512M32D1NP_046_WTB:
//strcpy(dram_man, "Micron MT53E512M32D1NP-046 WT:B");
strcpy(dram_man, "Micron 1a 4GB #FF8000 Contact me!#");
case LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D1NP_046_WTB:
case LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D1NP_046_WTB:
case LPDDR4X_AULA_4GB_MICRON_MT53E512M32D1NP_046_WTB:
strcpy(dram_man, "Micron MT53E512M32D1NP-046 WT:B");
break;
default:
@ -616,9 +612,9 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
// Parse fuses and display them.
s_printf(txt_buf,
"%X - %s - %s\n%02d: %s\n%d - %d (HOS: %s)\n%08X %08X %08X\n%08X%08X%08X%08X\n%08X\n%08X%08X%08X%08X\n%08X%08X%08X%08X\n%d\n"
"%s\n%d.%02d (0x%X)\n%d.%02d (0x%X)\n%d\n%d\n%d\n%d\n0x%X\n%d\n%d\n%d\n%d\n"
"%s\n%d.%02d (0x%X)\n%d.%02d (0x%X)\n%d\n%d\n%d\n%d\n0x%X\n%d\n%d (%d)\n%d (%d)\n%d (%d)\n"
"%d\n%d\n%d (0x%X)\n%d\n%d\n%d\n"
"ID: %02X, Major: A%02d, Minor: %d",
"ID: %02X, Major: %d, Minor: A%02d",
FUSE(FUSE_SKU_INFO), sku, fuse_read_hw_state() ? "Dev" : "Retail",
dram_id, dram_man, burnt_fuses_7, burnt_fuses_6, fuses_hos_version,
fuse_read_odm(4), fuse_read_odm(6), fuse_read_odm(7),
@ -635,7 +631,9 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
(FUSE(FUSE_OPT_CP_REV) >> 5) & 0x3F, FUSE(FUSE_OPT_CP_REV) & 0x1F, FUSE(FUSE_OPT_CP_REV),
FUSE(FUSE_CPU_SPEEDO_0_CALIB), FUSE(FUSE_CPU_SPEEDO_1_CALIB), FUSE(FUSE_CPU_SPEEDO_2_CALIB),
FUSE(FUSE_SOC_SPEEDO_0_CALIB), FUSE(FUSE_SOC_SPEEDO_1_CALIB), FUSE(FUSE_SOC_SPEEDO_2_CALIB),
FUSE(FUSE_CPU_IDDQ_CALIB), FUSE(FUSE_SOC_IDDQ_CALIB), FUSE(FUSE_GPU_IDDQ_CALIB),
FUSE(FUSE_CPU_IDDQ_CALIB), FUSE(FUSE_CPU_IDDQ_CALIB) * 4,
FUSE(FUSE_SOC_IDDQ_CALIB), FUSE(FUSE_SOC_IDDQ_CALIB) * 4,
FUSE(FUSE_GPU_IDDQ_CALIB), FUSE(FUSE_GPU_IDDQ_CALIB) * 5,
FUSE(FUSE_OPT_VENDOR_CODE), FUSE(FUSE_OPT_FAB_CODE), lot_bin, FUSE(FUSE_OPT_LOT_CODE_0),
FUSE(FUSE_OPT_WAFER_ID), FUSE(FUSE_OPT_X_COORDINATE), FUSE(FUSE_OPT_Y_COORDINATE),
(chip_id >> 8) & 0xFF, (chip_id >> 4) & 0xF, (chip_id >> 16) & 0xF);
@ -657,11 +655,11 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
emc_mr_data_t ram_rev0 = sdram_read_mrx(MR6_REV_ID1);
emc_mr_data_t ram_rev1 = sdram_read_mrx(MR7_REV_ID2);
emc_mr_data_t ram_density = sdram_read_mrx(MR8_DENSITY);
u32 ranks = EMC(EMC_ADR_CFG) + 1;
u32 ranks = EMC(EMC_ADR_CFG) + 1;
u32 channels = (EMC(EMC_FBIO_CFG7) >> 1) & 3;
channels = (channels & 1) + ((channels & 2) >> 1);
s_printf(txt_buf, "#00DDFF %s SDRAM ##FF8000 (Ch 0 | Ch 1):#\n#FF8000 Vendor:# ", h_cfg.t210b01 ? "LPDDR4X" : "LPDDR4");
switch (ram_vendor.rank0_ch0)
switch (ram_vendor.chip0.rank0_ch0)
{
case 1:
strcat(txt_buf, "Samsung");
@ -681,12 +679,24 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
case 9:
strcat(txt_buf, "ESMT");
break;
case 19:
strcat(txt_buf, "CXMT");
break;
case 26:
strcat(txt_buf, "Xi'an UniIC Semiconductors Co., Ltd");
strcat(txt_buf, "Xi'an UniIC");
break;
case 27:
strcat(txt_buf, "ISSI");
break;
case 28:
strcat(txt_buf, "JSC");
break;
case 197:
strcat(txt_buf, "SINKER");
break;
case 229:
strcat(txt_buf, "Dosilicon");
break;
case 248:
strcat(txt_buf, "Fidelix");
break;
@ -701,11 +711,11 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
strcat(txt_buf, "Micron");
break;
default:
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Unknown# (%d)", ram_vendor.rank0_ch0);
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Unknown# (%d)", ram_vendor.chip0.rank0_ch0);
break;
}
strcat(txt_buf, " #FF8000 |# ");
switch (ram_vendor.rank0_ch1)
switch (ram_vendor.chip1.rank0_ch0)
{
case 1:
strcat(txt_buf, "Samsung");
@ -717,12 +727,12 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
strcat(txt_buf, "Micron");
break;
default:
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Unknown# (%d)", ram_vendor.rank0_ch1);
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Unknown# (%d)", ram_vendor.chip1.rank0_ch0);
break;
}
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 Rev ID:# %X.%02X #FF8000 |# %X.%02X\n#FF8000 Density:# %d",
ram_rev0.rank0_ch0, ram_rev1.rank0_ch0, ram_rev0.rank0_ch1, ram_rev1.rank0_ch1, ranks * channels);
switch ((ram_density.rank0_ch0 & 0x3C) >> 2)
ram_rev0.chip0.rank0_ch0, ram_rev1.chip0.rank0_ch0, ram_rev0.chip1.rank0_ch0, ram_rev1.chip1.rank0_ch0, ranks * channels);
switch ((ram_density.chip0.rank0_ch0 & 0x3C) >> 2)
{
case 2:
strcat(txt_buf, " x 512MB");
@ -740,11 +750,11 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
strcat(txt_buf, " x 2GB");
break;
default:
s_printf(txt_buf + strlen(txt_buf), " x Unk (%d)", (ram_density.rank0_ch0 & 0x3C) >> 2);
s_printf(txt_buf + strlen(txt_buf), " x Unk (%d)", (ram_density.chip0.rank0_ch0 & 0x3C) >> 2);
break;
}
s_printf(txt_buf + strlen(txt_buf), " #FF8000 |# %d", ranks * channels);
switch ((ram_density.rank0_ch1 & 0x3C) >> 2)
switch ((ram_density.chip1.rank0_ch0 & 0x3C) >> 2)
{
case 2:
strcat(txt_buf, " x 512MB");
@ -762,7 +772,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
strcat(txt_buf, " x 2GB");
break;
default:
s_printf(txt_buf + strlen(txt_buf), " x Unk (%d)", (ram_density.rank0_ch1 & 0x3C) >> 2);
s_printf(txt_buf + strlen(txt_buf), " x Unk (%d)", (ram_density.chip1.rank0_ch0 & 0x3C) >> 2);
break;
}
strcat(txt_buf, "\n\n");
@ -800,6 +810,9 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
case 0x98:
strcat(txt_buf, "-???");
break;
case 0x99:
strcat(txt_buf, "-???");
break;
default:
strcat(txt_buf, " #FFDD00 Contact me!#");
break;
@ -819,13 +832,13 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
strcat(txt_buf, "02");
break;
case 0x96:
strcat(txt_buf, "XX");
strcat(txt_buf, "??");
break;
case 0x97:
strcat(txt_buf, "XX");
strcat(txt_buf, "??");
break;
case 0x98:
strcat(txt_buf, "XX");
strcat(txt_buf, "??");
break;
default:
strcat(txt_buf, " #FFDD00 Contact me!#");
@ -845,6 +858,15 @@ 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;
case PANEL_OEM_CLONE:
strcat(txt_buf, "#FFDD00 OEM Clone#");
break;
case 0xCCCC:
strcat(txt_buf, "#FFDD00 Failed to get info!#");
break;
@ -1088,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;
@ -1600,12 +1622,15 @@ 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",
emmc_storage.cid.manfid,
emmc_storage.cid.prod_name[0], emmc_storage.cid.prod_name[1], emmc_storage.cid.prod_name[2],
emmc_storage.cid.prod_name[3], emmc_storage.cid.prod_name[4], emmc_storage.cid.prod_name[5],
emmc_storage.cid.prod_name[3], emmc_storage.cid.prod_name[4], emmc_storage.cid.prod_name[5],
emmc_storage.cid.prv & 0xF, emmc_storage.cid.prv >> 4,
emmc_storage.cid.serial, emmc_storage.cid.month, emmc_storage.cid.year);
@ -1675,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,
@ -1716,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");
@ -1997,9 +2022,8 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
"Bus Width:\n"
"Current Rate:\n"
"Speed Class:\n"
"UHS Grade:\n"
"Video Class:\n"
"App perf class:\n"
"UHS Classes:\n"
"Max Bus Speed:\n\n"
"Write Protect:"
);
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
@ -2033,14 +2057,32 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
uhs_au_size /= 1024;
}
sd_func_modes_t fmodes = { 0 };
sd_storage_get_fmodes(&sd_storage, NULL, &fmodes);
char *bus_speed;
if (fmodes.cmd_system & SD_MODE_UHS_DDR200)
bus_speed = "DDR200";
else if (fmodes.access_mode & SD_MODE_UHS_SDR104)
bus_speed = "SDR104";
else if (fmodes.access_mode & SD_MODE_UHS_SDR50)
bus_speed = "SDR50";
else if (fmodes.access_mode & SD_MODE_UHS_DDR50)
bus_speed = "DDR50";
else if (fmodes.access_mode & SD_MODE_UHS_SDR25)
bus_speed = "SDR25";
else
bus_speed = "SDR12";
s_printf(txt_buf,
"#00DDFF v%d.0#\n%02X\n%d MiB\n%X (CP %X)\n%d\n%d MB/s (%d MHz)\n%d (AU: %d %s\nU%d\nV%d\nA%d\n%s",
"#00DDFF v%d.0#\n%02X\n%d MiB\n%X (CP %X)\n%d\n%d MB/s (%d MHz)\n%d (AU: %d %s\nU%d V%d A%d\n%s\n\n%s",
sd_storage.csd.structure + 1, sd_storage.csd.cmdclass,
sd_storage.sec_cnt >> 11, sd_storage.sec_cnt, sd_storage.ssr.protected_size >> 9,
sd_storage.ssr.bus_width, sd_storage.csd.busspeed,
(sd_storage.csd.busspeed > 10) ? (sd_storage.csd.busspeed * 2) : 50,
sd_storage.ssr.speed_class, uhs_au_size, uhs_au_mb ? "MiB)" : "KiB)", sd_storage.ssr.uhs_grade,
sd_storage.ssr.video_class, sd_storage.ssr.app_class, wp_info);
sd_storage.ssr.speed_class, uhs_au_size, uhs_au_mb ? "MiB)" : "KiB)",
sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class, sd_storage.ssr.app_class,
bus_speed, wp_info);
lv_label_set_text(lb_val2, txt_buf);
@ -2083,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));

View File

@ -1,5 +1,5 @@
/*
* 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,
@ -24,9 +24,9 @@
#include <libs/lvgl/lv_themes/lv_theme_hekate.h>
#include <libs/lvgl/lvgl.h>
#define CLOCK_MIN_YEAR 2023
#define CLOCK_MIN_YEAR 2024
#define CLOCK_MAX_YEAR (CLOCK_MIN_YEAR + 10)
#define CLOCK_YEARLIST "2023\n2024\n2025\n2026\n2027\n2028\n2029\n2030\n2031\n2032\n2033"
#define CLOCK_YEARLIST "2024\n2025\n2026\n2027\n2028\n2029\n2030\n2031\n2032\n2033\n2034"
extern hekate_config h_cfg;
extern nyx_config n_cfg;
@ -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)
@ -841,7 +841,8 @@ void first_time_clock_edit(void *param)
static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
{
FIL fp;
int error;
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;
@ -850,18 +851,26 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
char *data = (char *)malloc(SZ_16K);
char *txt_buf = (char *)malloc(SZ_4K);
if (nx_hoag)
if (!nx_hoag && !jc_pad)
error = 255;
// Try 2 times to get factory calibration data.
for (u32 i = 0; i < 2; i++)
{
error = hos_dump_cal0();
if (!error)
goto save_data;
cal_error = hos_dump_cal0();
if (!cal_error)
break;
}
if (!jc_pad || nx_hoag)
{
error = 255;
goto disabled;
}
if (cal_error && nx_hoag)
error = cal_error;
if (error)
goto disabled_or_cal0_issue;
if (nx_hoag)
goto save_data;
// Count valid joycon.
u32 joycon_found = jc_pad->bt_conn_l.type ? 1 : 0;
@ -873,18 +882,21 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
jc_pad->bt_conn_r.type = is_r_hos ? jc_pad->bt_conn_r.type : 0;
save_data:
error = !sd_mount();
error = !sd_mount() ? 5 : 0;
if (!error)
{
nx_emmc_cal0_t *cal0 = (nx_emmc_cal0_t *)cal0_buf;
f_mkdir("switchroot");
if (!nx_hoag)
{
// Save binary dump.
memcpy(data, &jc_pad->bt_conn_l, sizeof(jc_bt_conn_t));
memcpy(data + sizeof(jc_bt_conn_t), &jc_pad->bt_conn_r, sizeof(jc_bt_conn_t));
f_mkdir("switchroot");
error = sd_save_to_file((u8 *)data, sizeof(jc_bt_conn_t) * 2, "switchroot/joycon_mac.bin");
error = sd_save_to_file((u8 *)data, sizeof(jc_bt_conn_t) * 2, "switchroot/joycon_mac.bin") ? 4 : 0;
// Save readable dump.
jc_bt_conn_t *bt = &jc_pad->bt_conn_l;
@ -907,24 +919,59 @@ save_data:
bt->ltk[8], bt->ltk[9], bt->ltk[10], bt->ltk[11], bt->ltk[12], bt->ltk[13], bt->ltk[14], bt->ltk[15]);
if (!error)
error = f_open(&fp, "switchroot/joycon_mac.ini", FA_WRITE | FA_CREATE_ALWAYS);
error = f_open(&fp, "switchroot/joycon_mac.ini", FA_WRITE | FA_CREATE_ALWAYS) ? 4 : 0;
if (!error)
{
f_puts(data, &fp);
f_close(&fp);
}
}
else
{
nx_emmc_cal0_t *cal0 = (nx_emmc_cal0_t *)cal0_buf;
jc_calib_t *stick_cal_l = (jc_calib_t *)cal0->analog_stick_cal_l;
jc_calib_t *stick_cal_r = (jc_calib_t *)cal0->analog_stick_cal_r;
f_mkdir("switchroot");
// Save Lite Gamepad Calibration data.
// Save IMU Calibration data.
if (!error && !cal_error)
{
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
{
jc_calib_t *stick_cal_l = (jc_calib_t *)cal0->analog_stick_cal_l;
jc_calib_t *stick_cal_r = (jc_calib_t *)cal0->analog_stick_cal_r;
// Save Lite Gamepad and IMU Calibration data.
// Actual max/min are right/left and up/down offsets.
s_printf(data,
"lite_cal_l_type=0x%X\n"
"lite_cal_lx_lof=0x%X\n"
"lite_cal_lx_cnt=0x%X\n"
"lite_cal_lx_rof=0x%X\n"
@ -932,6 +979,7 @@ save_data:
"lite_cal_ly_cnt=0x%X\n"
"lite_cal_ly_uof=0x%X\n\n"
"lite_cal_r_type=0x%X\n"
"lite_cal_rx_lof=0x%X\n"
"lite_cal_rx_cnt=0x%X\n"
"lite_cal_rx_rof=0x%X\n"
@ -939,6 +987,7 @@ save_data:
"lite_cal_ry_cnt=0x%X\n"
"lite_cal_ry_uof=0x%X\n\n"
"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"
@ -954,18 +1003,20 @@ save_data:
"gyr_cal_scl_z=0x%X\n\n"
"device_bt_mac=%02X:%02X:%02X:%02X:%02X:%02X\n",
cal0->analog_stick_type_l,
stick_cal_l->x_min, stick_cal_l->x_center, stick_cal_l->x_max,
stick_cal_l->y_min, stick_cal_l->y_center, stick_cal_l->y_max,
cal0->analog_stick_type_r,
stick_cal_r->x_min, stick_cal_r->x_center, stick_cal_r->x_max,
stick_cal_r->y_min, stick_cal_r->y_center, stick_cal_r->y_max,
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);
error = f_open(&fp, "switchroot/switch.cal", FA_WRITE | FA_CREATE_ALWAYS) ? 4 : 0;
if (!error)
{
f_puts(data, &fp);
@ -976,7 +1027,7 @@ save_data:
sd_unmount();
}
disabled:;
disabled_or_cal0_issue:;
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(dark_bg, &mbox_darken);
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
@ -1028,6 +1079,9 @@ disabled:;
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
{
@ -1042,7 +1096,7 @@ disabled:;
if (!nx_hoag)
s_printf(txt_buf, "#FFDD00 Failed to dump Joy-Con pairing info!#\n#FFDD00 Error: %d#", error);
else
s_printf(txt_buf, "#FFDD00 Failed to get Lite Gamepad info!#\n");
s_printf(txt_buf, "#FFDD00 Failed to get Lite Gamepad info!#\n#FFDD00 Error: %d#", error);
}
lv_mbox_set_text(mbox, txt_buf);

View File

@ -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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2022 CTCaer
* Copyright (c) 2019-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -30,7 +30,7 @@
#define SECTORS_PER_GB 0x200000
#define HOS_MIN_SIZE_MB 2048
#define ANDROID_SYSTEM_SIZE_MB 4096 // 4 GB which is > 3888 MB of the actual size.
#define ANDROID_SYSTEM_SIZE_MB 6144 // 6 GB. Fits both Legacy (4912MB) and Dynamic (6144MB) partition schemes.
extern volatile boot_cfg_t *b_cfg;
extern volatile nyx_storage_t *nyx_str;
@ -49,6 +49,8 @@ typedef struct _partition_ctxt_t
bool emu_double;
bool emmc_is_64gb;
bool and_dynamic;
mbr_t mbr_old;
lv_obj_t *bar_hos;
@ -343,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.
@ -387,37 +389,66 @@ static void _prepare_and_flash_mbr_gpt()
if (part_info.l4t_size)
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, part_info.l4t_size << 11, (char[]) { 'l', 0, '4', 0, 't', 0 }, 6);
// Android Vendor partition. 1GB
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x200000, (char[]) { 'v', 0, 'e', 0, 'n', 0, 'd', 0, 'o', 0, 'r', 0 }, 12);
if (part_info.and_dynamic)
{
// Android Linux Kernel partition. 64MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x20000, (char[]) { 'b', 0, 'o', 0, 'o', 0, 't', 0 }, 8);
// Android System partition. 2GB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x400000, (char[]) { 'A', 0, 'P', 0, 'P', 0 }, 6);
// Android Recovery partition. 64MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x20000, (char[]) { 'r', 0, 'e', 0, 'c', 0, 'o', 0, 'v', 0, 'e', 0, 'r', 0, 'y', 0 }, 16);
// Android Linux Kernel partition. 32MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x10000, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6);
// Android Device Tree Reference partition. 1MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x800, (char[]) { 'd', 0, 't', 0, 'b', 0 }, 6);
// Android Recovery partition. 64MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x20000, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6);
// Android Misc partition. 3MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x1800, (char[]) { 'm', 0, 'i', 0, 's', 0, 'c', 0 }, 8);
// Android Device Tree Reference partition. 1MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x800, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6);
// Android Cache partition. 60MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x1E000, (char[]) { 'c', 0, 'a', 0, 'c', 0, 'h', 0, 'e', 0 }, 10);
// Android Encryption partition. 16MB.
// Note: 16MB size is for aligning UDA. If any other tiny partition must be added, it should split the MDA one.
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x8000, (void *)SDMMC_UPPER_BUFFER); // Clear the whole of it.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x8000, (char[]) { 'M', 0, 'D', 0, 'A', 0 }, 6);
// Android Super dynamic partition. 5922MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0xB91000, (char[]) { 's', 0, 'u', 0, 'p', 0, 'e', 0, 'r', 0 }, 10);
// Android Cache partition. 700MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x15E000, (char[]) { 'C', 0, 'A', 0, 'C', 0 }, 6);
// Android Userdata partition.
u32 uda_size = (part_info.and_size << 11) - 0xC00000; // Subtract the other partitions (6144MB).
if (!part_info.emu_size)
uda_size -= 0x800; // Reserve 1MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, uda_size, (char[]) { 'u', 0, 's', 0, 'e', 0, 'r', 0, 'd', 0, 'a', 0, 't', 0, 'a', 0 }, 16);
}
else
{
// Android Vendor partition. 1GB
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x200000, (char[]) { 'v', 0, 'e', 0, 'n', 0, 'd', 0, 'o', 0, 'r', 0 }, 12);
// Android Misc partition. 3MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x1800, (char[]) { 'M', 0, 'S', 0, 'C', 0 }, 6);
// Android System partition. 3GB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x600000, (char[]) { 'A', 0, 'P', 0, 'P', 0 }, 6);
// Android Userdata partition.
u32 uda_size = (part_info.and_size << 11) - 0x798000; // Subtract the other partitions (3888MB).
if (!part_info.emu_size)
uda_size -= 0x800; // Reserve 1MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, uda_size, (char[]) { 'U', 0, 'D', 0, 'A', 0 }, 6);
// Android Linux Kernel partition. 32MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x10000, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6);
// Android Recovery partition. 64MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x20000, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6);
// Android Device Tree Reference partition. 1MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x800, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6);
// Android Encryption partition. 16MB.
// Note: 16MB size is for aligning UDA. If any other tiny partition must be added, it should split the MDA one.
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x8000, (void *)SDMMC_UPPER_BUFFER); // Clear the whole of it.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x8000, (char[]) { 'M', 0, 'D', 0, 'A', 0 }, 6);
// Android Cache partition. 700MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x15E000, (char[]) { 'C', 0, 'A', 0, 'C', 0 }, 6);
// Android Misc partition. 3MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, 0x1800, (char[]) { 'M', 0, 'S', 0, 'C', 0 }, 6);
// Android Userdata partition.
u32 uda_size = (part_info.and_size << 11) - 0x998000; // Subtract the other partitions (4912MB).
if (!part_info.emu_size)
uda_size -= 0x800; // Reserve 1MB.
_create_gpt_partition(gpt, &gpt_idx, &curr_part_lba, uda_size, (char[]) { 'U', 0, 'D', 0, 'A', 0 }, 6);
}
// Handle emuMMC partitions manually.
if (part_info.emu_size)
@ -737,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));
@ -784,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);
@ -796,7 +827,7 @@ static bool _get_available_android_partition()
// Find kernel partition.
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (gpt->entries[i].lba_start && !memcmp(gpt->entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6))
if (gpt->entries[i].lba_start && (!memcmp(gpt->entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6) || !memcmp(gpt->entries[i].name, (char[]) { 'b', 0, 'o', 0, 'o', 0, 't', 0 }, 8)))
{
free(gpt);
@ -895,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;
@ -976,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);
@ -1026,7 +1057,7 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
// Find Kernel partition.
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (!memcmp(gpt->entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6))
if (!memcmp(gpt->entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6) || !memcmp(gpt->entries[i].name, (char[]) { 'b', 0, 'o', 0, 'o', 0, 't', 0 }, 8))
{
offset_sct = gpt->entries[i].lba_start;
size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start;
@ -1046,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;
@ -1090,7 +1121,7 @@ boot_img_not_found:
// Find Recovery partition.
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (!memcmp(gpt->entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6))
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))
{
offset_sct = gpt->entries[i].lba_start;
size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start;
@ -1110,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;
@ -1152,7 +1183,7 @@ recovery_not_found:
// Find Device Tree partition.
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (!memcmp(gpt->entries[i].name, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6))
if (!memcmp(gpt->entries[i].name, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6) || !memcmp(gpt->entries[i].name, (char[]) { 'd', 0, 't', 0, 'b', 0 }, 6))
{
offset_sct = gpt->entries[i].lba_start;
size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start;
@ -1172,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;
@ -1198,9 +1229,9 @@ dtb_not_found:
// Check if Recovery is flashed unconditionally.
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (!memcmp(gpt->entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6))
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;
@ -1679,7 +1710,7 @@ static lv_res_t _create_mbox_partitioning_option1(lv_obj_t *btns, const char *tx
return LV_RES_OK;
}
static lv_res_t _create_mbox_partitioning_next(lv_obj_t *btn)
static lv_res_t _create_mbox_partitioning_warn(lv_obj_t *btn)
{
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(dark_bg, &mbox_darken);
@ -1726,6 +1757,53 @@ static lv_res_t _create_mbox_partitioning_next(lv_obj_t *btn)
return LV_RES_OK;
}
static lv_res_t _create_mbox_partitioning_android(lv_obj_t *btns, const char *txt)
{
int btn_idx = lv_btnm_get_pressed(btns);
mbox_action(btns, txt);
part_info.and_dynamic = !btn_idx;
_create_mbox_partitioning_warn(NULL);
return LV_RES_INV;
}
static lv_res_t _create_mbox_partitioning_andr_part(lv_obj_t *btn)
{
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(dark_bg, &mbox_darken);
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
static const char *mbox_btn_map[] = { "\222Dynamic", "\222Legacy", "" };
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
lv_mbox_set_recolor_text(mbox, true);
lv_obj_set_width(mbox, LV_HOR_RES / 10 * 5);
lv_mbox_set_text(mbox, "#FF8000 Android Partitioning#");
lv_obj_t *lbl_status = lv_label_create(mbox, NULL);
lv_label_set_recolor(lbl_status, true);
lv_label_set_text(lbl_status,
"Please select a partition scheme:\n\n"
"#C7EA46 Dynamic:# Android 13+\n"
"#C7EA46 Legacy:# Android 10-11\n");
lv_mbox_add_btns(mbox, mbox_btn_map, _create_mbox_partitioning_android);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_top(mbox, true);
return LV_RES_OK;
}
static lv_res_t _create_mbox_partitioning_next(lv_obj_t *btn) {
if (part_info.and_size)
return _create_mbox_partitioning_andr_part(NULL);
else
return _create_mbox_partitioning_warn(NULL);
}
static void _update_partition_bar()
{
lv_obj_t *h1 = lv_obj_get_parent(part_info.bar_hos);
@ -2150,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;
@ -2201,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;
@ -2351,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.

View File

@ -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;
}

View File

@ -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.

View File

@ -65,7 +65,8 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20220209", 13, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 14.0.0 - 14.1.2.
{ "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)

View File

@ -111,6 +111,8 @@ static const u8 mkey_vector_7xx[HOS_KB_VERSION_MAX - HOS_KB_VERSION_810 + 1][SE_
{ 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 },
// 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)

View File

@ -257,7 +257,7 @@
#define FF_FS_NORTC 0
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2023
#define FF_NORTC_YEAR 2024
/* The option FF_FS_NORTC switches timestamp function. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp

View File

@ -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))

View File

@ -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