riscv-stub.c 2.0 KB

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