Iterating over a EFI handle array is a bit finicky, since we have to take mixed mode into account, where handles are only 32-bit while the native efi_handle_t type is 64-bit. So introduce a helper, and replace the various occurrences of this pattern.
Unified · Split
| @@ -135,6 +135,7 @@ static void setup_efi_pci(struct boot_params *params) · 134 unmodified lines | ||
| 135 | 135 | unsigned long size = 0; |
| 136 | 136 | unsigned long nr_pci; |
| 137 | 137 | struct setup_data *data; |
| 138 | + efi_handle_t h; | |
| 138 | 139 | int i; |
| 139 | 140 | |
| 140 | 141 | status = efi_call_early(locate_handle, |
| @@ -164,14 +165,11 @@ static void setup_efi_pci(struct boot_params *params) · 23 unmodified lines | ||
| 164 | 165 | while (data && data->next) |
| 165 | 166 | data = (struct setup_data *)(unsigned long)data->next; |
| 166 | 167 | |
| 167 | − nr_pci = size / (efi_is_64bit() ? sizeof(u64) : sizeof(u32)); | |
| 168 | − for (i = 0; i < nr_pci; i++) { | |
| 168 | + for_each_efi_handle(h, pci_handle, size, i) { | |
| 169 | 169 | efi_pci_io_protocol_t *pci = NULL; |
| 170 | 170 | struct pci_setup_rom *rom; |
| 171 | 171 | |
| 172 | − status = efi_call_early(handle_protocol, | |
| 173 | − efi_is_64bit() ? ((u64 *)pci_handle)[i] | |
| 174 | − : ((u32 *)pci_handle)[i], | |
| 172 | + status = efi_call_early(handle_protocol, h, | |
| 175 | 173 | &pci_proto, (void **)&pci); |
| 176 | 174 | if (status != EFI_SUCCESS || !pci) |
| 177 | 175 | continue; |
| @@ -266,6 +264,7 @@ setup_uga(struct screen_info *si, efi_guid_t *uga_proto, unsigned long size) · 88 unmodified lines | ||
| 266 | 264 | void **uga_handle = NULL; |
| 267 | 265 | efi_uga_draw_protocol_t *uga = NULL, *first_uga; |
| 268 | 266 | unsigned long nr_ugas; |
| 267 | + efi_handle_t handle; | |
| 269 | 268 | int i; |
| 270 | 269 | |
| 271 | 270 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, |
| @@ -283,13 +282,10 @@ setup_uga(struct screen_info *si, efi_guid_t *uga_proto, unsigned long size) · 11 unmodified lines | ||
| 283 | 282 | width = 0; |
| 284 | 283 | |
| 285 | 284 | first_uga = NULL; |
| 286 | − nr_ugas = size / (efi_is_64bit() ? sizeof(u64) : sizeof(u32)); | |
| 287 | − for (i = 0; i < nr_ugas; i++) { | |
| 285 | + for_each_efi_handle(handle, uga_handle, size, i) { | |
| 288 | 286 | efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID; |
| 289 | 287 | u32 w, h, depth, refresh; |
| 290 | 288 | void *pciio; |
| 291 | − unsigned long handle = efi_is_64bit() ? ((u64 *)uga_handle)[i] | |
| 292 | − : ((u32 *)uga_handle)[i]; | |
| 293 | 289 | |
| 294 | 290 | status = efi_call_early(handle_protocol, handle, |
| 295 | 291 | uga_proto, (void **)&uga); |
| @@ -91,7 +91,6 @@ setup_gop(efi_system_table_t *sys_table_arg, struct screen_info *si, · 90 unmodified lines | ||
| 91 | 91 | efi_guid_t *proto, unsigned long size, void **handles) |
| 92 | 92 | { |
| 93 | 93 | efi_graphics_output_protocol_t *gop, *first_gop; |
| 94 | − unsigned long nr_gops; | |
| 95 | 94 | u16 width, height; |
| 96 | 95 | u32 pixels_per_scan_line; |
| 97 | 96 | u32 ext_lfb_base; |
| @@ -99,22 +98,18 @@ setup_gop(efi_system_table_t *sys_table_arg, struct screen_info *si, · 1 unmodified line | ||
| 99 | 98 | efi_pixel_bitmask_t pixel_info; |
| 100 | 99 | int pixel_format; |
| 101 | 100 | efi_status_t status; |
| 101 | + efi_handle_t h; | |
| 102 | 102 | int i; |
| 103 | − bool is64 = efi_is_64bit(); | |
| 104 | 103 | |
| 105 | 104 | first_gop = NULL; |
| 106 | 105 | gop = NULL; |
| 107 | 106 | |
| 108 | − nr_gops = size / (is64 ? sizeof(u64) : sizeof(u32)); | |
| 109 | − for (i = 0; i < nr_gops; i++) { | |
| 107 | + for_each_efi_handle(h, handles, size, i) { | |
| 110 | 108 | efi_graphics_output_protocol_mode_t *mode; |
| 111 | 109 | efi_graphics_output_mode_info_t *info = NULL; |
| 112 | 110 | efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; |
| 113 | 111 | bool conout_found = false; |
| 114 | 112 | void *dummy = NULL; |
| 115 | − efi_handle_t h = (efi_handle_t)(unsigned long) | |
| 116 | − (is64 ? ((u64 *)handles)[i] | |
| 117 | − : ((u32 *)handles)[i]); | |
| 118 | 113 | efi_physical_addr_t current_fb_base; |
| 119 | 114 | |
| 120 | 115 | status = efi_call_early(handle_protocol, h, |
| @@ -48,6 +48,19 @@ typedef u16 efi_char16_t; /* UNICODE character */ · 47 unmodified lines | ||
| 48 | 48 | typedef u64 efi_physical_addr_t; |
| 49 | 49 | typedef void *efi_handle_t; |
| 50 | 50 | |
| 51 | +#define efi_get_handle_at(array, idx) \ | |
| 52 | + (efi_is_64bit() ? (efi_handle_t)(unsigned long)((u64 *)(array))[idx] \ | |
| 53 | + : (efi_handle_t)(unsigned long)((u32 *)(array))[idx]) | |
| 54 | + | |
| 55 | +#define efi_get_handle_num(size) \ | |
| 56 | + ((size) / (efi_is_64bit() ? sizeof(u64) : sizeof(u32))) | |
| 57 | + | |
| 58 | +#define for_each_efi_handle(handle, array, size, i) \ | |
| 59 | + for (i = 0; \ | |
| 60 | + i < efi_get_handle_num(size) && \ | |
| 61 | + ((handle = efi_get_handle_at((array), i)) || true); \ | |
| 62 | + i++) | |
| 63 | + | |
| 51 | 64 | /* |
| 52 | 65 | * The UEFI spec and EDK2 reference implementation both define EFI_GUID as |
| 53 | 66 | * struct { u32 a; u16; b; u16 c; u8 d[8]; }; and so the implied alignment |