All cards get their resources (memory and IO areas, interrupts) assigned and set by the system. Drivers and other programs may not modify these settings.
The PCI BIOS functions use the 680x0 CPU registers to pass arguments and to return status.
The routines may modify only those registers which are used to pass parameters or to return information in as specified for the specific function, plus the status register.
The routines must be called in Supervisor mode, and the available stack must be at least 1024 bytes.
The functions may disable interrupts during execution, but will return with the interrupts in the same state as when they were called.
All functions return an error code in D0 if an error occurred.
Every device on a PCI (or ISA) card is specified by using a device handle. The device handle is used as an opaque data type by the driver - no assumptions are to be made about the meaning of bits in this value. device handles are positive 32-bit integers - negative values are used for error codes for functions which return device handles.
The BIOS installs a "_PCI" cookie which points to the following structure of entry points to the individual functions:
dc.l 0 ; $00 pointer to sub cookie jar (for
; compatibility) or 0 if not present
dc.l $00010000 ; $04 version number of this structure
dc.l find_pci_device ; $08
dc.l find_pci_classcode ; $0C
dc.l read_config_byte
dc.l read_config_word
dc.l read_config_longword
dc.l fast_read_config_byte
dc.l fast_read_config_word
dc.l fast_read_config_longword
dc.l write_config_byte
dc.l write_config_word
dc.l write_config_longword
dc.l hook_interrupt
dc.l unhook_interrupt
dc.l special_cycle
dc.l get_routing
dc.l set_interrupt
dc.l get_resource
dc.l get_card_used
dc.l set_card_used
dc.l read_mem_byte
dc.l read_mem_word
dc.l read_mem_longword
dc.l fast_read_mem_byte
dc.l fast_read_mem_word
dc.l fast_read_mem_longword
dc.l write_mem_byte
dc.l write_mem_word
dc.l write_mem_longword
dc.l read_io_byte
dc.l read_io_word
dc.l read_io_longword
dc.l fast_read_io_byte
dc.l fast_read_io_word
dc.l fast_read_io_longword
dc.l write_io_byte
dc.l write_io_word
dc.l write_io_longword
dc.l get_machine_id
dc.l get_pagesize
dc.l virt_to_bus
dc.l bus_to_virt
dc.l virt_to_phys
dc.l phys_to_virt
The high word of the version number marks major changes which affect compatibility with older programs (this should be avoided). The minor version number marks changes in the structure which only add function entries or fix bugs in existing ones, but which do not cause incompatibilities with earlier revisions.
This structure, and the functions it points to, should be in ROM or some other place which is safe from being overwritten (eg. above phystop), if it is desirable that alternative Operating Systems can use the functions.
The circumstances for calling the functions may need to be specified further for this case.
For each hardware interrupt, there is a chain of interrupt handlers, as multiple cards can share the same interrupt.
By specifying a device handle, a driver can hook into the chain that handles this interrupt without knowing which one it actually is.
When an interrupt occurs, the driver is called with a value in A0 which is set by the driver when hooking into the interrupt. The meaning of this parameter depends on the driver - it can be a device handle, a pointer to some driver-internal data structure, etc..
interrupt_handler:
Input:
A0.L value as passed to hook_interrupt
D0.L BIOS internal data
Output:
D0.L bit 0 set if the interrupt was from this card. D0 unmodified
otherwise.
The interrupt handler must not modify any register except D0 (only as specified) and A0. If the interrupt was caused by the card which this handler is monitoring, it must make sure that the card returns the interrupt line to inactive state, and return with D0.0 set.
If the card did not cause the interrupt, the driver may not modify D0.
The interrupt handler returns by using an RTS instruction.
The following error codes can be returned by the PCI BIOS functions:
$00000000 PCI_SUCCESSFUL
$FFFFFFFE PCI_FUNC_NOT_SUPPORTED
$FFFFFFFD PCI_BAD_VENDOR_ID
$FFFFFFFC PCI_DEVICE_NOT_FOUND
$FFFFFFFB PCI_BAD_REGISTER_NUMBER
$FFFFFFFA PCI_SET_FAILED
$FFFFFFF9 PCI_BUFFER_TOO_SMALL
$FFFFFFF8 PCI_GENERAL_ERROR
$FFFFFFF7 PCI_BAD_HANDLE
The following error codes are not returned by PCI BIOS functions directly, but are reserved for use by a library which uses these routines.
$FFFFF001 PCI_BIOS_NOT_INSTALLED
$FFFFF000 PCI_BIOS_WRONG_VERSION