.text
-.global eret, boot_entry, boot_entry_psci, boot_entry_parking
+.global eret, boot_entry_bsp, boot_entry_psci, boot_entry_parking
+.type boot_entry_bsp, @function
+.type boot_entry_psci, @function
+.type boot_entry_parking, @function
/*
This is the kernel entry point. We distinguish between how and who booted
*/
-boot_entry:
- /* load the MULTIBOOT2_BOOTLOADER_MAGIC value into register x4. */
- movz x4, #(MULTIBOOT2_BOOTLOADER_MAGIC >> 16), LSL #16
- movk x4, #(MULTIBOOT2_BOOTLOADER_MAGIC & 0xffff)
-
- /* compare with register x0 */
- cmp x0, x4
-
- /* branch off to psci or parking boot */
- b.ne psci_or_parking_boot
-
- /* Calling the boot initialization function for the BSP core.
+boot_entry_bsp:
+ /* Calling the boot initialization function for the BSP core.
void boot_bsp_init(uint32_t magic,
lpaddr_t pointer,
before we branch off to the C function
*/
-psci_or_parking_boot:
+boot_entry_psci:
ldr x1, [x0, #OFFSETOF_COREDATA_KERNEL_STACK]
mov sp, x1
b boot_app_init
+ wfi
+
+boot_entry_parking:
+ wfi
/* Error return required to drop to lower execution levels */
eret:
entry, context).error;
}
-
+struct arch_config
+{
+ genpaddr_t arch_page_size;
+ size_t stack_size;
+ char boot_driver[256];
+ char boot_driver_entry[256];
+ char cpu_driver[256];
+ char monitor_binary[256];
+};
static errval_t get_arch_config(hwid_t hwid,
genpaddr_t *arch_page_size,
size_t *stack_size,
const char *monitor_binary,
- const char *cpu_binary)
+ const char *cpu_binary,
+ const char *entry_sym)
{
errval_t err;
err= skb_read_output("res(%255[^)])", monitor_binary);
if (err_is_fail(err)) return err;
+ err = skb_execute_query("boot_driver_entry(%"PRIu64",T), entry_symbol(T,S),"
+ " write(res(S)).", hwid);
+ if (err_is_fail(err)) {
+ printf("error: \n %s\n", skb_get_error_output());
+ return err;
+ }
+ err= skb_read_output("res(%255[^)])", entry_sym);
+ if (err_is_fail(err)) {
+ return err;
+ }
+
*arch_page_size= BASE_PAGE_SIZE;
*stack_size = ARMV8_KERNEL_STACK_SIZE;
static errval_t load_cpudriver(uint16_t em_machine, struct mem_info *cpumem,
lvaddr_t base, size_t size, size_t arch_page_size,
- genvaddr_t *retentry){
+ const char *entry_sym, genvaddr_t *retentry){
errval_t err;
DEBUG("Found %d program header(s)\n", ehdr->e_phnum);
+ lpaddr_t entry_point = 0;
+
+ if (entry_sym && strlen(entry_sym) > 0) {
+ DEBUG("Looking for entry: '%s'\n", entry_sym);
+ struct Elf64_Sym *entry;
+ entry = elf64_find_symbol_by_name(base, size, entry_sym, 0, STT_FUNC, 0);
+ if (!entry) {
+ debug_printf("Entry '%s' not found\n", entry_sym);
+ return ELF_ERR_PROGHDR;
+ }
+ entry_point = entry->st_value;
+ } else {
+ entry_point = ehdr->e_entry;
+ }
+
+ DEBUG("Entry point: %p\n", entry_point);
+
/* Load the CPU driver from its ELF image. */
bool found_entry_point= 0;
bool loaded = 0;
- lpaddr_t entry_point = 0;
+
struct Elf64_Phdr *phdr = (struct Elf64_Phdr *)(base + ehdr->e_phoff);
for(size_t i= 0; i < ehdr->e_phnum; i++) {
if(phdr[i].p_type != PT_LOAD) {
/* zero out BSS section */
memset(dest + phdr[i].p_filesz, 0, phdr[i].p_memsz - phdr[i].p_filesz);
- if(ehdr->e_entry >= phdr[i].p_vaddr &&
- ehdr->e_entry - phdr[i].p_vaddr < phdr[i].p_memsz) {
- entry_point= (dest_phys + (ehdr->e_entry - phdr[i].p_vaddr));
- found_entry_point= 1;
+ if (!found_entry_point) {
+ if(entry_point >= phdr[i].p_vaddr
+ && entry_point - phdr[i].p_vaddr < phdr[i].p_memsz) {
+ entry_point= (dest_phys + (entry_point - phdr[i].p_vaddr));
+ found_entry_point= 1;
+ }
}
}
DEBUG("Booting: %" PRIuCOREID ", hwid=%" PRIxHWID "\n", coreid, hwid);
- static char cpuname[256], monitorname[256];
+ static char cpuname[256], monitorname[256], entry_sym[256];
genpaddr_t arch_page_size;
size_t stack_size;
errval_t err;
return SPAWN_ERR_UNKNOWN_TARGET_ARCH;
}
- err = get_arch_config(hwid, &arch_page_size, &stack_size, monitorname, cpuname);
+ err = get_arch_config(hwid, &arch_page_size, &stack_size, monitorname,
+ cpuname, entry_sym);
if (err_is_fail(err)) {
DEBUG_ERR(err, "failed to obtain architecture configuration");
+ return err;
}
DEBUG("loading kernel: %s\n", cpuname);
DEBUG("loading 1st app: %s\n", monitorname);
+ DEBUG("entry symbol: %s\n", entry_sym);
// compute size of frame needed and allocate it
DEBUG("%s:%s:%d: urpc_frame_id.base=%"PRIxGENPADDR"\n",
genvaddr_t cpu_entry;
err = load_cpudriver(cpu_head->e_machine, &cpu_mem, cpu_binary.vaddr,
- cpu_binary.size, arch_page_size, &cpu_entry);
+ cpu_binary.size, arch_page_size, entry_sym, &cpu_entry);
if (err_is_fail(err)) {
DEBUG_ERR(err, "Can not load kernel .");
return err;