iPXE
fdtcon.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 (at your option) 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 #include <string.h>
27 #include <ipxe/serial.h>
28 #include <ipxe/devtree.h>
29 #include <ipxe/fdt.h>
30 
31 /** @file
32  *
33  * Flattened Device Tree serial console
34  *
35  */
36 
37 #ifdef SERIAL_FDT
38 #define SERIAL_PREFIX_fdt
39 #else
40 #define SERIAL_PREFIX_fdt __fdt_
41 #endif
42 
43 /** FDT console parent device */
44 static struct device fdtcon_parent = {
45  .name = "fdtcon",
46  .siblings = LIST_HEAD_INIT ( fdtcon_parent.siblings ),
47  .children = LIST_HEAD_INIT ( fdtcon_parent.children ),
48 };
49 
50 /** Colour for debug messages */
51 #define colour &fdtcon_parent
52 
53 /**
54  * Identify default serial console
55  *
56  * @ret uart Default serial console UART, or NULL
57  */
58 static struct uart * fdtcon_default ( void ) {
59  unsigned int chosen;
60  unsigned int stdout;
61  const char *path;
62  struct uart *prev;
63  struct uart *uart;
64  int rc;
65 
66  /* Record existing UART, if any */
67  prev = list_last_entry ( &uarts, struct uart, list );
68 
69  /* Locate "/chosen" node */
70  if ( ( rc = fdt_path ( &sysfdt, "/chosen", &chosen ) ) != 0 ) {
71  DBGC ( colour, "FDTCON could not locate \"/chosen\": %s\n",
72  strerror ( rc ) );
73  return NULL;
74  }
75 
76  /* Get console device path (or alias) */
77  path = fdt_string ( &sysfdt, chosen, "stdout-path" );
78  if ( ! path ) {
79  DBGC ( colour, "FDTCON has no console device\n" );
80  return NULL;
81  }
82  DBGC ( colour, "FDTCON console device is \"%s\"\n", path );
83 
84  /* Locate device */
85  if ( ( ( rc = fdt_path ( &sysfdt, path, &stdout ) ) != 0 ) &&
86  ( ( rc = fdt_alias ( &sysfdt, path, &stdout ) ) != 0 ) ) {
87  DBGC ( colour, "FDTCON could not locate \"/%s\": %s\n",
88  path, strerror ( rc ) );
89  return NULL;
90  }
91 
92  /* Probe device */
93  if ( ( rc = dt_probe_node ( &fdtcon_parent, stdout ) ) != 0 ) {
94  DBGC ( colour, "FDTCON could not probe \"%s\": %s\n",
95  path, strerror ( rc ) );
96  return NULL;
97  }
98 
99  /* Use newly added UART, if any */
100  uart = list_last_entry ( &uarts, struct uart, list );
101  if ( uart == prev )
102  return NULL;
103 
104  DBGC ( colour, "FDTCON using UART %s\n", uart->name );
105  return uart;
106 }
107 
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int fdt_alias(struct fdt *fdt, const char *name, unsigned int *offset)
Find node by alias.
Definition: fdt.c:465
A generic UART.
Definition: uart.h:17
int fdt_path(struct fdt *fdt, const char *path, unsigned int *offset)
Find node by path.
Definition: fdt.c:425
#define DBGC(...)
Definition: compiler.h:505
char name[40]
Name.
Definition: device.h:78
Serial console.
struct uart * default_serial_console(void)
Get serial console UART.
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition: list.h:346
const char * name
Name.
Definition: uart.h:21
struct list_head list
List of registered UARTs.
Definition: uart.h:23
A hardware device.
Definition: device.h:76
Devicetree bus.
static struct device fdtcon_parent
FDT console parent device.
Definition: fdtcon.c:44
const char * fdt_string(struct fdt *fdt, unsigned int offset, const char *name)
Find string property.
Definition: fdt.c:578
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct list_head siblings
Devices on the same bus.
Definition: device.h:84
struct list_head uarts
int dt_probe_node(struct device *parent, unsigned int offset)
Probe devicetree node.
Definition: devtree.c:196
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
A device tree.
Definition: fdt.h:88
#define colour
Colour for debug messages.
Definition: fdtcon.c:51
struct list_head children
Devices attached to this device.
Definition: device.h:86
Flattened Device Tree.
PROVIDE_SERIAL(fdt, default_serial_console, fdtcon_default)
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30
static struct uart * fdtcon_default(void)
Identify default serial console.
Definition: fdtcon.c:58
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
struct fdt sysfdt
The system flattened device tree (if present)
Definition: fdt.c:44