// 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;
	}

	conswitchp = &vga_con;
	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;
}
