iPXE
uart.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Generic UARTs
29  *
30  */
31 
32 #include <stdlib.h>
33 #include <strings.h>
34 #include <errno.h>
35 #include <ipxe/uart.h>
36 
37 /** List of registered UARTs */
38 LIST_HEAD ( uarts );
39 
40 static void null_uart_transmit ( struct uart *uart __unused,
41  uint8_t byte __unused ) {
42 }
43 
44 static int null_uart_data_ready ( struct uart *uart __unused ) {
45  return 0;
46 }
47 
49  return 0;
50 }
51 
52 static int null_uart_init ( struct uart *uart __unused ) {
53  return 0;
54 }
55 
56 static void null_uart_flush ( struct uart *uart __unused ) {
57 }
58 
59 /** Null UART operations */
62  .data_ready = null_uart_data_ready,
63  .receive = null_uart_receive,
64  .init = null_uart_init,
65  .flush = null_uart_flush,
66 };
67 
68 /**
69  * Allocate UART
70  *
71  * @v priv_len Length of private data
72  * @ret uart UART, or NULL on error
73  */
74 struct uart * alloc_uart ( size_t priv_len ) {
75  struct uart *uart;
76 
77  /* Allocate and initialise UART */
78  uart = zalloc ( sizeof ( *uart ) + priv_len );
79  if ( ! uart )
80  return NULL;
81  uart->priv = ( ( ( void * ) uart ) + sizeof ( *uart ) );
82 
83  return uart;
84 }
85 
86 /**
87  * Register fixed UARTs (when not provided by platform)
88  *
89  * @ret rc Return status code
90  */
92 
93  return 0;
94 }
95 
96 /**
97  * Register UART
98  *
99  * @v uart UART
100  * @ret rc Return status code
101  */
102 int uart_register ( struct uart *uart ) {
103 
104  /* Add to list of registered UARTs */
105  uart_get ( uart );
106  list_add_tail ( &uart->list, &uarts );
107  DBGC ( uart, "UART %s registered\n", uart->name );
108 
109  return 0;
110 }
111 
112 /**
113  * Unregister UART
114  *
115  * @v uart UART
116  */
117 void uart_unregister ( struct uart *uart ) {
118 
119  /* Remove from list of registered UARTs */
120  list_del ( &uart->list );
121  uart_put ( uart );
122 }
123 
124 /**
125  * Find named UART
126  *
127  * @v name UART name
128  * @ret uart UART, or NULL if not found
129  */
130 struct uart * uart_find ( const char *name ) {
131  struct uart *uart;
132  unsigned int index;
133  char *endp;
134  int rc;
135 
136  /* Register fixed platform UARTs if not already registered */
137  if ( list_empty ( &uarts ) ) {
138  if ( ( rc = uart_register_fixed() ) != 0 ) {
139  DBGC ( &uarts, "UART could not register fixed UARTs: "
140  "%s\n", strerror ( rc ) );
141  /* Continue anyway */
142  }
143  }
144 
145  /* Try parsing name as a numeric index */
146  index = strtoul ( name, &endp, 10 );
147 
148  /* Find matching UART, if any */
150 
151  /* Check for a matching name */
152  if ( strcasecmp ( name, uart->name ) == 0 )
153  return uart;
154 
155  /* Check for a matching numeric index */
156  if ( ( *endp == '\0' ) && ( index-- == 0 ) )
157  return uart;
158  }
159 
160  DBGC ( &uarts, "UART %s not found\n", name );
161  return NULL;
162 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
LIST_HEAD(uarts)
List of registered UARTs.
Generic UART.
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:484
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static int null_uart_init(struct uart *uart __unused)
Definition: uart.c:52
Error codes.
A generic UART.
Definition: uart.h:17
#define DBGC(...)
Definition: compiler.h:505
long index
Definition: bigint.h:62
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:208
int uart_register(struct uart *uart)
Register UART.
Definition: uart.c:102
static void null_uart_flush(struct uart *uart __unused)
Definition: uart.c:56
const char * name
Name.
Definition: uart.h:21
struct list_head list
List of registered UARTs.
Definition: uart.h:23
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
void(* transmit)(struct uart *uart, uint8_t byte)
Transmit byte.
Definition: uart.h:43
UART operations.
Definition: uart.h:35
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
__weak int uart_register_fixed(void)
Register fixed UARTs (when not provided by platform)
Definition: uart.c:91
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
struct uart_operations null_uart_operations
Null UART operations.
Definition: uart.c:60
void * priv
Driver-private data.
Definition: uart.h:31
static int null_uart_data_ready(struct uart *uart __unused)
Definition: uart.c:44
unsigned char uint8_t
Definition: stdint.h:10
struct list_head uarts
struct uart * uart_find(const char *name)
Find named UART.
Definition: uart.c:130
static void null_uart_transmit(struct uart *uart __unused, uint8_t byte __unused)
Definition: uart.c:40
#define __weak
Declare a function as weak (use before the definition)
Definition: compiler.h:219
struct uart * alloc_uart(size_t priv_len)
Allocate UART.
Definition: uart.c:74
void uart_unregister(struct uart *uart)
Unregister UART.
Definition: uart.c:117
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
static uint8_t null_uart_receive(struct uart *uart __unused)
Definition: uart.c:48