malta-amon.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2007 MIPS Technologies, Inc. All rights reserved.
  7. * Copyright (C) 2013 Imagination Technologies Ltd.
  8. *
  9. * Arbitrary Monitor Interface
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/smp.h>
  13. #include <asm/addrspace.h>
  14. #include <asm/mipsmtregs.h>
  15. #include <asm/mips-boards/launch.h>
  16. #include <asm/vpe.h>
  17. int amon_cpu_avail(int cpu)
  18. {
  19. struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
  20. if (cpu < 0 || cpu >= NCPULAUNCH) {
  21. pr_debug("avail: cpu%d is out of range\n", cpu);
  22. return 0;
  23. }
  24. launch += cpu;
  25. if (!(launch->flags & LAUNCH_FREADY)) {
  26. pr_debug("avail: cpu%d is not ready\n", cpu);
  27. return 0;
  28. }
  29. if (launch->flags & (LAUNCH_FGO|LAUNCH_FGONE)) {
  30. pr_debug("avail: too late.. cpu%d is already gone\n", cpu);
  31. return 0;
  32. }
  33. return 1;
  34. }
  35. int amon_cpu_start(int cpu,
  36. unsigned long pc, unsigned long sp,
  37. unsigned long gp, unsigned long a0)
  38. {
  39. volatile struct cpulaunch *launch =
  40. (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
  41. if (!amon_cpu_avail(cpu))
  42. return -1;
  43. if (cpu == smp_processor_id()) {
  44. pr_debug("launch: I am cpu%d!\n", cpu);
  45. return -1;
  46. }
  47. launch += cpu;
  48. pr_debug("launch: starting cpu%d\n", cpu);
  49. launch->pc = pc;
  50. launch->gp = gp;
  51. launch->sp = sp;
  52. launch->a0 = a0;
  53. smp_wmb(); /* Target must see parameters before go */
  54. launch->flags |= LAUNCH_FGO;
  55. smp_wmb(); /* Target must see go before we poll */
  56. while ((launch->flags & LAUNCH_FGONE) == 0)
  57. ;
  58. smp_rmb(); /* Target will be updating flags soon */
  59. pr_debug("launch: cpu%d gone!\n", cpu);
  60. return 0;
  61. }
  62. #ifdef CONFIG_MIPS_VPE_LOADER_CMP
  63. int vpe_run(struct vpe *v)
  64. {
  65. struct vpe_notifications *n;
  66. if (amon_cpu_start(aprp_cpu_index(), v->__start, 0, 0, 0) < 0)
  67. return -1;
  68. list_for_each_entry(n, &v->notify, list)
  69. n->start(VPE_MODULE_MINOR);
  70. return 0;
  71. }
  72. #endif