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
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to