| // The I/O APIC manages hardware interrupts for an SMP system. | |
| // http://www.intel.com/design/chipsets/datashts/29056601.pdf | |
| // See also picirq.c. | |
| // The redirection table starts at REG_TABLE and uses | |
| // two registers to configure each interrupt. | |
| // The first (low) register in a pair contains configuration bits. | |
| // The second (high) register contains a bitmask telling which | |
| // CPUs can serve that interrupt. | |
| volatile struct ioapic *ioapic; | |
| // IO APIC MMIO structure: write reg, then read or write data. | |
| struct ioapic { | |
| uint reg; | |
| uint pad[3]; | |
| uint data; | |
| }; | |
| static uint | |
| ioapicread(int reg) | |
| { | |
| ioapic->reg = reg; | |
| return ioapic->data; | |
| } | |
| static void | |
| ioapicwrite(int reg, uint data) | |
| { | |
| ioapic->reg = reg; | |
| ioapic->data = data; | |
| } | |
| void | |
| ioapicinit(void) | |
| { | |
| int i, id, maxintr; | |
| ioapic = (volatile struct ioapic*)IOAPIC; | |
| maxintr = (ioapicread(REG_VER) >> 16) & 0xFF; | |
| id = ioapicread(REG_ID) >> 24; | |
| if(id != ioapicid) | |
| cprintf("ioapicinit: id isn't equal to ioapicid; not a MP\n"); | |
| // Mark all interrupts edge-triggered, active high, disabled, | |
| // and not routed to any CPUs. | |
| for(i = 0; i <= maxintr; i++){ | |
| ioapicwrite(REG_TABLE+2*i, INT_DISABLED | (T_IRQ0 + i)); | |
| ioapicwrite(REG_TABLE+2*i+1, 0); | |
| } | |
| } | |
| void | |
| ioapicenable(int irq, int cpunum) | |
| { | |
| // Mark interrupt edge-triggered, active high, | |
| // enabled, and routed to the given cpunum, | |
| // which happens to be that cpu's APIC ID. | |
| ioapicwrite(REG_TABLE+2*irq, T_IRQ0 + irq); | |
| ioapicwrite(REG_TABLE+2*irq+1, cpunum << 24); | |
| } | |
Xet Storage Details
- Size:
- 2.05 kB
- Xet hash:
- 6e0005ac72cff08f4eb9b4fd30666e8f987e820b8790cd42d1a65967ce9c3db3
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.