Linux provides a number of functions for clearing one or more entries from the IO APIC registers as well as for disabling the whole APIC. These are typically used by the reboot code.
The function shown in Figure 14.26, from arch/i386/kernel/io_apic.c, is used by the reboot code. It clears all registers in all IO APICs before rebooting.
1029 void disable_IO_APIC(void)
Figure 14.26 Disabling IO APICs
1034 this clears all the registers in all IO APICs (see Section 22.214.171.124).
1036 this function reenables the PIC now that the APIC is disabled (see Section 126.96.36.199).
188.8.131.52 Clearing the redirection registers of all IO APICs
When disabling an IO APIC, it is necessary to clear all the redirection registers. The code to do this for all IO APICs is shown in Figure 14.27, from arch/i386/kernel/io_apic.c.
182 static void clear_IO_APIC (void)
18 7 for (pin=0; pin<nr_ioapic_registers[apic]; pin++)
188 clear_IO_APIC_pin(apic, pin);
Figure 14.27 Clearing the redirection registers of all IO APICs
186 this loop works its way through each IO APIC in the system.
187 this loop works through each pin on the APIC (and consequently each register). The number of pins in each is determined by the nr_ioapic_registers array, from Section 184.108.40.206.
188 this is the function that does the actual work; see Section 220.127.116.11.
18.104.22.168 Removing an entry from an IO APIC redirection table
The code shown in Figure 14.28, from arch/i386/kernel/io_apic.c, zeroes the entry in the redirection table corresponding to a particular pin of a specific IO APIC. It also masks (disables) that irq.
166 void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
168 struct IO_APIC_route_entry entry;
169 unsigned long flags;
174 memset(&entry, 0, sizeof(entry));
177 io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry)+ 0));
178 io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1));
179 spin_unlock_irqrestore(&ioapic_lock, flags);
Figure 14.28 Removing an entry from the routing table
166 the parameters identify the particular IO APIC, and the pin on that APIC (this in turn identifies the register).
174 the local variable entry, declared at line 168, is cleared to all zeros.
175 setting the mask bit to 1 disables the irq.
176-179 the write to the APIC register is protected by the interrupt-safe spinlock declared in Section 22.214.171.124.
177-178 the double write copies the struct entry to the APIC register corresponding to this pin. The function is described in Section 126.96.36.199.
The function shown in Figure 14.29, from arch/i386/kernel/apic.c, puts the motherboard back into PIC mode. It has an effect only on certain older boards, designated by the pic_mode flag being set (see Section 188.8.131.52). PIC mode effectively bypasses all APIC components and forces the system to operate in single processor mode. Note that APIC interrupts, including IPIs, do not work after this.
116 void disconnect_bsp_APIC(void)
125 printk("disabling APIC mode, entering PIC mode.\n");
126 outb(0x70, 0x22);
127 outb(0x00, 0x23);
Figure 14.29 Putting the motherboard back into PIC mode
118 this was declared the code in Section 184.108.40.206. It is set at bootup time; 1 means the Intel multiprocessor specification; 0 means virtual wire mode.
126 ports 0x2 2 and 0x2 3 are for the interrupt mode configuration register (IMCR). Writing 0x70 to port 0x2 2 selects the IMCR.
127 writing a value of 0x00 to port 0x2 3 connects the INTR (from PIC) and nmi lines directly to the bootstrap processor, bypassing the IO and local APICs. A value of 0x01 here disconnects the PIC and connects the interrupt lines to the IO APIC.
Was this article helpful?
Read how to maintain and repair any desktop and laptop computer. This Ebook has articles with photos and videos that show detailed step by step pc repair and maintenance procedures. There are many links to online videos that explain how you can build, maintain, speed up, clean, and repair your computer yourself. Put the money that you were going to pay the PC Tech in your own pocket.