1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 /* Function unit addresses. */
4 enum {
5 UP_TAG_BASE = 0x60000000,
6 TIMER_BASE = 0x60005000,
7 CLK_RST_BASE = 0x60006000,
8 FLOW_CTLR_BASE = 0x60007000,
9 TEGRA_EVP_BASE = 0x6000f000,
10 PMC_CTLR_BASE = 0x7000e400,
11 MC_CTLR_BASE = 0x70019000,
12 SYSCTR_CTLR_BASE = 0x700f0000
13 };
14
15 /* UP tag registers. */
16 static uint32_t *up_tag_ptr = (void *)(UP_TAG_BASE + 0x0);
17 enum {
18 UP_TAG_AVP = 0xaaaaaaaa
19 };
20
21 /* Timer registers. */
22 static uint32_t *timer_us_ptr = (void *)(TIMER_BASE + 0x10);
23
24 /* Clock and reset controller registers. */
25 static uint32_t *clk_rst_rst_devices_l_ptr = (void *)(CLK_RST_BASE + 0x4);
26 enum {
27 SWR_TRIG_SYS_RST = 0x1 << 2
28 };
29
30 static uint32_t *clk_rst_cclk_burst_policy_ptr = (void *)(CLK_RST_BASE + 0x20);
31 enum {
32 CCLK_PLLP_BURST_POLICY = 0x20004444
33 };
34
35 static uint32_t *clk_rst_super_cclk_div_ptr = (void *)(CLK_RST_BASE + 0x24);
36 enum {
37 SUPER_CDIV_ENB = 0x1 << 31
38 };
39
40 static uint32_t *clk_rst_osc_ctrl_ptr = (void *)(CLK_RST_BASE + 0x50);
41 enum {
42 OSC_XOE = 0x1 << 0,
43 OSC_XOFS_SHIFT = 4,
44 OSC_XOFS_MASK = 0x3f << OSC_XOFS_SHIFT,
45 OSC_FREQ_SHIFT = 28,
46 OSC_FREQ_MASK = 0xf << OSC_FREQ_SHIFT
47 };
48 enum {
49 OSC_FREQ_13 = 0,
50 OSC_FREQ_16P8 = 1,
51 OSC_FREQ_19P2 = 4,
52 OSC_FREQ_38P4 = 5,
53 OSC_FREQ_12 = 8,
54 OSC_FREQ_48 = 9,
55 OSC_FREQ_26 = 12
56 };
57
58 static uint32_t *clk_rst_pllu_base_ptr = (void *)(CLK_RST_BASE + 0xc0);
59 enum {
60 PLLU_DIVM_SHIFT = 0,
61 PLLU_DIVN_SHIFT = 8,
62 PLLU_OVERRIDE = 0x1 << 24,
63 PLLU_ENABLE = 0x1 << 30,
64 PLLU_BYPASS = 0x1 << 31
65 };
66
67 static uint32_t *clk_rst_pllu_misc_ptr = (void *)(CLK_RST_BASE + 0xcc);
68 enum {
69 PLLU_LFCON_SHIFT = 4,
70 PLLU_CPCON_SHIFT = 8,
71 PLLU_LOCK_ENABLE = 22
72 };
73
74 static uint32_t *clk_rst_pllx_base_ptr = (void *)(CLK_RST_BASE + 0xe0);
75 enum {
76 PLLX_ENABLE = 0x1 << 30
77 };
78
79 static uint32_t *clk_rst_rst_dev_u_clr_ptr = (void *)(CLK_RST_BASE + 0x314);
80 enum {
81 SWR_CSITE_RST = 0x1 << 9
82 };
83
84 static uint32_t *clk_rst_clk_enb_l_set_ptr = (void *)(CLK_RST_BASE + 0x320);
85 enum {
86 CLK_ENB_CPU = 0x1 << 0
87 };
88
89 static uint32_t *clk_rst_clk_out_enb_u_set_ptr =
90 (void *)(CLK_RST_BASE + 0x330);
91 enum {
92 CLK_ENB_CSITE = 0x1 << 9
93 };
94
95 static uint32_t *clk_rst_cpu_softrst_ctrl2_ptr =
96 (void *)(CLK_RST_BASE + 0x388);
97 enum {
98 CAR2PMC_CPU_ACK_WIDTH_SHIFT = 0,
99 CAR2PMC_CPU_ACK_WIDTH_MASK = 0xfff << CAR2PMC_CPU_ACK_WIDTH_SHIFT
100 };
101
102 static uint32_t *clk_rst_clk_src_mselect_ptr =
103 (void *)(CLK_RST_BASE + 0x3b4);
104 enum {
105 MSELECT_CLK_DIV_SHIFT = 0,
106 MSELECT_CLK_SRC_SHIFT = 29,
107 MSELECT_CLK_SRC_PLLP_OUT0 = 0x0 << MSELECT_CLK_SRC_SHIFT,
108 MSELECT_CLK_SRC_PLLC2_OUT0 = 0x1 << MSELECT_CLK_SRC_SHIFT,
109 MSELECT_CLK_SRC_PLLC_OUT0 = 0x2 << MSELECT_CLK_SRC_SHIFT,
110 MSELECT_CLK_SRC_PLLC3_OUT0 = 0x3 << MSELECT_CLK_SRC_SHIFT
111 };
112
113 static uint32_t *clk_rst_rst_dev_v_clr_ptr = (void *)(CLK_RST_BASE + 0x434);
114 enum {
115 SWR_MSELECT_RST = 0x1 << 3
116 };
117
118 static uint32_t *clk_rst_clk_enb_v_set_ptr = (void *)(CLK_RST_BASE + 0x440);
119 enum {
120 CLK_ENB_CPUG = 0x1 << 0,
121 CLK_ENB_CPULP = 0x1 << 1,
122 CLK_ENB_MSELECT = 0x1 << 3
123 };
124
125 static uint32_t *clk_rst_rst_cpulp_cmplx_clr_ptr =
126 (void *)(CLK_RST_BASE + 0x45c);
127 static uint32_t *clk_rst_rst_cpug_cmplx_clr_ptr =
128 (void *)(CLK_RST_BASE + 0x454);
129 enum {
130 CLR_CPURESET0 = 0x1 << 0,
131 CLR_CPURESET1 = 0x1 << 1,
132 CLR_CPURESET2 = 0x1 << 2,
133 CLR_CPURESET3 = 0x1 << 3,
134 CLR_DBGRESET0 = 0x1 << 12,
135 CLR_DBGRESET1 = 0x1 << 13,
136 CLR_DBGRESET2 = 0x1 << 14,
137 CLR_DBGRESET3 = 0x1 << 15,
138 CLR_CORERESET0 = 0x1 << 16,
139 CLR_CORERESET1 = 0x1 << 17,
140 CLR_CORERESET2 = 0x1 << 18,
141 CLR_CORERESET3 = 0x1 << 19,
142 CLR_CXRESET0 = 0x1 << 20,
143 CLR_CXRESET1 = 0x1 << 21,
144 CLR_CXRESET2 = 0x1 << 22,
145 CLR_CXRESET3 = 0x1 << 23,
146 CLR_NONCPURESET = 0x1 << 29
147 };
148
149 /* Reset vector. */
150 static uint32_t *evp_cpu_reset_ptr = (void *)(TEGRA_EVP_BASE + 0x100);
151
152 /* Flow controller registers. */
153 static uint32_t *flow_ctlr_halt_cop_events_ptr =
154 (void *)(FLOW_CTLR_BASE + 0x4);
155 enum {
156 EVENT_MSEC = 0x1 << 24,
157 EVENT_JTAG = 0x1 << 28,
158 FLOW_MODE_SHIFT = 29,
159 FLOW_MODE_STOP = 2 << FLOW_MODE_SHIFT,
160 };
161
162 static uint32_t *flow_ctlr_cluster_control_ptr =
163 (void *)(FLOW_CTLR_BASE + 0x2c);
164 enum {
165 FLOW_CLUSTER_ACTIVE_LP = 0x1 << 0
166 };
167
168 static uint32_t *flow_ctlr_ram_repair_ptr =
169 (void *)(FLOW_CTLR_BASE + 0x40);
170 static uint32_t *flow_ctlr_ram_repair_cluster1_ptr =
171 (void *)(FLOW_CTLR_BASE + 0x58);
172 enum {
173 RAM_REPAIR_REQ = 0x1 << 0,
174 RAM_REPAIR_STS = 0x1 << 1,
175 };
176
177 /* Power management controller registers. */
178 enum {
179 PARTID_CRAIL = 0,
180 PARTID_CELP = 12,
181 PARTID_CE0 = 14,
182 PARTID_C0NC = 15,
183 PARTID_C1NC = 16
184 };
185
186 static uint32_t *pmc_ctlr_clamp_status_ptr = (void *)(PMC_CTLR_BASE + 0x2c);
187
188 static uint32_t *pmc_ctlr_pwrgate_toggle_ptr = (void *)(PMC_CTLR_BASE + 0x30);
189 enum {
190 PWRGATE_TOGGLE_START = 0x1 << 8
191 };
192
193 static uint32_t *pmc_ctlr_pwrgate_status_ptr = (void *)(PMC_CTLR_BASE + 0x38);
194
195 static uint32_t *pmc_ctlr_scratch4_ptr = (void *)(PMC_CTLR_BASE + 0x60);
196 enum {
197 PMC_SCRATCH4_LP = 0x1 << 31
198 };
199
200 static uint32_t *pmc_ctlr_cpupwrgood_timer_ptr =
201 (void *)(PMC_CTLR_BASE + 0xc8);
202
203 static uint32_t *pmc_ctlr_scratch41_ptr = (void *)(PMC_CTLR_BASE + 0x140);
204
205 static uint32_t *pmc_ctlr_osc_edpd_over_ptr = (void *)(PMC_CTLR_BASE + 0x1a4);
206 enum {
207 PMC_XOFS_SHIFT = 1,
208 PMC_XOFS_MASK = 0x3f << PMC_XOFS_SHIFT
209 };
210
211 /* Memory controller registers. */
212 static uint32_t *mc_video_protect_size_mb_ptr = (void *)(MC_CTLR_BASE + 0x64c);
213
214 static uint32_t *mc_video_protect_reg_ctrl_ptr =
215 (void *)(MC_CTLR_BASE + 0x650);
216 enum {
217 VIDEO_PROTECT_WRITE_ACCESS_DISABLE = 0x1 << 0,
218 VIDEO_PROTECT_ALLOW_TZ_WRITE_ACCESS = 0x1 << 1
219 };
220
221 /* System counter registers. */
222 static uint32_t *sysctr_cntcr_ptr = (void *)(SYSCTR_CTLR_BASE + 0x0);
223 enum {
224 TSC_CNTCR_ENABLE = 0x1 << 0,
225 TSC_CNTCR_HDBG = 0x1 << 1
226 };
227
228 static uint32_t *sysctr_cntfid0_ptr = (void *)(SYSCTR_CTLR_BASE + 0x20);
229
230 /* Utility functions. */
halt(void)231 static __always_inline void __noreturn halt(void)
232 {
233 for (;;);
234 }
235
read32(const void * addr)236 static inline uint32_t read32(const void *addr)
237 {
238 return *(volatile uint32_t *)addr;
239 }
240
write32(void * addr,uint32_t val)241 static inline void write32(void *addr, uint32_t val)
242 {
243 *(volatile uint32_t *)addr = val;
244 }
245
setbits32(uint32_t bits,void * addr)246 static inline void setbits32(uint32_t bits, void *addr)
247 {
248 write32(addr, read32(addr) | bits);
249 }
250
clrbits32(uint32_t bits,void * addr)251 static inline void clrbits32(uint32_t bits, void *addr)
252 {
253 write32(addr, read32(addr) & ~bits);
254 }
255
reset(void)256 static void __noreturn reset(void)
257 {
258 write32(clk_rst_rst_devices_l_ptr, SWR_TRIG_SYS_RST);
259 halt();
260 }
261
udelay(unsigned int usecs)262 static void udelay(unsigned int usecs)
263 {
264 uint32_t start = read32(timer_us_ptr);
265 while (read32(timer_us_ptr) - start < usecs)
266 ;
267 }
268
269 /* Accessors. */
wakeup_on_lp(void)270 static int wakeup_on_lp(void)
271 {
272 return !!(read32(pmc_ctlr_scratch4_ptr) & PMC_SCRATCH4_LP);
273 }
274
get_wakeup_vector(void)275 static uint32_t get_wakeup_vector(void)
276 {
277 return read32(pmc_ctlr_scratch41_ptr);
278 }
279
get_osc_freq(void)280 static unsigned int get_osc_freq(void)
281 {
282 return (read32(clk_rst_osc_ctrl_ptr) & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
283 }
284
285 /* Clock configuration. */
config_oscillator(void)286 static void config_oscillator(void)
287 {
288 // Read oscillator drive strength from OSC_EDPD_OVER.XOFS and copy
289 // to OSC_CTRL.XOFS and set XOE.
290 uint32_t xofs = (read32(pmc_ctlr_osc_edpd_over_ptr) &
291 PMC_XOFS_MASK) >> PMC_XOFS_SHIFT;
292
293 uint32_t osc_ctrl = read32(clk_rst_osc_ctrl_ptr);
294 osc_ctrl &= ~OSC_XOFS_MASK;
295 osc_ctrl |= (xofs << OSC_XOFS_SHIFT);
296 osc_ctrl |= OSC_XOE;
297 write32(clk_rst_osc_ctrl_ptr, osc_ctrl);
298 }
299
config_pllu(void)300 static void config_pllu(void)
301 {
302 // Figure out what parameters to use for PLLU.
303 uint32_t divm, divn, cpcon, lfcon;
304 switch (get_osc_freq()) {
305 case OSC_FREQ_12:
306 case OSC_FREQ_48:
307 divm = 0x0c;
308 divn = 0x3c0;
309 cpcon = 0x0c;
310 lfcon = 0x02;
311 break;
312 case OSC_FREQ_16P8:
313 divm = 0x07;
314 divn = 0x190;
315 cpcon = 0x05;
316 lfcon = 0x02;
317 break;
318 case OSC_FREQ_19P2:
319 case OSC_FREQ_38P4:
320 divm = 0x04;
321 divn = 0xc8;
322 cpcon = 0x03;
323 lfcon = 0x02;
324 break;
325 case OSC_FREQ_26:
326 divm = 0x1a;
327 divn = 0x3c0;
328 cpcon = 0x0c;
329 lfcon = 0x02;
330 break;
331 default:
332 // Map anything that's not recognized to 13MHz.
333 divm = 0x0d;
334 divn = 0x3c0;
335 cpcon = 0x0c;
336 lfcon = 0x02;
337 }
338
339 // Configure PLLU.
340 uint32_t base = PLLU_BYPASS | PLLU_OVERRIDE |
341 (divn << PLLU_DIVN_SHIFT) | (divm << PLLU_DIVM_SHIFT);
342 write32(clk_rst_pllu_base_ptr, base);
343 uint32_t misc = (cpcon << PLLU_CPCON_SHIFT) |
344 (lfcon << PLLU_LFCON_SHIFT);
345 write32(clk_rst_pllu_misc_ptr, misc);
346
347 // Enable PLLU.
348 base &= ~PLLU_BYPASS;
349 base |= PLLU_ENABLE;
350 write32(clk_rst_pllu_base_ptr, base);
351 misc |= PLLU_LOCK_ENABLE;
352 write32(clk_rst_pllu_misc_ptr, misc);
353 }
354
config_tsc(void)355 static void config_tsc(void)
356 {
357 // Tell the TSC the oscillator frequency.
358 switch (get_osc_freq()) {
359 case OSC_FREQ_12:
360 write32(sysctr_cntfid0_ptr, 12000000);
361 break;
362 case OSC_FREQ_48:
363 write32(sysctr_cntfid0_ptr, 48000000);
364 break;
365 case OSC_FREQ_16P8:
366 write32(sysctr_cntfid0_ptr, 16800000);
367 break;
368 case OSC_FREQ_19P2:
369 write32(sysctr_cntfid0_ptr, 19200000);
370 break;
371 case OSC_FREQ_38P4:
372 write32(sysctr_cntfid0_ptr, 38400000);
373 break;
374 case OSC_FREQ_26:
375 write32(sysctr_cntfid0_ptr, 26000000);
376 break;
377 default:
378 // Default to 13MHz.
379 write32(sysctr_cntfid0_ptr, 13000000);
380 break;
381 }
382
383 // Enable the TSC.
384 setbits32(TSC_CNTCR_ENABLE | TSC_CNTCR_HDBG, sysctr_cntcr_ptr);
385 }
386
enable_cpu_clocks(void)387 static void enable_cpu_clocks(void)
388 {
389 // Enable the CPU complex clock.
390 write32(clk_rst_clk_enb_l_set_ptr, CLK_ENB_CPU);
391 write32(clk_rst_clk_enb_v_set_ptr, CLK_ENB_CPUG | CLK_ENB_CPULP);
392 }
393
394 /* Function unit configuration. */
config_core_sight(void)395 static void config_core_sight(void)
396 {
397 // Enable the CoreSight clock.
398 write32(clk_rst_clk_out_enb_u_set_ptr, CLK_ENB_CSITE);
399
400 /*
401 * De-assert CoreSight reset.
402 * NOTE: We're leaving the CoreSight clock on the oscillator for
403 * now. It will be restored to its original clock source
404 * when the CPU-side restoration code runs.
405 */
406 write32(clk_rst_rst_dev_u_clr_ptr, SWR_CSITE_RST);
407 }
408
config_mselect(void)409 static void config_mselect(void)
410 {
411 // Set MSELECT clock source to PLLP with 1:4 divider.
412 write32(clk_rst_clk_src_mselect_ptr,
413 (6 << MSELECT_CLK_DIV_SHIFT) | MSELECT_CLK_SRC_PLLP_OUT0);
414
415 // Enable clock to MSELECT.
416 write32(clk_rst_clk_enb_v_set_ptr, CLK_ENB_MSELECT);
417
418 udelay(2);
419
420 // Bring MSELECT out of reset.
421 write32(clk_rst_rst_dev_v_clr_ptr, SWR_MSELECT_RST);
422 }
423
424 /* Resets. */
clear_cpu_resets(void)425 static void clear_cpu_resets(void)
426 {
427 // Take the non-cpu of the G and LP clusters out of reset.
428 write32(clk_rst_rst_cpulp_cmplx_clr_ptr, CLR_NONCPURESET);
429 write32(clk_rst_rst_cpug_cmplx_clr_ptr, CLR_NONCPURESET);
430
431 // Clear software controlled reset of the slow cluster.
432 write32(clk_rst_rst_cpulp_cmplx_clr_ptr,
433 CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0);
434
435 // Clear software controlled reset of the fast cluster.
436 write32(clk_rst_rst_cpug_cmplx_clr_ptr,
437 CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0 |
438 CLR_CPURESET1 | CLR_DBGRESET1 | CLR_CORERESET1 | CLR_CXRESET1 |
439 CLR_CPURESET2 | CLR_DBGRESET2 | CLR_CORERESET2 | CLR_CXRESET2 |
440 CLR_CPURESET3 | CLR_DBGRESET3 | CLR_CORERESET3 | CLR_CXRESET3);
441 }
442
443 /* RAM repair */
ram_repair(void)444 void ram_repair(void)
445 {
446 // Request Cluster0 RAM repair.
447 setbits32(RAM_REPAIR_REQ, flow_ctlr_ram_repair_ptr);
448 // Poll for Cluster0 RAM repair status.
449 while (!(read32(flow_ctlr_ram_repair_ptr) & RAM_REPAIR_STS))
450 ;
451
452 // Request Cluster1 RAM repair.
453 setbits32(RAM_REPAIR_REQ, flow_ctlr_ram_repair_cluster1_ptr);
454 // Poll for Cluster1 RAM repair status.
455 while (!(read32(flow_ctlr_ram_repair_cluster1_ptr) & RAM_REPAIR_STS))
456 ;
457 }
458
459 /* Power. */
power_on_partition(unsigned int id)460 static void power_on_partition(unsigned int id)
461 {
462 uint32_t bit = 0x1 << id;
463 if (!(read32(pmc_ctlr_pwrgate_status_ptr) & bit)) {
464 // Partition is not on. Turn it on.
465 write32(pmc_ctlr_pwrgate_toggle_ptr, id | PWRGATE_TOGGLE_START);
466
467 // Wait until the partition is powerd on.
468 while (!(read32(pmc_ctlr_pwrgate_status_ptr) & bit))
469 ;
470
471 // Wait until clamp is off.
472 while (read32(pmc_ctlr_clamp_status_ptr) & bit)
473 ;
474 }
475 }
476
power_on_main_cpu(void)477 static void power_on_main_cpu(void)
478 {
479 /*
480 * Reprogram PMC_CPUPWRGOOD_TIMER register:
481 *
482 * XXX This is a fragile assumption. XXX
483 * The kernel prepares PMC_CPUPWRGOOD_TIMER based on a 32768Hz clock.
484 * Note that PMC_CPUPWRGOOD_TIMER is running at pclk.
485 *
486 * We need to reprogram PMC_CPUPWRGOOD_TIMER based on the current pclk
487 * which is at 204Mhz (pclk = sclk = pllp_out2) after BootROM. Multiply
488 * PMC_CPUPWRGOOD_TIMER by 204M / 32K.
489 *
490 * Save the original PMC_CPUPWRGOOD_TIMER register which we need to
491 * restore after the CPU is powered up.
492 */
493 uint32_t orig_timer = read32(pmc_ctlr_cpupwrgood_timer_ptr);
494
495 write32(pmc_ctlr_cpupwrgood_timer_ptr,
496 orig_timer * (204000000 / 32768));
497
498 if (wakeup_on_lp()) {
499 power_on_partition(PARTID_C1NC);
500 power_on_partition(PARTID_CELP);
501 } else {
502 power_on_partition(PARTID_CRAIL);
503 power_on_partition(PARTID_C0NC);
504 power_on_partition(PARTID_CE0);
505 }
506
507 // Restore the original PMC_CPUPWRGOOD_TIMER.
508 write32(pmc_ctlr_cpupwrgood_timer_ptr, orig_timer);
509 }
510
511 /* Entry point. */
lp0_resume(void)512 void lp0_resume(void)
513 {
514 // If not on the AVP, reset.
515 if (read32(up_tag_ptr) != UP_TAG_AVP)
516 reset();
517
518 config_oscillator();
519
520 // Tell the flow controller which cluster to wake up. The default is
521 // the fast cluster.
522 if (wakeup_on_lp())
523 setbits32(FLOW_CLUSTER_ACTIVE_LP,
524 flow_ctlr_cluster_control_ptr);
525
526 // Program SUPER_CCLK_DIVIDER.
527 write32(clk_rst_super_cclk_div_ptr, SUPER_CDIV_ENB);
528
529 config_core_sight();
530
531 config_pllu();
532
533 // Set the CPU reset vector.
534 write32(evp_cpu_reset_ptr, get_wakeup_vector());
535
536 // Select CPU complex clock source.
537 write32(clk_rst_cclk_burst_policy_ptr, CCLK_PLLP_BURST_POLICY);
538
539 config_mselect();
540
541 // Disable PLLX since it isn't used as CPU clock source.
542 clrbits32(PLLX_ENABLE, clk_rst_pllx_base_ptr);
543
544 // Set CAR2PMC_CPU_ACK_WIDTH to 408.
545 uint32_t ack_width = read32(clk_rst_cpu_softrst_ctrl2_ptr);
546 ack_width &= ~CAR2PMC_CPU_ACK_WIDTH_MASK;
547 ack_width |= 408 << CAR2PMC_CPU_ACK_WIDTH_SHIFT;
548 write32(clk_rst_cpu_softrst_ctrl2_ptr, ack_width);
549
550 config_tsc();
551
552 // Disable VPR.
553 write32(mc_video_protect_size_mb_ptr, 0);
554 write32(mc_video_protect_reg_ctrl_ptr,
555 VIDEO_PROTECT_WRITE_ACCESS_DISABLE);
556
557 enable_cpu_clocks();
558
559 power_on_main_cpu();
560
561 // Perform RAM repair after CPU is powered on.
562 ram_repair();
563
564 clear_cpu_resets();
565
566 // Halt the AVP.
567 while (1)
568 write32(flow_ctlr_halt_cop_events_ptr,
569 FLOW_MODE_STOP | EVENT_JTAG);
570 }
571
572 /* Header. */
573 extern uint8_t blob_data;
574 extern uint8_t blob_data_size;
575 extern uint8_t blob_total_size;
576
577 struct lp0_header {
578 uint32_t length_insecure; // Insecure total length.
579 uint32_t reserved[3];
580 uint8_t rsa_modulus[256]; // RSA key modulus.
581 uint8_t aes_signature[16]; // AES signature.
582 uint8_t rsa_signature[256]; // RSA-PSS signature.
583 uint8_t random_aes_block[16]; // Random data, may be zero.
584 uint32_t length_secure; // Secure total length.
585 uint32_t destination; // Where to load the blob in iRAM.
586 uint32_t entry_point; // Entry point for the blob.
587 uint32_t code_length; // Length of just the data.
588 } __packed;
589
590 struct lp0_header header __attribute__((section(".header"))) =
591 {
592 .length_insecure = (uintptr_t)&blob_total_size,
593 .length_secure = (uintptr_t)&blob_total_size,
594 .destination = (uintptr_t)&blob_data,
595 .entry_point = (uintptr_t)&lp0_resume,
596 .code_length = (uintptr_t)&blob_data_size
597 };
598