#include <pci_device_base.hpp>


Public Types | |
| typedef SpaceT | config_space_type |
| The PCI configuration space type, this device was instantiated with. | |
Public Member Functions | |
| static_assert ((is_convertible< config_space_type &, pci_config_header64 & >::conforms),"SpaceT must be a descendant class of pci_config_header64") | |
| pci_device_base (machine_base &machine, const string &name) | |
| virtual const char * | name (void) const |
| Returns the device's name. | |
| virtual void | irq_moved (l4_irq_t from, l4_irq_t to) |
| Called whenever the IRQ management chooses to assign this device annother IRQ than the requested one. | |
| virtual l4_hva_t | map_mmio_region (int flags, l4_gpa_t base, l4_gpa_t size=1) |
| Stub implementation, which always returns an invalid value (0). | |
| virtual int | unmap_mmio_region (l4_gpa_t base, l4_gpa_t size=1) |
| Stub implementation, which always returns -L4_ENOTSUPP. | |
| virtual int | reset (void) |
| Resets the device's state back to defaults as when powering up the machine. | |
| virtual const pci_ioregion * | get_ioregion (const uint8_t region_num) const |
| Returns a device's I/O region by its index or NULL, if the index is invalid. | |
| virtual const search_result | search_ioregion (enum pci_ioregion::type type, l4_gpa_t base, l4_gpa_t size=1) const |
| Searchs an I/O region and returns it in a search_result struct. | |
| virtual const pci_config_header64 & | get_config_space (void) const |
| Returns a device's PCI configuration space. | |
| virtual l4_umword_t | read_config_space (pci_config_header16::offset_t offset, access_size access_size) |
| Emulates a device's PCI configuration space read access and returns the value that should have been read. | |
| virtual int | write_config_space (pci_config_header16::offset_t offset, l4_umword_t data, access_size access_size) |
| Emulates a device's PCI configuration space write access. | |
Static Public Member Functions | |
| static bool | is_valid_ioregion (const uint8_t region_num) |
| Returns whether an I/O region number is valid. | |
| static uint8_t | offset2region_num (const pci_config_header16::offset_t offset) |
| Converts a PCI configuration space offset to the corresponding I/O region number. | |
Static Public Attributes | |
| static const bool | VERBOSE_ALLOCATION = false |
| static const uint8_t | NUM_IOREGIONS = pci_config_header64::NUM_BASE_ADDRESSES + 1 |
| Number of I/O regions this PCI device implementation can handle. | |
| static const uint8_t | EXPANSION_ROM_SLOT = NUM_IOREGIONS - 1 |
| The last index used to store the expansion ROM I/O region. | |
Protected Member Functions | |
| virtual int | use_irq (irq_manager::irq_flags use=irq_manager::VIRTUAL, l4_irq_t requested_irq=irq_manager::NO_IRQ, l4_irq_t physical_irq=irq_manager::NO_IRQ, bool verbose=VERBOSE_ALLOCATION) |
| Allocate an IRQ for the specified usage. | |
| virtual int | free_irq (bool verbose=VERBOSE_ALLOCATION) |
| Free the (previously allocated) IRQ. | |
| virtual int | use_ioregion (enum pci_ioregion::type type, l4_gpa_t size, l4_hva_t virtual_base=0) |
| Requests to provide a (virtual) I/O region using an arbitrary free address register. | |
| virtual int | use_ioregion (uint8_t region_num, enum pci_ioregion::type type, l4_gpa_t size, l4_hva_t virtual_base=0) |
| Requests to provide a (virtual) I/O region using the specified address register. | |
| virtual int | ioregion_relocated (uint8_t region_num, l4_gpa_t old_base) |
| Called whenever the PCI configuration space write handler updates an address register. | |
Protected Attributes | |
| config_space_type | config_space |
| This device's (virtual) PCI configuration space. | |
| pci_ioregion | ioregions [NUM_IOREGIONS] |
| This device's current (virtual) I/O regions' states. | |
Private Member Functions | |
| int | write_address_register (pci_config_header16::offset_t offset, l4_gpa_t data, access_size access_size) |
Extends pci_device with a PCI configuration space along with some functions for common write accesses and the ability to manage I/O regions.
The following PCI configuration space registers are handled by pci_device_base (write accesses, read accesses do always work):
* * register offset size policy handled by * pci_device_base * ------------------------------------------------------------------------ * vendorID 0x00 2 ro yes * deviceID 0x02 2 ro yes * command 0x04 2 rw no * status 0x06 2 rw/c yes (always clears bits) * revisionID 0x08 1 ro yes * class_code.interface 0x09 1 ro yes * class_code.sub 0x0a 1 ro yes * class_code.base 0x0b 1 ro yes * cache_line_size 0x0c 1 rw no * master_latency_timer 0x0d 1 rw no * header_type 0x0e 1 ro yes * bist 0x0f 1 rw yes (always returns OK) * * base_address[0] 0x10 4 rw yes * base_address[1] 0x14 4 rw yes * base_address[2] 0x18 4 rw yes * base_address[3] 0x1c 4 rw yes * base_address[4] 0x20 4 rw yes * base_address[5] 0x24 4 rw yes * cardbus_CIS_pointer 0x28 4 ro yes * subsystem_vendorID 0x2c 2 ro yes * subsystem_deviceID 0x2e 2 ro yes * expansion_ROM_address 0x30 4 rw yes * capabilities_pointer 0x34 1 ro yes * interrupt_line 0x3c 1 rw yes * interrupt_pin 0x3d 1 ro yes * min_grant 0x3e 1 ro yes * max_latency 0x3f 1 ro yes *
| virtual void pci_device_base< SpaceT >::irq_moved | ( | l4_irq_t | from, | |
| l4_irq_t | to | |||
| ) | [inline, virtual] |
Called whenever the IRQ management chooses to assign this device annother IRQ than the requested one.
Updates the stored IRQ.
Reimplemented from device_base.
| l4_hva_t pci_device_base< SpaceT >::map_mmio_region | ( | int | flags, | |
| l4_gpa_t | base, | |||
| l4_gpa_t | size = 1 | |||
| ) | [inline, virtual] |
Stub implementation, which always returns an invalid value (0).
Implemented here as a dummy to avoid unnecessary overriding in descendant classes. This function is intended to be overridden.
Reimplemented from device_base.
Reimplemented in l4io_device.
References pci_ioregion::IOMEMORY, pci_device_base< SpaceT >::ioregions, pci_device::search_result::is_valid(), pci_device::search_result::region, pci_device::search_result::region_num, and pci_device_base< SpaceT >::search_ioregion().
| int pci_device_base< SpaceT >::unmap_mmio_region | ( | l4_gpa_t | base, | |
| l4_gpa_t | size = 1 | |||
| ) | [inline, virtual] |
Stub implementation, which always returns -L4_ENOTSUPP.
Implemented here as a dummy to avoid unnecessary overriding in descendant classes. This function is intended to be overridden.
Reimplemented from device_base.
Reimplemented in l4io_device.
References pci_ioregion::IOMEMORY, pci_device_base< SpaceT >::ioregions, pci_device::search_result::is_valid(), pci_device::search_result::region, pci_device::search_result::region_num, and pci_device_base< SpaceT >::search_ioregion().
| const pci_device::search_result pci_device_base< SpaceT >::search_ioregion | ( | enum pci_ioregion::type | type, | |
| l4_gpa_t | base, | |||
| l4_gpa_t | size = 1 | |||
| ) | const [inline, virtual] |
Searchs an I/O region and returns it in a search_result struct.
base & size are I/O space addresses or guest physical addresses depending on the type to search for.
Implements pci_device.
References detail::resource_region< AddressT >::contains(), pci_device_base< SpaceT >::ioregions, pci_ioregion::is(), pci_ioregion::is_used(), and pci_device_base< SpaceT >::NUM_IOREGIONS.
Referenced by pci_device_base< SpaceT >::map_mmio_region(), and pci_device_base< SpaceT >::unmap_mmio_region().
| virtual l4_umword_t pci_device_base< SpaceT >::read_config_space | ( | pci_config_header16::offset_t | offset, | |
| access_size | access_size | |||
| ) | [inline, virtual] |
Emulates a device's PCI configuration space read access and returns the value that should have been read.
This function is intended to be overridden.
Implements pci_device.
Reimplemented in l4io_device.
| int pci_device_base< SpaceT >::write_config_space | ( | pci_config_header16::offset_t | offset, | |
| l4_umword_t | data, | |||
| access_size | access_size | |||
| ) | [inline, virtual] |
Emulates a device's PCI configuration space write access.
This function is intended to be overridden.
Implements pci_device.
Reimplemented in dummy_device, l4io_device, and piix_ide.
References pci_device_base< SpaceT >::config_space.
| virtual int pci_device_base< SpaceT >::use_irq | ( | irq_manager::irq_flags | use = irq_manager::VIRTUAL, |
|
| l4_irq_t | requested_irq = irq_manager::NO_IRQ, |
|||
| l4_irq_t | physical_irq = irq_manager::NO_IRQ, |
|||
| bool | verbose = VERBOSE_ALLOCATION | |||
| ) | [inline, protected, virtual] |
Allocate an IRQ for the specified usage.
The virtual IRQ is returned and additionally stored as attribute irq. Negative values denote error conditions.
Reimplemented from device_base.
| int pci_device_base< SpaceT >::use_ioregion | ( | enum pci_ioregion::type | type, | |
| l4_gpa_t | size, | |||
| l4_hva_t | virtual_base = 0 | |||
| ) | [inline, protected, virtual] |
Requests to provide a (virtual) I/O region using an arbitrary free address register.
virtual_base is optional, since only required for memory regions.
References pci_device_base< SpaceT >::EXPANSION_ROM_SLOT, pci_device_base< SpaceT >::ioregions, pci_device_base< SpaceT >::name(), pci_device_base< SpaceT >::NUM_IOREGIONS, and pci_ioregion::ROM.
| int pci_device_base< SpaceT >::use_ioregion | ( | uint8_t | region_num, | |
| enum pci_ioregion::type | type, | |||
| l4_gpa_t | size, | |||
| l4_hva_t | virtual_base = 0 | |||
| ) | [inline, protected, virtual] |
Requests to provide a (virtual) I/O region using the specified address register.
virtual_base is optional, since only required for memory regions.
References pci_device_base< SpaceT >::config_space, pci_device_base< SpaceT >::EXPANSION_ROM_SLOT, pci_device_base< SpaceT >::ioregions, pci_ioregion::is_used(), pci_device_base< SpaceT >::name(), pci_device_base< SpaceT >::NUM_IOREGIONS, and pci_ioregion::ROM.
| int pci_device_base< SpaceT >::ioregion_relocated | ( | uint8_t | region_num, | |
| l4_gpa_t | old_base | |||
| ) | [inline, protected, virtual] |
Called whenever the PCI configuration space write handler updates an address register.
The corresponding pci_ioregion has already been updated. Only resources may be freed/(re-)requested to respond to the new location's accesses. The default implementation simply unregisters and registers itself.
Reimplemented in l4io_device, and piix_ide.
References detail::resource_region< AddressT >::base, device_base::free_iomemory(), device_base::free_iospace(), pci_device_base< SpaceT >::ioregions, pci_ioregion::is_iomemory(), pci_ioregion::is_iospace(), pci_device_base< SpaceT >::name(), pci_ioregion::print_short(), detail::resource_region< AddressT >::size, device_base::use_iomemory(), and device_base::use_iospace().
| static bool pci_device_base< SpaceT >::is_valid_ioregion | ( | const uint8_t | region_num | ) | [inline, static] |
Returns whether an I/O region number is valid.
That is it ranges from 0 to 5 (base address registers) and 6 (expansion ROM).
Referenced by pci_device_base< dummy_device_config_space >::get_ioregion().
| static uint8_t pci_device_base< SpaceT >::offset2region_num | ( | const pci_config_header16::offset_t | offset | ) | [inline, static] |
Converts a PCI configuration space offset to the corresponding I/O region number.
Returns an undefined value, if the offset is not an address register.