mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-16 15:11:52 +00:00
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
This commit is contained in:
parent
b15317c431
commit
eba1a249df
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=308938
@ -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));
|
||||
}
|
||||
|
@ -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, const char *sig);
|
||||
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__ */
|
||||
|
@ -40,6 +40,7 @@ struct uart_class;
|
||||
struct acpi_uart_compat_data {
|
||||
const char *hid;
|
||||
struct uart_class *clas;
|
||||
uint16_t port_subtype;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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, struct uart_bas *b2)
|
||||
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_devinfo *di)
|
||||
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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user