gpt.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /* Copyright (c) 2018 SiFive, Inc */
  2. /* SPDX-License-Identifier: Apache-2.0 */
  3. /* SPDX-License-Identifier: GPL-2.0-or-later */
  4. /* See the file LICENSE for further information */
  5. #include "comdef.h"
  6. #include "gpt.h"
  7. #define _ASSERT_SIZEOF(type, size) \
  8. _Static_assert(sizeof(type) == (size), #type " must be " #size " bytes wide")
  9. #define _ASSERT_OFFSETOF(type, member, offset) \
  10. _Static_assert(offsetof(type, member) == (offset), #type "." #member " must be at offset " #offset)
  11. typedef struct
  12. {
  13. gpt_guid partition_type_guid;
  14. gpt_guid partition_guid;
  15. uint64_t first_lba;
  16. uint64_t last_lba;
  17. uint64_t attributes;
  18. uint16_t name[36]; // UTF-16
  19. } gpt_partition_entry;
  20. _ASSERT_SIZEOF(gpt_partition_entry, 128);
  21. // GPT represents GUIDs with the first three blocks as little-endian
  22. #if 0
  23. // c12a7328-f81f-11d2-ba4b-00a0c93ec93b
  24. const gpt_guid gpt_guid_efi = {{
  25. 0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11, 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
  26. }};
  27. // 2e54b353-1271-4842-806f-e436d6af6985
  28. const gpt_guid gpt_guid_sifive_bare_metal = {{
  29. 0x53, 0xb3, 0x54, 0x2e, 0x71, 0x12, 0x42, 0x48, 0x80, 0x6f, 0xe4, 0x36, 0xd6, 0xaf, 0x69, 0x85
  30. }};
  31. #endif
  32. // 5b193300-fc78-40cd-8002-e86c45580b47
  33. const gpt_guid gpt_guid_sifive_uboot = {{
  34. 0x00, 0x33, 0x19, 0x5b, 0x78, 0xfc, 0xcd, 0x40, 0x80, 0x02, 0xe8, 0x6c, 0x45, 0x58, 0x0b, 0x47
  35. }};
  36. // EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
  37. const gpt_guid gpt_guid_sifive_kernel = {{
  38. 0xa2,0xa0,0xd0,0xeb,0xe5,0xb9,0x33,0x44,0x87,0xc0,0x68,0xb6,0xb7,0x26,0x99,0xc7
  39. }};
  40. static inline bool guid_equal(const gpt_guid* a, const gpt_guid* b)
  41. {
  42. for (int i = 0; i < GPT_GUID_SIZE; i++) {
  43. if (a->bytes[i] != b->bytes[i]) {
  44. return false;
  45. }
  46. }
  47. return true;
  48. }
  49. // Public functions
  50. /**
  51. * Search the given block of partition entries for a partition with the given
  52. * GUID. Return a range of [0, 0] to indicate that the partition was not found.
  53. */
  54. gpt_partition_range gpt_find_partition_by_guid(const void* entries, const gpt_guid* guid, uint32_t num_entries)
  55. {
  56. gpt_partition_entry* gpt_entries = (gpt_partition_entry*) entries;
  57. for (uint32_t i = 0; i < num_entries; i++) {
  58. if (guid_equal(&gpt_entries[i].partition_type_guid, guid)) {
  59. return (gpt_partition_range) {
  60. .first_lba = gpt_entries[i].first_lba,
  61. .last_lba = gpt_entries[i].last_lba,
  62. };
  63. }
  64. }
  65. return (gpt_partition_range) { .first_lba = 0, .last_lba = 0 };
  66. }