On 01/29/2019 10:21 AM, Ard Biesheuvel wrote:
Move the x86 EFI earlyprintk implementation to a shared location under
drivers/firmware and tweak it slightly so we can expose it as an earlycon
implementation (which is generic) rather than earlyprintk (which is only
implemented for a few architectures)

This also involves switching to write-combine mappings by default (which
is required on ARM since device mappings lack memory semantics, and so
memcpy/memset may not be used on them), and adding support for shared
memory framebuffers on cache coherent non-x86 systems (which do not
tolerate mismatched attributes)

Note that 32-bit ARM does not populate its struct screen_info early
enough for earlycon=efifb to work, so it is disabled there.

Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
---
  Documentation/admin-guide/kernel-parameters.txt |   8 +-
  arch/x86/Kconfig.debug                          |  10 -
  arch/x86/include/asm/efi.h                      |   1 -
  arch/x86/kernel/early_printk.c                  |   4 -
  arch/x86/platform/efi/Makefile                  |   1 -
  arch/x86/platform/efi/early_printk.c            | 240 --------------------
  drivers/firmware/efi/Kconfig                    |   6 +
  drivers/firmware/efi/Makefile                   |   1 +
  drivers/firmware/efi/earlycon.c                 | 208 +++++++++++++++++
  9 files changed, 222 insertions(+), 257 deletions(-)


[...]

+static int __init efi_earlycon_setup(struct earlycon_device *device,
+                                    const char *opt)
+{
+       struct screen_info *si;
+       u16 xres, yres;
+       u32 i;
+
+       if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
+               return -ENODEV;
+
+       fb_base = screen_info.lfb_base;
+       if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
+               fb_base |= (u64)screen_info.ext_lfb_base << 32;
+
+       if (opt && !strcmp(opt, "ram"))
+               fb_prot = PAGE_KERNEL;
+       else
+               fb_prot = pgprot_writecombine(PAGE_KERNEL);

Can you determine the default from the UEFI memory map?

Also, doesn't the current logic map it as WC on x86 too? Is that intentional?


Alex

+
+       si = &screen_info;
+       xres = si->lfb_width;
+       yres = si->lfb_height;
+
+       /*
+        * efi_earlycon_write_char() implicitly assumes a framebuffer with
+        * 32-bits per pixel.
+        */
+       if (si->lfb_depth != 32)
+               return -ENODEV;
+
+       font = get_default_font(xres, yres, -1, -1);
+       if (!font)
+               return -ENODEV;
+
+       efi_y = rounddown(yres, font->height) - font->height;
+       for (i = 0; i < (yres - efi_y) / font->height; i++)
+               efi_earlycon_scroll_up();
+
+       device->con->write = efi_earlycon_write;
+       return 0;
+}
+EARLYCON_DECLARE(efifb, efi_earlycon_setup);


Reply via email to