undirom.c File Reference

UNDI expansion ROMs. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <pxe.h>
#include <realmode.h>
#include <undirom.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static LIST_HEAD (undiroms)
 List of all UNDI ROMs.
static int undirom_parse_pxeromid (struct undi_rom *undirom, unsigned int pxeromid)
 Parse PXE ROM ID structure.
static int undirom_parse_pcirheader (struct undi_rom *undirom, unsigned int pcirheader)
 Parse PCI expansion header.
static int undirom_probe (unsigned int rom_segment)
 Probe UNDI ROM.
static void undirom_probe_all_roms (void)
 Create UNDI ROMs for all possible expansion ROMs.
struct undi_romundirom_find_pci (unsigned int vendor_id, unsigned int device_id, unsigned int rombase)
 Find UNDI ROM for PCI device.


Detailed Description

UNDI expansion ROMs.

Definition in file undirom.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static LIST_HEAD ( undiroms   )  [static]

List of all UNDI ROMs.

static int undirom_parse_pxeromid ( struct undi_rom undirom,
unsigned int  pxeromid 
) [static]

Parse PXE ROM ID structure.

Parameters:
undirom UNDI ROM
pxeromid Offset within ROM to PXE ROM ID structure
Return values:
rc Return status code

Definition at line 44 of file undirom.c.

References undi_rom::code_size, undi_rom_id::CodeSize, copy_from_real, undi_rom::data_size, undi_rom_id::DataSize, DBGC, EINVAL, undi_rom::loader_entry, s_SEGOFF16::offset, undi_rom::rom_segment, s_SEGOFF16::segment, undi_rom_id::Signature, UNDI_ROM_ID_SIGNATURE, and undi_rom_id::UNDILoader.

Referenced by undirom_probe().

00045                                                            {
00046         struct undi_rom_id undi_rom_id;
00047         unsigned int undiloader;
00048 
00049         DBGC ( undirom, "UNDIROM %p has PXE ROM ID at %04x:%04x\n", undirom,
00050                undirom->rom_segment, pxeromid );
00051 
00052         /* Read PXE ROM ID structure and verify */
00053         copy_from_real ( &undi_rom_id, undirom->rom_segment, pxeromid,
00054                          sizeof ( undi_rom_id ) );
00055         if ( undi_rom_id.Signature != UNDI_ROM_ID_SIGNATURE ) {
00056                 DBGC ( undirom, "UNDIROM %p has bad PXE ROM ID signature "
00057                        "%08x\n", undirom, undi_rom_id.Signature );
00058                 return -EINVAL;
00059         }
00060 
00061         /* Check for UNDI loader */
00062         undiloader = undi_rom_id.UNDILoader;
00063         if ( ! undiloader ) {
00064                 DBGC ( undirom, "UNDIROM %p has no UNDI loader\n", undirom );
00065                 return -EINVAL;
00066         }
00067 
00068         /* Fill in UNDI ROM loader fields */
00069         undirom->loader_entry.segment = undirom->rom_segment;
00070         undirom->loader_entry.offset = undiloader;
00071         undirom->code_size = undi_rom_id.CodeSize;
00072         undirom->data_size = undi_rom_id.DataSize;
00073 
00074         DBGC ( undirom, "UNDIROM %p has UNDI loader at %04x:%04x "
00075                "(code %04zx data %04zx)\n", undirom,
00076                undirom->loader_entry.segment, undirom->loader_entry.offset,
00077                undirom->code_size, undirom->data_size );
00078         return 0;
00079 }

static int undirom_parse_pcirheader ( struct undi_rom undirom,
unsigned int  pcirheader 
) [static]

Parse PCI expansion header.

Parameters:
undirom UNDI ROM
pcirheader Offset within ROM to PCI expansion header

Definition at line 87 of file undirom.c.

References undi_rom::bus_id, undi_rom::bus_type, copy_from_real, DBGC, pcir_header::device_id, undi_pci_device_id::device_id, EINVAL, undi_device_id::pci, PCI_NIC, PCIR_SIGNATURE, undi_rom::rom_segment, pcir_header::signature, pcir_header::vendor_id, and undi_pci_device_id::vendor_id.

Referenced by undirom_probe().

00088                                                                {
00089         struct pcir_header pcir_header;
00090 
00091         DBGC ( undirom, "UNDIROM %p has PCI expansion header at %04x:%04x\n",
00092                undirom, undirom->rom_segment, pcirheader );
00093 
00094         /* Read PCI expansion header and verify */
00095         copy_from_real ( &pcir_header, undirom->rom_segment, pcirheader,
00096                          sizeof ( pcir_header ) );
00097         if ( pcir_header.signature != PCIR_SIGNATURE ) {
00098                 DBGC ( undirom, "UNDIROM %p has bad PCI expansion header "
00099                        "signature %08x\n", undirom, pcir_header.signature );
00100                 return -EINVAL;
00101         }
00102 
00103         /* Fill in UNDI ROM PCI device fields */
00104         undirom->bus_type = PCI_NIC;
00105         undirom->bus_id.pci.vendor_id = pcir_header.vendor_id;
00106         undirom->bus_id.pci.device_id = pcir_header.device_id;
00107 
00108         DBGC ( undirom, "UNDIROM %p is for PCI devices %04x:%04x\n", undirom,
00109                undirom->bus_id.pci.vendor_id, undirom->bus_id.pci.device_id );
00110         return 0;
00111         
00112 }

static int undirom_probe ( unsigned int  rom_segment  )  [static]

Probe UNDI ROM.

Parameters:
rom_segment ROM segment address
Return values:
rc Return status code

Definition at line 120 of file undirom.c.

References copy_from_real, DBG, DBGC, EINVAL, ENOMEM, free(), undi_rom::list, list_add, NULL, undi_rom_header::PCIRHeader, undi_rom_header::PXEROMID, undi_rom::rom_segment, ROM_SIGNATURE, undi_rom_header::ROMLength, undi_rom_header::Signature, undirom_parse_pcirheader(), undirom_parse_pxeromid(), and zalloc().

Referenced by undirom_probe_all_roms().

00120                                                       {
00121         struct undi_rom *undirom = NULL;
00122         struct undi_rom_header romheader;
00123         size_t rom_len;
00124         unsigned int pxeromid;
00125         unsigned int pcirheader;
00126         int rc;
00127 
00128         /* Read expansion ROM header and verify */
00129         copy_from_real ( &romheader, rom_segment, 0, sizeof ( romheader ) );
00130         if ( romheader.Signature != ROM_SIGNATURE ) {
00131                 rc = -EINVAL;
00132                 goto err;
00133         }
00134         rom_len = ( romheader.ROMLength * 512 );
00135 
00136         /* Allocate memory for UNDI ROM */
00137         undirom = zalloc ( sizeof ( *undirom ) );
00138         if ( ! undirom ) {
00139                 DBG ( "Could not allocate UNDI ROM structure\n" );
00140                 rc = -ENOMEM;
00141                 goto err;
00142         }
00143         DBGC ( undirom, "UNDIROM %p trying expansion ROM at %04x:0000 "
00144                "(%zdkB)\n", undirom, rom_segment, ( rom_len / 1024 ) );
00145         undirom->rom_segment = rom_segment;
00146 
00147         /* Check for and parse PXE ROM ID */
00148         pxeromid = romheader.PXEROMID;
00149         if ( ! pxeromid ) {
00150                 DBGC ( undirom, "UNDIROM %p has no PXE ROM ID\n", undirom );
00151                 rc = -EINVAL;
00152                 goto err;
00153         }
00154         if ( pxeromid > rom_len ) {
00155                 DBGC ( undirom, "UNDIROM %p PXE ROM ID outside ROM\n",
00156                        undirom );
00157                 rc = -EINVAL;
00158                 goto err;
00159         }
00160         if ( ( rc = undirom_parse_pxeromid ( undirom, pxeromid ) ) != 0 )
00161                 goto err;
00162 
00163         /* Parse PCIR header, if present */
00164         pcirheader = romheader.PCIRHeader;
00165         if ( pcirheader )
00166                 undirom_parse_pcirheader ( undirom, pcirheader );
00167 
00168         /* Add to UNDI ROM list and return */
00169         DBGC ( undirom, "UNDIROM %p registered\n", undirom );
00170         list_add ( &undirom->list, &undiroms );
00171         return 0;
00172 
00173  err:
00174         free ( undirom );
00175         return rc;
00176 }

static void undirom_probe_all_roms ( void   )  [static]

Create UNDI ROMs for all possible expansion ROMs.

Return values:
 

Definition at line 183 of file undirom.c.

References DBG, and undirom_probe().

Referenced by undirom_find_pci().

00183                                             {
00184         static int probed = 0;
00185         unsigned int rom_segment;
00186 
00187         /* Perform probe only once */
00188         if ( probed )
00189                 return;
00190 
00191         DBG ( "Scanning for PXE expansion ROMs\n" );
00192 
00193         /* Scan through expansion ROM region at 512 byte intervals */
00194         for ( rom_segment = 0xc000 ; rom_segment < 0x10000 ;
00195               rom_segment += 0x20 ) {
00196                 undirom_probe ( rom_segment );
00197         }
00198 
00199         probed = 1;
00200 }

struct undi_rom* undirom_find_pci ( unsigned int  vendor_id,
unsigned int  device_id,
unsigned int  rombase 
) [read]

Find UNDI ROM for PCI device.

Parameters:
vendor_id PCI vendor ID
device_id PCI device ID
rombase ROM base address, or 0 for any
Return values:
undirom UNDI ROM, or NULL

Definition at line 210 of file undirom.c.

References undi_rom::bus_id, undi_rom::bus_type, DBG, DBGC, undi_pci_device_id::device_id, undi_rom::list, list_for_each_entry, NULL, undi_device_id::pci, PCI_NIC, undi_rom::rom_segment, undirom_probe_all_roms(), and undi_pci_device_id::vendor_id.

Referenced by undipci_find_rom().

00212                                                             {
00213         struct undi_rom *undirom;
00214 
00215         undirom_probe_all_roms();
00216 
00217         list_for_each_entry ( undirom, &undiroms, list ) {
00218                 if ( undirom->bus_type != PCI_NIC )
00219                         continue;
00220                 if ( undirom->bus_id.pci.vendor_id != vendor_id )
00221                         continue;
00222                 if ( undirom->bus_id.pci.device_id != device_id )
00223                         continue;
00224                 if ( rombase && ( ( undirom->rom_segment << 4 ) != rombase ) )
00225                         continue;
00226                 DBGC ( undirom, "UNDIROM %p matched PCI %04x:%04x (%08x)\n",
00227                        undirom, vendor_id, device_id, rombase );
00228                 return undirom;
00229         }
00230 
00231         DBG ( "No UNDI ROM matched PCI %04x:%04x (%08x)\n",
00232               vendor_id, device_id, rombase );
00233         return NULL;
00234 }


Generated on Tue Apr 6 20:01:12 2010 for gPXE by  doxygen 1.5.7.1