Pci irq table error

pci irq table error

PCI Interrupt Request(IRQ) Error. Thread starter regan; Start date Sep PCI IRQ routing table error {EE} what does this mean and how can i fix. Waiting time: 60 Seconds, Instant ; Site advertising: American, PCI ; How long to keep files: Interface, Bios ; Maximum file upload size: Tables, Slots. The PCIe slot works fine for my video card. I have tried clearing the CMOS and retring the flash but to no availe. There is no options in the.

Pci irq table error - realize

As we explained earlier, most exceptions are handled simply by sending a Unix signal to the process that caused the exception. The action to be taken is thus deferred until the process receives the signal; as a result, the kernel is able to process the exception quickly.

This approach does not hold for interrupts, because they frequently arrive long after the process to which they are related (for instance, a process that requested a data transfer) has been suspended and a completely unrelated process is running. So it would make no sense to send a Unix signal to the current process.

Interrupt handling depends on the type of interrupt. For our purposes, we’ll distinguish three main classes of interrupts:

I/O interrupts

An I/O device requires attention; the corresponding interrupt handler must query the device to determine the proper course of action. We cover this type of interrupt in the later section "I/O Interrupt Handling.”

Timer interrupts

Some timer, either a local APIC timer or an external timer, has issued an interrupt; this kind of interrupt tells the kernel that a fixed-time interval has elapsed. These interrupts are handled mostly as I/O interrupts; we discuss the peculiar characteristics of timer interrupts in Chapter 6.

Interprocessor interrupts

A CPU issued an interrupt to another CPU of a multiprocessor system. We cover such interrupts in the later section "Interprocessor Interrupt Handling.”

In general, an I/O interrupt handler must be flexible enough to service several devices at the same time. In the PCI bus architecture, for instance, several devices may share the same IRQ line. This means that the interrupt vector alone does not tell the whole story. In the example shown in Table , the same vector 43 is assigned to the USB port and to the sound card. However, some hardware devices found in older PC architectures (such as ISA) do not reliably operate if their IRQ line is shared with other devices.

Interrupt handler flexibility is achieved in two distinct ways, as discussed in the following list.

IRQ sharing

The interrupt handler executes several interrupt service routines (ISRs). Each ISR is a function related to a single device sharing the IRQ line. Because it is not possible to know in advance which particular device issued the IRQ, each ISR is executed to verify whether its device needs attention; if so, the ISR performs all the operations that need to be executed when the device raises an interrupt.

IRQ dynamic allocation

An IRQ line is associated with a device driver at the last possible moment; for instance, the IRQ line of the floppy device is allocated only when a user accesses the floppy disk device. In this way, the same IRQ vector may be used by several hardware devices even if they cannot share the IRQ line; of course, the hardware devices cannot be used at the same time. (See the discussion at the end of this section.)

Not all actions to be performed when an interrupt occurs have the same urgency. In fact, the interrupt handler itself is not a suitable place for all kind of actions. Long noncritical operations should be deferred, because while an interrupt handler is running, the signals on the corresponding IRQ line are temporarily ignored. Most important, the process on behalf of which an interrupt handler is executed must always stay in the state, or a system freeze can occur. Therefore, interrupt handlers cannot perform any blocking procedure such as an I/O disk operation. Linux divides the actions to be performed following an interrupt into three classes:

Critical

Actions such as acknowledging an interrupt to the PIC, reprogramming the PIC or the device controller, or updating data structures accessed by both the device and the processor. These can be executed quickly and are critical, because they must be performed as soon as possible. Critical actions are executed within the interrupt handler immediately, with maskable interrupts disabled.

Noncritical

Actions such as updating data structures that are accessed only by the processor (for instance, reading the scan code after a keyboard key has been pushed). These actions can also finish quickly, so they are executed by the interrupt handler immediately, with the interrupts enabled.

Noncritical deferrable

Actions such as copying a buffer’s contents into the address space of a process (for instance, sending the keyboard line buffer to the terminal handler process). These may be delayed for a long time interval without affecting the kernel operations; the interested process will just keep waiting for the data. Noncritical deferrable actions are performed by means of separate functions that are discussed in the later section "Softirqs and Tasklets.”

Regardless of the kind of circuit that caused the interrupt, all I/O interrupt handlers perform the same four basic actions:

  1. Save the IRQ value and the register’s contents on the Kernel Mode stack.

  2. Send an acknowledgment to the PIC that is servicing the IRQ line, thus allowing it to issue further interrupts.

  3. Execute the interrupt service routines (ISRs) associated with all the devices that share the IRQ.

  4. Terminate by jumping to the address.

Several descriptors are needed to represent both the state of the IRQ lines and the functions to be executed when an interrupt occurs. Figure represents in a schematic way the hardware circuits and the software functions used to handle an interrupt. These functions are discussed in the following sections.

As illustrated in Table , physical IRQs may be assigned any vector in the range However, Linux uses vector to implement system calls.

The IBM-compatible PC architecture requires that some devices be statically connected to specific IRQ lines. In particular:

  • The interval timer device must be connected to the IRQ 0 line (see Chapter 6).

  • The slave A PIC must be connected to the IRQ 2 line (although more advanced PICs are now being used, Linux still supports A-style PICs).

    Figure  I/O interrupt handling

  • The external mathematical coprocessor must be connected to the IRQ 13 line (although recent 80 × 86 processors no longer use such a device, Linux continues to support the hardy model).

  • In general, an I/O device can be connected to a limited number of IRQ lines. (As a matter of fact, when playing with an old PC where IRQ sharing is not possible, you might not succeed in installing a new card because of IRQ conflicts with other already present hardware devices.)

Table  Interrupt vectors in Linux

Vector range

Use

0–19 -

Nonmaskable interrupts and exceptions

20–31 -

Intel-reserved

32– -

External interrupts (IRQs)

Programmed exception for system calls (see Chapter 10)

– -

External interrupts (IRQs)

Local APIC timer interrupt (see Chapter 6)

()

Local APIC thermal interrupt (introduced in the Pentium 4 models)

– -

Reserved by Linux for future use

– -

Interprocessor interrupts (see the section "Interprocessor Interrupt Handling" later in this chapter)

()

Local APIC error interrupt (generated when the local APIC detects an erroneous condition)

()

Local APIC spurious interrupt (generated if the CPU masks an interrupt while the hardware device raises it)

There are three ways to select a line for an IRQ-configurable device:

  • By setting hardware jumpers (only on very old device cards).

  • By a utility program shipped with the device and executed when installing it. Such a program may either ask the user to select an available IRQ number or probe the system to determine an available number by itself.

  • By a hardware protocol executed at system startup. Peripheral devices declare which interrupt lines they are ready to use; the final values are then negotiated to reduce conflicts as much as possible. Once this is done, each interrupt handler can read the assigned IRQ by using a function that accesses some I/O ports of the device. For instance, drivers for devices that comply with the Peripheral Component Interconnect (PCI) standard use a group of functions such as to access the device configuration space.

Table shows a fairly arbitrary arrangement of devices and IRQs, such as those that might be found on one particular PC.

Table  An example of IRQ assignment to I/O devices

IRQ

INT

Hardware device

0

32

Timer

1

33

Keyboard

2

34

PIC cascading

3

35

Second serial port

4

36

First serial port

6

38

Floppy disk

8

40

System clock

10

42

Network interface

11

43

USB port, sound card

12

44

PS/2 mouse

13

45

Mathematical coprocessor

14

46

EIDE disk controller’s first chain

15

47

EIDE disk controller’s second chain

The kernel must discover which I/O device corresponds to the IRQ number before enabling interrupts. Otherwise, for example, how could the kernel handle a signal from a SCSI disk without knowing which vector corresponds to the device? The correspondence is established while initializing each device driver (see Chapter 13).

As always, when discussing complicated operations involving state transitions, it helps to understand first where key data is stored. Thus, this section explains the data structures that support interrupt handling and how they are laid out in various descriptors. Figure illustrates schematically the relationships between the main descriptors that represent the state of the IRQ lines. (The figure does not illustrate the data structures needed to handle softirqs and tasklets; they are discussed later in this chapter.)

Figure  IRQ descriptors

Every interrupt vector has its own descriptor, whose fields are listed in Table All such descriptors are grouped together in the array.

Table  The irq_desc_t descriptor

Field

Description

Points to the PIC object ( descriptor) that services the IRQ line.

Pointer to data used by the PIC methods.

Identifies the interrupt service routines to be invoked when the IRQ occurs. The field points to the first element of the list of descriptors associated with the IRQ. The descriptor is described later in the chapter.

A set of flags describing the IRQ line status (see Table ).

Shows 0 if the IRQ line is enabled and a positive value if it has been disabled at least once.

Counter of interrupt occurrences on the IRQ line (for diagnostic use only).

Counter of unhandled interrupt occurrences on the IRQ line (for diagnostic use only).

A spin lock used to serialize the accesses to the IRQ descriptor and to the PIC (see Chapter 5).

An interrupt is unexpected if it is not handled by the kernel, that is, either if there is no ISR associated with the IRQ line, or if no ISR associated with the line recognizes the interrupt as raised by its own hardware device. Usually the kernel checks the number of unexpected interrupts received on an IRQ line, so as to disable the line in case a faulty hardware device keeps raising an interrupt over and over. Because the IRQ line can be shared among several devices, the kernel does not disable the line as soon as it detects a single unhandled interrupt. Rather, the kernel stores in the and fields of the descriptor the total number of interrupts and the number of unexpected interrupts, respectively; when the ,th interrupt is raised, the kernel disables the line if the number of unhandled interrupts is above 99, (that is, if less than interrupts over the last , received are expected interrupts from hardware devices sharing the line).

The status of an IRQ line is described by the flags listed in Table

Table  Flags describing the IRQ line status

Flag name

Description

A handler for the IRQ is being executed.

The IRQ line has been deliberately disabled by a device driver.

An IRQ has occurred on the line; its occurrence has been acknowledged to the PIC, but it has not yet been serviced by the kernel.

The IRQ line has been disabled but the previous IRQ occurrence has not yet been acknowledged to the PIC.

The kernel is using the IRQ line while performing a hardware device probe.

The kernel is using the IRQ line while performing a hardware device probe; moreover, the corresponding interrupt has not been raised.

Not used on the 80 × 86 architecture.

Not used.

Not used on the 80 × 86 architecture.

The field and the flag of the descriptor specify whether the IRQ line is enabled or disabled. Every time the or function is invoked, the field is increased; if is equal to 0, the function disables the IRQ line and sets its flag.[*] Conversely, each invocation of the function decreases the field; if becomes 0, the function enables the IRQ line and clears its flag.

During system initialization, the function sets the field of each IRQ main descriptor to . Moreover, updates the IDT by replacing the interrupt gates set up by (see the section "Preliminary Initialization of the IDT,” earlier in this chapter) with new ones. This is accomplished through the following statements:

for (i = 0; i < NR_IRQS; i++) if (i+32 != ) set_intr_gate(i+32,interrupt[i]);

This code looks in the array to find the interrupt handler addresses that it uses to set up the interrupt gates . Each entry n of the array stores the address of the interrupt handler for IRQ n (see the later section "Saving the registers for the interrupt handler“). Notice that the interrupt gate corresponding to vector is left untouched, because it is used for the system call’s programmed exception.

In addition to the A chip that was mentioned near the beginning of this chapter, Linux supports several other PIC circuits such as the SMP IO-APIC, Intel PIIX4’s internal PIC, and SGI’s Visual Workstation Cobalt (IO-)APIC. To handle all such devices in a uniform way, Linux uses a PIC object, consisting of the PIC name and seven PIC standard methods. The advantage of this object-oriented approach is that drivers need not to be aware of the kind of PIC installed in the system. Each driver-visible interrupt source is transparently wired to the appropriate controller. The data structure that defines a PIC object is called (also called ).

For the sake of concreteness, let’s assume that our computer is a uniprocessor with two A PICs, which provide 16 standard IRQs. In this case, the field in each of the 16 descriptors points to the variable, which describes the A PIC. This variable is initialized as follows:

struct hw_interrupt_type iA_irq_type = { .typename = "XT-PIC", .startup = startup_A_irq, .shutdown = shutdown_A_irq, .enable = enable_A_irq, .disable = disable_A_irq, .ack = mask_and_ack_A, .end = end_A_irq, .set_affinity = NULL };

The first field in this structure, , is the PIC name. Next come the pointers to six different functions used to program the PIC. The first two functions start up and shut down an IRQ line of the chip, respectively. But in the case of the A chip, these functions coincide with the third and fourth functions, which enable and disable the line. The function acknowledges the IRQ received by sending the proper bytes to the A I/O ports. The function is invoked when the interrupt handler for the IRQ line terminates. The last method is set to : it is used in multiprocessor systems to declare the “affinity” of CPUs for specified IRQs — that is, which CPUs are enabled to handle specific IRQs.

As described earlier, multiple devices can share a single IRQ. Therefore, the kernel maintains descriptors (see Figure earlier in this chapter), each of which refers to a specific hardware device and a specific interrupt. The fields included in such descriptor are shown in Table , and the flags are shown in Table

Table  Fields of the irqaction descriptor

Field name

Description

Points to the interrupt service routine for an I/O device. This is the key field that allows many devices to share the same IRQ.

This field includes a few fields that describe the relationships between the IRQ line and the I/O device (see Table ).

Not used.

The name of the I/O device (shown when listing the serviced IRQs by reading the /proc/interrupts file).

A private field for the I/O device. Typically, it identifies the I/O device itself (for instance, it could be equal to its major and minor numbers; see the section "Device Files" in Chapter 13), or it points to the device driver’s data.

Points to the next element of a list of descriptors. The elements in the list refer to hardware devices that share the same IRQ.

irq

IRQ line.

dir

Points to the descriptor of the /proc/irq/n directory associated with the IRQn.

Table  Flags of the irqaction descriptor

Flag name

Description

The handler must execute with interrupts disabled.

The device permits its IRQ line to be shared with other devices.

The device may be considered a source of events that occurs randomly; it can thus be used by the kernel random number generator. (Users can access this feature by taking random numbers from the /dev/random and /dev/urandom device files.)

Finally, the array includes entries, one for every possible CPU in the system. Each entry of type includes a few counters and flags used by the kernel to keep track of what each CPU is currently doing (see Table ).

Table  Fields of the irq_cpustat_t structure

Field name

Description

Set of flags denoting the pending softirqs (see the section "Softirqs" later in this chapter)

Time when the CPU became idle (significant only if the CPU is currently idle)

Number of occurrences of NMI interrupts

Number of occurrences of local APIC timer interrupts (see Chapter 6)

IRQ distribution in multiprocessor systems

Linux sticks to the Symmetric Multiprocessing model (SMP ); this means, essentially, that the kernel should not have any bias toward one CPU with respect to the others. As a consequence, the kernel tries to distribute the IRQ signals coming from the hardware devices in a round-robin fashion among all the CPUs. Therefore, all the CPUs should spend approximately the same fraction of their execution time servicing I/O interrupts.

In the earlier section "The Advanced Programmable Interrupt Controller (APIC),” we said that the multi-APIC system has sophisticated mechanisms to dynamically distribute the IRQ signals among the CPUs.

During system bootstrap, the booting CPU executes the function to initialize the I/O APIC chip. The 24 entries of the Interrupt Redirection Table of the chip are filled, so that all IRQ signals from the I/O hardware devices can be routed to each CPU in the system according to the “lowest priority” scheme (see the earlier section "IRQs and Interrupts“). During system bootstrap, moreover, all CPUs execute the function, which takes care of initializing the local APICs. In particular, the task priority register (TPR) of each chip is initialized to a fixed value, meaning that the CPU is willing to handle every kind of IRQ signal, regardless of its priority. The Linux kernel never modifies this value after its initialization.

All task priority registers contain the same value, thus all CPUs always have the same priority. To break a tie, the multi-APIC system uses the values in the arbitration priority registers of local APICs, as explained earlier. Because such values are automatically changed after every interrupt, the IRQ signals are, in most cases, fairly distributed among all CPUs.[*]

In short, when a hardware device raises an IRQ signal, the multi-APIC system selects one of the CPUs and delivers the signal to the corresponding local APIC, which in turn interrupts its CPU. No other CPUs are notified of the event.

All this is magically done by the hardware, so it should be of no concern for the kernel after multi-APIC system initialization. Unfortunately, in some cases the hardware fails to distribute the interrupts among the microprocessors in a fair way (for instance, some Pentium 4-based SMP motherboards have this problem). Therefore, Linux makes use of a special kernel thread called kirqd to correct, if necessary, the automatic assignment of IRQs to CPUs.

The kernel thread exploits a nice feature of multi-APIC systems, called the IRQ affinity of a CPU: by modifying the Interrupt Redirection Table entries of the I/O APIC, it is possible to route an interrupt signal to a specific CPU. This can be done by invoking the function, which acts on two parameters: the IRQ vector to be rerouted and a bit mask denoting the CPUs that can receive the IRQ. The IRQ affinity of a given interrupt also can be changed by the system administrator by writing a new CPU bitmap mask into the /proc/irq/n/smp_affinity file (n being the interrupt vector).

The kirqd kernel thread periodically executes the function, which keeps track of the number of interrupt occurrences received by every CPU in the most recent time interval. If the function discovers that the IRQ load imbalance between the heaviest loaded CPU and the least loaded CPU is significantly high, then it either selects an IRQ to be “moved” from a CPU to another, or rotates all IRQs among all existing CPUs.

Multiple Kernel Mode stacks

As mentioned in the section "Identifying a Process" in Chapter 3, the descriptor of each process is coupled with a Kernel Mode stack in a data structure composed by one or two page frames, according to an option selected when the kernel has been compiled. If the size of the structure is 8 KB, the Kernel Mode stack of the current process is used for every type of kernel control path: exceptions, interrupts, and deferrable functions (see the later section "Softirqs and Tasklets“). Conversely, if the size of the structure is 4 KB, the kernel makes use of three types of Kernel Mode stacks:

  • The exception stack is used when handling exceptions (including system calls). This is the stack contained in the per-process data structure, thus the kernel makes use of a different exception stack for each process in the system.

  • The hard IRQ stack is used when handling interrupts. There is one hard IRQ stack for each CPU in the system, and each stack is contained in a single page frame.

  • The soft IRQ stack is used when handling deferrable functions (softirqs or tasklets; see the later section "Softirqs and Tasklets“). There is one soft IRQ stack for each CPU in the system, and each stack is contained in a single page frame.

All hard IRQ stacks are contained in the array, while all soft IRQ stacks are contained in the array. Each array element is a union of type that span a single page. At the bottom of this page is stored a structure, while the spare memory locations are used for the stack; remember that each stack grows towards lower addresses. Thus, hard IRQ stacks and soft IRQ stacks are very similar to the exception stacks described in the section "Identifying a Process" in Chapter 3; the only difference is that the structure coupled with each stack is associated with a CPU rather than a process.

The and arrays allow the kernel to quickly determine the hard IRQ stack and soft IRQ stack of a given CPU, respectively: they contain pointers to the corresponding elements.

Saving the registers for the interrupt handler

When a CPU receives an interrupt, it starts executing the code at the address found in the corresponding gate of the IDT (see the earlier section "Hardware Handling of Interrupts and Exceptions“).

As with other context switches, the need to save registers leaves the kernel developer with a somewhat messy coding job, because the registers have to be saved and restored using assembly language code. However, within those operations, the processor is expected to call and return from a C function. In this section, we describe the assembly language task of handling registers; in the next, we show some of the acrobatics required in the C function that is subsequently invoked.

Saving registers is the first task of the interrupt handler. As already mentioned, the address of the interrupt handler for IRQ n is initially stored in the entry and then copied into the interrupt gate included in the proper IDT entry.

The array is built through a few assembly language instructions in the arch/i/kernel/entry.S file. The array includes elements, where the macro yields either the number if the kernel supports a recent I/O APIC chip,[*] or the number 16 if the kernel uses the older A PIC chips. The element at index n in the array stores the address of the following two assembly language instructions:

pushl $n jmp common_interrupt

The result is to save on the stack the IRQ number associated with the interrupt minus The kernel represents all IRQs through negative numbers, because it reserves positive interrupt numbers to identify system calls (see Chapter 10). The same code for all interrupt handlers can then be executed while referring to this number. The common code starts at label and consists of the following assembly language macros and instructions:

common_interrupt: SAVE_ALL movl %esp,%eax call do_IRQ jmp ret_from_intr

The macro expands to the following fragment:

cld push %es push %ds pushl %eax pushl %ebp pushl %edi pushl %esi pushl %edx pushl %ecx pushl %ebx movl $ _ _USER_DS,%edx movl %edx,%ds movl %edx,%es

saves all the CPU registers that may be used by the interrupt handler on the stack, except for , , , , and , which are already saved automatically by the control unit (see the earlier section "Hardware Handling of Interrupts and Exceptions“). The macro then loads the selector of the user data segment into and .

After saving the registers, the address of the current top stack location is saved in the register; then, the interrupt handler invokes the function. When the instruction of is executed (when that function terminates) control is transferred to (see the later section "Returning from Interrupts and Exceptions“).

The function is invoked to execute all interrupt service routines associated with an interrupt. It is declared as follows:

_ _attribute_ _((regparm(3))) unsigned int do_IRQ(struct pt_regs *regs)

The keyword instructs the function to go to the register to find the value of the argument; as seen above, points to the stack location containing the last register value pushed on by .

The function executes the following actions:

  1. Executes the macro, which increases a counter representing the number of nested interrupt handlers. The counter is stored in the field of the structure of the current process (see Table later in this chapter).

  2. If the size of the structure is 4 KB, it switches to the hard IRQ sprers.eu particular, the function performs the following substeps:

    1. Executes the function to get the address of the descriptor associated with the Kernel Mode stack addressed by the register (see the section "Identifying a Process" in Chapter 3).

    2. Compares the address of the descriptor obtained in the previous step with the address stored in , that is, the address of the descriptor associated with the local CPU. If the two addresses are equal, the kernel is already using the hard IRQ stack, thus jumps to step 3. This happens when an IRQ is raised while the kernel is still handling another interrupt.

    3. Here the Kernel Mode stack has to be switched. Stores the pointer to the current process descriptor in the field of the descriptor in union of the local CPU. This is done so that the macro works as expected while the kernel is using the hard IRQ stack (see the section "Identifying a Process" in Chapter 3).

    4. Stores the current value of the stack pointer register in the field of the descriptor in the union of the local CPU (this field is used only when preparing the function call trace for a kernel oops).

    5. Loads in the stack register the top location of the hard IRQ stack of the local CPU (the value in plus ); the previous value of the register is saved in the register.

  3. Invokes the function passing to it the pointer and the IRQ number obtained from the field (see the following section).

  4. If the hard IRQ stack has been effectively switched in step 2e above, the function copies the original stack pointer from the register into the register, thus switching back to the exception stack or soft IRQ stack that were in use before.

  5. Executes the macro, which decreases the interrupt counter and checks whether deferrable kernel functions are waiting to be executed (see the section "Softirqs and Tasklets" later in this chapter).

  6. Terminates: the control is transferred to the function (see the later section "Returning from Interrupts and Exceptions“).

The _ _do_IRQ( ) function

The function receives as its parameters an IRQ number (through the register) and a pointer to the structure where the User Mode register values have been saved (through the register).

The function is equivalent to the following code fragment:

spin_lock(&(irq_desc[irq].lock)); irq_desc[irq].handler->ack(irq); irq_desc[irq].status &= ~(IRQ_REPLAY IRQ_REPLAY)) == IRQ_PENDING) { irq_desc[irq].status = IRQ_REPLAY; hw_resend_irq(irq_desc[irq].handler,irq); } irq_desc[irq].handler->enable(irq); } spin_lock_irqrestore(&(irq_desc[irq].lock), flags);

The function detects that an interrupt was lost by checking the value of the flag. The flag is always cleared when leaving the interrupt handler; therefore, if the IRQ line is disabled and the flag is set, then an interrupt occurrence has been acknowledged but not yet serviced. In this case the function raises a new interrupt. This is obtained by forcing the local APIC to generate a self-interrupt (see the later section "Interprocessor Interrupt Handling“). The role of the flag is to ensure that exactly one self-interrupt is generated. Remember that the _ _ function clears that flag when it starts handling the interrupt.

Interrupt service routines

As mentioned previously, an interrupt service routine handles an interrupt by executing an operation specific to one type of device. When an interrupt handler must execute the ISRs, it invokes the function. This function essentially performs the following steps:

  1. Enables the local interrupts with the assembly language instruction if the flag is clear.

  2. Executes each interrupt service routine of the interrupt through the following code:

    retval = 0; do { retval

    Precision or OptiPlex Systems give Error allocating Mem BAR for PCI device errors during POST

     


    Table of Contents:

    1. Precision or OptiPlex Systems give "Error allocating Mem BAR for PCI device" errors during POST
    2. Possible Causes

    1. Precision or OptiPlex Systems give "Error allocating Mem BAR for PCI device" errors during POST

    A user may report that they receive an error during the Power On Self Test (POST) routine on an OptiPlex or Precision system.

    The error, "Error allocating Mem BAR for PCI device", occurs when attempting to use multiple PCI cards of the same type, including video, audio or Network cards. The system is unable to allocate DMA, I/O addresses or IRQ's across the multiple PCI\PCIe devices.

    Back to Top


    2. Possible Causes

    This issue may be caused by one of the following:

    1. A Faulty Device.
    2. A BIOS or NVRAM issue.
    3. Faulty PCI Slot or Chipset on the Motherboard.

    i. A Faulty Device.

    One of the PCI cards may be faulty. If possible, replace each card one at a time with a verified working card of the same type.

    Also check for Firmware updates for your card.  This can usually be found on the Manufacturers website for your particular card.

     

    Back to Top of Section

     

    ii. A BIOS or NVRAM issue.

    Make sure your system has the latest version of the BIOS. Please refer to the Dell support site sprers.eu and download the latest BIOS version for your system.

    Another area which may cause this issue is within the Non-Volatile Random Access Memory (NVRAM) which stores information relating to devices installed on your system. By resetting the NVRAM, this will allow the system to search for all devices again and re-initialise the information held in memory.

    Back to Top of Section

     

    iii. A Faulty PCI Slot or Chipset on the Motherboard.

    There may be an issue with a faulty PCI slot on the Motherboard or an issue with the Chipset.
    Please refer to the Dell Support Site sprers.eu and download the latest chipset version for your system.

    To troubleshoot the PCI slot on the Motherboard, proceed as follows:

    1. Remove all PCI cards from the system.

    2. Select one card and install into the 1st slot and test by powering on the system.

    3. Remove the 1st card and install into the 2nd slot of the system. Test by powering on the system.

    4. Continue by moving the card into each slot and testing the functionality of the card in each slot.

    5. Perform the above checks with each card.

    6. If the test results are inconclusive, install 2 cards and move each card into different slots and test after each permutation.

    If you find one of the PCI slots are indeed faulty, Please call Dell Technical Support with your findings and for advice on how to proceed.

    Back to Top of Section

    Back to Top


    Cause

    Resolution

    SA_SAMPLE_RANDOM, "floppy", NULL);

    As can be observed, the interrupt service routine must execute with the interrupts disabled ( flag set) and no sharing of the IRQ ( flag missing). The flag set means that accesses to the floppy disk are a good source of random events to be used for the kernel random number generator. When the operation on the floppy disk is concluded (either the I/O operation on /dev/fd0 terminates or the filesystem is unmounted), the driver releases IRQ 6:

    free_irq(6, NULL);

    To insert an descriptor in the proper list, the kernel invokes the function, passing to it the parameters , the IRQ number, and (the address of a previously allocated descriptor). This function:

    1. Checks whether another device is already using the IRQ and, if so, whether the flags in the descriptors of both devices specify that the IRQ line can be shared. Returns an error code if the IRQ line cannot be used.

    2. Adds (the new descriptor pointed to by ) at the end of the list to which points.

    3. If no other device is sharing the same IRQ, the function clears the , , , and flags in the field of and invokes the method of the PIC object to make sure that IRQ signals are enabled.

    Here is an example of how is used, drawn from system initialization. The kernel initializes the descriptor of the interval timer device by executing the following instructions in the function (see Chapter 6):

    struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; setup_irq(0, &irq0);

    First, the variable of type is initialized: the field is set to the address of the function, the field is set to , the field is set to "timer", and the fifth field is set to to show that no value is used. Next, the kernel invokes to insert in the list of descriptors associated with IRQ 0.

Interprocessor Interrupt Handling

Interprocessor interrupts allow a CPU to send interrupt signals to any other CPU in the system. As explained in the section "The Advanced Programmable Interrupt Controller (APIC)" earlier in this chapter, an interprocessor interrupt (IPI) is delivered not through an IRQ line, but directly as a message on the bus that connects the local APIC of all CPUs (either a dedicated bus in older motherboards, or the system bus in the Pentium 4-based motherboards).

On multiprocessor systems, Linux makes use of three kinds of interprocessor interrupts (see also Table ):

(vector)

Sent to all CPUs but the sender, forcing those CPUs to run a function passed by the sender. The corresponding interrupt handler is named . The function (whose address is passed in the global variable) may, for instance, force all other CPUs to stop, or may force them to set the contents of the Memory Type Range Registers (MTRRs).[*] Usually this interrupt is sent to all CPUs except the CPU executing the calling function by means of the facility function.

(vector)

When a CPU receives this type of interrupt, the corresponding handler — named — limits itself to acknowledging the interrupt. Rescheduling is done automatically when returning from the interrupt (see the section "Returning from Interrupts and Exceptions" later in this chapter).

(vector)

Sent to all CPUs but the sender, forcing them to invalidate their Translation Lookaside Buffers. The corresponding handler, named , flushes some TLB entries of the processor as described in the section "Handling the Hardware Cache and the TLB" in Chapter 2.

The assembly language code of the interprocessor interrupt handlers is generated by the macro: it saves the registers, pushes the vector number minus on the stack, and then invokes a high-level C function having the same name as the low-level handler preceded by . For instance, the high-level handler of the interprocessor interrupt that is invoked by the low-level handler is named . Each high-level handler acknowledges the interprocessor interrupt on the local APIC and then performs the specific action triggered by the interrupt.

Thanks to the following group of functions, issuing interprocessor interrupts (IPIs) becomes an easy task:

Sends an IPI to all CPUs (including the sender)

Sends an IPI to all CPUs except the sender

Sends an IPI to the sender CPU

Sends an IPI to a group of CPUs specified by a bit mask

Get Understanding the Linux Kernel, 3rd Edition now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly publishers.

Start your free trial

SA_SAMPLE_RANDOM, "floppy", NULL);

As can be observed, pci irq table error, the interrupt service routine must execute with the interrupts disabled ( flag set) and no sharing of the IRQ ( flag missing). The flag set means that accesses to the floppy disk are a good source of random events to be used for the kernel random number generator. When the operation on the floppy disk is concluded (either the I/O operation on canon mp160 error e5 terminates or the filesystem is unmounted), the driver releases IRQ 6:

free_irq(6, NULL);

To insert an descriptor in the proper list, the kernel invokes the function, passing to it the parametersthe IRQ number, pci irq table error, and (the address of a previously allocated descriptor). This function:

  1. Checks whether another device is already using the IRQ and, if so, whether the flags in the descriptors of both devices specify that the IRQ line can be shared. Returns an error code if the IRQ line cannot be used.

  2. Adds (the new descriptor pointed to by ) at the end of the list to which points.

  3. If no other device is sharing the same IRQ, the function clears the,and flags in the field of and invokes the method of the PIC object to make sure that IRQ signals are enabled.

Here is an example of how is used, drawn from system initialization. The kernel initializes the descriptor of the interval timer device by executing the following instructions in the function (see Chapter 6):

struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; setup_irq(0, &irq0);

First, the variable of type is initialized: the field is set to the address of the function, the field is set tothe field is set to "timer", and the fifth field is set to to show that no value is used. Next, the kernel invokes to insert in the list of descriptors associated with IRQ 0.

Interprocessor Interrupt Handling

Interprocessor interrupts allow a CPU to send interrupt signals to any other CPU in the system. As explained in the section "The Advanced Programmable Interrupt Controller (APIC)" earlier in this chapter, an interprocessor interrupt (IPI) is delivered not through an IRQ line, but directly as a message on the bus that connects the local APIC of all CPUs (either a dedicated bus in older motherboards, or the system bus in the Pentium 4-based motherboards).

On multiprocessor systems, Linux makes use of three kinds of interprocessor interrupts (see also Table ):

(vector)

Sent to all CPUs but the sender, forcing those CPUs to run a function passed by the sender. The corresponding interrupt handler is named. The function (whose address is passed in the global variable) may, for instance, force all other CPUs to stop, or may force them to set the contents of the Memory Type Range Registers (MTRRs).[*] Usually this interrupt is sent to all CPUs except the CPU executing the calling function by means of the facility function.

(vector)

When a CPU receives this type of interrupt, the corresponding handler — named — limits itself to acknowledging the interrupt. Rescheduling is done automatically when returning from the interrupt (see the section "Returning from Interrupts and Exceptions" later in this chapter).

(vector)

Sent to all CPUs but the sender, forcing them to invalidate their Translation Lookaside Buffers. The corresponding handler, namedflushes some TLB entries of the processor as described in the section "Handling the Hardware Cache and the TLB" in Chapter 2.

The assembly language code of the interprocessor interrupt handlers is generated by the macro: it saves the registers, pushes the vector number minus on the stack, and then invokes a high-level C function having the same name as the low-level handler preceded by. For instance, the high-level handler of the interprocessor interrupt that is invoked by the low-level handler is named. Each high-level handler acknowledges the interprocessor interrupt on the local Rounding error solaris 10 and then performs the specific action triggered by the interrupt.

Thanks to the following error logining intro develop center of functions, issuing interprocessor interrupts (IPIs) becomes an easy task:

Sends an IPI to all CPUs (including the sender)

Sends an IPI to all CPUs except the sender

Sends an IPI to the sender CPU

Sends an IPI to a group of CPUs specified by a bit mask