mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-04-24 10:49:54 +02:00
555624c0d1
To prepare for completely separating the VGA console screen_info from the one used in EFI/sysfb, rename the vgacon instances and make them local as much as possible. ia64 and arm both have confurations with vgacon and efi, but the contents never overlaps because ia64 has no EFI framebuffer, and arm only has vga console on legacy platforms without EFI. Renaming these is required before the EFI screen_info can be moved into drivers/firmware. The ia64 vga console is actually registered in two places from setup_arch(), but one of them is wrong, so drop the one in pcdp.c and fix the one in setup.c to use the correct conditional. x86 has to keep them together, as the boot protocol is used to switch between VGA text console and framebuffer through the screen_info data. Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Khalid Aziz <khalid@gonehiking.org> Acked-by: Helge Deller <deller@gmx.de> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Link: https://lore.kernel.org/r/20231009211845.3136536-7-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
135 lines
3.2 KiB
C
135 lines
3.2 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Parse the EFI PCDP table to locate the console device.
|
|
*
|
|
* (c) Copyright 2002, 2003, 2004 Hewlett-Packard Development Company, L.P.
|
|
* Khalid Aziz <khalid.aziz@hp.com>
|
|
* Alex Williamson <alex.williamson@hp.com>
|
|
* Bjorn Helgaas <bjorn.helgaas@hp.com>
|
|
*/
|
|
|
|
#include <linux/acpi.h>
|
|
#include <linux/console.h>
|
|
#include <linux/efi.h>
|
|
#include <linux/serial.h>
|
|
#include <linux/serial_core.h>
|
|
#include <asm/vga.h>
|
|
#include "pcdp.h"
|
|
|
|
static int __init
|
|
setup_serial_console(struct pcdp_uart *uart)
|
|
{
|
|
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
|
int mmio;
|
|
static char options[64], *p = options;
|
|
char parity;
|
|
|
|
mmio = (uart->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY);
|
|
p += sprintf(p, "uart8250,%s,0x%llx",
|
|
mmio ? "mmio" : "io", uart->addr.address);
|
|
if (uart->baud) {
|
|
p += sprintf(p, ",%llu", uart->baud);
|
|
if (uart->bits) {
|
|
switch (uart->parity) {
|
|
case 0x2: parity = 'e'; break;
|
|
case 0x3: parity = 'o'; break;
|
|
default: parity = 'n';
|
|
}
|
|
p += sprintf(p, "%c%d", parity, uart->bits);
|
|
}
|
|
}
|
|
|
|
add_preferred_console("uart", 8250, &options[9]);
|
|
return setup_earlycon(options);
|
|
#else
|
|
return -ENODEV;
|
|
#endif
|
|
}
|
|
|
|
static int __init
|
|
setup_vga_console(struct pcdp_device *dev)
|
|
{
|
|
#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
|
|
u8 *if_ptr;
|
|
|
|
if_ptr = ((u8 *)dev + sizeof(struct pcdp_device));
|
|
if (if_ptr[0] == PCDP_IF_PCI) {
|
|
struct pcdp_if_pci if_pci;
|
|
|
|
/* struct copy since ifptr might not be correctly aligned */
|
|
|
|
memcpy(&if_pci, if_ptr, sizeof(if_pci));
|
|
|
|
if (if_pci.trans & PCDP_PCI_TRANS_IOPORT)
|
|
vga_console_iobase = if_pci.ioport_tra;
|
|
|
|
if (if_pci.trans & PCDP_PCI_TRANS_MMIO)
|
|
vga_console_membase = if_pci.mmio_tra;
|
|
}
|
|
|
|
if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) {
|
|
printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n");
|
|
return -ENODEV;
|
|
}
|
|
|
|
printk(KERN_INFO "PCDP: VGA console\n");
|
|
return 0;
|
|
#else
|
|
return -ENODEV;
|
|
#endif
|
|
}
|
|
|
|
extern unsigned long hcdp_phys;
|
|
|
|
int __init
|
|
efi_setup_pcdp_console(char *cmdline)
|
|
{
|
|
struct pcdp *pcdp;
|
|
struct pcdp_uart *uart;
|
|
struct pcdp_device *dev, *end;
|
|
int i, serial = 0;
|
|
int rc = -ENODEV;
|
|
|
|
if (hcdp_phys == EFI_INVALID_TABLE_ADDR)
|
|
return -ENODEV;
|
|
|
|
pcdp = early_memremap(hcdp_phys, 4096);
|
|
printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, hcdp_phys);
|
|
|
|
if (strstr(cmdline, "console=hcdp")) {
|
|
if (pcdp->rev < 3)
|
|
serial = 1;
|
|
} else if (strstr(cmdline, "console=")) {
|
|
printk(KERN_INFO "Explicit \"console=\"; ignoring PCDP\n");
|
|
goto out;
|
|
}
|
|
|
|
if (pcdp->rev < 3 && efi_uart_console_only())
|
|
serial = 1;
|
|
|
|
for (i = 0, uart = pcdp->uart; i < pcdp->num_uarts; i++, uart++) {
|
|
if (uart->flags & PCDP_UART_PRIMARY_CONSOLE || serial) {
|
|
if (uart->type == PCDP_CONSOLE_UART) {
|
|
rc = setup_serial_console(uart);
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
|
|
end = (struct pcdp_device *) ((u8 *) pcdp + pcdp->length);
|
|
for (dev = (struct pcdp_device *) (pcdp->uart + pcdp->num_uarts);
|
|
dev < end;
|
|
dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) {
|
|
if (dev->flags & PCDP_PRIMARY_CONSOLE) {
|
|
if (dev->type == PCDP_CONSOLE_VGA) {
|
|
rc = setup_vga_console(dev);
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
|
|
out:
|
|
early_memunmap(pcdp, 4096);
|
|
return rc;
|
|
}
|