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