efistub.c (2479B)
1 #include "efi.h" 2 3 #include "kernel.h" 4 5 void 6 efi_die(struct efi_system_table *table, c16 *msg); 7 8 EFI_IMAGE_ENTRY_POINT(__efi_entry) 9 { 10 efi_status_t err; 11 12 struct efi_simple_text_output_protocol *stdout = system_table->con_out; 13 stdout->reset(stdout, false); 14 stdout->output_string(stdout, u"UEFI\r\n"); 15 16 struct efi_boot_services *boot_services = system_table->boot_services; 17 struct efi_boot_info boot_info; 18 19 /* TODO: find acpi data */ 20 21 /* TODO: setup framebuffer */ 22 23 /* exit UEFI boot services 24 * NOTE: exit_boot_services() can return EFI_INVALID_PARAMETER, in 25 * which case the process needs to be restarted with a new 26 * memory map key 27 */ 28 do { 29 umm mem_map_size = 0, mem_map_key, descriptor_size; 30 u32 descriptor_version; 31 32 err = boot_services->get_memory_map(&mem_map_size, NULL, 33 &mem_map_key, 34 &descriptor_size, 35 &descriptor_version); 36 37 if (err != EFI_BUFFER_TOO_SMALL || mem_map_size == 0) 38 efi_die(system_table, u"ERROR: failed to get memory map size\r\n"); 39 40 /* overallocate memory map buffer to avoid second get_memory_map() error */ 41 umm buf_size = mem_map_size + (4 * descriptor_size); 42 boot_info.memory_map.map_size = boot_info.memory_map.buf_size = buf_size; 43 44 err = boot_services->allocate_pool(EFI_LOADER_DATA, 45 boot_info.memory_map.buf_size, 46 (void **) &boot_info.memory_map.map); 47 48 if (err) 49 efi_die(system_table, u"ERROR: failed to allocate memory map buffer\r\n"); 50 51 err = boot_services->get_memory_map(&boot_info.memory_map.map_size, 52 boot_info.memory_map.map, 53 &boot_info.memory_map.key, 54 &boot_info.memory_map.desc_size, 55 &boot_info.memory_map.desc_ver); 56 57 if (err) { 58 boot_services->free_pool(boot_info.memory_map.map); 59 efi_die(system_table, u"ERROR: failed to get memory map\r\n"); 60 } 61 62 err = boot_services->exit_boot_services(image_handle, 63 boot_info.memory_map.key); 64 65 if (err == EFI_INVALID_PARAMETER) { 66 boot_services->free_pool(boot_info.memory_map.map); 67 } else { 68 efi_die(system_table, u"ERROR: failed to exit boot services\r\n"); 69 } 70 } while (err == EFI_INVALID_PARAMETER); 71 72 /* go into the kernel proper */ 73 ksetup(&boot_info); 74 kmain(&boot_info); 75 76 for (;;); 77 78 return EFI_SUCCESS; 79 } 80 81 void 82 efi_die(struct efi_system_table *system_table, c16 *msg) 83 { 84 system_table->con_out->output_string(system_table->con_out, msg); 85 system_table->runtime_services->reset_system(EFI_RESET_SHUTDOWN, EFI_LOAD_ERROR, 0, NULL); 86 }