Microsoft specifies a SPCR (Serial Port Console Redirection Table) [1].
Let's provide it in U-Boot.

[1] 
https://msdn.microsoft.com/en-us/library/windows/hardware/dn639132(v=vs.85).aspx

Signed-off-by: Andy Shevchenko <andriy.shevche...@linux.intel.com>
---
 arch/x86/include/asm/acpi_table.h |  2 +
 arch/x86/lib/acpi_table.c         | 85 +++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/arch/x86/include/asm/acpi_table.h 
b/arch/x86/include/asm/acpi_table.h
index 51cc806673..e3b65cff66 100644
--- a/arch/x86/include/asm/acpi_table.h
+++ b/arch/x86/include/asm/acpi_table.h
@@ -327,6 +327,8 @@ struct acpi_global_nvs;
 #define ACPI_DBG2_USB_XHCI             0x0000
 #define ACPI_DBG2_USB_EHCI             0x0001
 
+#define ACPI_DBG2_UNKNOWN              0x00FF
+
 /* SPCR (Serial Port Console Redirection table) */
 struct __packed acpi_spcr {
        struct acpi_table_header header;
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index c6b2026613..d8b44aea02 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -12,6 +12,7 @@
 #include <cpu.h>
 #include <dm.h>
 #include <dm/uclass-internal.h>
+#include <serial.h>
 #include <version.h>
 #include <asm/acpi/global_nvs.h>
 #include <asm/acpi_table.h>
@@ -338,6 +339,82 @@ static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
        header->checksum = table_compute_checksum((void *)mcfg, header->length);
 }
 
+static void acpi_create_spcr(struct acpi_spcr *spcr)
+{
+       struct acpi_table_header *header = &(spcr->header);
+       struct serial_device_info info = {0};
+       int access_size;
+       int ret;
+
+       /* Fill out header fields */
+       acpi_fill_header(header, "SPCR");
+       header->length = sizeof(struct acpi_spcr);
+       header->revision = 2;
+
+       ret = serial_getinfo(&info);
+       if (ret)
+               spcr->interface_type = ACPI_DBG2_UNKNOWN;
+       else
+               spcr->interface_type = ACPI_DBG2_16550_COMPATIBLE;
+       debug("UART type %u (serial_getinfo() rc=%d)\n", spcr->interface_type, 
ret);
+
+       /* Encode baud rate */
+       switch (info.baudrate) {
+       case 9600:
+               spcr->baud_rate = 3;
+               break;
+       case 19200:
+               spcr->baud_rate = 4;
+               break;
+       case 57600:
+               spcr->baud_rate = 6;
+               break;
+       case 115200:
+               spcr->baud_rate = 7;
+               break;
+       default:
+               spcr->baud_rate = 0;
+               break;
+       }
+
+       /* Encode register access size */
+       switch (info.reg_shift) {
+       case 0:
+               access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
+               break;
+       case 1:
+               access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
+               break;
+       case 2:
+               access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+               break;
+       case 3:
+               access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS;
+               break;
+       default:
+               access_size = ACPI_ACCESS_SIZE_UNDEFINED;
+               break;
+       }
+
+       spcr->serial_port.space_id = ACPI_ADDRESS_SPACE_MEMORY;
+       spcr->serial_port.bit_width = info.reg_width;
+       spcr->serial_port.bit_offset = info.reg_offset;
+       spcr->serial_port.access_size = access_size;
+       spcr->serial_port.addrl = info.addr >> 0;
+       spcr->serial_port.addrh = info.addr >> 32;
+
+       /* REVISIT: Hard coded values for now */
+       spcr->parity = 0;
+       spcr->stop_bits = 1;
+
+       /* REVISIT: No PCI devices for now */
+       spcr->pci_device_id = 0xffff;
+       spcr->pci_vendor_id = 0xffff;
+
+       /* Fix checksum */
+       header->checksum = table_compute_checksum((void *)spcr, header->length);
+}
+
 /*
  * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
  */
@@ -352,6 +429,7 @@ ulong write_acpi_tables(ulong start)
        struct acpi_fadt *fadt;
        struct acpi_mcfg *mcfg;
        struct acpi_madt *madt;
+       struct acpi_spcr *spcr;
        int i;
 
        current = start;
@@ -440,6 +518,13 @@ ulong write_acpi_tables(ulong start)
        acpi_add_table(rsdp, mcfg);
        current = ALIGN(current, 16);
 
+       debug("ACPI:    * SPCR\n");
+       spcr = (struct acpi_spcr *)current;
+       acpi_create_spcr(spcr);
+       current += spcr->header.length;
+       acpi_add_table(rsdp, spcr);
+       current = ALIGN(current, 16);
+
        debug("current = %x\n", current);
 
        acpi_rsdp_addr = (unsigned long)rsdp;
-- 
2.19.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to