summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/acpi.c112
-rw-r--r--src/arch/x86/include/arch/acpi.h44
2 files changed, 156 insertions, 0 deletions
diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c
index 02884c494c..56f64084e8 100644
--- a/src/arch/x86/acpi.c
+++ b/src/arch/x86/acpi.c
@@ -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));
diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h
index 1b239912d7..5418420342 100644
--- a/src/arch/x86/include/arch/acpi.h
+++ b/src/arch/x86/include/arch/acpi.h
@@ -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,