Previous Next Contents

2. General

2.1 Resources

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.

2.2 Calling Conventions

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.

2.3 Device Handles

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.

2.4 Locating the function entry points

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.

2.5 Interrupt Handlers

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.

2.6 Error codes

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 


Previous Next Contents