Building the hwinfo section

Use the hwi_alloc_tag() and hwi_alloc_item() functions to add tags and items to the hwinfo section of the system page.

To build an item:

  1. Call hwi_alloc_item() to build a top-level item (an item in which the owner field will be set to HWI_NULL_OFF).
  2. Use hwi_alloc_tag() to add whatever other tag structures you want in the item.
  3. Call hwi_alloc_item() again to start a new item. This item can be either another top-level item, or a child of the first item you created.

You can build the items in any order you wish, provided that the parent is built before the child.

When building a child item, if you remembered its owner only in a variable, or you know only its item name, you can find the correct value of the owner argument by calling the hwi_find_item() function.

Default items and tags

Before main() is invoked in the startup program, the library adds some initial entries to serve as a basis for later items.

HWI_TAG_INFO() is a macro defined in the startup.h header and expands out to the three name, size, align parameters for hwi_alloc_tag() and hwi_alloc_item() based on some clever macro names.

void
hwi_default() {
    hwi_tag     *tag;
    hwi_tag     *tag;

    hwi_alloc_item(HWI_TAG_INFO(group), HWI_ITEM_ROOT_AS,
                   HWI_NULL_OFF);
    tag = hwi_alloc_item(HWI_TAG_INFO(group), HWI_ITEM_ROOT_HW,
                         HWI_NULL_OFF);

    hwi_alloc_item(HWI_TAG_INFO(bus), HWI_ITEM_BUS_UNKNOWN,
                   hwi_tag2off(tag));

    loc = hwi_find_item(HWI_NULL_OFF, HWI_ITEM_ROOT_AS, NULL);

    tag = hwi_alloc_item(HWI_TAG_INFO(addrspace),
                         HWI_ITEM_AS_MEMORY, loc);
    tag->addrspace.base = 0;
    tag->addrspace.len  = (uint64_t)1 << 32;
    #ifndef __X86__
       loc = hwi_tag2off(tag);
    #endif
    tag = hwi_alloc_item(HWI_TAG_INFO(addrspace), HWI_ITEM_AS_IO,
                         loc);
    tag->addrspace.base = 0;
    #ifdef __X86__
        tag->addrspace.len  = (uint64_t)1 << 16;
    #else
        tag->addrspace.len  = (uint64_t)1 << 32;
    #endif
}

Other useful hwi_*() functions

The following functions are defined in the C library, since they are useful, not just to startup code, but also to code processing the hwinfo section of the system page.

hwi_tag2off()
unsigned hwi_tag2off(void *);

Given a pointer to the start of a tag, return the offset, in bytes, from the beginning of the start of the hwinfo section.

hwi_off2tag()
void *hwi_off2tag(unsigned);

Given an offset, in bytes, from the start of the hwinfo section, return a pointer to the start of the tag.

hwi_find_tag()
unsigned hwi_find_tag(unsigned start, int curr_item, const char *tagname);

Find the tag named tagname. The start parameter works the same as the one in hwi_find_item(). If curr_item is nonzero, the search stops at the end of the current item (whatever item the start parameter points into). If curr_item is zero, the search continues until the end of the section. If the tag isn't found, HWI_NULL_OFF is returned.

hwi_next_item()
unsigned hwi_next_item( unsigned off );

Get the offset of the next item after the given offset from the start of the hwinfo section.

hwi_next_tag()
unsigned hwi_next_tag( unsigned off, int curr_item );

Get the offset of the next tag after the given offset from the start of the hwinfo section. As it is for hwi_find_tag(), the curr_item restricts the search to the current item.

For more information about these functions, see the QNX Neutrino C Library Reference.