iPXE
efi_disklog.c File Reference

EFI disk log console. More...

#include <assert.h>
#include <errno.h>
#include <string.h>
#include <ipxe/console.h>
#include <ipxe/disklog.h>
#include <ipxe/init.h>
#include <ipxe/umalloc.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/BlockIo.h>
#include <ipxe/efi/Protocol/PartitionInfo.h>
#include <config/console.h>

Go to the source code of this file.

Macros

#define CONSOLE_DISKLOG   ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int efi_disklog_write (void)
 Write current logical block.
static void efi_disklog_putchar (int character)
 Write character to console.
static int efi_disklog_open (EFI_HANDLE handle)
 Open EFI disk log partition.
static void efi_disklog_init (void)
 Initialise EFI disk log console.
struct init_fn efi_disklog_init_fn __init_fn (INIT_CONSOLE)
 EFI disk log console initialisation function.
static void efi_disklog_shutdown (int booting __unused)
 Shut down EFI disk log console.
struct startup_fn efi_disklog_startup_fn __startup_fn (STARTUP_EARLY)
 EFI disk log console shutdown function.
 IPXE_NOTE (DISKLOG)

Variables

static EFI_HANDLE efi_disklog_handle
 EFI disk log console device handle.
static EFI_BLOCK_IO_PROTOCOLefi_disklog_block
 EFI disk log console block I/O protocol.
static UINT32 efi_disklog_media_id
 EFI disk log console media ID.
static struct disklog efi_disklog
 EFI disk log console.
struct console_driver efi_disklog_console __console_driver
 EFI disk log console driver.
static struct disklog_operations efi_disklog_op
 EFI disk log console operations.

Detailed Description

EFI disk log console.

Definition in file efi_disklog.c.

Macro Definition Documentation

◆ CONSOLE_DISKLOG

#define CONSOLE_DISKLOG   ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )

Definition at line 48 of file efi_disklog.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ efi_disklog_write()

int efi_disklog_write ( void )
static

Write current logical block.

Return values
rcReturn status code

Definition at line 70 of file efi_disklog.c.

70 {
72 struct disklog *disklog = &efi_disklog;
73 EFI_STATUS efirc;
74 int rc;
75
76 /* Write disk block */
77 if ( ( efirc = block->WriteBlocks ( block, efi_disklog_media_id,
79 disklog->buffer ) ) != 0 ) {
80 rc = -EEFI ( efirc );
81 DBGC ( disklog, "EFIDISKLOG %s could not write LBA %#llx: "
83 ( ( unsigned long long ) disklog->lba ),
84 strerror ( rc ) );
85 return rc;
86 }
87
88 return 0;
89}
struct _EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL
Definition BlockIo.h:22
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
static EFI_HANDLE efi_disklog_handle
EFI disk log console device handle.
Definition efi_disklog.c:52
static UINT32 efi_disklog_media_id
EFI disk log console media ID.
Definition efi_disklog.c:58
static struct disklog efi_disklog
EFI disk log console.
Definition efi_disklog.c:61
static EFI_BLOCK_IO_PROTOCOL * efi_disklog_block
EFI disk log console block I/O protocol.
Definition efi_disklog.c:55
#define DBGC(...)
Definition compiler.h:530
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:181
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A disk log.
Definition disklog.h:25
uint8_t * buffer
Logical block data buffer.
Definition disklog.h:31
size_t blksize
Logical block size.
Definition disklog.h:33
uint64_t lba
Current logical block index.
Definition disklog.h:35

References disklog::blksize, block, disklog::buffer, DBGC, EEFI, efi_disklog, efi_disklog_block, efi_disklog_handle, efi_disklog_media_id, efi_handle_name(), disklog::lba, rc, and strerror().

◆ efi_disklog_putchar()

void efi_disklog_putchar ( int character)
static

Write character to console.

Parameters
characterCharacter

Definition at line 101 of file efi_disklog.c.

101 {
102
103 /* Write character */
104 disklog_putchar ( &efi_disklog, character );
105}
void disklog_putchar(struct disklog *disklog, int character)
Write character to disk log console.
Definition disklog.c:85

References disklog_putchar(), and efi_disklog.

◆ efi_disklog_open()

int efi_disklog_open ( EFI_HANDLE handle)
static

Open EFI disk log partition.

Parameters
handleBlock device handle
Return values
rcReturn status code

Definition at line 113 of file efi_disklog.c.

113 {
114 struct disklog *disklog = &efi_disklog;
118 void *buffer;
119 EFI_STATUS efirc;
120 int rc;
121
122 /* Record handle */
124
125 /* Open block I/O protocol for ephemeral usage */
127 &block ) ) != 0 ) {
128 DBGC ( disklog, "EFIDISKLOG %s could not open: %s\n",
130 goto err_open;
131 }
132 media = block->Media;
134 efi_disklog_media_id = media->MediaId;
135
136 /* Check this is a partition */
137 if ( ! media->LogicalPartition ) {
138 DBGC2 ( disklog, "EFIDISKLOG %s is not a partition\n",
140 rc = -ENOTTY;
141 goto err_not_partition;
142 }
143
144 /* Check partition type (if exposed by the platform) */
146 &part ) ) == 0 ) {
147 if ( ( part->Type != PARTITION_TYPE_MBR ) ||
149 DBGC ( disklog, "EFIDISKLOG %s is not a log "
150 "partition\n", efi_handle_name ( handle ) );
151 rc = -ENOTTY;
152 goto err_not_log;
153 }
154 } else {
155 DBGC2 ( disklog, "EFIDISKLOG %s has no partition info\n",
157 /* Continue anyway */
158 }
159
160 /* Allocate buffer */
161 buffer = umalloc ( media->BlockSize );
162 if ( ! buffer ) {
163 rc = -ENOMEM;
164 goto err_alloc;
165 }
166
167 /* Read partition signature */
168 if ( ( efirc = block->ReadBlocks ( block, efi_disklog_media_id, 0,
169 media->BlockSize, buffer ) ) != 0 ){
170 rc = -EEFI ( efirc );
171 DBGC ( disklog, "EFIDISKLOG %s could not read block 0: %s\n",
173 goto err_read;
174 }
175
176 /* Initialise disk log console */
177 disklog_init ( disklog, &efi_disklog_op, &efi_disklog_console, buffer,
178 media->BlockSize, 0, media->LastBlock );
179
180 /* Open disk log console */
181 if ( ( rc = disklog_open ( disklog ) ) != 0 ) {
182 DBGC ( disklog, "EFIDISKLOG %s could not initialise log: "
183 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
184 goto err_init;
185 }
186
187 /* Reopen handle for long-term use */
189 &block ) ) != 0 ) {
190 DBGC ( disklog, "EFIDISKLOG %s could not reopen: %s\n",
192 goto err_reopen;
193 }
194 if ( block != efi_disklog_block ) {
195 DBGC ( disklog, "EFIDISKLOG %s changed during reopening\n",
197 rc = -EPIPE;
198 goto err_reopen_mismatch;
199 }
200
201 DBGC ( disklog, "EFIDISKLOG using %s\n", efi_handle_name ( handle ) );
202 DBGC2 ( disklog, "EFIDISKLOG has %zd-byte LBA [%#x,%#llx]\n",
203 disklog->blksize, 0,
204 ( ( unsigned long long ) disklog->max_lba ) );
205 return 0;
206
207 err_reopen_mismatch:
209 err_reopen:
210 err_init:
211 err_read:
212 ufree ( buffer );
213 err_alloc:
214 err_not_log:
215 err_not_partition:
217 err_open:
219 return rc;
220}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
#define PARTITION_TYPE_MBR
int disklog_open(struct disklog *disklog)
Open disk log console.
Definition disklog.c:46
#define DISKLOG_PARTITION_TYPE
Disk log partition type.
Definition disklog.h:84
static void disklog_init(struct disklog *disklog, struct disklog_operations *op, struct console_driver *console, void *buffer, size_t blksize, uint64_t lba, uint64_t max_lba)
Initialise disk log console.
Definition disklog.h:66
static struct disklog_operations efi_disklog_op
EFI disk log console operations.
Definition efi_disklog.c:92
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
Definition efi_guid.c:146
EFI_GUID efi_partition_info_protocol_guid
Partition information protocol GUID.
Definition efi_guid.c:314
void efi_close_by_driver(EFI_HANDLE handle, EFI_GUID *protocol)
Close protocol opened for persistent use by a driver.
Definition efi_open.c:279
#define DBGC2(...)
Definition compiler.h:547
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER).
Definition netvsc.h:5
#define EPIPE
Broken pipe.
Definition errno.h:620
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
#define efi_open_by_driver(handle, protocol, interface)
Open protocol for persistent use by a driver.
Definition efi.h:483
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition efi.h:453
uint16_t handle
Handle.
Definition smbios.h:5
static __always_inline void * umalloc(size_t size)
Allocate external memory.
Definition umalloc.h:57
static __always_inline void ufree(void *ptr)
Free external memory.
Definition umalloc.h:68
Block IO read only mode data and updated only via members of BlockIO.
Definition BlockIo.h:130
Partition Information Protocol structure.
MBR_PARTITION_RECORD Mbr
MBR data.
union EFI_PARTITION_INFO_PROTOCOL::@056321252157326256300375054226170121123346213234 Info
UINT8 OSIndicator
Definition Mbr.h:35
uint64_t max_lba
Maximum logical block index.
Definition disklog.h:37
static char media[]
Definition sundance.c:85

References disklog::blksize, block, buffer, DBGC, DBGC2, disklog_init(), disklog_open(), DISKLOG_PARTITION_TYPE, EEFI, efi_block_io_protocol_guid, efi_close_by_driver(), efi_disklog, efi_disklog_block, efi_disklog_handle, efi_disklog_media_id, efi_disklog_op, EFI_HANDLE, efi_handle_name(), efi_open, efi_open_by_driver, efi_partition_info_protocol_guid, ENOMEM, ENOTTY, EPIPE, handle, EFI_PARTITION_INFO_PROTOCOL::Info, disklog::max_lba, EFI_PARTITION_INFO_PROTOCOL::Mbr, media, NULL, MBR_PARTITION_RECORD::OSIndicator, PARTITION_TYPE_MBR, rc, strerror(), EFI_PARTITION_INFO_PROTOCOL::Type, ufree(), and umalloc().

Referenced by efi_disklog_init().

◆ efi_disklog_init()

void efi_disklog_init ( void )
static

Initialise EFI disk log console.

Definition at line 226 of file efi_disklog.c.

226 {
227 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
229 EFI_HANDLE *handles;
230 UINTN count;
231 unsigned int i;
232 EFI_STATUS efirc;
233 int rc;
234
235 /* Locate all block I/O protocol handles */
236 if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol, protocol,
237 NULL, &count,
238 &handles ) ) != 0 ) {
239 rc = -EEFI ( efirc );
240 DBGC ( &efi_disklog, "EFIDISKLOG could not locate block I/O: "
241 "%s\n", strerror ( rc ) );
242 goto err_locate;
243 }
244
245 /* Try each handle in turn */
246 for ( i = 0 ; i < count ; i++ ) {
247 if ( ( rc = efi_disklog_open ( handles[i] ) ) == 0 )
248 break;
249 }
250
251 bs->FreePool ( handles );
252 err_locate:
253 return;
254}
UINT64 UINTN
Unsigned value of native width.
GUID EFI_GUID
128-bit buffer containing a unique identifier value.
@ ByProtocol
Retrieve the set of handles from the handle database that support a specified protocol.
Definition UefiSpec.h:1530
static int efi_disklog_open(EFI_HANDLE handle)
Open EFI disk log partition.
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define EFI_HANDLE
Definition efi.h:53
EFI_SYSTEM_TABLE * efi_systab
uint16_t protocol
Protocol ID.
Definition stp.h:7
EFI Boot Services Table.
Definition UefiSpec.h:1930
EFI_FREE_POOL FreePool
Definition UefiSpec.h:1949
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
Definition UefiSpec.h:2007

References ByProtocol, count, DBGC, EEFI, efi_block_io_protocol_guid, efi_disklog, efi_disklog_open(), EFI_HANDLE, efi_systab, EFI_BOOT_SERVICES::FreePool, EFI_BOOT_SERVICES::LocateHandleBuffer, NULL, protocol, rc, and strerror().

Referenced by __init_fn().

◆ __init_fn()

struct init_fn efi_disklog_init_fn __init_fn ( INIT_CONSOLE )

EFI disk log console initialisation function.

References __init_fn, efi_disklog_init(), and INIT_CONSOLE.

◆ efi_disklog_shutdown()

void efi_disklog_shutdown ( int booting __unused)
static

Shut down EFI disk log console.

Parameters
bootingSystem is shutting down for OS boot

Definition at line 269 of file efi_disklog.c.

269 {
270 struct disklog *disklog = &efi_disklog;
271
272 /* Do nothing if we have no EFI disk log console */
273 if ( ! efi_disklog_handle )
274 return;
275
276 /* Close EFI disk log console */
277 DBGC ( disklog, "EFIDISKLOG %s closed\n",
281 ufree ( disklog->buffer );
285}

References __unused, disklog::buffer, DBGC, efi_block_io_protocol_guid, efi_close_by_driver(), efi_disklog, efi_disklog_block, efi_disklog_handle, efi_handle_name(), NULL, and ufree().

Referenced by __startup_fn().

◆ __startup_fn()

struct startup_fn efi_disklog_startup_fn __startup_fn ( STARTUP_EARLY )

EFI disk log console shutdown function.

References __startup_fn, efi_disklog_shutdown(), and STARTUP_EARLY.

◆ IPXE_NOTE()

IPXE_NOTE ( DISKLOG )

Variable Documentation

◆ efi_disklog_handle

EFI_HANDLE efi_disklog_handle
static

EFI disk log console device handle.

Definition at line 52 of file efi_disklog.c.

Referenced by efi_disklog_open(), efi_disklog_shutdown(), and efi_disklog_write().

◆ efi_disklog_block

EFI_BLOCK_IO_PROTOCOL* efi_disklog_block
static

EFI disk log console block I/O protocol.

Definition at line 55 of file efi_disklog.c.

Referenced by efi_disklog_open(), efi_disklog_shutdown(), and efi_disklog_write().

◆ efi_disklog_media_id

UINT32 efi_disklog_media_id
static

EFI disk log console media ID.

Definition at line 58 of file efi_disklog.c.

Referenced by efi_disklog_open(), and efi_disklog_write().

◆ efi_disklog

struct disklog efi_disklog
static

◆ __console_driver

struct console_driver efi_disklog_console __console_driver
Initial value:
= {
.putchar = efi_disklog_putchar,
.disabled = CONSOLE_DISABLED,
.usage = CONSOLE_DISKLOG,
}
static void efi_disklog_putchar(int character)
Write character to console.
#define CONSOLE_DISKLOG
Definition efi_disklog.c:48
#define CONSOLE_DISABLED
Console is disabled for all uses.
Definition console.h:112

EFI disk log console driver.

Definition at line 63 of file efi_disklog.c.

◆ efi_disklog_op

struct disklog_operations efi_disklog_op
static
Initial value:
= {
}
static int efi_disklog_write(void)
Write current logical block.
Definition efi_disklog.c:70

EFI disk log console operations.

Definition at line 92 of file efi_disklog.c.

92 {
93 .write = efi_disklog_write,
94};

Referenced by efi_disklog_open().