Commit 732ea9db9d8a ("efi: libstub: Move screen_info handling to common code") reorganized the earlycon handling so that all architectures pass the screen_info data via a EFI config table instead of populating struct screen_info directly, as the latter is only possible when the EFI stub is baked into the kernel (and not into the decompressor). However, this means that struct screen_info may not have been populated yet by the time the earlycon probe takes place, and this results in a non-functional early console. So let's probe again right after parsing the config tables and populating struct screen_info. Note that this means that earlycon output starts a bit later than before, and so it may fail to capture issues that occur while doing the early EFI initialization.
Unified · Split
| @@ -215,6 +215,14 @@ efi_earlycon_write(struct console *con, const char *str, unsigned int num) · 214 unmodified lines | ||
| 215 | 215 | } |
| 216 | 216 | } |
| 217 | 217 | |
| 218 | +static bool __initdata fb_probed; | |
| 219 | + | |
| 220 | +void __init efi_earlycon_reprobe(void) | |
| 221 | +{ | |
| 222 | + if (fb_probed) | |
| 223 | + setup_earlycon("efifb"); | |
| 224 | +} | |
| 225 | + | |
| 218 | 226 | static int __init efi_earlycon_setup(struct earlycon_device *device, |
| 219 | 227 | const char *opt) |
| 220 | 228 | { |
| @@ -222,15 +230,17 @@ static int __init efi_earlycon_setup(struct earlycon_device *device, · 1 unmodified line | ||
| 222 | 230 | u16 xres, yres; |
| 223 | 231 | u32 i; |
| 224 | 232 | |
| 225 | − if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) | |
| 233 | + fb_wb = opt && !strcmp(opt, "ram"); | |
| 234 | + | |
| 235 | + if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) { | |
| 236 | + fb_probed = true; | |
| 226 | 237 | return -ENODEV; |
| 238 | + } | |
| 227 | 239 | |
| 228 | 240 | fb_base = screen_info.lfb_base; |
| 229 | 241 | if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) |
| 230 | 242 | fb_base |= (u64)screen_info.ext_lfb_base << 32; |
| 231 | 243 | |
| 232 | − fb_wb = opt && !strcmp(opt, "ram"); | |
| 233 | − | |
| 234 | 244 | si = &screen_info; |
| 235 | 245 | xres = si->lfb_width; |
| 236 | 246 | yres = si->lfb_height; |
| @@ -72,6 +72,9 @@ static void __init init_screen_info(void) · 71 unmodified lines | ||
| 72 | 72 | if (memblock_is_map_memory(screen_info.lfb_base)) |
| 73 | 73 | memblock_mark_nomap(screen_info.lfb_base, |
| 74 | 74 | screen_info.lfb_size); |
| 75 | + | |
| 76 | + if (IS_ENABLED(CONFIG_EFI_EARLYCON)) | |
| 77 | + efi_earlycon_reprobe(); | |
| 75 | 78 | } |
| 76 | 79 | } |
| 77 | 80 | |
| @@ -693,6 +693,7 @@ efi_guid_to_str(efi_guid_t *guid, char *out) · 692 unmodified lines | ||
| 693 | 693 | } |
| 694 | 694 | |
| 695 | 695 | extern void efi_init (void); |
| 696 | +extern void efi_earlycon_reprobe(void); | |
| 696 | 697 | #ifdef CONFIG_EFI |
| 697 | 698 | extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */ |
| 698 | 699 | #else |