Subject: Re: access to external proms for PCI
To: Johan Danielsson <joda@pdc.kth.se>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: tech-kern
Date: 12/13/2005 09:28:17
Johan Danielsson wrote:

>FWIW, there's a CardBus function to map EXROM already. Whatever you
>decide to do should probably be synced with that (as they are
>~identical).
>
>/Johan
>  
>
Thanks for the pointer.

It looks like CardBus does this differently -- it maps each ROM up into
memory space, and copies them out, then parses them into separate
structures.   This is all done at initialization time.

I can certainly follow the same code path, but it would mean modifying
the common PCI configuration layer to have this logic, and then I'd have
to add some storage for the ROM data.

Strangely though, I can't see anywhere where it does anything with the
results.

I'm inclined to seperate this functionality, though.  I think it should
be possible to get the entire expansion rom, unparsed, so that callers
can examine it for themselves.  Then having a routine to parse the
resultant image would be nice.

Therefore, I propose this new API:

/* determine the size of PCI expansion ROM */
size_t pci_exrom_size(pci_chipset_tag_t, pcitag_t);

/* copy raw expansion rom contents to kernel buffer */
boolean_t pci_exrom_copy(pci_chipset_tag_t, pcitag_t, size_t offset,
size_t cnt, void *dest);

#define PCI_EXROM_CODE_X86   0
#define PCI_EXROM_CODE_OBP   1
#define PCI_EXROM_CODE_HPPA  2

struct pci_exrom {
    SIMPLEQ_ENTRY(pci_exrom)   next;
    uint16_t                   data_offset;
    uint16_t                   code_offset;

    /* these are parsed details from the data section */
    pci_vendor_id_t            vendor;
    pci_product_id_t           product;
    uint32_t                   class_code;
    size_t                     image_len;
    uint8_t                    code_type;
    uint16_t                   vpd_offset; /* removed in PCI 2.2 */
    uint16_t                   revision;   /* code revision level */
};

struct pci_exrom *pci_exrom_parse(void *image, size_t size);

I will then implement pci_exrom_parse and pci_exrom_size in the PCI MI
layer.  (The exrom_size routine can just use standard BAR writing
techniques to determine the size, and restore the EXROM BAR when it is
done.)  The pci_exrom_copy() routine can be left to the MD code, and
lazy implemented as already noted.

These routines then also become applicable for CardBus.

Initially I won't disturb the CardBus implementation, but I'd be happy
to submit patches to unify the code, assuming no one else objects.

-- 
Garrett D'Amore                          http://www.tadpolecomputer.com/
Sr. Staff Engineer          Extending the Power of 64-bit UNIX Computing
Tadpole Computer, Inc.                             Phone: (951) 325-2134