* the voyager hal to provide the functionality
*/
#include <linux/config.h>
+#include <linux/module.h>
#include <linux/mm.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <asm/mtrr.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
-#include <asm/desc.h>
#include <asm/arch_hooks.h>
-#include <linux/irq.h>
-
-int reboot_smp = 0;
-
/* TLB state -- visible externally, indexed physically */
DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 };
/* CPU IRQ affinity -- set to all ones initially */
static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = ~0UL };
-/* Set when the idlers are all forked - Set in main.c but not actually
- * used by any other parts of the kernel */
-int smp_threads_ready = 0;
-
/* per CPU data structure (for /proc/cpuinfo et al), visible externally
* indexed physically */
struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_data);
/* physical ID of the CPU used to boot the system */
unsigned char boot_cpu_id;
/* Bitmask of currently online CPUs - used by setup.c for
/proc/cpuinfo, visible externally but still physical */
cpumask_t cpu_online_map = CPU_MASK_NONE;
+EXPORT_SYMBOL(cpu_online_map);
/* Bitmask of CPUs present in the system - exported by i386_syms.c, used
* by scheduler but indexed physically */
cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
-/* estimate of time used to flush the SMP-local cache - used in
- * processor affinity calculations */
-cycles_t cacheflush_time = 0;
-
-/* cache decay ticks for scheduler---a fairly useless quantity for the
- voyager system with its odd affinity and huge L3 cache */
-unsigned long cache_decay_ticks = 20;
-
/* The internal functions */
static void send_CPI(__u32 cpuset, __u8 cpi);
static void vic_enable_cpi(void);
static void do_boot_cpu(__u8 cpuid);
static void do_quad_bootstrap(void);
-static inline void wrapper_smp_local_timer_interrupt(struct pt_regs *);
int hard_smp_processor_id(void);
}
}
+static inline void
+wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
+{
+ irq_enter();
+ smp_local_timer_interrupt(regs);
+ irq_exit();
+}
+
static inline void
send_one_CPI(__u8 cpu, __u8 cpi)
{
* 8259 IRQs except that masks and things must be kept per processor
*/
static struct hw_interrupt_type vic_irq_type = {
- "VIC-level",
- startup_vic_irq, /* startup */
- disable_vic_irq, /* shutdown */
- enable_vic_irq, /* enable */
- disable_vic_irq, /* disable */
- before_handle_vic_irq, /* ack */
- after_handle_vic_irq, /* end */
- set_vic_irq_affinity, /* affinity */
+ .typename = "VIC-level",
+ .startup = startup_vic_irq,
+ .shutdown = disable_vic_irq,
+ .enable = enable_vic_irq,
+ .disable = disable_vic_irq,
+ .ack = before_handle_vic_irq,
+ .end = after_handle_vic_irq,
+ .set_affinity = set_vic_irq_affinity,
};
/* used to count up as CPUs are brought on line (starts at 0) */
/* This is for the new dynamic CPU boot code */
cpumask_t cpu_callin_map = CPU_MASK_NONE;
cpumask_t cpu_callout_map = CPU_MASK_NONE;
+EXPORT_SYMBOL(cpu_callout_map);
+cpumask_t cpu_possible_map = CPU_MASK_NONE;
+EXPORT_SYMBOL(cpu_possible_map);
/* The per processor IRQ masks (these are usually kept in sync) */
static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
static __u16 vic_irq_enable_mask[NR_CPUS] __cacheline_aligned = { 0 };
/* Lock for enable/disable of VIC interrupts */
-static spinlock_t vic_irq_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+static __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock);
/* The boot processor is correctly set up in PC mode when it
* comes up, but the secondaries need their master/slave 8259
cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16;
cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24;
+ cpu_possible_map = phys_cpu_present_map;
printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_addr(phys_cpu_present_map)[0]);
/* Here we set up the VIC to enable SMP */
/* enable the CPIs by writing the base vector to their register */
}
/* Routine initially called when a non-boot CPU is brought online */
-int __init
+static void __init
start_secondary(void *unused)
{
__u8 cpuid = hard_smp_processor_id();
/* external functions not defined in the headers */
extern void calibrate_delay(void);
- extern int cpu_idle(void);
cpu_init();
cpu_set(cpuid, cpu_online_map);
wmb();
- return cpu_idle();
+ cpu_idle();
}
smp_vic_cmn_interrupt(struct pt_regs *regs)
{
static __u8 in_cmn_int = 0;
- static spinlock_t cmn_int_lock = SPIN_LOCK_UNLOCKED;
+ static DEFINE_SPINLOCK(cmn_int_lock);
/* common ints are broadcast, so make sure we only do this once */
_raw_spin_lock(&cmn_int_lock);
static struct mm_struct * flush_mm;
static unsigned long flush_va;
-static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tlbstate_lock);
#define FLUSH_ALL 0xffffffff
/*
preempt_enable();
}
+EXPORT_SYMBOL(flush_tlb_page);
/* enable the requested IRQs */
static void
cpu_clear(smp_processor_id(), cpu_online_map);
local_irq_disable();
for(;;)
- __asm__("hlt");
+ halt();
}
-static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(call_lock);
struct call_data_struct {
void (*func) (void *info);
return 0;
}
+EXPORT_SYMBOL(smp_call_function);
/* Sorry about the name. In an APIC based system, the APICs
* themselves are programmed to send a timer interrupt. This is used
smp_local_timer_interrupt(regs);
}
-static inline void
-wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
-{
- irq_enter();
- smp_local_timer_interrupt(regs);
- irq_exit();
-}
-
/* local (per CPU) timer interrupt. It does both profiling and
* process statistics/rescheduling.
*
per_cpu(prof_counter, cpu);
}
- update_process_times(user_mode(regs));
+ update_process_times(user_mode_vm(regs));
}
if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
printk("VOYAGER SMP: CPU%d lost interrupt %d\n",
cpu, irq);
- for_each_cpu(real_cpu, mask) {
+ for_each_possible_cpu(real_cpu, mask) {
outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu,
VIC_PROCESSOR_ID);
{
cpu_set(smp_processor_id(), cpu_online_map);
cpu_set(smp_processor_id(), cpu_callout_map);
+ cpu_set(smp_processor_id(), cpu_possible_map);
}
int __devinit