Commit a6830278 authored by Jaswinder Singh Rajput's avatar Jaswinder Singh Rajput Committed by Ingo Molnar

x86: mpparse: clean up code by introducing a few helper functions

Impact: cleanup

Refactor the MP-table parsing code via the introduction of the
following helper functions:

  skip_entry()
  smp_reserve_bootmem()
  check_irq_src()
  check_slot()

To simplify the code flow and to reduce the size of the
following oversized functions: smp_read_mpc(), smp_scan_config().

There should be no impact to functionality.
Signed-off-by: default avatarJaswinder Singh Rajput <jaswinderrajput@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent cde5edbd
...@@ -109,9 +109,6 @@ static void __init MP_bus_info(struct mpc_bus *m) ...@@ -109,9 +109,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
} else } else
printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
} }
#endif
#ifdef CONFIG_X86_IO_APIC
static int bad_ioapic(unsigned long address) static int bad_ioapic(unsigned long address)
{ {
...@@ -224,8 +221,12 @@ static void __init MP_intsrc_info(struct mpc_intsrc *m) ...@@ -224,8 +221,12 @@ static void __init MP_intsrc_info(struct mpc_intsrc *m)
if (++mp_irq_entries == MAX_IRQ_SOURCES) if (++mp_irq_entries == MAX_IRQ_SOURCES)
panic("Max # of irq sources exceeded!!\n"); panic("Max # of irq sources exceeded!!\n");
} }
#else /* CONFIG_X86_IO_APIC */
static inline void __init MP_bus_info(struct mpc_bus *m) {}
static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {}
static inline void __init MP_intsrc_info(struct mpc_intsrc *m) {}
#endif /* CONFIG_X86_IO_APIC */
#endif
static void __init MP_lintsrc_info(struct mpc_lintsrc *m) static void __init MP_lintsrc_info(struct mpc_lintsrc *m)
{ {
...@@ -275,6 +276,12 @@ static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str) ...@@ -275,6 +276,12 @@ static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str)
return 1; return 1;
} }
static void skip_entry(unsigned char **ptr, int *count, int size)
{
*ptr += size;
*count += size;
}
static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
{ {
char str[16]; char str[16];
...@@ -310,55 +317,27 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) ...@@ -310,55 +317,27 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
while (count < mpc->length) { while (count < mpc->length) {
switch (*mpt) { switch (*mpt) {
case MP_PROCESSOR: case MP_PROCESSOR:
{
struct mpc_cpu *m = (struct mpc_cpu *)mpt;
/* ACPI may have already provided this data */ /* ACPI may have already provided this data */
if (!acpi_lapic) if (!acpi_lapic)
MP_processor_info(m); MP_processor_info((struct mpc_cpu *)&mpt);
mpt += sizeof(*m); skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
count += sizeof(*m);
break; break;
}
case MP_BUS: case MP_BUS:
{ MP_bus_info((struct mpc_bus *)&mpt);
struct mpc_bus *m = (struct mpc_bus *)mpt; skip_entry(&mpt, &count, sizeof(struct mpc_bus));
#ifdef CONFIG_X86_IO_APIC
MP_bus_info(m);
#endif
mpt += sizeof(*m);
count += sizeof(*m);
break; break;
}
case MP_IOAPIC: case MP_IOAPIC:
{ MP_ioapic_info((struct mpc_ioapic *)&mpt);
#ifdef CONFIG_X86_IO_APIC skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
struct mpc_ioapic *m = (struct mpc_ioapic *)mpt;
MP_ioapic_info(m);
#endif
mpt += sizeof(struct mpc_ioapic);
count += sizeof(struct mpc_ioapic);
break; break;
}
case MP_INTSRC: case MP_INTSRC:
{ MP_intsrc_info((struct mpc_intsrc *)&mpt);
#ifdef CONFIG_X86_IO_APIC skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
MP_intsrc_info(m);
#endif
mpt += sizeof(struct mpc_intsrc);
count += sizeof(struct mpc_intsrc);
break; break;
}
case MP_LINTSRC: case MP_LINTSRC:
{ MP_lintsrc_info((struct mpc_lintsrc *)&mpt);
struct mpc_lintsrc *m = skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
(struct mpc_lintsrc *)mpt;
MP_lintsrc_info(m);
mpt += sizeof(*m);
count += sizeof(*m);
break; break;
}
default: default:
/* wrong mptable */ /* wrong mptable */
printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"); printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n");
...@@ -689,6 +668,31 @@ void __init get_smp_config(void) ...@@ -689,6 +668,31 @@ void __init get_smp_config(void)
__get_smp_config(0); __get_smp_config(0);
} }
static void smp_reserve_bootmem(struct mpf_intel *mpf)
{
unsigned long size = get_mpc_size(mpf->physptr);
#ifdef CONFIG_X86_32
/*
* We cannot access to MPC table to compute table size yet,
* as only few megabytes from the bottom is mapped now.
* PC-9800's MPC table places on the very last of physical
* memory; so that simply reserving PAGE_SIZE from mpf->physptr
* yields BUG() in reserve_bootmem.
* also need to make sure physptr is below than max_low_pfn
* we don't need reserve the area above max_low_pfn
*/
unsigned long end = max_low_pfn * PAGE_SIZE;
if (mpf->physptr < end) {
if (mpf->physptr + size > end)
size = end - mpf->physptr;
reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
}
#else
reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
#endif
}
static int __init smp_scan_config(unsigned long base, unsigned long length, static int __init smp_scan_config(unsigned long base, unsigned long length,
unsigned reserve) unsigned reserve)
{ {
...@@ -718,34 +722,8 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, ...@@ -718,34 +722,8 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
return 1; return 1;
reserve_bootmem_generic(virt_to_phys(mpf), sizeof(*mpf), reserve_bootmem_generic(virt_to_phys(mpf), sizeof(*mpf),
BOOTMEM_DEFAULT); BOOTMEM_DEFAULT);
if (mpf->physptr) { if (mpf->physptr)
unsigned long size = get_mpc_size(mpf->physptr); smp_reserve_bootmem(mpf);
#ifdef CONFIG_X86_32
/*
* We cannot access to MPC table to compute
* table size yet, as only few megabytes from
* the bottom is mapped now.
* PC-9800's MPC table places on the very last
* of physical memory; so that simply reserving
* PAGE_SIZE from mpf->physptr yields BUG()
* in reserve_bootmem.
* also need to make sure physptr is below than
* max_low_pfn
* we don't need reserve the area above max_low_pfn
*/
unsigned long end = max_low_pfn * PAGE_SIZE;
if (mpf->physptr < end) {
if (mpf->physptr + size > end)
size = end - mpf->physptr;
reserve_bootmem_generic(mpf->physptr, size,
BOOTMEM_DEFAULT);
}
#else
reserve_bootmem_generic(mpf->physptr, size,
BOOTMEM_DEFAULT);
#endif
}
return 1; return 1;
} }
...@@ -848,7 +826,57 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m) ...@@ -848,7 +826,57 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m)
#define SPARE_SLOT_NUM 20 #define SPARE_SLOT_NUM 20
static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM]; static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM];
#endif
static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
{
int i;
apic_printk(APIC_VERBOSE, "OLD ");
print_MP_intsrc_info(m);
i = get_MP_intsrc_index(m);
if (i > 0) {
assign_to_mpc_intsrc(&mp_irqs[i], m);
apic_printk(APIC_VERBOSE, "NEW ");
print_mp_irq_info(&mp_irqs[i]);
return;
}
if (!i) {
/* legacy, do nothing */
return;
}
if (*nr_m_spare < SPARE_SLOT_NUM) {
/*
* not found (-1), or duplicated (-2) are invalid entries,
* we need to use the slot later
*/
m_spare[*nr_m_spare] = m;
*nr_m_spare += 1;
}
}
#else /* CONFIG_X86_IO_APIC */
static inline void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
#endif /* CONFIG_X86_IO_APIC */
static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length,
int count)
{
if (!mpc_new_phys) {
pr_info("No spare slots, try to append...take your risk, "
"new mpc_length %x\n", count);
} else {
if (count <= mpc_new_length)
pr_info("No spare slots, try to append..., "
"new mpc_length %x\n", count);
else {
pr_err("mpc_new_length %lx is too small\n",
mpc_new_length);
return -1;
}
}
return 0;
}
static int __init replace_intsrc_all(struct mpc_table *mpc, static int __init replace_intsrc_all(struct mpc_table *mpc,
unsigned long mpc_new_phys, unsigned long mpc_new_phys,
...@@ -856,71 +884,30 @@ static int __init replace_intsrc_all(struct mpc_table *mpc, ...@@ -856,71 +884,30 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
{ {
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
int i; int i;
int nr_m_spare = 0;
#endif #endif
int count = sizeof(*mpc); int count = sizeof(*mpc);
int nr_m_spare = 0;
unsigned char *mpt = ((unsigned char *)mpc) + count; unsigned char *mpt = ((unsigned char *)mpc) + count;
printk(KERN_INFO "mpc_length %x\n", mpc->length); printk(KERN_INFO "mpc_length %x\n", mpc->length);
while (count < mpc->length) { while (count < mpc->length) {
switch (*mpt) { switch (*mpt) {
case MP_PROCESSOR: case MP_PROCESSOR:
{ skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
struct mpc_cpu *m = (struct mpc_cpu *)mpt;
mpt += sizeof(*m);
count += sizeof(*m);
break; break;
}
case MP_BUS: case MP_BUS:
{ skip_entry(&mpt, &count, sizeof(struct mpc_bus));
struct mpc_bus *m = (struct mpc_bus *)mpt;
mpt += sizeof(*m);
count += sizeof(*m);
break; break;
}
case MP_IOAPIC: case MP_IOAPIC:
{ skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
mpt += sizeof(struct mpc_ioapic);
count += sizeof(struct mpc_ioapic);
break; break;
}
case MP_INTSRC: case MP_INTSRC:
{ check_irq_src((struct mpc_intsrc *)&mpt, &nr_m_spare);
#ifdef CONFIG_X86_IO_APIC skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
apic_printk(APIC_VERBOSE, "OLD ");
print_MP_intsrc_info(m);
i = get_MP_intsrc_index(m);
if (i > 0) {
assign_to_mpc_intsrc(&mp_irqs[i], m);
apic_printk(APIC_VERBOSE, "NEW ");
print_mp_irq_info(&mp_irqs[i]);
} else if (!i) {
/* legacy, do nothing */
} else if (nr_m_spare < SPARE_SLOT_NUM) {
/*
* not found (-1), or duplicated (-2)
* are invalid entries,
* we need to use the slot later
*/
m_spare[nr_m_spare] = m;
nr_m_spare++;
}
#endif
mpt += sizeof(struct mpc_intsrc);
count += sizeof(struct mpc_intsrc);
break; break;
}
case MP_LINTSRC: case MP_LINTSRC:
{ skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
struct mpc_lintsrc *m =
(struct mpc_lintsrc *)mpt;
mpt += sizeof(*m);
count += sizeof(*m);
break; break;
}
default: default:
/* wrong mptable */ /* wrong mptable */
printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"); printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n");
...@@ -950,16 +937,8 @@ static int __init replace_intsrc_all(struct mpc_table *mpc, ...@@ -950,16 +937,8 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
} else { } else {
struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
count += sizeof(struct mpc_intsrc); count += sizeof(struct mpc_intsrc);
if (!mpc_new_phys) { if (!check_slot(mpc_new_phys, mpc_new_length, count))
printk(KERN_INFO "No spare slots, try to append...take your risk, new mpc_length %x\n", count);
} else {
if (count <= mpc_new_length)
printk(KERN_INFO "No spare slots, try to append..., new mpc_length %x\n", count);
else {
printk(KERN_ERR "mpc_new_length %lx is too small\n", mpc_new_length);
goto out; goto out;
}
}
assign_to_mpc_intsrc(&mp_irqs[i], m); assign_to_mpc_intsrc(&mp_irqs[i], m);
mpc->length = count; mpc->length = count;
mpt += sizeof(struct mpc_intsrc); mpt += sizeof(struct mpc_intsrc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment