xref: /DragonStub/apps/riscv-stub.c (revision 3e6106c4d60a23aae3c0740979c5e6fb728b63c3)
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 }