blob: 599da009e848f4acad5578b7760413991ae60d6d [file] [log] [blame]
/*
* Top-level entry points to the Boot ROM. This includes:
* - Reset, exception and interrupt vectors.
* - C run-time initialization.
* - Secondary CPU boot code.
*
* Copyright 2025 Google LLC
* Copyright (C) ASPEED Technology Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define KiB (1024)
#define SRAM_SIZE (128 * KiB)
.section .bss
.global next_boot_addr
.type next_boot_addr, %object
next_boot_addr:
.skip 8
.size next_boot_addr, . - next_boot_addr
.section .text.vectors, "ax"
.global _start
.type _start, %function
_start:
b reset
. = 0x04
b undefined_instruction
. = 0x08
b software_interrupt
. = 0x0c
b prefetch_abort
. = 0x10
b data_abort
. = 0x18
b interrupt
. = 0x1c
b fast_interrupt
undefined_instruction:
mov x0, #1
b handle_exception
software_interrupt:
mov x0, #2
b handle_exception
prefetch_abort:
mov x0, #3
b handle_exception
data_abort:
mov x0, #4
b handle_exception
interrupt:
mov x0, #6
b handle_exception
fast_interrupt:
mov x0, #7
b handle_exception
vectors_end:
.text
.align 2
handle_exception:
.global panic
.type panic, %function
panic:
1: wfi
b 1b
.size panic, . - panic
.type reset, %function
reset:
mov x0, #0
// Determine the current core ID using MPIDR_EL1.
// If it's core 0, jump to CPU0 initialization routine.
// Otherwise, wait for CPU0 to publish the boot entry point.
mrs x1, MPIDR_EL1
and x1, x1, #0x03
cbz x1, cpu0_init
// Non-CPU0 cores wait here until CPU0 sets the next_boot_addr.
// Once it's non-zero, jump to that address.
1:
ldr x2, =next_boot_addr
ldr x3, [x2]
cbnz x3, 2f
wfe
b 1b
// Perform synchronization before branching to boot image.
2:
dsb sy
isb
br x3
// Should never reach here unless boot entry is invalid.
b panic
.size reset, . - reset
.type cpu0_init, %function
cpu0_init:
// Set up stack pointer to top of SRAM (with 16-byte safety margin).
// This ensures the stack is within the SRAM region and avoids overflow.
ldr x1, sram_base_addr
mov x2, #SRAM_SIZE
sub x2, x2, #0x10 // leave 16-byte safety margin
add sp, x1, x2 // SP = base + size - 0x10
// Copy initialized .data section from ROM (LMA) to RAM (VMA)
ldr x3, =__data_loadaddr // source address in ROM
ldr x4, =__data // destination address in RAM
ldr x5, =__edata // end of .data in RAM
copy_data_loop:
cmp x4, x5
b.ge data_copy_done
ldr w6, [x3], #4 // load word from ROM and post-increment
str w6, [x4] // store word to RAM
add x4, x4, #4 // move to next word
b copy_data_loop
data_copy_done:
// Zero-initialize the .bss section in RAM
ldr x4, =__bss_start
ldr x5, =__bss_end
clear_bss_loop:
cmp x4, x5
b.ge bss_clear_done
mov w6, #0
str w6, [x4] // store zero to memory
add x4, x4, #4 // move to next word
b clear_bss_loop
bss_clear_done:
// Load the boot image.
// Returns the entry point in x0
bl load_boot_image
// Write entry point to shared memory for other CPUs
// and send an event to wake them up from WFE.
// x0 now holds the boot image entry point
ldr x2, =next_boot_addr
str x0, [x2]
dsb st
sev
// Synchronize memory and pipeline before jumping to the boot image.
dsb sy
isb
br x0
// Should never reach here unless something goes wrong.
b panic
.size cpu0_init, . - cpu0_init
.section .rodata
.type sram_base_addr, %object
sram_base_addr:
.dword 0x10000000
.size sram_base_addr, . - sram_base_addr