Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic EFI romheaders support #5

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion romheaders/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ STRIP = strip
CFLAGS = -O2 -Wall -Wextra
INCLUDES = -I../shared

SOURCES = romheaders.c ../shared/classcodes.c
SOURCES = romheaders.c ../shared/classcodes.c ../shared/eficodes.c

.SUFFIXES: .c

Expand Down
40 changes: 39 additions & 1 deletion romheaders/romheaders.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,15 @@ char *rom=NULL;
size_t romlen=0;


/* Prototypes for functions exported from devsupp/pci/classcodes.c */
/* Prototypes for functions exported from:
* - shared/classcodes.c
* - shared/eficodes.c
*/

char *pci_device_class_name(u32 code);
char *pci_code_type_name(unsigned char code);
char *efi_subsystem_name(u16 code);
char *efi_machine_type_name(u16 code);

/* Functions local to this file:
bool dump_rom_header(rom_header_t *data);
Expand Down Expand Up @@ -119,6 +124,7 @@ static bool dump_pci_data(pci_data_t *data)
static void dump_platform_extensions(u8 type, rom_header_t *data)
{
u32 entry;
efirom_header_t *efidata;

switch (type) {
case 0x00:
Expand Down Expand Up @@ -162,6 +168,38 @@ static void dump_platform_extensions(u8 type, rom_header_t *data)
printf(" Pointer to FCode program: 0x%04x\n\n",
data->reserved[1]<<8|data->reserved[0]);
break;
case 0x03:
efidata = (efirom_header_t *) data;

if (LITTLE_ENDIAN_WORD_FETCH(efidata->efi_signature) != 0x0ef1) {
printf("EFI signature is missing.\n");
printf(" This is not a valid EFI option rom.\n");
break;
}

printf("Platform specific data for EFI compliant option rom:\n");

printf(" Initialization size: %d\n",
LITTLE_ENDIAN_WORD_FETCH(efidata->initialization_size)*512);
printf(" EFI signature: 0x%04x\n",
LITTLE_ENDIAN_LONG_FETCH(efidata->efi_signature));
printf(" EFI subsystem: %d (%s)\n",
LITTLE_ENDIAN_WORD_FETCH(efidata->efi_subsystem),
efi_subsystem_name(LITTLE_ENDIAN_WORD_FETCH(efidata->efi_subsystem))
);
printf(" EFI machine type: 0x%04x (%s)\n",
LITTLE_ENDIAN_WORD_FETCH(efidata->efi_machine_type),
efi_machine_type_name(LITTLE_ENDIAN_WORD_FETCH(efidata->efi_machine_type))
);
printf(" EFI image %s compressed\n",
(LITTLE_ENDIAN_WORD_FETCH(efidata->compression_type) ? "is" : "is not"));
printf(" EFI image header offset: 0x%x\n",
LITTLE_ENDIAN_WORD_FETCH(efidata->efi_image_header_offset));
break;
case 0xff:
printf("This looks to be an iPXE ROM (full length). If there is\n");
printf(" also a code type 0x00 ROM, that one is an iPXE MROM (stub).\n");
break;
default:
printf("Parsing of platform specific data not available for this image\n\n");
}
Expand Down
219 changes: 219 additions & 0 deletions shared/eficodes.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/*
* OpenBIOS - free your system!
* ( FCode tokenizer )
*
* This program is part of a free implementation of the IEEE 1275-1994
* Standard for Boot (Initialization Configuration) Firmware.
*
* Copyright (C) 2001-2005 Stefan Reinauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
*
*/

/* **************************************************************************
*
* Functions to correlate EFI subsystem type and machine name
* with their printable names.
*
* (C) Copyright 2018. All Rights Reserved.
* Module Author: Radek Zajic [email protected]
*
* Based on the classcodes.c file
* (C) Copyright 2005 IBM Corporation. All Rights Reserved.
* Module Author: David L. Paktor [email protected]
*
**************************************************************************** */

#include <stdlib.h>
#include "types.h"

/* **************************************************************************
*
* Functions Eported:
* efi_subsystem_name
* Convert a numeric EFI subsystem type to a printable Name
*
* efi_machine_type_name
* Convert a numeric EFI machine type to a printable Name
*
**************************************************************************** */

const char *efi_machine_type_name(u16 code);
const char *efi_subsystem_name(u16 code);


typedef struct {
const u32 classcode;
const char *classname;
} num_to_name_table ;


/* **************************************************************************
*
* Function name: convert_num_to_name
* Synopsis: Find the Name, in the given table, for the given Number.
* Support function for Exported Functions.
*
* Inputs:
* Parameters:
* u32 num Number to look up
* num_to_name_table *table Pointer to Table to scan
* int max Maximum Index of Table
* char *not_found String to return if Number not in Table
*
* Outputs:
* Returned Value: Pointer to string giving the Name
*
* Error Detection:
* Unrecognized Number
* Return "not_found" string
*
* Process Explanation:
* Scan the Table for a match.
*
* Still to be done / Misc remarks:
* Had been considering a more sophisticated binary search,
* but the database is too small to merit the extra code.
* Stayed with the KISS principle...
*
*
**************************************************************************** */

static const char *convert_num_to_name(u32 num,
num_to_name_table *table,
int max,
const char *not_found)
{
int indx;
const char *retval;

retval = not_found;

for (indx = 0; indx < max ; indx++)
{
if ( num == table[indx].classcode )
{
retval = table[indx].classname ;
break ;
}
}
return ( retval );
}


/* **************************************************************************
*
*
* Structures:
* efi_machine_type_name_table Constant Data Table that correlates
* Machine Types with their Names.
*
* efi_subsystem_name_table Constant Data Table that correlates
* Subsytem Codes with their Names.
*
**************************************************************************** */


static const num_to_name_table efi_machine_type_name_table[] = {
{ 0x01c2 , "ARMTHUMB_MIXED (ARM32/Thumb)" },
{ 0x014c , "IA32 (x86)" },
{ 0x0200 , "IA64 (Itanium)" },
{ 0x8664 , "AMD64 (x86-64)" },
{ 0xAA64 , "ARM64 (AArch64)" },
{ 0x0EBC , "EFI byte code" }
};


static const num_to_name_table efi_subsystem_name_table[] = {
{ 10 , "EFI Application" },
{ 11 , "EFI Boot Service Driver" },
{ 12 , "EFI Runtime Driver." },

};

/* **************************************************************************
*
* Function name: efi_machine_type_name
* Synopsis: Return the machine type name for the given machine code
*
* Inputs:
* Parameters:
* u32 code Numeric EFI machine type code
*
* Outputs:
* Returned Value: Pointer to string giving the machine type
*
* Error Detection:
* Unrecognized machine type
* String returned is "unknown as of EFI specs 2.7"
*
* Process Explanation:
* Scan the efi_machine_type_name for a match.
*
*
**************************************************************************** */

const char *efi_machine_type_name(u16 code)
{
const int pdc_max_indx =
sizeof(efi_machine_type_name_table)/sizeof(num_to_name_table) ;
const char *result ;

result = convert_num_to_name(
code,
(num_to_name_table *)efi_machine_type_name_table,
pdc_max_indx,
"unknown as of EFI specs 2.7");

return ( result );
}


/* **************************************************************************
*
* Function name: efi_subsystem_name
* Synopsis: Return a printable Name for the given EFI subsystem name
*
* Inputs:
* Parameters:
* u16 code Numeric EFI subsystem code
*
* Outputs:
* Returned Value: Pointer to string giving printable Name
*
* Error Detection:
* Unrecognized EFI subsystem code
* String returned is "unknown as of EFI specs 2.7"
*
* Process Explanation:
* Scan the efi_subsystem_name for a match.
*
*
**************************************************************************** */

const char *efi_subsystem_name(u16 code)
{
const int pct_max_indx =
sizeof(efi_subsystem_name_table)/sizeof(num_to_name_table) ;
const char *result ;

result = convert_num_to_name(
(u32)code,
(num_to_name_table *)efi_subsystem_name_table,
pct_max_indx,
"unknown as of EFI specs 2.7");
return ( result );
}

13 changes: 13 additions & 0 deletions shared/pcihdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,19 @@ typedef struct {
le_u16(padd);
} rom_header_t;

typedef struct {
be_u16(signature);
le_u16(initialization_size);
le_u32(efi_signature);
le_u16(efi_subsystem);
le_u16(efi_machine_type);
le_u16(compression_type);
u8 reserved[0x8];
le_u16(efi_image_header_offset);
le_u16(data_ptr);
le_u16(padd);
} efirom_header_t;


typedef struct {
be_u32 (signature);
Expand Down