iPXE
Macros | Functions | Variables
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. More...
 

Functions

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

Variables

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

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.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ spcr_16550()

static 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 }
#define le32_to_cpu(value)
Definition: byteswap.h:113
#define NS16550_LEN
Length of register region.
Definition: ns16550.h:15
A generic UART.
Definition: uart.h:17
void * base
Register base address.
Definition: ns16550.h:82
#define DBGC(...)
Definition: compiler.h:505
static struct ns16550_uart spcr_ns16550
SPCR-defined 16550 UART.
Definition: spcr.c:51
unsigned int clock
Input clock frequency.
Definition: ns16550.h:86
void * priv
Driver-private data.
Definition: uart.h:31
A 16550-compatible UART.
Definition: ns16550.h:80
uint32_t clock
Clock frequency.
Definition: spcr.h:67
#define ENODEV
No such device.
Definition: errno.h:509
struct uart_operations ns16550_operations
16550 UART operations
Definition: ns16550.c:171
struct acpi_address base
Base address.
Definition: spcr.h:27
void * acpi_ioremap(struct acpi_address *address, size_t len)
Map an ACPI generic address.
Definition: acpi.c:269
struct uart_operations * op
UART operations.
Definition: uart.h:29

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

Referenced by spcr_console().

◆ spcr_console()

static 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 ) ) {
137  baud = ( SPCR_BAUD_BASE / spcr_baud_divisor[spcr->baud] );
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:
146  case SPCR_TYPE_16550_GAS:
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 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define le32_to_cpu(value)
Definition: byteswap.h:113
static struct uart spcr_uart
SPCR-defined UART.
Definition: spcr.c:45
A generic UART.
Definition: uart.h:17
#define SPCR_TYPE_16550
16550-compatible
Definition: spcr.h:75
struct uart * fixed_serial_console(void)
Get fixed serial console UART.
Definition: serial.c:76
uint16_t pci_device_id
PCI device ID.
Definition: spcr.h:53
uint16_t pci_vendor_id
PCI vendor ID.
Definition: spcr.h:55
#define DBGC(...)
Definition: compiler.h:505
static const uint8_t spcr_baud_divisor[SPCR_BAUD_MAX]
SPCR baud rate divisors.
Definition: spcr.c:59
const struct acpi_header * acpi_table(uint32_t signature, unsigned int index)
Locate ACPI table.
Definition: acpi.c:92
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
A Serial Port Console Redirection table.
Definition: spcr.h:19
#define SPCR_TYPE_16550_GAS
16550-compatible
Definition: spcr.h:77
uint32_t precise
Precise baud rate.
Definition: spcr.h:69
#define SPCR_BAUD_BASE
Base baud rate for SPCR divisors.
Definition: spcr.c:56
uint8_t pci_segment
PCI segment.
Definition: spcr.h:65
unsigned int baud
Baud rate (if specified)
Definition: uart.h:26
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
uint32_t length
Length of table, in bytes, including header.
Definition: acpi.h:183
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:66
#define SPCR_SIGNATURE
Serial Port Console Redirection table signature.
Definition: spcr.h:16
#define DBGC2_HDA(...)
Definition: compiler.h:523
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:311
uint8_t type
Interface type.
Definition: spcr.h:23
struct acpi_header acpi
ACPI header.
Definition: spcr.h:21
struct acpi_address base
Base address.
Definition: spcr.h:27
uint8_t pci_func
PCI function number.
Definition: spcr.h:61
#define le16_to_cpu(value)
Definition: byteswap.h:112
static int spcr_16550(struct spcr_table *spcr, struct uart *uart)
Configure 16550-based serial console.
Definition: spcr.c:76
uint8_t pci_bus
PCI bus number.
Definition: spcr.h:57
uint8_t type
Address space type.
Definition: acpi.h:24
uint8_t pci_dev
PCI device number.
Definition: spcr.h:59
uint64_t address
Address.
Definition: acpi.h:32
#define DBGC2(...)
Definition: compiler.h:522
uint8_t baud
Baud rate.
Definition: spcr.h:41
#define cpu_to_le16(value)
Definition: byteswap.h:106
#define SPCR_TYPE_16450
16450-compatible
Definition: spcr.h:76
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:47
#define le64_to_cpu(value)
Definition: byteswap.h:114
#define PCI_ANY_ID
Match-anything ID.
Definition: pci.h:186

References spcr_table::acpi, acpi, acpi_table(), acpi_address::address, spcr_table::base, uart::baud, spcr_table::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, spcr_table::type, acpi_address::type, and typeof().

◆ 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",
}
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition: refcnt.h:77
void ref_no_free(struct refcnt *refcnt __unused)
Do not free reference-counted object.
Definition: refcnt.c:101

SPCR-defined UART.

Definition at line 45 of file spcr.c.

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.

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 ),
}
#define SPCR_BAUD_BASE
Base baud rate for SPCR divisors.
Definition: spcr.c:56

SPCR baud rate divisors.

Definition at line 59 of file spcr.c.

Referenced by spcr_console().