Previous Next Contents

3. PCI BIOS functions

3.1 Find PCI device

This function returns a device handle for a device that matches the given device and vendor ID.

A driver can query multiple devices with the same device and vendor ID by starting with index 0 and calling this function until PCI_DEVICE_NOT_FOUND is returned.


find_pci_device:
Input:
  D0.L      Device ID in bits 31..16 (0 - $FFFF), 
            Vendor ID in bits 15..0  (0 - $FFFE)
  D1.W      Index (0 - # of cards with these IDs)
Output:
  D0.L      device handle or error code

As a special case, Vendor ID $FFFF can be used to query all cards found in the system, the specified device ID is ignored in this case.

3.2 Find PCI class code

This function returns a device handle for a device that matches the given class code.

A driver can query multiple devices with the same class code by starting with index 0 and calling this function until PCI_DEVICE_NOT_FOUND is returned.


find_pci_classcode:
Input:
  D0.L      class code in bits 23..0:
              Base class in bit 23..16 (0 - $FF),
              Sub  class in bit 15..8  (0 - $FF),
              Prog. If.  in bit  7..0  (0)
            mask in bits 26..24:
              bit 26: if 0 = compare base class, else ignore it
              bit 25: if 0 = compare sub class, else ignore it
              bit 24: if 0 = compare prog. if, else ignore it
  D1.W      Index (0 - # of cards with these IDs)
Output:
  D0.L      device handle or error code

3.3 Read Configuration {Byte|Word|Longword}

These three functions read data from the PCI configuration space of a given card.

The data is in little endian format, as described in the PCI specification.


read_config_byte:
read_config_word:
read_config_longword:
Input:
  D0.L      device handle
  A0.L      pointer to space for read data
  D1.B      Register number (0,1,2,... for Byte access)
  D1.B      Register number (0,2,4,... for Word access)
  D1.B      Register number (0,4,8,... for Longword access)
Output:
  D0.L      error code
            read data at buffer pointed to by A0

3.4 Read Configuration {Byte|Word|Longword} FAST

These three functions read data from the PCI configuration space of a given card. They do only minimal error checking and are meant to be used only when access to configuration space is needed in interrupt handlers.

The data is in little endian format, as described in the PCI specification.


fast_read_config_byte:
fast_read_config_word:
fast_read_config_longword:
Input:
  D0.L      device handle
  D1.B      Register number (0,1,2,... for Byte access)
  D1.B      Register number (0,2,4,... for Word access)
  D1.B      Register number (0,4,8,... for Longword access)
Output:
  D0        read data (8, 16 or 32 bits)
  SR:       carry flag may be set if an error occurred 
            (implementation dependent)

3.5 Write Configuration {Byte|Word|Longword}

These three functions write data to the PCI configuration space of a given card.

The data is in little endian format, as described in the PCI specification.


write_config_byte:
write_config_word:
write_config_longword:
Input:
  D0.L      device handle
  D1.B      Register number (0,1,2,... for Byte access)
  D1.B      Register number (0,2,4,... for Word access)
  D1.B      Register number (0,4,8,... for Longword access)
  D2        data to write (8/16/32 bits)
Output:
  D0.L      error code

3.6 Hook Interrupt Vector

This function hooks the driver into the interrupt chain to which a specific interrupt on the given card is routed. The interrupt is enabled on the system level, however, it is the drivers responsibility to enable the interrupt on the card as needed.

The driver should first hook into the interrupt chain, and then enable the interrupt on the card, in order not to cause spurious interrupts.


hook_interrupt:
Input:
  D0.L      device handle
  A0.L      pointer to interrupt handler
  A1.L      parameter for interrupt handler.
Output:
  D0.L      error code

The parameter (from A1) is passed to the interrupt handler unmodified - its meaning is totally driver dependent.

3.7 Unhook Interrupt Vector

This function removes the driver from the interrupt chain to which a specific interrupt on the given card is routed. The driver must turn off interrupt generation on the card before calling this function.


unhook_interrupt:
Input:
  D0.L      device handle 
Output:
  D0.L      error code

3.8 Generate Special Cycle

This function generates a special cycle on the PCI bus.


special_cycle:
Input:
  D0.B      bus number
  D1.L      special cycle data
Output:
  D0.L      error code

3.9 Get Interrupt Routing Options

to be defined. Not for use by device drivers.

3.10 Set Hardware Interrupt

to be defined. Not for use by device drivers.

3.11 Get Resource Data

This function returns data about the resources which a device uses. The returned structure may not be modified by the driver.

The driver can then use these information and directly access the device if he knows the type of byte ordering, or it can use the system routines (read|write_mem|io...) which handle this transparently.

The function returns a pointer to the first resource descriptor for this device. The driver can get the next descriptor by adding the length field to the address of the current descriptor.

The descriptors are in the same order as the base address registers in the PCI configuration space of the device.

If bit 15 of the flags is set, there is no next descriptor.

A device can have multiple resources of the same type.


get_resource:
Input:
  D0.L      device handle 
Output:
  D0.L      pointer to array of resource descriptors or error code

The resource descriptors look like this:


struct resource_descriptor:
  next      DS.W 1    ; length of this structure in bytes
                      ; Use this to get next descriptor
  flags     DS.W 1    ; type of resource and misc flags
  start     DS.L 1    ; start address of resource in PCI address space
  length    DS.L 1    ; length of resource
  offset    DS.L 1    ; offset from PCI to physical CPU address
  dmaoffset DS.L 1    ; offset for DMA-Memory transfers.
  private   DS.B n    ; private data, used only by the PCI BIOS. Do not touch.

The flags field is bit-coded as follows:


  RSC_IO      = $4000 ; This is an IO area (Memory area if bit is clear)
  RSC_LAST    = $8000 ; last resource for this device

  FLG_8BIT    = $0100 ; 8-bit accesses are supported
  FLG_16BIT   = $0200 ; 16-bit accesses are supported
  FLG_32BIT   = $0400 ; 32-bit accesses are supported
  FLG_ENDMASK = $000F ; Bit 0..3 specify which byte ordering is used:
                        0 = Motorola.
                        1 = Intel, address-swapped
                        2 = Intel, lane-swapped
                        3..14 = reserved
                        15 = unknown. Access card only via BIOS functions.

The start field contains the start address on the PCI bus of the resource. If the resource is not directly accessible, the start address is 0. The length field contains its length.

The offset field contains the offset from physical CPU to PCI address for the resource - ie. the value that must be added to the PCI address to get the physical address in CPU address space.

The dmaoffset gives the offset that must be added to a PCI address to get the physical address in CPU address space when doing DMA transfers.

What are all these byte orders?

Motorola byte ordering (big endian) is what you would expect on a 680x0 system: 8/16/32 bit accesses work as expected.

When address-swapped Intel (little endian) byte ordering is used, 32 bit accesses work without modifications. On 16 bit accesses, the address needs to be XOR'd with a value of 2, on 8-bit accesses the address is XOR'd with a value of 3. The data read or written is in correct format.

When lane-swapped Intel (little endian) byte ordering is used, the address needs no modifications. 8-bit accesses work normal, on 16 and 32 bit accesses the read or written data needs to be swapped (ror.w #8,d0 for 16 bit, ror.w d0:swap d0:ror.w d0 for 32 bit).

3.12 Memory Read / Memory Write

These functions read or write 8, 16 or 32-bit values from a memory region and take care of the byte ordering - ie. the data and address are converted as if Motorola byte ordering was in use.

A driver can use these functions for access to registers and small buffers. For larger amounts of data, the driver can choose to use his own copy routines, provided it knows the byte order in use.


read_mem_byte:
read_mem_word:
read_mem_longword:
Input:
  D0.L      device handle
  D1.L      address to access (in PCI memory address space)
  A0.L      pointer to data in memory
Output:
  D0.L      error code
  read data at buffer pointed to by A0


write_mem_byte:
write_mem_word:
write_mem_longword:
Input:
  D0.L      device handle
  D1.L      address to access (in PCI memory address space)
  D2        data to write (8/16/32 bits)
Output:
  D0.L      error code

3.13 IO Read / IO Write

These functions read or write 8, 16 or 32-bit values from a IO region and take care of the byte ordering - ie. the data and address are converted as if Motorola byte ordering was in use.


read_io_byte:
read_io_word:
read_io_longword:
Input:
  D0.L      device handle
  D1.L      address to access (in PCI IO address space)
  A0.L      pointer to data in memory
Output:
  D0.L      error code


write_io_byte:
write_io_word:
write_io_longword:
Input:
  D0.L      device handle
  D1.L      address to access (in PCI IO address space)
  D2        data to write (8/16/32 bits)
Output:
  D0.L      error code

3.14 FAST Memory/IO Read

These functions are alternatives for the normal memory/io read functions. They return the read value in D0 and return no error code, which makes them easier to use in C.


fast_read_mem_byte:
fast_read_mem_word:
fast_read_mem_longword:
fast_read_io_byte:
fast_read_io_word:
fast_read_io_longword:
Input:
  D0.L      device handle
  D1.L      address to access (in PCI IO address space)
Output:
  D0.L      read data

3.15 Example


Previous Next Contents