1*bbd0abdaSPaul Mackerras /* 2*bbd0abdaSPaul Mackerras * Smp support for CHRP machines. 3*bbd0abdaSPaul Mackerras * 4*bbd0abdaSPaul Mackerras * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great 5*bbd0abdaSPaul Mackerras * deal of code from the sparc and intel versions. 6*bbd0abdaSPaul Mackerras * 7*bbd0abdaSPaul Mackerras * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu> 8*bbd0abdaSPaul Mackerras * 9*bbd0abdaSPaul Mackerras */ 10*bbd0abdaSPaul Mackerras 11*bbd0abdaSPaul Mackerras #include <linux/config.h> 12*bbd0abdaSPaul Mackerras #include <linux/kernel.h> 13*bbd0abdaSPaul Mackerras #include <linux/sched.h> 14*bbd0abdaSPaul Mackerras #include <linux/smp.h> 15*bbd0abdaSPaul Mackerras #include <linux/smp_lock.h> 16*bbd0abdaSPaul Mackerras #include <linux/interrupt.h> 17*bbd0abdaSPaul Mackerras #include <linux/kernel_stat.h> 18*bbd0abdaSPaul Mackerras #include <linux/delay.h> 19*bbd0abdaSPaul Mackerras #include <linux/init.h> 20*bbd0abdaSPaul Mackerras #include <linux/spinlock.h> 21*bbd0abdaSPaul Mackerras 22*bbd0abdaSPaul Mackerras #include <asm/ptrace.h> 23*bbd0abdaSPaul Mackerras #include <asm/atomic.h> 24*bbd0abdaSPaul Mackerras #include <asm/irq.h> 25*bbd0abdaSPaul Mackerras #include <asm/page.h> 26*bbd0abdaSPaul Mackerras #include <asm/pgtable.h> 27*bbd0abdaSPaul Mackerras #include <asm/sections.h> 28*bbd0abdaSPaul Mackerras #include <asm/io.h> 29*bbd0abdaSPaul Mackerras #include <asm/prom.h> 30*bbd0abdaSPaul Mackerras #include <asm/smp.h> 31*bbd0abdaSPaul Mackerras #include <asm/residual.h> 32*bbd0abdaSPaul Mackerras #include <asm/time.h> 33*bbd0abdaSPaul Mackerras #include <asm/open_pic.h> 34*bbd0abdaSPaul Mackerras #include <asm/machdep.h> 35*bbd0abdaSPaul Mackerras 36*bbd0abdaSPaul Mackerras extern unsigned long smp_chrp_cpu_nr; 37*bbd0abdaSPaul Mackerras 38*bbd0abdaSPaul Mackerras static int __init smp_chrp_probe(void) 39*bbd0abdaSPaul Mackerras { 40*bbd0abdaSPaul Mackerras if (smp_chrp_cpu_nr > 1) 41*bbd0abdaSPaul Mackerras openpic_request_IPIs(); 42*bbd0abdaSPaul Mackerras 43*bbd0abdaSPaul Mackerras return smp_chrp_cpu_nr; 44*bbd0abdaSPaul Mackerras } 45*bbd0abdaSPaul Mackerras 46*bbd0abdaSPaul Mackerras static void __devinit smp_chrp_kick_cpu(int nr) 47*bbd0abdaSPaul Mackerras { 48*bbd0abdaSPaul Mackerras *(unsigned long *)KERNELBASE = nr; 49*bbd0abdaSPaul Mackerras asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); 50*bbd0abdaSPaul Mackerras } 51*bbd0abdaSPaul Mackerras 52*bbd0abdaSPaul Mackerras static void __devinit smp_chrp_setup_cpu(int cpu_nr) 53*bbd0abdaSPaul Mackerras { 54*bbd0abdaSPaul Mackerras if (OpenPIC_Addr) 55*bbd0abdaSPaul Mackerras do_openpic_setup_cpu(); 56*bbd0abdaSPaul Mackerras } 57*bbd0abdaSPaul Mackerras 58*bbd0abdaSPaul Mackerras static DEFINE_SPINLOCK(timebase_lock); 59*bbd0abdaSPaul Mackerras static unsigned int timebase_upper = 0, timebase_lower = 0; 60*bbd0abdaSPaul Mackerras 61*bbd0abdaSPaul Mackerras void __devinit smp_chrp_give_timebase(void) 62*bbd0abdaSPaul Mackerras { 63*bbd0abdaSPaul Mackerras spin_lock(&timebase_lock); 64*bbd0abdaSPaul Mackerras rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); 65*bbd0abdaSPaul Mackerras timebase_upper = get_tbu(); 66*bbd0abdaSPaul Mackerras timebase_lower = get_tbl(); 67*bbd0abdaSPaul Mackerras spin_unlock(&timebase_lock); 68*bbd0abdaSPaul Mackerras 69*bbd0abdaSPaul Mackerras while (timebase_upper || timebase_lower) 70*bbd0abdaSPaul Mackerras barrier(); 71*bbd0abdaSPaul Mackerras rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); 72*bbd0abdaSPaul Mackerras } 73*bbd0abdaSPaul Mackerras 74*bbd0abdaSPaul Mackerras void __devinit smp_chrp_take_timebase(void) 75*bbd0abdaSPaul Mackerras { 76*bbd0abdaSPaul Mackerras while (!(timebase_upper || timebase_lower)) 77*bbd0abdaSPaul Mackerras barrier(); 78*bbd0abdaSPaul Mackerras spin_lock(&timebase_lock); 79*bbd0abdaSPaul Mackerras set_tb(timebase_upper, timebase_lower); 80*bbd0abdaSPaul Mackerras timebase_upper = 0; 81*bbd0abdaSPaul Mackerras timebase_lower = 0; 82*bbd0abdaSPaul Mackerras spin_unlock(&timebase_lock); 83*bbd0abdaSPaul Mackerras printk("CPU %i taken timebase\n", smp_processor_id()); 84*bbd0abdaSPaul Mackerras } 85*bbd0abdaSPaul Mackerras 86*bbd0abdaSPaul Mackerras /* CHRP with openpic */ 87*bbd0abdaSPaul Mackerras struct smp_ops_t chrp_smp_ops = { 88*bbd0abdaSPaul Mackerras .message_pass = smp_openpic_message_pass, 89*bbd0abdaSPaul Mackerras .probe = smp_chrp_probe, 90*bbd0abdaSPaul Mackerras .kick_cpu = smp_chrp_kick_cpu, 91*bbd0abdaSPaul Mackerras .setup_cpu = smp_chrp_setup_cpu, 92*bbd0abdaSPaul Mackerras .give_timebase = smp_chrp_give_timebase, 93*bbd0abdaSPaul Mackerras .take_timebase = smp_chrp_take_timebase, 94*bbd0abdaSPaul Mackerras }; 95