This patch is motivated by a subsequent patch which will allow for more memory map entries on EFI supported systems than can be passed via the x86 legacy BIOS E820 interface. The legacy interface is limited to E820MAX == 128 memory entries, and that "E820MAX" manifest constant was used as the size for several arrays and loops over those arrays. The primary change in this patch is to change code loop sizes over those arrays from using the constant E820MAX, to using the ARRAY_SIZE() macro evaluated for the array being looped. That way, a subsequent patch can change the size of some of these arrays, without breaking this code. This patch also adds a parameter to the sanitize_e820_map() routine, which had an implicit size for the array passed it of E820MAX entries. This new parameter explicitly passes the size of said array. Once again, this will allow a subsequent patch to change that array size for some calls to sanitize_e820_map() without breaking the code. As part of enhancing the sanitize_e820_map() interface this way, I further combined the unnecessarily distinct x86_32 and x86_64 declarations for this routine into a single, commonly used, declaration. This patch in itself should make no difference to the resulting kernel binary. [ mingo@elte.hu: merged to -tip ] Signed-off-by: Paul Jackson <pj@sgi.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
188 lines
4.3 KiB
C
188 lines
4.3 KiB
C
/*
|
|
* Machine specific setup for generic
|
|
*/
|
|
|
|
#include <linux/smp.h>
|
|
#include <linux/init.h>
|
|
#include <linux/interrupt.h>
|
|
#include <asm/acpi.h>
|
|
#include <asm/arch_hooks.h>
|
|
#include <asm/e820.h>
|
|
#include <asm/setup.h>
|
|
|
|
#ifdef CONFIG_HOTPLUG_CPU
|
|
#define DEFAULT_SEND_IPI (1)
|
|
#else
|
|
#define DEFAULT_SEND_IPI (0)
|
|
#endif
|
|
|
|
int no_broadcast=DEFAULT_SEND_IPI;
|
|
|
|
/**
|
|
* pre_intr_init_hook - initialisation prior to setting up interrupt vectors
|
|
*
|
|
* Description:
|
|
* Perform any necessary interrupt initialisation prior to setting up
|
|
* the "ordinary" interrupt call gates. For legacy reasons, the ISA
|
|
* interrupts should be initialised here if the machine emulates a PC
|
|
* in any way.
|
|
**/
|
|
void __init pre_intr_init_hook(void)
|
|
{
|
|
init_ISA_irqs();
|
|
}
|
|
|
|
/*
|
|
* IRQ2 is cascade interrupt to second interrupt controller
|
|
*/
|
|
static struct irqaction irq2 = {
|
|
.handler = no_action,
|
|
.mask = CPU_MASK_NONE,
|
|
.name = "cascade",
|
|
};
|
|
|
|
/**
|
|
* intr_init_hook - post gate setup interrupt initialisation
|
|
*
|
|
* Description:
|
|
* Fill in any interrupts that may have been left out by the general
|
|
* init_IRQ() routine. interrupts having to do with the machine rather
|
|
* than the devices on the I/O bus (like APIC interrupts in intel MP
|
|
* systems) are started here.
|
|
**/
|
|
void __init intr_init_hook(void)
|
|
{
|
|
#ifdef CONFIG_X86_LOCAL_APIC
|
|
apic_intr_init();
|
|
#endif
|
|
|
|
if (!acpi_ioapic)
|
|
setup_irq(2, &irq2);
|
|
}
|
|
|
|
/**
|
|
* pre_setup_arch_hook - hook called prior to any setup_arch() execution
|
|
*
|
|
* Description:
|
|
* generally used to activate any machine specific identification
|
|
* routines that may be needed before setup_arch() runs. On VISWS
|
|
* this is used to get the board revision and type.
|
|
**/
|
|
void __init pre_setup_arch_hook(void)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* trap_init_hook - initialise system specific traps
|
|
*
|
|
* Description:
|
|
* Called as the final act of trap_init(). Used in VISWS to initialise
|
|
* the various board specific APIC traps.
|
|
**/
|
|
void __init trap_init_hook(void)
|
|
{
|
|
}
|
|
|
|
static struct irqaction irq0 = {
|
|
.handler = timer_interrupt,
|
|
.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL,
|
|
.mask = CPU_MASK_NONE,
|
|
.name = "timer"
|
|
};
|
|
|
|
/**
|
|
* time_init_hook - do any specific initialisations for the system timer.
|
|
*
|
|
* Description:
|
|
* Must plug the system timer interrupt source at HZ into the IRQ listed
|
|
* in irq_vectors.h:TIMER_IRQ
|
|
**/
|
|
void __init time_init_hook(void)
|
|
{
|
|
irq0.mask = cpumask_of_cpu(0);
|
|
setup_irq(0, &irq0);
|
|
}
|
|
|
|
#ifdef CONFIG_MCA
|
|
/**
|
|
* mca_nmi_hook - hook into MCA specific NMI chain
|
|
*
|
|
* Description:
|
|
* The MCA (Microchannel Architecture) has an NMI chain for NMI sources
|
|
* along the MCA bus. Use this to hook into that chain if you will need
|
|
* it.
|
|
**/
|
|
void mca_nmi_hook(void)
|
|
{
|
|
/* If I recall correctly, there's a whole bunch of other things that
|
|
* we can do to check for NMI problems, but that's all I know about
|
|
* at the moment.
|
|
*/
|
|
|
|
printk("NMI generated from unknown source!\n");
|
|
}
|
|
#endif
|
|
|
|
static __init int no_ipi_broadcast(char *str)
|
|
{
|
|
get_option(&str, &no_broadcast);
|
|
printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" :
|
|
"IPI Broadcast");
|
|
return 1;
|
|
}
|
|
|
|
__setup("no_ipi_broadcast=", no_ipi_broadcast);
|
|
|
|
static int __init print_ipi_mode(void)
|
|
{
|
|
printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" :
|
|
"Shortcut");
|
|
return 0;
|
|
}
|
|
|
|
late_initcall(print_ipi_mode);
|
|
|
|
/**
|
|
* machine_specific_memory_setup - Hook for machine specific memory setup.
|
|
*
|
|
* Description:
|
|
* This is included late in kernel/setup.c so that it can make
|
|
* use of all of the static functions.
|
|
**/
|
|
|
|
char * __init machine_specific_memory_setup(void)
|
|
{
|
|
char *who;
|
|
|
|
|
|
who = "BIOS-e820";
|
|
|
|
/*
|
|
* Try to copy the BIOS-supplied E820-map.
|
|
*
|
|
* Otherwise fake a memory map; one section from 0k->640k,
|
|
* the next section from 1mb->appropriate_mem_k
|
|
*/
|
|
sanitize_e820_map(boot_params.e820_map,
|
|
ARRAY_SIZE(boot_params.e820_map),
|
|
&boot_params.e820_entries);
|
|
if (copy_e820_map(boot_params.e820_map, boot_params.e820_entries)
|
|
< 0) {
|
|
unsigned long mem_size;
|
|
|
|
/* compare results from other methods and take the greater */
|
|
if (boot_params.alt_mem_k
|
|
< boot_params.screen_info.ext_mem_k) {
|
|
mem_size = boot_params.screen_info.ext_mem_k;
|
|
who = "BIOS-88";
|
|
} else {
|
|
mem_size = boot_params.alt_mem_k;
|
|
who = "BIOS-e801";
|
|
}
|
|
|
|
e820.nr_map = 0;
|
|
add_memory_region(0, LOWMEMSIZE(), E820_RAM);
|
|
add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
|
|
}
|
|
return who;
|
|
}
|