Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 3316
b: refs/heads/master
c: 208fb93
h: refs/heads/master
v: v3
  • Loading branch information
Eric W. Biederman authored and Linus Torvalds committed Jun 25, 2005
1 parent 2d0162e commit 44ac287
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 650927ef8ab1e9b05b77a3f32ca7adcedaae9306
refs/heads/master: 208fb93162d51faa69b9774fa7809858d84fd9dc
38 changes: 37 additions & 1 deletion trunk/arch/x86_64/kernel/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void __init connect_bsp_APIC(void)
}
}

void disconnect_bsp_APIC(void)
void disconnect_bsp_APIC(int virt_wire_setup)
{
if (pic_mode) {
/*
Expand All @@ -146,6 +146,42 @@ void disconnect_bsp_APIC(void)
outb(0x70, 0x22);
outb(0x00, 0x23);
}
else {
/* Go back to Virtual Wire compatibility mode */
unsigned long value;

/* For the spurious interrupt use vector F, and enable it */
value = apic_read(APIC_SPIV);
value &= ~APIC_VECTOR_MASK;
value |= APIC_SPIV_APIC_ENABLED;
value |= 0xf;
apic_write_around(APIC_SPIV, value);

if (!virt_wire_setup) {
/* For LVT0 make it edge triggered, active high, external and enabled */
value = apic_read(APIC_LVT0);
value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
apic_write_around(APIC_LVT0, value);
}
else {
/* Disable LVT0 */
apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
}

/* For LVT1 make it edge triggered, active high, nmi and enabled */
value = apic_read(APIC_LVT1);
value &= ~(
APIC_MODE_MASK | APIC_SEND_PENDING |
APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
apic_write_around(APIC_LVT1, value);
}
}

void disable_local_APIC(void)
Expand Down
36 changes: 34 additions & 2 deletions trunk/arch/x86_64/kernel/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ static int find_irq_entry(int apic, int pin, int type)
/*
* Find the pin to which IRQ[irq] (ISA) is connected
*/
static int __init find_isa_irq_pin(int irq, int type)
static int find_isa_irq_pin(int irq, int type)
{
int i;

Expand Down Expand Up @@ -1132,12 +1132,44 @@ static void __init enable_IO_APIC(void)
*/
void disable_IO_APIC(void)
{
int pin;
/*
* Clear the IO-APIC before rebooting:
*/
clear_IO_APIC();

disconnect_bsp_APIC();
/*
* If the i82559 is routed through an IOAPIC
* Put that IOAPIC in virtual wire mode
* so legacy interrups can be delivered.
*/
pin = find_isa_irq_pin(0, mp_ExtINT);
if (pin != -1) {
struct IO_APIC_route_entry entry;
unsigned long flags;

memset(&entry, 0, sizeof(entry));
entry.mask = 0; /* Enabled */
entry.trigger = 0; /* Edge */
entry.irr = 0;
entry.polarity = 0; /* High */
entry.delivery_status = 0;
entry.dest_mode = 0; /* Physical */
entry.delivery_mode = 7; /* ExtInt */
entry.vector = 0;
entry.dest.physical.physical_dest = 0;


/*
* Add it to the IO-APIC irq-routing table:
*/
spin_lock_irqsave(&ioapic_lock, flags);
io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
spin_unlock_irqrestore(&ioapic_lock, flags);
}

disconnect_bsp_APIC(pin != -1);
}

/*
Expand Down
2 changes: 1 addition & 1 deletion trunk/include/asm-x86_64/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ static inline void ack_APIC_irq(void)
extern int get_maxlvt (void);
extern void clear_local_APIC (void);
extern void connect_bsp_APIC (void);
extern void disconnect_bsp_APIC (void);
extern void disconnect_bsp_APIC (int virt_wire_setup);
extern void disable_local_APIC (void);
extern int verify_local_APIC (void);
extern void cache_APIC_registers (void);
Expand Down

0 comments on commit 44ac287

Please sign in to comment.