iPXE
spcr.c File Reference

ACPI Serial Port Console Redirection (SPCR) More...

#include <errno.h>
#include <ipxe/serial.h>
#include <ipxe/pci.h>
#include <ipxe/ns16550.h>
#include <ipxe/spcr.h>

Go to the source code of this file.

Macros

#define SERIAL_PREFIX_spcr   __spcr_
#define SPCR_BAUD_BASE   115200
 Base baud rate for SPCR divisors.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int spcr_16550 (struct spcr_table *spcr, struct uart *uart)
 Configure 16550-based serial console.
static struct uartspcr_console (void)
 Identify default serial console.
 PROVIDE_SERIAL (spcr, default_serial_console, spcr_console)

Variables

static struct uart spcr_uart
 SPCR-defined UART.
static struct ns16550_uart spcr_ns16550
 SPCR-defined 16550 UART.
static const uint8_t spcr_baud_divisor [SPCR_BAUD_MAX]
 SPCR baud rate divisors.

Detailed Description

ACPI Serial Port Console Redirection (SPCR)

Definition in file spcr.c.

Macro Definition Documentation

◆ SERIAL_PREFIX_spcr

#define SERIAL_PREFIX_spcr   __spcr_

Definition at line 41 of file spcr.c.

◆ SPCR_BAUD_BASE

#define SPCR_BAUD_BASE   115200

Base baud rate for SPCR divisors.

Definition at line 56 of file spcr.c.

Referenced by spcr_console().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ spcr_16550()

int spcr_16550 ( struct spcr_table * spcr,
struct uart * uart )
static

Configure 16550-based serial console.

Parameters
spcrSPCR table
uartUART to configure
Return values
rcReturn status code

Definition at line 76 of file spcr.c.

76 {
77 struct ns16550_uart *ns16550 = &spcr_ns16550;
78
79 /* Set base address */
80 ns16550->base = acpi_ioremap ( &spcr->base, NS16550_LEN );
81 if ( ! ns16550->base ) {
82 DBGC ( uart, "SPCR could not map registers\n" );
83 return -ENODEV;
84 }
85
86 /* Set clock frequency, if specified */
87 if ( spcr->clock )
88 ns16550->clock = le32_to_cpu ( spcr->clock );
89
90 /* Configure UART as a 16550 */
92 uart->priv = ns16550;
93
94 return 0;
95}
void * acpi_ioremap(struct acpi_address *address, size_t len)
Map an ACPI generic address.
Definition acpi.c:270
#define DBGC(...)
Definition compiler.h:505
#define ENODEV
No such device.
Definition errno.h:510
#define le32_to_cpu(value)
Definition byteswap.h:114
#define NS16550_LEN
Length of register region.
Definition ns16550.h:15
struct uart_operations ns16550_operations
16550 UART operations
Definition ns16550.c:171
static struct ns16550_uart spcr_ns16550
SPCR-defined 16550 UART.
Definition spcr.c:51
A 16550-compatible UART.
Definition ns16550.h:80
unsigned int clock
Input clock frequency.
Definition ns16550.h:86
void * base
Register base address.
Definition ns16550.h:82
uint32_t clock
Clock frequency.
Definition spcr.h:67
struct acpi_address base
Base address.
Definition spcr.h:27
A generic UART.
Definition uart.h:17
struct uart_operations * op
UART operations.
Definition uart.h:29
void * priv
Driver-private data.
Definition uart.h:31

References acpi_ioremap(), ns16550_uart::base, spcr_table::base, ns16550_uart::clock, spcr_table::clock, DBGC, ENODEV, le32_to_cpu, NS16550_LEN, ns16550_operations, uart::op, uart::priv, and spcr_ns16550.

Referenced by spcr_console().

◆ spcr_console()

struct uart * spcr_console ( void )
static

Identify default serial console.

Return values
uartDefault serial console UART, or NULL

Definition at line 102 of file spcr.c.

102 {
103 struct uart *uart = &spcr_uart;
104 struct spcr_table *spcr;
105 unsigned int baud;
106 int rc;
107
108 /* Locate SPCR table */
109 spcr = container_of ( acpi_table ( SPCR_SIGNATURE, 0 ),
110 struct spcr_table, acpi );
111 if ( ! spcr ) {
112 DBGC ( uart, "SPCR found no table\n" );
113 goto err_table;
114 }
115 DBGC2 ( uart, "SPCR found table:\n" );
116 DBGC2_HDA ( uart, 0, spcr, sizeof ( *spcr ) );
117 DBGC ( uart, "SPCR is type %d at %02x:%08llx\n",
118 spcr->type, spcr->base.type,
119 ( ( unsigned long long ) le64_to_cpu ( spcr->base.address ) ) );
120 if ( spcr->pci_vendor_id != cpu_to_le16 ( PCI_ANY_ID ) ) {
121 DBGC ( uart, "SPCR is PCI " PCI_FMT " (%04x:%04x)\n",
122 spcr->pci_segment, spcr->pci_bus, spcr->pci_dev,
123 spcr->pci_func, le16_to_cpu ( spcr->pci_vendor_id ),
124 le16_to_cpu ( spcr->pci_device_id ) );
125 }
126
127 /* Get baud rate */
128 baud = 0;
129 if ( le32_to_cpu ( spcr->acpi.length ) >=
130 ( offsetof ( typeof ( *spcr ), precise ) +
131 sizeof ( spcr->precise ) ) ) {
132 baud = le32_to_cpu ( spcr->precise );
133 if ( baud )
134 DBGC ( uart, "SPCR has precise baud rate %d\n", baud );
135 }
136 if ( ( ! baud ) && spcr->baud && ( spcr->baud < SPCR_BAUD_MAX ) ) {
138 DBGC ( uart, "SPCR has baud rate %d\n", baud );
139 }
140 uart->baud = baud;
141
142 /* Initialise according to type */
143 switch ( spcr->type ) {
144 case SPCR_TYPE_16550:
145 case SPCR_TYPE_16450:
147 if ( ( rc = spcr_16550 ( spcr, uart ) ) != 0 )
148 goto err_type;
149 break;
150 default:
151 DBGC ( uart, "SPCR unsupported type %d\n", spcr->type );
152 goto err_type;
153 }
154
155 return uart;
156
157 err_type:
158 err_table:
159 /* Fall back to using fixed serial console */
160 return fixed_serial_console();
161}
const struct acpi_header * acpi_table(uint32_t signature, unsigned int index)
Locate ACPI table.
Definition acpi.c:93
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition efi_block.c:67
#define DBGC2(...)
Definition compiler.h:522
#define DBGC2_HDA(...)
Definition compiler.h:523
#define le16_to_cpu(value)
Definition byteswap.h:113
#define le64_to_cpu(value)
Definition byteswap.h:115
#define cpu_to_le16(value)
Definition byteswap.h:107
#define PCI_ANY_ID
Match-anything ID.
Definition pci.h:187
#define PCI_FMT
PCI device debug message format.
Definition pci.h:312
struct uart * fixed_serial_console(void)
Get fixed serial console UART.
Definition serial.c:76
static int spcr_16550(struct spcr_table *spcr, struct uart *uart)
Configure 16550-based serial console.
Definition spcr.c:76
#define SPCR_BAUD_BASE
Base baud rate for SPCR divisors.
Definition spcr.c:56
static const uint8_t spcr_baud_divisor[SPCR_BAUD_MAX]
SPCR baud rate divisors.
Definition spcr.c:59
static struct uart spcr_uart
SPCR-defined UART.
Definition spcr.c:45
#define SPCR_TYPE_16550
16550-compatible
Definition spcr.h:75
#define SPCR_TYPE_16450
16450-compatible
Definition spcr.h:76
#define SPCR_SIGNATURE
Serial Port Console Redirection table signature.
Definition spcr.h:16
#define SPCR_TYPE_16550_GAS
16550-compatible
Definition spcr.h:77
@ SPCR_BAUD_MAX
Definition spcr.h:88
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
uint8_t type
Address space type.
Definition acpi.h:25
uint64_t address
Address.
Definition acpi.h:33
uint32_t length
Length of table, in bytes, including header.
Definition acpi.h:184
A Serial Port Console Redirection table.
Definition spcr.h:19
uint8_t pci_segment
PCI segment.
Definition spcr.h:65
struct acpi_header acpi
ACPI header.
Definition spcr.h:21
uint8_t pci_func
PCI function number.
Definition spcr.h:61
uint8_t pci_dev
PCI device number.
Definition spcr.h:59
uint8_t type
Interface type.
Definition spcr.h:23
uint8_t baud
Baud rate.
Definition spcr.h:41
uint32_t precise
Precise baud rate.
Definition spcr.h:69
uint16_t pci_device_id
PCI device ID.
Definition spcr.h:53
uint8_t pci_bus
PCI bus number.
Definition spcr.h:57
uint16_t pci_vendor_id
PCI vendor ID.
Definition spcr.h:55
unsigned int baud
Baud rate (if specified)
Definition uart.h:26

References acpi, spcr_table::acpi, acpi_table(), acpi_address::address, spcr_table::base, spcr_table::baud, uart::baud, container_of, cpu_to_le16, DBGC, DBGC2, DBGC2_HDA, fixed_serial_console(), le16_to_cpu, le32_to_cpu, le64_to_cpu, acpi_header::length, offsetof, PCI_ANY_ID, spcr_table::pci_bus, spcr_table::pci_dev, spcr_table::pci_device_id, PCI_FMT, spcr_table::pci_func, spcr_table::pci_segment, spcr_table::pci_vendor_id, spcr_table::precise, rc, spcr_16550(), SPCR_BAUD_BASE, spcr_baud_divisor, SPCR_BAUD_MAX, SPCR_SIGNATURE, SPCR_TYPE_16450, SPCR_TYPE_16550, SPCR_TYPE_16550_GAS, spcr_uart, acpi_address::type, spcr_table::type, and typeof().

Referenced by PROVIDE_SERIAL().

◆ PROVIDE_SERIAL()

PROVIDE_SERIAL ( spcr ,
default_serial_console ,
spcr_console  )

Variable Documentation

◆ spcr_uart

struct uart spcr_uart
static
Initial value:
= {
.refcnt = REF_INIT ( ref_no_free ),
.name = "SPCR",
}
void ref_no_free(struct refcnt *refcnt __unused)
Do not free reference-counted object.
Definition refcnt.c:102
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition refcnt.h:78

SPCR-defined UART.

Definition at line 45 of file spcr.c.

45 {
46 .refcnt = REF_INIT ( ref_no_free ),
47 .name = "SPCR",
48};

Referenced by spcr_console().

◆ spcr_ns16550

struct ns16550_uart spcr_ns16550
static
Initial value:
= {
}
#define NS16550_CLK_DEFAULT
Default input clock rate (1.8432 MHz)
Definition ns16550.h:95

SPCR-defined 16550 UART.

Definition at line 51 of file spcr.c.

51 {
52 .clock = NS16550_CLK_DEFAULT,
53};

Referenced by spcr_16550().

◆ spcr_baud_divisor

const uint8_t spcr_baud_divisor[SPCR_BAUD_MAX]
static
Initial value:
= {
[SPCR_BAUD_115200] = ( SPCR_BAUD_BASE / 115200 ),
}
@ SPCR_BAUD_4800
Definition spcr.h:82
@ SPCR_BAUD_115200
Definition spcr.h:87
@ SPCR_BAUD_38400
Definition spcr.h:85
@ SPCR_BAUD_57600
Definition spcr.h:86
@ SPCR_BAUD_2400
Definition spcr.h:81
@ SPCR_BAUD_9600
Definition spcr.h:83
@ SPCR_BAUD_19200
Definition spcr.h:84

SPCR baud rate divisors.

Definition at line 59 of file spcr.c.

59 {
60 [SPCR_BAUD_2400] = ( SPCR_BAUD_BASE / 2400 ),
61 [SPCR_BAUD_4800] = ( SPCR_BAUD_BASE / 4800 ),
62 [SPCR_BAUD_9600] = ( SPCR_BAUD_BASE / 9600 ),
63 [SPCR_BAUD_19200] = ( SPCR_BAUD_BASE / 19200 ),
64 [SPCR_BAUD_38400] = ( SPCR_BAUD_BASE / 38400 ),
65 [SPCR_BAUD_57600] = ( SPCR_BAUD_BASE / 57600 ),
66 [SPCR_BAUD_115200] = ( SPCR_BAUD_BASE / 115200 ),
67};

Referenced by spcr_console().