svn commit: r308938 - in head/sys: arm64/acpica arm64/include dev/uart

Andrew Turner andrew at FreeBSD.org
Mon Nov 21 19:27:00 UTC 2016


Author: andrew
Date: Mon Nov 21 19:26:58 2016
New Revision: 308938
URL: https://svnweb.freebsd.org/changeset/base/308938

Log:
  Add support to find the arm64 serial using the ACPI tables. This uses the
  Serial Port Console Redirection Table to find the device to use.
  
  Obtained from:	ABT Systems Ltd
  Sponsored by:	The FreeBSD Foundation

Modified:
  head/sys/arm64/acpica/acpi_machdep.c
  head/sys/arm64/include/acpica_machdep.h
  head/sys/dev/uart/uart_cpu_acpi.h
  head/sys/dev/uart/uart_cpu_arm64.c
  head/sys/dev/uart/uart_dev_pl011.c

Modified: head/sys/arm64/acpica/acpi_machdep.c
==============================================================================
--- head/sys/arm64/acpica/acpi_machdep.c	Mon Nov 21 19:26:22 2016	(r308937)
+++ head/sys/arm64/acpica/acpi_machdep.c	Mon Nov 21 19:26:58 2016	(r308938)
@@ -44,6 +44,8 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/acpica/acpivar.h>
 
+extern struct bus_space memmap_bus;
+
 int
 acpi_machdep_init(device_t dev)
 {
@@ -215,3 +217,19 @@ acpi_find_table(const char *sig)
 
 	return (addr);
 }
+
+int
+acpi_map_addr(struct acpi_generic_address *addr, bus_space_tag_t *tag,
+    bus_space_handle_t *handle, bus_size_t size)
+{
+	bus_addr_t phys;
+
+	/* Check if the device is Memory mapped */
+	if (addr->SpaceId != 0)
+		return (ENXIO);
+
+	phys = addr->Address;
+	*tag = &memmap_bus;
+
+	return (bus_space_map(*tag, phys, size, 0, handle));
+}

Modified: head/sys/arm64/include/acpica_machdep.h
==============================================================================
--- head/sys/arm64/include/acpica_machdep.h	Mon Nov 21 19:26:22 2016	(r308937)
+++ head/sys/arm64/include/acpica_machdep.h	Mon Nov 21 19:26:58 2016	(r308938)
@@ -39,6 +39,8 @@
 
 #ifdef _KERNEL
 
+#include <machine/_bus.h>
+
 /* Only use the reduced hardware model */
 #define	ACPI_REDUCED_HARDWARE	1
 
@@ -50,6 +52,11 @@ void	*acpi_map_table(vm_paddr_t pa, cons
 void	acpi_unmap_table(void *table);
 vm_paddr_t acpi_find_table(const char *sig);
 
+struct acpi_generic_address;
+
+int	acpi_map_addr(struct acpi_generic_address  *, bus_space_tag_t *,
+    bus_space_handle_t *, bus_size_t);
+
 #endif /* _KERNEL */
 
 #endif /* __ACPICA_MACHDEP_H__ */

Modified: head/sys/dev/uart/uart_cpu_acpi.h
==============================================================================
--- head/sys/dev/uart/uart_cpu_acpi.h	Mon Nov 21 19:26:22 2016	(r308937)
+++ head/sys/dev/uart/uart_cpu_acpi.h	Mon Nov 21 19:26:58 2016	(r308938)
@@ -40,6 +40,7 @@ struct uart_class;
 struct acpi_uart_compat_data {
 	const char *hid;
 	struct uart_class *clas;
+	uint16_t port_subtype;
 };
 
 /*

Modified: head/sys/dev/uart/uart_cpu_arm64.c
==============================================================================
--- head/sys/dev/uart/uart_cpu_arm64.c	Mon Nov 21 19:26:22 2016	(r308937)
+++ head/sys/dev/uart/uart_cpu_arm64.c	Mon Nov 21 19:26:58 2016	(r308938)
@@ -48,6 +48,12 @@ __FBSDID("$FreeBSD$");
 #include <dev/uart/uart_bus.h>
 #include <dev/uart/uart_cpu.h>
 
+#ifdef DEV_ACPI
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/actables.h>
+#include <dev/uart/uart_cpu_acpi.h>
+#endif
+
 #ifdef FDT
 #include <dev/fdt/fdt_common.h>
 #include <dev/ofw/ofw_bus.h>
@@ -72,6 +78,76 @@ uart_cpu_eqres(struct uart_bas *b1, stru
 	return ((pmap_kextract(b1->bsh) == pmap_kextract(b2->bsh)) ? 1 : 0);
 }
 
+#ifdef DEV_ACPI
+static struct acpi_uart_compat_data *
+uart_cpu_acpi_scan(uint8_t interface_type)
+{
+	struct acpi_uart_compat_data **cd;
+
+	SET_FOREACH(cd, uart_acpi_class_and_device_set) {
+		if ((*cd)->port_subtype == interface_type)
+			return (*cd);
+	}
+
+	SET_FOREACH(cd, uart_acpi_class_set) {
+		if ((*cd)->port_subtype == interface_type)
+			return (*cd);
+	}
+
+	return (NULL);
+}
+
+static int
+uart_cpu_acpi_probe(struct uart_class **classp, bus_space_tag_t *bst,
+    bus_space_handle_t *bsh, int *baud, u_int *rclk, u_int *shiftp)
+{
+	struct acpi_uart_compat_data *cd;
+	ACPI_TABLE_SPCR *spcr;
+	vm_paddr_t spcr_physaddr;
+	int err;
+
+	err = ENXIO;
+	spcr_physaddr = acpi_find_table(ACPI_SIG_SPCR);
+	if (spcr_physaddr == 0)
+		return (ENXIO);
+
+	spcr = acpi_map_table(spcr_physaddr, ACPI_SIG_SPCR);
+
+	cd = uart_cpu_acpi_scan(spcr->InterfaceType);
+	if (cd == NULL)
+		goto out;
+
+	switch(spcr->BaudRate) {
+	case 3:
+		*baud = 9600;
+		break;
+	case 4:
+		*baud = 19200;
+		break;
+	case 6:
+		*baud = 57600;
+		break;
+	case 7:
+		*baud = 115200;
+		break;
+	default:
+		goto out;
+	}
+
+	err = acpi_map_addr(&spcr->SerialPort, bst, bsh, PAGE_SIZE);
+	if (err != 0)
+		goto out;
+
+	*classp = cd->clas;
+	*rclk = 0;
+	*shiftp = 2;
+
+out:
+	acpi_unmap_table(spcr);
+	return (err);
+}
+#endif
+
 int
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
@@ -91,8 +167,14 @@ uart_cpu_getdev(int devtype, struct uart
 		return (ENXIO);
 
 	err = ENXIO;
+#ifdef DEV_ACPI
+	err = uart_cpu_acpi_probe(&class, &bst, &bsh, &br, &rclk, &shift);
+#endif
 #ifdef FDT
-	err = uart_cpu_fdt_probe(&class, &bst, &bsh, &br, &rclk, &shift);
+	if (err != 0) {
+		err = uart_cpu_fdt_probe(&class, &bst, &bsh, &br, &rclk,
+		    &shift);
+	}
 #endif
 	if (err != 0)
 		return (err);

Modified: head/sys/dev/uart/uart_dev_pl011.c
==============================================================================
--- head/sys/dev/uart/uart_dev_pl011.c	Mon Nov 21 19:26:22 2016	(r308937)
+++ head/sys/dev/uart/uart_dev_pl011.c	Mon Nov 21 19:26:58 2016	(r308938)
@@ -38,15 +38,18 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/uart/uart.h>
 #include <dev/uart/uart_cpu.h>
-#ifdef DEV_ACPI
-#include <dev/uart/uart_cpu_acpi.h>
-#endif
 #ifdef FDT
 #include <dev/uart/uart_cpu_fdt.h>
 #endif
 #include <dev/uart/uart_bus.h>
 #include "uart_if.h"
 
+#ifdef DEV_ACPI
+#include <dev/uart/uart_cpu_acpi.h>
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/actables.h>
+#endif
+
 #include <sys/kdb.h>
 
 /* PL011 UART registers and masks*/
@@ -296,8 +299,8 @@ UART_FDT_CLASS_AND_DEVICE(compat_data);
 
 #ifdef DEV_ACPI
 static struct acpi_uart_compat_data acpi_compat_data[] = {
-	{"ARMH0011", &uart_pl011_class},
-	{NULL, NULL},
+	{"ARMH0011", &uart_pl011_class, ACPI_DBG2_ARM_PL011},
+	{NULL, NULL, 0},
 };
 UART_ACPI_CLASS_AND_DEVICE(acpi_compat_data);
 #endif


More information about the svn-src-head mailing list