1/* 2 * Machine specific setup for generic 3 */ 4 5#include <linux/smp.h> 6#include <linux/init.h> 7#include <linux/interrupt.h> 8#include <asm/acpi.h> 9#include <asm/arch_hooks.h> 10#include <asm/e820.h> 11#include <asm/setup.h> 12 13#ifdef CONFIG_HOTPLUG_CPU 14#define DEFAULT_SEND_IPI (1) 15#else 16#define DEFAULT_SEND_IPI (0) 17#endif 18 19int no_broadcast=DEFAULT_SEND_IPI; 20 21/** 22 * pre_intr_init_hook - initialisation prior to setting up interrupt vectors 23 * 24 * Description: 25 * Perform any necessary interrupt initialisation prior to setting up 26 * the "ordinary" interrupt call gates. For legacy reasons, the ISA 27 * interrupts should be initialised here if the machine emulates a PC 28 * in any way. 29 **/ 30void __init pre_intr_init_hook(void) 31{ 32 init_ISA_irqs(); 33} 34 35/* 36 * IRQ2 is cascade interrupt to second interrupt controller 37 */ 38static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; 39 40/** 41 * intr_init_hook - post gate setup interrupt initialisation 42 * 43 * Description: 44 * Fill in any interrupts that may have been left out by the general 45 * init_IRQ() routine. interrupts having to do with the machine rather 46 * than the devices on the I/O bus (like APIC interrupts in intel MP 47 * systems) are started here. 48 **/ 49void __init intr_init_hook(void) 50{ 51#ifdef CONFIG_X86_LOCAL_APIC 52 apic_intr_init(); 53#endif 54 55 if (!acpi_ioapic) 56 setup_irq(2, &irq2); 57} 58 59/** 60 * pre_setup_arch_hook - hook called prior to any setup_arch() execution 61 * 62 * Description: 63 * generally used to activate any machine specific identification 64 * routines that may be needed before setup_arch() runs. On VISWS 65 * this is used to get the board revision and type. 66 **/ 67void __init pre_setup_arch_hook(void) 68{ 69} 70 71/** 72 * trap_init_hook - initialise system specific traps 73 * 74 * Description: 75 * Called as the final act of trap_init(). Used in VISWS to initialise 76 * the various board specific APIC traps. 77 **/ 78void __init trap_init_hook(void) 79{ 80} 81 82static struct irqaction irq0 = { 83 .handler = timer_interrupt, 84 .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, 85 .mask = CPU_MASK_NONE, 86 .name = "timer" 87}; 88 89/** 90 * time_init_hook - do any specific initialisations for the system timer. 91 * 92 * Description: 93 * Must plug the system timer interrupt source at HZ into the IRQ listed 94 * in irq_vectors.h:TIMER_IRQ 95 **/ 96void __init time_init_hook(void) 97{ 98 irq0.mask = cpumask_of_cpu(0); 99 setup_irq(0, &irq0); 100} 101 102#ifdef CONFIG_MCA 103/** 104 * mca_nmi_hook - hook into MCA specific NMI chain 105 * 106 * Description: 107 * The MCA (Microchannel Arcitecture) has an NMI chain for NMI sources 108 * along the MCA bus. Use this to hook into that chain if you will need 109 * it. 110 **/ 111void mca_nmi_hook(void) 112{ 113 /* If I recall correctly, there's a whole bunch of other things that 114 * we can do to check for NMI problems, but that's all I know about 115 * at the moment. 116 */ 117 118 printk("NMI generated from unknown source!\n"); 119} 120#endif 121 122static __init int no_ipi_broadcast(char *str) 123{ 124 get_option(&str, &no_broadcast); 125 printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : 126 "IPI Broadcast"); 127 return 1; 128} 129 130__setup("no_ipi_broadcast", no_ipi_broadcast); 131 132static int __init print_ipi_mode(void) 133{ 134 printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : 135 "Shortcut"); 136 return 0; 137} 138 139late_initcall(print_ipi_mode); 140 141/** 142 * machine_specific_memory_setup - Hook for machine specific memory setup. 143 * 144 * Description: 145 * This is included late in kernel/setup.c so that it can make 146 * use of all of the static functions. 147 **/ 148 149char * __init machine_specific_memory_setup(void) 150{ 151 char *who; 152 153 154 who = "BIOS-e820"; 155 156 /* 157 * Try to copy the BIOS-supplied E820-map. 158 * 159 * Otherwise fake a memory map; one section from 0k->640k, 160 * the next section from 1mb->appropriate_mem_k 161 */ 162 sanitize_e820_map(E820_MAP, &E820_MAP_NR); 163 if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { 164 unsigned long mem_size; 165 166 /* compare results from other methods and take the greater */ 167 if (ALT_MEM_K < EXT_MEM_K) { 168 mem_size = EXT_MEM_K; 169 who = "BIOS-88"; 170 } else { 171 mem_size = ALT_MEM_K; 172 who = "BIOS-e801"; 173 } 174 175 e820.nr_map = 0; 176 add_memory_region(0, LOWMEMSIZE(), E820_RAM); 177 add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); 178 } 179 return who; 180} 181