Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/loader/loader.c
1471 views
1
/*
2
* Copyright (c) 2019-2024 CTCaer
3
*
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms and conditions of the GNU General Public License,
6
* version 2, as published by the Free Software Foundation.
7
*
8
* This program is distributed in the hope it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11
* more details.
12
*
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15
*/
16
17
#include <string.h>
18
#include <stdlib.h>
19
20
#include "payload_00.h"
21
#include "payload_01.h"
22
23
#include <memory_map.h>
24
#include <libs/compr/lz.h>
25
#include <soc/clock.h>
26
#include <soc/t210.h>
27
28
// 0x4003D000: Safe for panic preserving, 0x40038000: Safe for debugging needs.
29
#define IPL_RELOC_TOP 0x40038000
30
#define IPL_PATCHED_RELOC_SZ 0x94
31
32
boot_cfg_t __attribute__((section ("._boot_cfg"))) b_cfg;
33
const volatile ipl_ver_meta_t __attribute__((section ("._ipl_version"))) ipl_ver = {
34
.magic = BL_MAGIC,
35
.version = (BL_VER_MJ + '0') | ((BL_VER_MN + '0') << 8) | ((BL_VER_HF + '0') << 16) | ((BL_VER_RL) << 24),
36
.rsvd0 = 0,
37
.rsvd1 = 0
38
};
39
40
const char __attribute__((section ("._octopus"))) octopus[] =
41
"\n"
42
" ___\n"
43
" .-' `'.\n"
44
" / \\\n"
45
" | ;\n"
46
" | | ___.--,\n"
47
" _.._ |0) = (0) | _.---'`__.-( (_.\n"
48
" __.--'`_.. '.__.\\ '--. \\_.-' ,.--'` `\"\"`\n"
49
" ( ,.--'` ',__ /./; ;, '.__.'` __\n"
50
" _`) ) .---.__.' / | |\\ \\__..--\"\" \"\"\"--.,_\n"
51
" `---' .'.''-._.-'`_./ /\\ '. \\ _.--''````'''--._`-.__.'\n"
52
" | | .' _.-' | | \\ \\ '. `----`\n"
53
" \\ \\/ .' \\ \\ '. '-._)\n"
54
" \\/ / \\ \\ `=.__`'-.\n"
55
" / /\\ `) ) / / `\"\".`\\\n"
56
" , _.-'.'\\ \\ / / ( ( / /\n"
57
" `--'` ) ) .-'.' '.'. | (\n"
58
" (/` ( (` ) ) '-; [switchbrew]\n";
59
60
void loader_main()
61
{
62
// Preliminary BPMP clocks init.
63
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
64
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set SCLK div to 1.
65
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set clk source to Run and PLLP_OUT2 (204MHz).
66
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1.
67
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
68
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // Set SCLK to PLLP_OUT (408MHz).
69
70
// Set arbiter.
71
ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x12412D1;
72
ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x0000000;
73
ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x220244A;
74
ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320369B;
75
76
// Get Payload size.
77
u32 payload_size = sizeof(payload_00) + sizeof(payload_01); // Actual payload size.
78
payload_size += (u32)payload_01 - (u32)payload_00 - sizeof(payload_00); // Add compiler alignment.
79
payload_size = ALIGN(payload_size, 4); // Align size to 4 bytes.
80
u32 *payload_addr = (u32 *)payload_00;
81
82
// Relocate payload to a safer place.
83
u32 words = payload_size >> 2;
84
u32 *src = payload_addr + words - 1;
85
u32 *dst = (u32 *)(IPL_RELOC_TOP - 4);
86
while (words)
87
{
88
*dst = *src;
89
src--;
90
dst--;
91
words--;
92
}
93
94
// Set source address of the first part.
95
u8 *src_addr = (void *)(IPL_RELOC_TOP - payload_size);
96
// Uncompress first part.
97
u32 dst_pos = LZ_Uncompress((const u8 *)src_addr, (u8 *)IPL_LOAD_ADDR, sizeof(payload_00));
98
99
// Set source address of the second part. Includes compiler alignment.
100
src_addr += (u32)payload_01 - (u32)payload_00;
101
// Uncompress second part.
102
LZ_Uncompress((const u8 *)src_addr, (u8 *)IPL_LOAD_ADDR + dst_pos, sizeof(payload_01));
103
104
// Copy over boot configuration storage.
105
memcpy((u8 *)(IPL_LOAD_ADDR + IPL_PATCHED_RELOC_SZ), &b_cfg, sizeof(boot_cfg_t));
106
107
// Chainload into uncompressed payload.
108
void (*ipl_ptr)() = (void *)IPL_LOAD_ADDR;
109
(*ipl_ptr)();
110
111
// Halt if we managed to get out of execution.
112
while (true)
113
;
114
}
115
116