iPXE
Data Structures | Defines | Typedefs | Functions | Variables
fdt.h File Reference

Flattened Device Tree. More...

#include <stdint.h>

Go to the source code of this file.

Data Structures

struct  fdt_header
 Device tree header. More...
struct  fdt_prop
 Property fragment. More...
struct  fdt
 A device tree. More...

Defines

#define FDT_MAGIC   0xd00dfeed
 Magic signature.
#define FDT_VERSION   16
 Expected device tree version.
#define FDT_BEGIN_NODE   0x00000001
 Begin node token.
#define FDT_END_NODE   0x00000002
 End node token.
#define FDT_PROP   0x00000003
 Property token.
#define FDT_NOP   0x00000004
 NOP token.
#define FDT_END   0x00000009
 End of structure block.
#define FDT_STRUCTURE_ALIGN   ( sizeof ( fdt_token_t ) )
 Alignment of structure block.

Typedefs

typedef uint32_t fdt_token_t
 Device tree token.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
struct fdt_header __attribute__ ((packed))
int fdt_path (const char *path, unsigned int *offset)
 Find node by path.
int fdt_alias (const char *name, unsigned int *offset)
 Find node by alias.
const char * fdt_string (unsigned int offset, const char *name)
 Find string property.
int fdt_mac (unsigned int offset, struct net_device *netdev)
 Get MAC address from property.
int register_fdt (const struct fdt_header *hdr)
 Register device tree.

Variables

uint32_t magic
 Magic signature.
uint32_t totalsize
 Total size of device tree.
uint32_t off_dt_struct
 Offset to structure block.
uint32_t off_dt_strings
 Offset to strings block.
uint32_t off_mem_rsvmap
 Offset to memory reservation block.
uint32_t version
 Version of this data structure.
uint32_t last_comp_version
 Lowest version to which this structure is compatible.
uint32_t boot_cpuid_phys
 Physical ID of the boot CPU.
uint32_t size_dt_strings
 Length of string block.
uint32_t size_dt_struct
 Length of structure block.
uint32_t len
 Data length.
uint32_t name_off
 Name offset.
struct fdt __attribute__

Detailed Description

Flattened Device Tree.

Definition in file fdt.h.


Define Documentation

#define FDT_MAGIC   0xd00dfeed

Magic signature.

Definition at line 41 of file fdt.h.

Referenced by register_fdt().

#define FDT_VERSION   16

Expected device tree version.

Definition at line 44 of file fdt.h.

Referenced by register_fdt().

#define FDT_BEGIN_NODE   0x00000001

Begin node token.

Definition at line 50 of file fdt.h.

Referenced by fdt_traverse().

#define FDT_END_NODE   0x00000002

End node token.

Definition at line 53 of file fdt.h.

Referenced by fdt_traverse().

#define FDT_PROP   0x00000003

Property token.

Definition at line 56 of file fdt.h.

Referenced by fdt_traverse().

#define FDT_NOP   0x00000004

NOP token.

Definition at line 67 of file fdt.h.

Referenced by fdt_traverse().

#define FDT_END   0x00000009

End of structure block.

Definition at line 70 of file fdt.h.

#define FDT_STRUCTURE_ALIGN   ( sizeof ( fdt_token_t ) )

Alignment of structure block.

Definition at line 73 of file fdt.h.

Referenced by fdt_traverse(), and register_fdt().


Typedef Documentation

Device tree token.

Definition at line 47 of file fdt.h.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
struct fdt_header __attribute__ ( (packed)  )
int fdt_path ( const char *  path,
unsigned int *  offset 
)

Find node by path.

Parameters:
pathNode path
offsetOffset to fill in
Return values:
rcReturn status code

Definition at line 241 of file fdt.c.

References DBGC2, fdt_child(), rc, and strchr().

Referenced by fdt_alias().

                                                        {
        char *tmp = ( ( char * ) path );
        char *del;
        int rc;

        /* Initialise offset */
        *offset = 0;

        /* Traverse tree one path segment at a time */
        while ( *tmp ) {

                /* Skip any leading '/' */
                while ( *tmp == '/' )
                        tmp++;

                /* Find next '/' delimiter and convert to NUL */
                del = strchr ( tmp, '/' );
                if ( del )
                        *del = '\0';

                /* Find child and restore delimiter */
                rc = fdt_child ( *offset, tmp, offset );
                if ( del )
                        *del = '/';
                if ( rc != 0 )
                        return rc;

                /* Move to next path component, if any */
                while ( *tmp && ( *tmp != '/' ) )
                        tmp++;
        }

        DBGC2 ( &fdt, "FDT found path \"%s\" at +%#04x\n", path, *offset );
        return 0;
}
int fdt_alias ( const char *  name,
unsigned int *  offset 
)

Find node by alias.

Parameters:
nameAlias name
offsetOffset to fill in
Return values:
rcReturn status code

Definition at line 284 of file fdt.c.

References DBGC, ENOENT, fdt_child(), fdt_path(), fdt_string(), NULL, and rc.

Referenced by smscusb_fdt_fetch_mac().

                                                         {
        const char *alias;
        int rc;

        /* Locate "/aliases" node */
        if ( ( rc = fdt_child ( 0, "aliases", offset ) ) != 0 )
                return rc;

        /* Locate alias property */
        if ( ( alias = fdt_string ( *offset, name ) ) == NULL )
                return -ENOENT;
        DBGC ( &fdt, "FDT alias \"%s\" is \"%s\"\n", name, alias );

        /* Locate aliased node */
        if ( ( rc = fdt_path ( alias, offset ) ) != 0 )
                return rc;

        return 0;
}
const char* fdt_string ( unsigned int  offset,
const char *  name 
)

Find string property.

Parameters:
offsetStarting node offset
nameProperty name
Return values:
stringString property, or NULL on error

Definition at line 352 of file fdt.c.

References fdt_descriptor::data, DBGC, fdt_property(), fdt_descriptor::len, NULL, rc, and strnlen().

Referenced by fdt_alias(), and register_fdt().

                                                                  {
        struct fdt_descriptor desc;
        int rc;

        /* Find property */
        if ( ( rc = fdt_property ( offset, name, &desc ) ) != 0 )
                return NULL;

        /* Check NUL termination */
        if ( strnlen ( desc.data, desc.len ) == desc.len ) {
                DBGC ( &fdt, "FDT unterminated string property \"%s\"\n",
                       name );
                return NULL;
        }

        return desc.data;
}
int fdt_mac ( unsigned int  offset,
struct net_device netdev 
)

Get MAC address from property.

Parameters:
offsetStarting node offset
netdevNetwork device
Return values:
rcReturn status code

Definition at line 377 of file fdt.c.

References fdt_descriptor::data, DBGC, DBGC_HDA, ERANGE, fdt_property(), net_device::hw_addr, ll_protocol::hw_addr_len, fdt_descriptor::len, len, net_device::ll_protocol, memcpy(), fdt_descriptor::name, and rc.

Referenced by smscusb_fdt_fetch_mac().

                                                               {
        struct fdt_descriptor desc;
        size_t len;
        int rc;

        /* Find applicable MAC address property */
        if ( ( ( rc = fdt_property ( offset, "mac-address", &desc ) ) != 0 ) &&
             ( ( rc = fdt_property ( offset, "local-mac-address",
                                     &desc ) ) != 0 ) ) {
                return rc;
        }

        /* Check length */
        len = netdev->ll_protocol->hw_addr_len;
        if ( len != desc.len ) {
                DBGC ( &fdt, "FDT malformed MAC address \"%s\":\n",
                       desc.name );
                DBGC_HDA ( &fdt, 0, desc.data, desc.len );
                return -ERANGE;
        }

        /* Fill in MAC address */
        memcpy ( netdev->hw_addr, desc.data, len );

        return 0;
}
int register_fdt ( const struct fdt_header hdr)

Register device tree.

Parameters:
fdtDevice tree header
Return values:
rcReturn status code

Definition at line 410 of file fdt.c.

References be32_to_cpu, cpu_to_be32, DBGC, DBGC_HDA, EINVAL, end, FDT_MAGIC, fdt_string(), FDT_STRUCTURE_ALIGN, FDT_VERSION, hdr, fdt::hdr, fdt_header::last_comp_version, fdt::len, fdt_header::magic, NULL, fdt_header::off_dt_strings, fdt_header::off_dt_struct, fdt::raw, fdt_header::size_dt_strings, fdt_header::size_dt_struct, fdt::strings, fdt::strings_len, fdt::structure, fdt::structure_len, fdt_header::totalsize, and fdt_header::version.

Referenced by efi_fdt_init().

                                                  {
        const uint8_t *end;

        /* Record device tree location */
        fdt.hdr = hdr;
        fdt.len = be32_to_cpu ( hdr->totalsize );
        DBGC ( &fdt, "FDT version %d at %p+%#04zx\n",
               be32_to_cpu ( hdr->version ), fdt.hdr, fdt.len );

        /* Check signature */
        if ( hdr->magic != cpu_to_be32 ( FDT_MAGIC ) ) {
                DBGC ( &fdt, "FDT has invalid magic value %#08x\n",
                       be32_to_cpu ( hdr->magic ) );
                goto err;
        }

        /* Check version */
        if ( hdr->last_comp_version != cpu_to_be32 ( FDT_VERSION ) ) {
                DBGC ( &fdt, "FDT unsupported version %d\n",
                       be32_to_cpu ( hdr->last_comp_version ) );
                goto err;
        }

        /* Record structure block location */
        fdt.structure = be32_to_cpu ( hdr->off_dt_struct );
        fdt.structure_len = be32_to_cpu ( hdr->size_dt_struct );
        DBGC ( &fdt, "FDT structure block at +[%#04x,%#04zx)\n",
               fdt.structure, ( fdt.structure + fdt.structure_len ) );
        if ( ( fdt.structure > fdt.len ) ||
             ( fdt.structure_len > ( fdt.len - fdt.structure ) ) ) {
                DBGC ( &fdt, "FDT structure block exceeds table\n" );
                goto err;
        }
        if ( ( fdt.structure | fdt.structure_len ) &
             ( FDT_STRUCTURE_ALIGN - 1 ) ) {
                DBGC ( &fdt, "FDT structure block is misaligned\n" );
                goto err;
        }

        /* Record strings block location */
        fdt.strings = be32_to_cpu ( hdr->off_dt_strings );
        fdt.strings_len = be32_to_cpu ( hdr->size_dt_strings );
        DBGC ( &fdt, "FDT strings block at +[%#04x,%#04zx)\n",
               fdt.strings, ( fdt.strings + fdt.strings_len ) );
        if ( ( fdt.strings > fdt.len ) ||
             ( fdt.strings_len > ( fdt.len - fdt.strings ) ) ) {
                DBGC ( &fdt, "FDT strings block exceeds table\n" );
                goto err;
        }

        /* Shrink strings block to ensure NUL termination safety */
        end = ( fdt.raw + fdt.strings + fdt.strings_len );
        for ( ; fdt.strings_len ; fdt.strings_len-- ) {
                if ( *(--end) == '\0' )
                        break;
        }
        if ( fdt.strings_len != be32_to_cpu ( hdr->size_dt_strings ) ) {
                DBGC ( &fdt, "FDT strings block shrunk to +[%#04x,%#04zx)\n",
                       fdt.strings, ( fdt.strings + fdt.strings_len ) );
        }

        /* Print model name (for debugging) */
        DBGC ( &fdt, "FDT model is \"%s\"\n", fdt_string ( 0, "model" ) );

        return 0;

 err:
        DBGC_HDA ( &fdt, 0, hdr, sizeof ( *hdr ) );
        fdt.hdr = NULL;
        return -EINVAL;
}

Variable Documentation

Total size of device tree.

Definition at line 42 of file fdt.h.

Offset to structure block.

Definition at line 44 of file fdt.h.

Offset to strings block.

Definition at line 46 of file fdt.h.

Offset to memory reservation block.

Definition at line 48 of file fdt.h.

Version of this data structure.

Definition at line 50 of file fdt.h.

Lowest version to which this structure is compatible.

Definition at line 52 of file fdt.h.

Physical ID of the boot CPU.

Definition at line 54 of file fdt.h.

Length of string block.

Definition at line 56 of file fdt.h.

Length of structure block.

Definition at line 58 of file fdt.h.

Data length.

Definition at line 66 of file fdt.h.

Name offset.

Definition at line 68 of file fdt.h.

Referenced by fdt_traverse().