diag.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Implementation of s390 diagnose codes
  3. *
  4. * Copyright IBM Corp. 2007
  5. * Author(s): Michael Holzheu <holzheu@de.ibm.com>
  6. */
  7. #include <linux/module.h>
  8. #include <asm/diag.h>
  9. /*
  10. * Diagnose 10: Release pages
  11. */
  12. void diag10(unsigned long addr)
  13. {
  14. if (addr >= 0x7ff00000)
  15. return;
  16. asm volatile(
  17. #ifdef CONFIG_64BIT
  18. " sam31\n"
  19. " diag %0,%0,0x10\n"
  20. "0: sam64\n"
  21. #else
  22. " diag %0,%0,0x10\n"
  23. "0:\n"
  24. #endif
  25. EX_TABLE(0b, 0b)
  26. : : "a" (addr));
  27. }
  28. EXPORT_SYMBOL(diag10);
  29. /*
  30. * Diagnose 14: Input spool file manipulation
  31. */
  32. int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
  33. {
  34. register unsigned long _ry1 asm("2") = ry1;
  35. register unsigned long _ry2 asm("3") = subcode;
  36. int rc = 0;
  37. asm volatile(
  38. #ifdef CONFIG_64BIT
  39. " sam31\n"
  40. " diag %2,2,0x14\n"
  41. " sam64\n"
  42. #else
  43. " diag %2,2,0x14\n"
  44. #endif
  45. " ipm %0\n"
  46. " srl %0,28\n"
  47. : "=d" (rc), "+d" (_ry2)
  48. : "d" (rx), "d" (_ry1)
  49. : "cc");
  50. return rc;
  51. }
  52. EXPORT_SYMBOL(diag14);
  53. /*
  54. * Diagnose 210: Get information about a virtual device
  55. */
  56. int diag210(struct diag210 *addr)
  57. {
  58. /*
  59. * diag 210 needs its data below the 2GB border, so we
  60. * use a static data area to be sure
  61. */
  62. static struct diag210 diag210_tmp;
  63. static DEFINE_SPINLOCK(diag210_lock);
  64. unsigned long flags;
  65. int ccode;
  66. spin_lock_irqsave(&diag210_lock, flags);
  67. diag210_tmp = *addr;
  68. #ifdef CONFIG_64BIT
  69. asm volatile(
  70. " lhi %0,-1\n"
  71. " sam31\n"
  72. " diag %1,0,0x210\n"
  73. "0: ipm %0\n"
  74. " srl %0,28\n"
  75. "1: sam64\n"
  76. EX_TABLE(0b, 1b)
  77. : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
  78. #else
  79. asm volatile(
  80. " lhi %0,-1\n"
  81. " diag %1,0,0x210\n"
  82. "0: ipm %0\n"
  83. " srl %0,28\n"
  84. "1:\n"
  85. EX_TABLE(0b, 1b)
  86. : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
  87. #endif
  88. *addr = diag210_tmp;
  89. spin_unlock_irqrestore(&diag210_lock, flags);
  90. return ccode;
  91. }
  92. EXPORT_SYMBOL(diag210);