1 #include <dragonstub/dragonstub.h> 2 #include <dragonstub/linux/unaligned.h> 3 #include "efilib.h" 4 #include <libfdt.h> 5 6 /// @brief 当前的hartid 7 static unsigned long hartid; 8 9 static efi_status_t get_boot_hartid_from_fdt(void) 10 { 11 const void *fdt; 12 int chosen_node, len; 13 const void *prop; 14 15 // efi_guid_t device_tree_guid = *(efi_guid_t *)&tmp; 16 fdt = get_efi_config_table(DEVICE_TREE_GUID); 17 if (!fdt) { 18 efi_err("Failed to get FDT from EFI config table\n"); 19 return EFI_INVALID_PARAMETER; 20 } 21 22 chosen_node = fdt_path_offset(fdt, "/chosen"); 23 if (chosen_node < 0) { 24 efi_err("Failed to find /chosen node in FDT\n"); 25 return EFI_INVALID_PARAMETER; 26 } 27 28 prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len); 29 if (!prop) { 30 efi_err("Failed to find boot-hartid property in FDT\n"); 31 return EFI_INVALID_PARAMETER; 32 } 33 34 if (len == sizeof(u32)) 35 hartid = (unsigned long)fdt32_to_cpu(*(fdt32_t *)prop); 36 else if (len == sizeof(u64)) 37 hartid = (unsigned long)fdt64_to_cpu( 38 __get_unaligned_t(fdt64_t, prop)); 39 else { 40 efi_err("Invalid boot-hartid property in FDT\n"); 41 return EFI_INVALID_PARAMETER; 42 } 43 44 return 0; 45 } 46 47 static efi_status_t get_boot_hartid_from_efi(void) 48 { 49 efi_guid_t boot_protocol_guid = RISCV_EFI_BOOT_PROTOCOL_GUID; 50 struct riscv_efi_boot_protocol *boot_protocol; 51 efi_status_t status; 52 53 status = efi_bs_call(LocateProtocol, &boot_protocol_guid, NULL, 54 (void **)&boot_protocol); 55 if (status != EFI_SUCCESS) 56 return status; 57 return efi_call_proto(boot_protocol, get_boot_hartid, &hartid); 58 } 59 60 efi_status_t check_platform_features(void) 61 { 62 efi_info("Checking platform features...\n"); 63 efi_status_t status = -1; 64 int ret; 65 efi_info("Try to get boot hartid from EFI\n"); 66 status = get_boot_hartid_from_efi(); 67 if (status != EFI_SUCCESS) { 68 efi_info("Try to get boot hartid from FDT\n"); 69 ret = get_boot_hartid_from_fdt(); 70 if (ret) { 71 efi_err("Failed to get boot hartid!\n"); 72 return EFI_UNSUPPORTED; 73 } 74 } 75 76 efi_info("Boot hartid: %ld\n", hartid); 77 return EFI_SUCCESS; 78 }