Skip to content

Commit

Permalink
Merge branch 'x86/apic-cleanups' into x86/urgent
Browse files Browse the repository at this point in the history
Merge reason: Topic is ready for upstream.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Ingo Molnar committed Jan 10, 2011
2 parents 91d88ce + 1c2a48c commit 30285c6
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 228 deletions.
2 changes: 1 addition & 1 deletion arch/x86/include/asm/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ extern void init_bsp_APIC(void);
extern void setup_local_APIC(void);
extern void end_local_APIC_setup(void);
extern void init_apic_mappings(void);
void register_lapic_address(unsigned long address);
extern void setup_boot_APIC_clock(void);
extern void setup_secondary_APIC_clock(void);
extern int APIC_init_uniprocessor(void);
Expand All @@ -244,7 +245,6 @@ extern int apic_force_enable(void);
* On 32bit this is mach-xxx local
*/
#ifdef CONFIG_X86_64
extern void early_init_lapic_mapping(void);
extern int apic_is_clustered_box(void);
#else
static inline int apic_is_clustered_box(void)
Expand Down
3 changes: 3 additions & 0 deletions arch/x86/include/asm/io_apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);

extern int get_nr_irqs_gsi(void);

extern void setup_ioapic_ids_from_mpc(void);
extern void setup_ioapic_ids_from_mpc_nocheck(void);

Expand All @@ -183,6 +184,8 @@ int mp_find_ioapic_pin(int ioapic, u32 gsi);
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
extern void __init pre_init_apic_IRQ0(void);

extern void mp_save_irq(struct mpc_intsrc *m);

#else /* !CONFIG_X86_IO_APIC */

#define io_apic_assign_pci_irqs 0
Expand Down
48 changes: 5 additions & 43 deletions arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -852,18 +852,6 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
* returns 0 on success, < 0 on error
*/

static void __init acpi_register_lapic_address(unsigned long address)
{
mp_lapic_addr = address;

set_fixmap_nocache(FIX_APIC_BASE, address);
if (boot_cpu_physical_apicid == -1U) {
boot_cpu_physical_apicid = read_apic_id();
apic_version[boot_cpu_physical_apicid] =
GET_APIC_VERSION(apic_read(APIC_LVR));
}
}

static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
{
int count;
Expand All @@ -885,7 +873,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
return count;
}

acpi_register_lapic_address(acpi_lapic_addr);
register_lapic_address(acpi_lapic_addr);

return count;
}
Expand All @@ -912,7 +900,7 @@ static int __init acpi_parse_madt_lapic_entries(void)
return count;
}

acpi_register_lapic_address(acpi_lapic_addr);
register_lapic_address(acpi_lapic_addr);

count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
acpi_parse_sapic, MAX_LOCAL_APIC);
Expand Down Expand Up @@ -954,32 +942,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
extern int es7000_plat;
#endif

static void assign_to_mp_irq(struct mpc_intsrc *m,
struct mpc_intsrc *mp_irq)
{
memcpy(mp_irq, m, sizeof(struct mpc_intsrc));
}

static int mp_irq_cmp(struct mpc_intsrc *mp_irq,
struct mpc_intsrc *m)
{
return memcmp(mp_irq, m, sizeof(struct mpc_intsrc));
}

static void save_mp_irq(struct mpc_intsrc *m)
{
int i;

for (i = 0; i < mp_irq_entries; i++) {
if (!mp_irq_cmp(&mp_irqs[i], m))
return;
}

assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]);
if (++mp_irq_entries == MAX_IRQ_SOURCES)
panic("Max # of irq sources exceeded!!\n");
}

void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
{
int ioapic;
Expand Down Expand Up @@ -1010,7 +972,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */
mp_irq.dstirq = pin; /* INTIN# */

save_mp_irq(&mp_irq);
mp_save_irq(&mp_irq);

isa_irq_to_gsi[bus_irq] = gsi;
}
Expand Down Expand Up @@ -1085,7 +1047,7 @@ void __init mp_config_acpi_legacy_irqs(void)
mp_irq.srcbusirq = i; /* Identity mapped */
mp_irq.dstirq = pin;

save_mp_irq(&mp_irq);
mp_save_irq(&mp_irq);
}
}

Expand Down Expand Up @@ -1122,7 +1084,7 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
mp_irq.dstapic = mp_ioapics[ioapic].apicid;
mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);

save_mp_irq(&mp_irq);
mp_save_irq(&mp_irq);
#endif
return 0;
}
Expand Down
64 changes: 26 additions & 38 deletions arch/x86/kernel/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,12 +1191,15 @@ static void __cpuinit lapic_setup_esr(void)
oldvalue, value);
}


/**
* setup_local_APIC - setup the local APIC
*
* Used to setup local APIC while initializing BSP or bringin up APs.
* Always called with preemption disabled.
*/
void __cpuinit setup_local_APIC(void)
{
int cpu = smp_processor_id();
unsigned int value, queued;
int i, j, acked = 0;
unsigned long long tsc = 0, ntsc;
Expand All @@ -1221,8 +1224,6 @@ void __cpuinit setup_local_APIC(void)
#endif
perf_events_lapic_init();

preempt_disable();

/*
* Double-check whether this APIC is really registered.
* This is meaningless in clustered apic mode, so we skip it.
Expand Down Expand Up @@ -1338,33 +1339,29 @@ void __cpuinit setup_local_APIC(void)
* TODO: set up through-local-APIC from through-I/O-APIC? --macro
*/
value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
if (!smp_processor_id() && (pic_mode || !value)) {
if (!cpu && (pic_mode || !value)) {
value = APIC_DM_EXTINT;
apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
smp_processor_id());
apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", cpu);
} else {
value = APIC_DM_EXTINT | APIC_LVT_MASKED;
apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
smp_processor_id());
apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", cpu);
}
apic_write(APIC_LVT0, value);

/*
* only the BP should see the LINT1 NMI signal, obviously.
*/
if (!smp_processor_id())
if (!cpu)
value = APIC_DM_NMI;
else
value = APIC_DM_NMI | APIC_LVT_MASKED;
if (!lapic_is_integrated()) /* 82489DX */
value |= APIC_LVT_LEVEL_TRIGGER;
apic_write(APIC_LVT1, value);

preempt_enable();

#ifdef CONFIG_X86_MCE_INTEL
/* Recheck CMCI information after local APIC is up on CPU #0 */
if (smp_processor_id() == 0)
if (!cpu)
cmci_recheck();
#endif
}
Expand Down Expand Up @@ -1633,28 +1630,6 @@ static int __init detect_init_APIC(void)
}
#endif

#ifdef CONFIG_X86_64
void __init early_init_lapic_mapping(void)
{
/*
* If no local APIC can be found then go out
* : it means there is no mpatable and MADT
*/
if (!smp_found_config)
return;

set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
APIC_BASE, mp_lapic_addr);

/*
* Fetch the APIC ID of the BSP in case we have a
* default configuration (or the MP table is broken).
*/
boot_cpu_physical_apicid = read_apic_id();
}
#endif

/**
* init_apic_mappings - initialize APIC mappings
*/
Expand All @@ -1680,10 +1655,7 @@ void __init init_apic_mappings(void)
* acpi_register_lapic_address()
*/
if (!acpi_lapic && !smp_found_config)
set_fixmap_nocache(FIX_APIC_BASE, apic_phys);

apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
APIC_BASE, apic_phys);
register_lapic_address(apic_phys);
}

/*
Expand All @@ -1705,6 +1677,22 @@ void __init init_apic_mappings(void)
}
}

void __init register_lapic_address(unsigned long address)
{
mp_lapic_addr = address;

if (!x2apic_mode) {
set_fixmap_nocache(FIX_APIC_BASE, address);
apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
APIC_BASE, mp_lapic_addr);
}
if (boot_cpu_physical_apicid == -1U) {
boot_cpu_physical_apicid = read_apic_id();
apic_version[boot_cpu_physical_apicid] =
GET_APIC_VERSION(apic_read(APIC_LVR));
}
}

/*
* This initializes the IO-APIC and APIC hardware if this is
* a UP kernel.
Expand Down
28 changes: 26 additions & 2 deletions arch/x86/kernel/apic/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,26 @@ static int __init parse_noapic(char *str)
}
early_param("noapic", parse_noapic);

/* Will be called in mpparse/acpi/sfi codes for saving IRQ info */
void mp_save_irq(struct mpc_intsrc *m)
{
int i;

apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x,"
" IRQ %02x, APIC ID %x, APIC INT %02x\n",
m->irqtype, m->irqflag & 3, (m->irqflag >> 2) & 3, m->srcbus,
m->srcbusirq, m->dstapic, m->dstirq);

for (i = 0; i < mp_irq_entries; i++) {
if (!memcmp(&mp_irqs[i], m, sizeof(*m)))
return;
}

memcpy(&mp_irqs[mp_irq_entries], m, sizeof(*m));
if (++mp_irq_entries == MAX_IRQ_SOURCES)
panic("Max # of irq sources exceeded!!\n");
}

struct irq_pin_list {
int apic, pin;
struct irq_pin_list *next;
Expand All @@ -135,6 +155,7 @@ static struct irq_pin_list *alloc_irq_pin_list(int node)
return kzalloc_node(sizeof(struct irq_pin_list), GFP_KERNEL, node);
}


/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
#ifdef CONFIG_SPARSE_IRQ
static struct irq_cfg irq_cfgx[NR_IRQS_LEGACY];
Expand Down Expand Up @@ -2006,9 +2027,12 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
= mp_ioapics[apic_id].apicid;

/*
* Read the right value from the MPC table and
* write it into the ID register.
* Update the ID register according to the right value
* from the MPC table if they are different.
*/
if (mp_ioapics[apic_id].apicid == reg_00.bits.ID)
continue;

apic_printk(APIC_VERBOSE, KERN_INFO
"...changing IO-APIC physical APIC ID to %d ...",
mp_ioapics[apic_id].apicid);
Expand Down
Loading

0 comments on commit 30285c6

Please sign in to comment.