acpi: Add function to add ARM PL011 to ACPI DBG2

Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Change-Id: I3c3f7f579ec0ec4fdb72e1f6b785026daab17bac
Reviewed-on: https://review.coreboot.org/c/coreboot/+/76297
Reviewed-by: Tim Wawrzynczak <inforichland@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c
index edd2ca5..e30b7d3 100644
--- a/src/acpi/acpi.c
+++ b/src/acpi/acpi.c
@@ -23,6 +23,7 @@
 #include <cpu/cpu.h>
 #include <device/mmio.h>
 #include <device/pci.h>
+#include <drivers/uart/pl011.h>
 #include <string.h>
 #include <types.h>
 #include <version.h>
@@ -817,13 +818,49 @@
 	header->checksum = acpi_checksum((uint8_t *)dbg2, header->length);
 }
 
-unsigned long acpi_write_dbg2_pci_uart(acpi_rsdp_t *rsdp, unsigned long current,
-				const struct device *dev, uint8_t access_size)
+static unsigned long acpi_write_dbg2_uart(acpi_rsdp_t *rsdp, unsigned long current,
+					  int space_id, uint64_t base, uint32_t size,
+					  int access_size, const char *name)
 {
 	acpi_dbg2_header_t *dbg2 = (acpi_dbg2_header_t *)current;
-	struct resource *res;
 	acpi_addr_t address;
 
+	memset(&address, 0, sizeof(address));
+
+	address.space_id = space_id;
+	address.addrl = (uint32_t)base;
+	address.addrh = (uint32_t)((base >> 32) & 0xffffffff);
+	address.access_size = access_size;
+
+	int subtype;
+	/* 16550-compatible with parameters defined in Generic Address Structure */
+	if (CONFIG(DRIVERS_UART_8250IO) || CONFIG(DRIVERS_UART_8250MEM))
+		subtype = ACPI_DBG2_PORT_SERIAL_16550;
+	else if (CONFIG(DRIVERS_UART_PL011))
+		subtype = ACPI_DBG2_PORT_SERIAL_ARM_PL011;
+	else
+		return current;
+
+	acpi_create_dbg2(dbg2,
+			 ACPI_DBG2_PORT_SERIAL,
+			 subtype,
+			 &address, size,
+			 name);
+
+	if (dbg2->header.length) {
+		current += dbg2->header.length;
+		current = acpi_align_current(current);
+		acpi_add_table(rsdp, dbg2);
+	}
+
+	return current;
+}
+
+unsigned long acpi_write_dbg2_pci_uart(acpi_rsdp_t *rsdp, unsigned long current,
+				       const struct device *dev, uint8_t access_size)
+{
+	struct resource *res;
+
 	if (!dev) {
 		printk(BIOS_DEBUG, "%s: Device not found\n", __func__);
 		return current;
@@ -839,33 +876,25 @@
 		return current;
 	}
 
-	memset(&address, 0, sizeof(address));
+	int space_id;
 	if (res->flags & IORESOURCE_IO)
-		address.space_id = ACPI_ADDRESS_SPACE_IO;
+		space_id = ACPI_ADDRESS_SPACE_IO;
 	else if (res->flags & IORESOURCE_MEM)
-		address.space_id = ACPI_ADDRESS_SPACE_MEMORY;
+		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;
+	return acpi_write_dbg2_uart(rsdp, current, space_id, res->base, res->size, access_size, acpi_device_path(dev));
+}
 
-	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;
+unsigned long acpi_pl011_write_dbg2_uart(acpi_rsdp_t *rsdp, unsigned long current,
+					 uint64_t base, const char *name)
+{
+	return acpi_write_dbg2_uart(rsdp, current, ACPI_ADDRESS_SPACE_MEMORY, base,
+				    sizeof(struct pl011_uart), ACPI_ACCESS_SIZE_DWORD_ACCESS,
+				    name);
 }
 
 static void acpi_create_facs(void *header)
diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h
index 1d68b8e..7651863 100644
--- a/src/include/acpi/acpi.h
+++ b/src/include/acpi/acpi.h
@@ -1622,7 +1622,10 @@
 void generate_cpu_entries(const struct device *device);
 
 unsigned long acpi_write_dbg2_pci_uart(acpi_rsdp_t *rsdp, unsigned long current,
-				const struct device *dev, uint8_t access_size);
+				       const struct device *dev, uint8_t access_size);
+unsigned long acpi_pl011_write_dbg2_uart(acpi_rsdp_t *rsdp, unsigned long current,
+					 uint64_t base, const char *name);
+
 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,