arch/x86/acpi: Add support for writing ACPI DBG2 table
Add a function to create an ACPI DBG2 table, which is a Microsoft ACPI extension for providing a description of the available debug interface on a board. A convenience function is provided for creating a DBG2 table with a 16550 UART based on a PCI device. This is tested by generating a device and verifying it with iasl: [000h 0000 4] Signature : "DBG2" [004h 0004 4] Table Length : 00000061 [008h 0008 1] Revision : 00 [009h 0009 1] Checksum : 3B [00Ah 0010 6] Oem ID : "CORE " [010h 0016 8] Oem Table ID : "COREBOOT" [018h 0024 4] Oem Revision : 00000000 [01Ch 0028 4] Asl Compiler ID : "CORE" [020h 0032 4] Asl Compiler Revision : 00000000 [024h 0036 4] Info Offset : 0000002C [028h 0040 4] Info Count : 00000001 [02Ch 0044 1] Revision : 00 [02Dh 0045 2] Length : 0035 [02Fh 0047 1] Register Count : 01 [030h 0048 2] Namepath Length : 000F [032h 0050 2] Namepath Offset : 0026 [034h 0052 2] OEM Data Length : 0000 [036h 0054 2] OEM Data Offset : 0000 [038h 0056 2] Port Type : 8000 [03Ah 0058 2] Port Subtype : 0000 [03Ch 0060 2] Reserved : 0000 [03Eh 0062 2] Base Address Offset : 0016 [040h 0064 2] Address Size Offset : 0022 [042h 0066 12] Base Address Register : [Generic Address Structure] [042h 0066 1] Space ID : 00 [SystemMemory] [043h 0067 1] Bit Width : 00 [044h 0068 1] Bit Offset : 00 [045h 0069 1] Encoded Access Width : 03 [DWord Access:32] [046h 0070 8] Address : 00000000FE034000 [04Eh 0078 4] Address Size : 00001000 [052h 0082 15] Namepath : "\_SB.PCI0.UAR2" Raw Table Data: Length 97 (0x61) 0000: 44 42 47 32 61 00 00 00 00 3B 43 4F 52 45 20 20 // DBG2a....;CORE 0010: 43 4F 52 45 42 4F 4F 54 00 00 00 00 43 4F 52 45 // COREBOOT....CORE 0020: 00 00 00 00 2C 00 00 00 01 00 00 00 00 35 00 01 // ....,........5.. 0030: 0F 00 26 00 00 00 00 00 00 80 00 00 00 00 16 00 // ..&............. 0040: 22 00 00 00 00 03 00 40 03 FE 00 00 00 00 00 10 // "......@........ 0050: 00 00 5C 5F 53 42 2E 50 43 49 30 2E 55 41 52 32 // ..\_SB.PCI0.UAR2 0060: 00 // . Change-Id: I55aa3f24776b2f8aa38d7da117f422d8b8ec5479 Signed-off-by: Duncan Laurie <dlaurie@google.com> Reviewed-on: https://review.coreboot.org/22452 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
parent
8f20044c77
commit
e4a36c7b52
2 changed files with 156 additions and 0 deletions
|
@ -658,6 +658,118 @@ unsigned long acpi_write_hpet(device_t device, unsigned long current,
|
|||
return current;
|
||||
}
|
||||
|
||||
void acpi_create_dbg2(acpi_dbg2_header_t *dbg2,
|
||||
int port_type, int port_subtype,
|
||||
acpi_addr_t *address, uint32_t address_size,
|
||||
const char *device_path)
|
||||
{
|
||||
uintptr_t current;
|
||||
acpi_dbg2_device_t *device;
|
||||
uint32_t *dbg2_addr_size;
|
||||
acpi_header_t *header;
|
||||
size_t path_len;
|
||||
const char *path;
|
||||
char *namespace;
|
||||
|
||||
/* Fill out header fields. */
|
||||
current = (uintptr_t)dbg2;
|
||||
memset(dbg2, 0, sizeof(acpi_dbg2_header_t));
|
||||
header = &(dbg2->header);
|
||||
header->revision = 0;
|
||||
memcpy(header->signature, "DBG2", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||
|
||||
/* One debug device defined */
|
||||
dbg2->devices_offset = sizeof(acpi_dbg2_header_t);
|
||||
dbg2->devices_count = 1;
|
||||
current += sizeof(acpi_dbg2_header_t);
|
||||
|
||||
/* Device comes after the header */
|
||||
device = (acpi_dbg2_device_t *)current;
|
||||
memset(device, 0, sizeof(acpi_dbg2_device_t));
|
||||
current += sizeof(acpi_dbg2_device_t);
|
||||
|
||||
device->revision = 0;
|
||||
device->address_count = 1;
|
||||
device->port_type = port_type;
|
||||
device->port_subtype = port_subtype;
|
||||
|
||||
/* Base Address comes after device structure */
|
||||
memcpy((void *)current, address, sizeof(acpi_addr_t));
|
||||
device->base_address_offset = current - (uintptr_t)device;
|
||||
current += sizeof(acpi_addr_t);
|
||||
|
||||
/* Address Size comes after address structure */
|
||||
dbg2_addr_size = (uint32_t *)current;
|
||||
device->address_size_offset = current - (uintptr_t)device;
|
||||
*dbg2_addr_size = address_size;
|
||||
current += sizeof(uint32_t);
|
||||
|
||||
/* Namespace string comes last, use '.' if not provided */
|
||||
path = device_path ? : ".";
|
||||
/* Namespace string length includes NULL terminator */
|
||||
path_len = strlen(path) + 1;
|
||||
namespace = (char *)current;
|
||||
device->namespace_string_length = path_len;
|
||||
device->namespace_string_offset = current - (uintptr_t)device;
|
||||
strncpy(namespace, path, path_len);
|
||||
current += path_len;
|
||||
|
||||
/* Update structure lengths and checksum */
|
||||
device->length = current - (uintptr_t)device;
|
||||
header->length = current - (uintptr_t)dbg2;
|
||||
header->checksum = acpi_checksum((uint8_t *)dbg2, header->length);
|
||||
}
|
||||
|
||||
unsigned long acpi_write_dbg2_pci_uart(acpi_rsdp_t *rsdp, unsigned long current,
|
||||
struct device *dev, uint8_t access_size)
|
||||
{
|
||||
acpi_dbg2_header_t *dbg2 = (acpi_dbg2_header_t *)current;
|
||||
struct resource *res;
|
||||
acpi_addr_t address;
|
||||
|
||||
if (!dev) {
|
||||
printk(BIOS_ERR, "%s: Device not found\n", __func__);
|
||||
return current;
|
||||
}
|
||||
res = find_resource(dev, PCI_BASE_ADDRESS_0);
|
||||
if (!res) {
|
||||
printk(BIOS_ERR, "%s: Unable to find resource for %s\n",
|
||||
__func__, dev_path(dev));
|
||||
return current;
|
||||
}
|
||||
|
||||
memset(&address, 0, sizeof(address));
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
address.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
else if (res->flags & IORESOURCE_MEM)
|
||||
address.space_id = ACPI_ADDRESS_SPACE_MEMORY;
|
||||
else {
|
||||
printk(BIOS_ERR, "%s: Unknown address space type\n", __func__);
|
||||
return current;
|
||||
}
|
||||
|
||||
address.addrl = (uint32_t)res->base;
|
||||
address.addrh = (uint32_t)((res->base >> 32) & 0xffffffff);
|
||||
address.access_size = access_size;
|
||||
|
||||
acpi_create_dbg2(dbg2,
|
||||
ACPI_DBG2_PORT_SERIAL,
|
||||
ACPI_DBG2_PORT_SERIAL_16550,
|
||||
&address, res->size,
|
||||
acpi_device_path(dev));
|
||||
|
||||
if (dbg2->header.length) {
|
||||
current += dbg2->header.length;
|
||||
current = acpi_align_current(current);
|
||||
acpi_add_table(rsdp, dbg2);
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
void acpi_create_facs(acpi_facs_t *facs)
|
||||
{
|
||||
memset((void *)facs, 0, sizeof(acpi_facs_t));
|
||||
|
|
|
@ -404,6 +404,43 @@ typedef struct acpi_madt_irqoverride {
|
|||
u16 flags; /* MPS INTI flags */
|
||||
} __packed acpi_madt_irqoverride_t;
|
||||
|
||||
#define ACPI_DBG2_PORT_SERIAL 0x8000
|
||||
#define ACPI_DBG2_PORT_SERIAL_16550 0x0000
|
||||
#define ACPI_DBG2_PORT_SERIAL_16550_DBGP 0x0001
|
||||
#define ACPI_DBG2_PORT_SERIAL_ARM_PL011 0x0003
|
||||
#define ACPI_DBG2_PORT_SERIAL_ARM_SBSA 0x000e
|
||||
#define ACPI_DBG2_PORT_SERIAL_ARM_DDC 0x000f
|
||||
#define ACPI_DBG2_PORT_SERIAL_BCM2835 0x0010
|
||||
#define ACPI_DBG2_PORT_IEEE1394 0x8001
|
||||
#define ACPI_DBG2_PORT_IEEE1394_STANDARD 0x0000
|
||||
#define ACPI_DBG2_PORT_USB 0x8002
|
||||
#define ACPI_DBG2_PORT_USB_XHCI 0x0000
|
||||
#define ACPI_DBG2_PORT_USB_EHCI 0x0001
|
||||
#define ACPI_DBG2_PORT_NET 0x8003
|
||||
|
||||
/* DBG2: Microsoft Debug Port Table 2 header */
|
||||
typedef struct acpi_dbg2_header {
|
||||
struct acpi_table_header header;
|
||||
uint32_t devices_offset;
|
||||
uint32_t devices_count;
|
||||
} __attribute__ ((packed)) acpi_dbg2_header_t;
|
||||
|
||||
/* DBG2: Microsoft Debug Port Table 2 device entry */
|
||||
typedef struct acpi_dbg2_device {
|
||||
uint8_t revision;
|
||||
uint16_t length;
|
||||
uint8_t address_count;
|
||||
uint16_t namespace_string_length;
|
||||
uint16_t namespace_string_offset;
|
||||
uint16_t oem_data_length;
|
||||
uint16_t oem_data_offset;
|
||||
uint16_t port_type;
|
||||
uint16_t port_subtype;
|
||||
uint8_t reserved[2];
|
||||
uint16_t base_address_offset;
|
||||
uint16_t address_size_offset;
|
||||
} __attribute__ ((packed)) acpi_dbg2_device_t;
|
||||
|
||||
/* FADT (Fixed ACPI Description Table) */
|
||||
typedef struct acpi_fadt {
|
||||
struct acpi_table_header header;
|
||||
|
@ -667,6 +704,13 @@ void acpi_create_mcfg(acpi_mcfg_t *mcfg);
|
|||
|
||||
void acpi_create_facs(acpi_facs_t *facs);
|
||||
|
||||
void acpi_create_dbg2(acpi_dbg2_header_t *dbg2_header,
|
||||
int port_type, int port_subtype,
|
||||
acpi_addr_t *address, uint32_t address_size,
|
||||
const char *device_path);
|
||||
|
||||
unsigned long acpi_write_dbg2_pci_uart(acpi_rsdp_t *rsdp, unsigned long current,
|
||||
struct device *dev, uint8_t access_size);
|
||||
void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
|
||||
unsigned long (*acpi_fill_dmar)(unsigned long));
|
||||
unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
|
||||
|
|
Loading…
Reference in a new issue