cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pcdp.c (3256B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Parse the EFI PCDP table to locate the console device.
      4 *
      5 * (c) Copyright 2002, 2003, 2004 Hewlett-Packard Development Company, L.P.
      6 *	Khalid Aziz <khalid.aziz@hp.com>
      7 *	Alex Williamson <alex.williamson@hp.com>
      8 *	Bjorn Helgaas <bjorn.helgaas@hp.com>
      9 */
     10
     11#include <linux/acpi.h>
     12#include <linux/console.h>
     13#include <linux/efi.h>
     14#include <linux/serial.h>
     15#include <linux/serial_core.h>
     16#include <asm/vga.h>
     17#include "pcdp.h"
     18
     19static int __init
     20setup_serial_console(struct pcdp_uart *uart)
     21{
     22#ifdef CONFIG_SERIAL_8250_CONSOLE
     23	int mmio;
     24	static char options[64], *p = options;
     25	char parity;
     26
     27	mmio = (uart->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY);
     28	p += sprintf(p, "uart8250,%s,0x%llx",
     29		mmio ? "mmio" : "io", uart->addr.address);
     30	if (uart->baud) {
     31		p += sprintf(p, ",%llu", uart->baud);
     32		if (uart->bits) {
     33			switch (uart->parity) {
     34			    case 0x2: parity = 'e'; break;
     35			    case 0x3: parity = 'o'; break;
     36			    default:  parity = 'n';
     37			}
     38			p += sprintf(p, "%c%d", parity, uart->bits);
     39		}
     40	}
     41
     42	add_preferred_console("uart", 8250, &options[9]);
     43	return setup_earlycon(options);
     44#else
     45	return -ENODEV;
     46#endif
     47}
     48
     49static int __init
     50setup_vga_console(struct pcdp_device *dev)
     51{
     52#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
     53	u8 *if_ptr;
     54
     55	if_ptr = ((u8 *)dev + sizeof(struct pcdp_device));
     56	if (if_ptr[0] == PCDP_IF_PCI) {
     57		struct pcdp_if_pci if_pci;
     58
     59		/* struct copy since ifptr might not be correctly aligned */
     60
     61		memcpy(&if_pci, if_ptr, sizeof(if_pci));
     62
     63		if (if_pci.trans & PCDP_PCI_TRANS_IOPORT)
     64			vga_console_iobase = if_pci.ioport_tra;
     65
     66		if (if_pci.trans & PCDP_PCI_TRANS_MMIO)
     67			vga_console_membase = if_pci.mmio_tra;
     68	}
     69
     70	if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) {
     71		printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n");
     72		return -ENODEV;
     73	}
     74
     75	conswitchp = &vga_con;
     76	printk(KERN_INFO "PCDP: VGA console\n");
     77	return 0;
     78#else
     79	return -ENODEV;
     80#endif
     81}
     82
     83extern unsigned long hcdp_phys;
     84
     85int __init
     86efi_setup_pcdp_console(char *cmdline)
     87{
     88	struct pcdp *pcdp;
     89	struct pcdp_uart *uart;
     90	struct pcdp_device *dev, *end;
     91	int i, serial = 0;
     92	int rc = -ENODEV;
     93
     94	if (hcdp_phys == EFI_INVALID_TABLE_ADDR)
     95		return -ENODEV;
     96
     97	pcdp = early_memremap(hcdp_phys, 4096);
     98	printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, hcdp_phys);
     99
    100	if (strstr(cmdline, "console=hcdp")) {
    101		if (pcdp->rev < 3)
    102			serial = 1;
    103	} else if (strstr(cmdline, "console=")) {
    104		printk(KERN_INFO "Explicit \"console=\"; ignoring PCDP\n");
    105		goto out;
    106	}
    107
    108	if (pcdp->rev < 3 && efi_uart_console_only())
    109		serial = 1;
    110
    111	for (i = 0, uart = pcdp->uart; i < pcdp->num_uarts; i++, uart++) {
    112		if (uart->flags & PCDP_UART_PRIMARY_CONSOLE || serial) {
    113			if (uart->type == PCDP_CONSOLE_UART) {
    114				rc = setup_serial_console(uart);
    115				goto out;
    116			}
    117		}
    118	}
    119
    120	end = (struct pcdp_device *) ((u8 *) pcdp + pcdp->length);
    121	for (dev = (struct pcdp_device *) (pcdp->uart + pcdp->num_uarts);
    122	     dev < end;
    123	     dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) {
    124		if (dev->flags & PCDP_PRIMARY_CONSOLE) {
    125			if (dev->type == PCDP_CONSOLE_VGA) {
    126				rc = setup_vga_console(dev);
    127				goto out;
    128			}
    129		}
    130	}
    131
    132out:
    133	early_memunmap(pcdp, 4096);
    134	return rc;
    135}