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