|
9 | 9 | #include <asm/addrspace.h> |
10 | 10 | #include "efistub.h" |
11 | 11 |
|
12 | | -typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long fdt); |
| 12 | +typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long cmdline, |
| 13 | + unsigned long systab); |
13 | 14 |
|
14 | 15 | extern int kernel_asize; |
15 | 16 | extern int kernel_fsize; |
@@ -42,19 +43,60 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, |
42 | 43 | return status; |
43 | 44 | } |
44 | 45 |
|
45 | | -void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned long fdt, unsigned long fdt_size) |
| 46 | +struct exit_boot_struct { |
| 47 | + efi_memory_desc_t *runtime_map; |
| 48 | + int runtime_entry_count; |
| 49 | +}; |
| 50 | + |
| 51 | +static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv) |
| 52 | +{ |
| 53 | + struct exit_boot_struct *p = priv; |
| 54 | + |
| 55 | + /* |
| 56 | + * Update the memory map with virtual addresses. The function will also |
| 57 | + * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME |
| 58 | + * entries so that we can pass it straight to SetVirtualAddressMap() |
| 59 | + */ |
| 60 | + efi_get_virtmap(map->map, map->map_size, map->desc_size, |
| 61 | + p->runtime_map, &p->runtime_entry_count); |
| 62 | + |
| 63 | + return EFI_SUCCESS; |
| 64 | +} |
| 65 | + |
| 66 | +efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image, |
| 67 | + unsigned long kernel_addr, char *cmdline_ptr) |
46 | 68 | { |
47 | 69 | kernel_entry_t real_kernel_entry; |
| 70 | + struct exit_boot_struct priv; |
| 71 | + unsigned long desc_size; |
| 72 | + efi_status_t status; |
| 73 | + u32 desc_ver; |
| 74 | + |
| 75 | + status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver); |
| 76 | + if (status != EFI_SUCCESS) { |
| 77 | + efi_err("Unable to retrieve UEFI memory map.\n"); |
| 78 | + return status; |
| 79 | + } |
| 80 | + |
| 81 | + efi_info("Exiting boot services\n"); |
| 82 | + |
| 83 | + efi_novamap = false; |
| 84 | + status = efi_exit_boot_services(handle, &priv, exit_boot_func); |
| 85 | + if (status != EFI_SUCCESS) |
| 86 | + return status; |
| 87 | + |
| 88 | + /* Install the new virtual address map */ |
| 89 | + efi_rt_call(set_virtual_address_map, |
| 90 | + priv.runtime_entry_count * desc_size, desc_size, |
| 91 | + desc_ver, priv.runtime_map); |
48 | 92 |
|
49 | 93 | /* Config Direct Mapping */ |
50 | 94 | csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0); |
51 | 95 | csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1); |
52 | 96 |
|
53 | 97 | real_kernel_entry = (kernel_entry_t) |
54 | | - ((unsigned long)&kernel_entry - entrypoint + VMLINUX_LOAD_ADDRESS); |
| 98 | + ((unsigned long)&kernel_entry - kernel_addr + VMLINUX_LOAD_ADDRESS); |
55 | 99 |
|
56 | | - if (!efi_novamap) |
57 | | - real_kernel_entry(true, fdt); |
58 | | - else |
59 | | - real_kernel_entry(false, fdt); |
| 100 | + real_kernel_entry(true, (unsigned long)cmdline_ptr, |
| 101 | + (unsigned long)efi_system_table); |
60 | 102 | } |
0 commit comments