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> 37bbd0abdaSPaul Mackerras 38bbd0abdaSPaul Mackerras static void __devinit smp_chrp_kick_cpu(int nr) 39bbd0abdaSPaul Mackerras { 40bbd0abdaSPaul Mackerras *(unsigned long *)KERNELBASE = nr; 41bbd0abdaSPaul Mackerras asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); 42bbd0abdaSPaul Mackerras } 43bbd0abdaSPaul Mackerras 44bbd0abdaSPaul Mackerras static void __devinit smp_chrp_setup_cpu(int cpu_nr) 45bbd0abdaSPaul Mackerras { 4680579e1fSPaul Mackerras mpic_setup_this_cpu(); 47bbd0abdaSPaul Mackerras } 48bbd0abdaSPaul Mackerras 49bbd0abdaSPaul Mackerras static DEFINE_SPINLOCK(timebase_lock); 50bbd0abdaSPaul Mackerras static unsigned int timebase_upper = 0, timebase_lower = 0; 51bbd0abdaSPaul Mackerras 52bbd0abdaSPaul Mackerras void __devinit smp_chrp_give_timebase(void) 53bbd0abdaSPaul Mackerras { 54bbd0abdaSPaul Mackerras spin_lock(&timebase_lock); 55bbd0abdaSPaul Mackerras rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); 56bbd0abdaSPaul Mackerras timebase_upper = get_tbu(); 57bbd0abdaSPaul Mackerras timebase_lower = get_tbl(); 58bbd0abdaSPaul Mackerras spin_unlock(&timebase_lock); 59bbd0abdaSPaul Mackerras 60bbd0abdaSPaul Mackerras while (timebase_upper || timebase_lower) 61bbd0abdaSPaul Mackerras barrier(); 62bbd0abdaSPaul Mackerras rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); 63bbd0abdaSPaul Mackerras } 64bbd0abdaSPaul Mackerras 65bbd0abdaSPaul Mackerras void __devinit smp_chrp_take_timebase(void) 66bbd0abdaSPaul Mackerras { 67bbd0abdaSPaul Mackerras while (!(timebase_upper || timebase_lower)) 68bbd0abdaSPaul Mackerras barrier(); 69bbd0abdaSPaul Mackerras spin_lock(&timebase_lock); 70bbd0abdaSPaul Mackerras set_tb(timebase_upper, timebase_lower); 71bbd0abdaSPaul Mackerras timebase_upper = 0; 72bbd0abdaSPaul Mackerras timebase_lower = 0; 73bbd0abdaSPaul Mackerras spin_unlock(&timebase_lock); 74bbd0abdaSPaul Mackerras printk("CPU %i taken timebase\n", smp_processor_id()); 75bbd0abdaSPaul Mackerras } 76bbd0abdaSPaul Mackerras 77bbd0abdaSPaul Mackerras /* CHRP with openpic */ 78bbd0abdaSPaul Mackerras struct smp_ops_t chrp_smp_ops = { 7980579e1fSPaul Mackerras .message_pass = smp_mpic_message_pass, 80*5ad57078SPaul Mackerras .probe = smp_mpic_probe, 81bbd0abdaSPaul Mackerras .kick_cpu = smp_chrp_kick_cpu, 82bbd0abdaSPaul Mackerras .setup_cpu = smp_chrp_setup_cpu, 83bbd0abdaSPaul Mackerras .give_timebase = smp_chrp_give_timebase, 84bbd0abdaSPaul Mackerras .take_timebase = smp_chrp_take_timebase, 85bbd0abdaSPaul Mackerras }; 86