
Applied Micro Circuits Corporation
6195 Lusk Blvd., San Diego, CA 92121 (619) 450-9333
15-58
S5933
PCI CONTROLLER
Code Segment 3 demonstrates the use of the PCI
Base Address registers.
dword base_address;
/* AMCC Operation Registers base address */
word base_address_segment; /* Bits 20-4 of base address */
word base_address_offset;
/* Bits 3-0 of base address */
char far *ptr;
/* Obtain base address first */
/* Parse out segment and offset of base address */
base_address_segment = base_address >> 4;
base_address_offset = base_address & 0xf;
/* Make far pointer */
ptr = MK_FP(base_address_segment, base_address_offset);
Code Segment 4
byte bus;
/* Bus number of device */
byte device_and_function;
/* Device Number bits 7-3, Function bits 2-0 */
dword base_address;
/* Base Address */
/* Must Determine bus and device_and_function of device first */
if (read_configuration_dword(bus, device_and_function,
PCI_CS_BASE_ADDRESS_1, &base_address)) {
/* Determine if Memory Address */
if (base_address & 0x01) {
/* Mask off bits 3-0 */
base_address &= 0xF0;
printf(“Memory Base Address = %x\n”, base_address);
}
else {
/* Mask off bits 1-0 */
base_address &= 0xFC;
printf(“I/O Base Address = %x\n”, base_address);
}
Code Segment 3
This program fragment reads a double-word from the
Base Address 0 configuration space register. Bit 0 of
the returned value is then examined to determine if
the base address describes a memory or an I/O
space and either 2 or 4 bits masked off to determine
the actual base address.
The memory Base Address is a 32-bit address in
physical memory. To use this address from a real-
mode program under DOS, it must be converted to a
segment:offset format in order to access the memory
via a C pointer. This method will only work if the
memory is mapped below the 1-megabyte memory-
addressing limit of real-mode programs (20 bits). To
convert the base address to a segment:offset pointer,
one needs to extract bits 0-3 as the offset and shift-
right the upper bits four places to obtain the segment.
The program fragment performs this conversion.
(See Code Segment 4.)
First, the program fragment defines a far pointer to a
structure. The actual definition of the structure will
depend upon the particular application. Next, it ob-
tains the segment and offset from the base address.
Once this is determined, one can use the MK_FP
macro to convert the segment:offset to a far pointer.