Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137863404
D20357.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D20357.diff
View Options
Index: head/sys/conf/files
===================================================================
--- head/sys/conf/files
+++ head/sys/conf/files
@@ -3164,6 +3164,7 @@
dev/uart/uart_bus_puc.c optional uart puc
dev/uart/uart_bus_scc.c optional uart scc
dev/uart/uart_core.c optional uart
+dev/uart/uart_cpu_acpi.c optional uart acpi
dev/uart/uart_dbg.c optional uart gdb
dev/uart/uart_dev_msm.c optional uart uart_msm fdt
dev/uart/uart_dev_mvebu.c optional uart uart_mvebu
Index: head/sys/dev/uart/uart_cpu_acpi.h
===================================================================
--- head/sys/dev/uart/uart_cpu_acpi.h
+++ head/sys/dev/uart/uart_cpu_acpi.h
@@ -66,4 +66,7 @@
#define UART_ACPI_CLASS(data) \
DATA_SET(uart_acpi_class_set, data)
+/* Try to initialize UART device from SPCR data. */
+int uart_cpu_acpi_spcr(int devtype, struct uart_devinfo *di);
+
#endif /* _DEV_UART_CPU_ACPI_H_ */
Index: head/sys/dev/uart/uart_cpu_acpi.c
===================================================================
--- head/sys/dev/uart/uart_cpu_acpi.c
+++ head/sys/dev/uart/uart_cpu_acpi.c
@@ -0,0 +1,167 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2016 The FreeBSD Foundation
+ * Copyright (c) 2019 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_acpi.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+extern bus_space_tag_t uart_bus_space_io;
+extern bus_space_tag_t uart_bus_space_mem;
+
+static struct acpi_uart_compat_data *
+uart_cpu_acpi_scan(uint8_t interface_type)
+{
+ struct acpi_uart_compat_data **cd, *curcd;
+ int i;
+
+ SET_FOREACH(cd, uart_acpi_class_and_device_set) {
+ curcd = *cd;
+ for (i = 0; curcd[i].cd_hid != NULL; i++) {
+ if (curcd[i].cd_port_subtype == interface_type)
+ return (&curcd[i]);
+ }
+ }
+
+ SET_FOREACH(cd, uart_acpi_class_set) {
+ curcd = *cd;
+ for (i = 0; curcd[i].cd_hid != NULL; i++) {
+ if (curcd[i].cd_port_subtype == interface_type)
+ return (&curcd[i]);
+ }
+ }
+
+ return (NULL);
+}
+
+int
+uart_cpu_acpi_spcr(int devtype, struct uart_devinfo *di)
+{
+ vm_paddr_t spcr_physaddr;
+ ACPI_TABLE_SPCR *spcr;
+ struct acpi_uart_compat_data *cd;
+ struct uart_class *class;
+ int error = ENXIO;
+
+ /* SPCR only tells us about consoles. */
+ if (devtype != UART_DEV_CONSOLE)
+ return (error);
+
+ /* Look for the SPCR table. */
+ spcr_physaddr = acpi_find_table(ACPI_SIG_SPCR);
+ if (spcr_physaddr == 0)
+ return (error);
+ spcr = acpi_map_table(spcr_physaddr, ACPI_SIG_SPCR);
+ if (spcr == NULL) {
+ printf("Unable to map the SPCR table!\n");
+ return (error);
+ }
+
+ /* Search for information about this SPCR interface type. */
+ cd = uart_cpu_acpi_scan(spcr->InterfaceType);
+ if (cd == NULL)
+ goto out;
+ class = cd->cd_class;
+
+ /* Fill in some fixed details. */
+ di->bas.chan = 0;
+ di->bas.rclk = 0;
+ di->databits = 8;
+ di->stopbits = 1;
+ di->parity = UART_PARITY_NONE;
+ di->ops = uart_getops(class);
+
+ /* Fill in details from SPCR table. */
+ switch (spcr->SerialPort.SpaceId) {
+ case 0:
+ di->bas.bst = uart_bus_space_mem;
+ break;
+ case 1:
+ di->bas.bst = uart_bus_space_io;
+ break;
+ default:
+ printf("UART in unrecognized address space: %d!\n",
+ (int)spcr->SerialPort.SpaceId);
+ goto out;
+ }
+ if (spcr->SerialPort.AccessWidth == 0)
+ di->bas.regshft = 0;
+ else
+ di->bas.regshft = spcr->SerialPort.AccessWidth - 1;
+ di->bas.regiowidth = spcr->SerialPort.BitWidth / 8;
+ switch (spcr->BaudRate) {
+ case 0:
+ /* Special value; means "keep current value unchanged". */
+ di->baudrate = 0;
+ break;
+ case 3:
+ di->baudrate = 9600;
+ break;
+ case 4:
+ di->baudrate = 19200;
+ break;
+ case 6:
+ di->baudrate = 57600;
+ break;
+ case 7:
+ di->baudrate = 115200;
+ break;
+ default:
+ printf("SPCR has reserved BaudRate value: %d!\n",
+ (int)spcr->BaudRate);
+ goto out;
+ }
+
+ /* Apply device tweaks. */
+ if ((cd->cd_quirks & UART_F_IGNORE_SPCR_REGSHFT) ==
+ UART_F_IGNORE_SPCR_REGSHFT) {
+ di->bas.regshft = cd->cd_regshft;
+ }
+
+ /* Create a bus space handle. */
+ error = bus_space_map(di->bas.bst, spcr->SerialPort.Address,
+ uart_getrange(class), 0, &di->bas.bsh);
+
+out:
+ acpi_unmap_table(spcr);
+ return (error);
+}
Index: head/sys/dev/uart/uart_cpu_arm64.c
===================================================================
--- head/sys/dev/uart/uart_cpu_arm64.c
+++ head/sys/dev/uart/uart_cpu_arm64.c
@@ -80,97 +80,6 @@
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, *curcd;
- int i;
-
- SET_FOREACH(cd, uart_acpi_class_and_device_set) {
- curcd = *cd;
- for (i = 0; curcd[i].cd_hid != NULL; i++) {
- if (curcd[i].cd_port_subtype == interface_type)
- return (&curcd[i]);
- }
- }
-
- SET_FOREACH(cd, uart_acpi_class_set) {
- curcd = *cd;
- for (i = 0; curcd[i].cd_hid != NULL; i++) {
- if (curcd[i].cd_port_subtype == interface_type)
- return (&curcd[i]);
- }
- }
-
- 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,
- u_int *iowidthp)
-{
- 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 0:
- /*
- * A BaudRate of 0 is a special value which means not to
- * change the rate that's already programmed.
- */
- *baud = 0;
- break;
- 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->cd_class;
- *rclk = 0;
- *shiftp = spcr->SerialPort.AccessWidth - 1;
- *iowidthp = spcr->SerialPort.BitWidth / 8;
-
- if ((cd->cd_quirks & UART_F_IGNORE_SPCR_REGSHFT) ==
- UART_F_IGNORE_SPCR_REGSHFT) {
- *shiftp = cd->cd_regshft;
- }
-
-out:
- acpi_unmap_table(spcr);
- return (err);
-}
-#endif
-
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
@@ -186,14 +95,16 @@
if (err == 0)
return (0);
+#ifdef DEV_ACPI
+ /* Check if SPCR can tell us what console to use. */
+ if (uart_cpu_acpi_spcr(devtype, di) == 0)
+ return (0);
+#endif
+
if (devtype != UART_DEV_CONSOLE)
return (ENXIO);
err = ENXIO;
-#ifdef DEV_ACPI
- err = uart_cpu_acpi_probe(&class, &bst, &bsh, &br, &rclk, &shift,
- &iowidth);
-#endif
#ifdef FDT
if (err != 0) {
err = uart_cpu_fdt_probe(&class, &bst, &bsh, &br, &rclk,
Index: head/sys/dev/uart/uart_cpu_x86.c
===================================================================
--- head/sys/dev/uart/uart_cpu_x86.c
+++ head/sys/dev/uart/uart_cpu_x86.c
@@ -26,6 +26,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_acpi.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -37,6 +39,7 @@
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_acpi.h>
bus_space_tag_t uart_bus_space_io = X86_BUS_SPACE_IO;
bus_space_tag_t uart_bus_space_mem = X86_BUS_SPACE_MEM;
@@ -61,6 +64,12 @@
/* Check the environment. */
if (uart_getenv(devtype, di, class) == 0)
return (0);
+
+#ifdef DEV_ACPI
+ /* Check if SPCR can tell us what console to use. */
+ if (uart_cpu_acpi_spcr(devtype, di) == 0)
+ return (0);
+#endif
/*
* Scan the hints. We only try units 0 to 3 (inclusive). This
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 27, 2:15 PM (13 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26257154
Default Alt Text
D20357.diff (9 KB)
Attached To
Mode
D20357: Use ACPI SPCR on x86
Attached
Detach File
Event Timeline
Log In to Comment