[U-Boot] [PATCH v1 2/2] WIP: x86: acpi: Generate SPCR table
Bin Meng
bmeng.cn at gmail.com
Tue Sep 25 02:27:33 UTC 2018
Hi Andy,
On Sat, Sep 22, 2018 at 9:05 PM Andy Shevchenko
<andriy.shevchenko at linux.intel.com> wrote:
>
> TBD
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> ---
> arch/x86/include/asm/acpi_table.h | 25 ++++++++++
> arch/x86/lib/acpi_table.c | 82 +++++++++++++++++++++++++++++++
> 2 files changed, 107 insertions(+)
>
> diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h
> index 95fae036f6..27435871b9 100644
> --- a/arch/x86/include/asm/acpi_table.h
> +++ b/arch/x86/include/asm/acpi_table.h
> @@ -303,6 +303,31 @@ struct acpi_mcfg_mmconfig {
> /* ACPI global NVS structure */
> struct acpi_global_nvs;
>
> +/* SPCR (Serial Port Console Redirection table) */
> +struct __packed acpi_spcr {
> + struct acpi_table_header header; /* Common ACPI table header */
> + u8 interface_type; /* 0=full 16550, 1=subset of 16550 */
> + u8 reserved[3];
> + struct acpi_gen_regaddr serial_port; /* The base address of the Serial Port register set */
> + u8 interrupt_type;
> + u8 pc_interrupt;
> + u32 interrupt; /* Global system interrupt */
> + u8 baud_rate;
> + u8 parity;
> + u8 stop_bits;
> + u8 flow_control;
> + u8 terminal_type;
> + u8 reserved1;
> + u16 pci_device_id; /* Must be 0xffff if not PCI device */
> + u16 pci_vendor_id; /* Must be 0xffff if not PCI device */
> + u8 pci_bus;
> + u8 pci_device;
> + u8 pci_function;
> + u32 pci_flags;
> + u8 pci_segment;
> + u32 reserved2;
> +};
> +
> /* These can be used by the target port */
>
> void acpi_fill_header(struct acpi_table_header *header, char *signature);
> diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
> index c6b2026613..551a78b11a 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,79 @@ 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)
> + debug("Can't get information of serial device: %d\n", 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;
> +
> + /* Hard coded values for now */
> + spcr->parity = 0;
> + spcr->stop_bits = 1;
> +
> + /* No PCI devices for now */
> + spcr->pci_device_id = 0xffff;
> + spcr->pci_vendor_id = 0xffff;
> +
I see not every member of 'struct __packed acpi_spcr' is populated.
Are they not used by kernel? If kernel does not use it, it is used by
Windows?
> + /* 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 +426,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 +515,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;
> --
Regards,
Bin
More information about the U-Boot
mailing list