1/* 2 * arch/sh/boards/saturn/smp.c 3 * 4 * SMP support for the Sega Saturn. 5 * 6 * Copyright (c) 2002 Paul Mundt 7 * 8 * Released under the terms of the GNU GPL v2.0. 9 */ 10#include <linux/kernel.h> 11#include <linux/init.h> 12#include <linux/smp.h> 13 14#include <asm/saturn/smpc.h> 15 16extern void start_secondary(void); 17 18void __smp_send_ipi(unsigned int cpu, unsigned int action) 19{ 20 /* Nothing here yet .. */ 21} 22 23unsigned int __smp_probe_cpus(void) 24{ 25 /* 26 * This is just a straightforward master/slave configuration, 27 * and probing isn't really supported.. 28 */ 29 return 2; 30} 31 32/* 33 * We're only allowed to do byte-access to SMPC registers. In 34 * addition to which, we treat them as write-only, since 35 * reading from them will return undefined data. 36 */ 37static inline void smpc_slave_stop(unsigned int cpu) 38{ 39 smpc_barrier(); 40 ctrl_outb(1, SMPC_STATUS); 41 42 ctrl_outb(SMPC_CMD_SSHOFF, SMPC_COMMAND); 43 smpc_barrier(); 44} 45 46static inline void smpc_slave_start(unsigned int cpu) 47{ 48 ctrl_outb(1, SMPC_STATUS); 49 ctrl_outb(SMPC_CMD_SSHON, SMPC_COMMAND); 50 51 smpc_barrier(); 52} 53 54void __smp_slave_init(unsigned int cpu) 55{ 56 register unsigned long vbr; 57 void **entry; 58 59 __asm__ __volatile__ ("stc vbr, %0\n\t" : "=r" (vbr)); 60 entry = (void **)(vbr + 0x310 + 0x94); 61 62 smpc_slave_stop(cpu); 63 64 *(void **)entry = (void *)start_secondary; 65 66 smpc_slave_start(cpu); 67} 68