smp.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. #include <asm/saturn/smpc.h>
  14. extern void start_secondary(void);
  15. void __smp_send_ipi(unsigned int cpu, unsigned int action)
  16. {
  17. /* Nothing here yet .. */
  18. }
  19. unsigned int __smp_probe_cpus(void)
  20. {
  21. /*
  22. * This is just a straightforward master/slave configuration,
  23. * and probing isn't really supported..
  24. */
  25. return 2;
  26. }
  27. /*
  28. * We're only allowed to do byte-access to SMPC registers. In
  29. * addition to which, we treat them as write-only, since
  30. * reading from them will return undefined data.
  31. */
  32. static inline void smpc_slave_stop(unsigned int cpu)
  33. {
  34. smpc_barrier();
  35. ctrl_outb(1, SMPC_STATUS);
  36. ctrl_outb(SMPC_CMD_SSHOFF, SMPC_COMMAND);
  37. smpc_barrier();
  38. }
  39. static inline void smpc_slave_start(unsigned int cpu)
  40. {
  41. ctrl_outb(1, SMPC_STATUS);
  42. ctrl_outb(SMPC_CMD_SSHON, SMPC_COMMAND);
  43. smpc_barrier();
  44. }
  45. void __smp_slave_init(unsigned int cpu)
  46. {
  47. register unsigned long vbr;
  48. void **entry;
  49. __asm__ __volatile__ ("stc vbr, %0\n\t" : "=r" (vbr));
  50. entry = (void **)(vbr + 0x310 + 0x94);
  51. smpc_slave_stop(cpu);
  52. *(void **)entry = (void *)start_secondary;
  53. smpc_slave_start(cpu);
  54. }