LparData.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * Copyright 2001 Mike Corrigan, IBM Corp
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. */
  9. #include <linux/config.h>
  10. #include <linux/types.h>
  11. #include <linux/threads.h>
  12. #include <linux/module.h>
  13. #include <linux/bitops.h>
  14. #include <asm/processor.h>
  15. #include <asm/ptrace.h>
  16. #include <asm/naca.h>
  17. #include <asm/abs_addr.h>
  18. #include <asm/iSeries/ItLpNaca.h>
  19. #include <asm/lppaca.h>
  20. #include <asm/iSeries/ItLpRegSave.h>
  21. #include <asm/paca.h>
  22. #include <asm/iSeries/HvReleaseData.h>
  23. #include <asm/iSeries/LparMap.h>
  24. #include <asm/iSeries/ItVpdAreas.h>
  25. #include <asm/iSeries/ItIplParmsReal.h>
  26. #include <asm/iSeries/ItExtVpdPanel.h>
  27. #include <asm/iSeries/ItLpQueue.h>
  28. #include <asm/iSeries/IoHriProcessorVpd.h>
  29. #include <asm/iSeries/ItSpCommArea.h>
  30. /* The HvReleaseData is the root of the information shared between
  31. * the hypervisor and Linux.
  32. */
  33. struct HvReleaseData hvReleaseData = {
  34. .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */
  35. .xSize = sizeof(struct HvReleaseData),
  36. .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas),
  37. .xSlicNacaAddr = &naca, /* 64-bit Naca address */
  38. .xMsNucDataOffset = 0x4800, /* offset of LparMap within loadarea (see head.S) */
  39. .xTagsMode = 1, /* tags inactive */
  40. .xAddressSize = 0, /* 64 bit */
  41. .xNoSharedProcs = 0, /* shared processors */
  42. .xNoHMT = 0, /* HMT allowed */
  43. .xRsvd2 = 6, /* TEMP: This allows non-GA driver */
  44. .xVrmIndex = 4, /* We are v5r2m0 */
  45. .xMinSupportedPlicVrmIndex = 3, /* v5r1m0 */
  46. .xMinCompatablePlicVrmIndex = 3, /* v5r1m0 */
  47. .xVrmName = { 0xd3, 0x89, 0x95, 0xa4, /* "Linux 2.4.64" ebcdic */
  48. 0xa7, 0x40, 0xf2, 0x4b,
  49. 0xf4, 0x4b, 0xf6, 0xf4 },
  50. };
  51. extern void system_reset_iSeries(void);
  52. extern void machine_check_iSeries(void);
  53. extern void data_access_iSeries(void);
  54. extern void instruction_access_iSeries(void);
  55. extern void hardware_interrupt_iSeries(void);
  56. extern void alignment_iSeries(void);
  57. extern void program_check_iSeries(void);
  58. extern void fp_unavailable_iSeries(void);
  59. extern void decrementer_iSeries(void);
  60. extern void trap_0a_iSeries(void);
  61. extern void trap_0b_iSeries(void);
  62. extern void system_call_iSeries(void);
  63. extern void single_step_iSeries(void);
  64. extern void trap_0e_iSeries(void);
  65. extern void performance_monitor_iSeries(void);
  66. extern void data_access_slb_iSeries(void);
  67. extern void instruction_access_slb_iSeries(void);
  68. struct ItLpNaca itLpNaca = {
  69. .xDesc = 0xd397d581, /* "LpNa" ebcdic */
  70. .xSize = 0x0400, /* size of ItLpNaca */
  71. .xIntHdlrOffset = 0x0300, /* offset to int array */
  72. .xMaxIntHdlrEntries = 19, /* # ents */
  73. .xPrimaryLpIndex = 0, /* Part # of primary */
  74. .xServiceLpIndex = 0, /* Part # of serv */
  75. .xLpIndex = 0, /* Part # of me */
  76. .xMaxLpQueues = 0, /* # of LP queues */
  77. .xLpQueueOffset = 0x100, /* offset of start of LP queues */
  78. .xPirEnvironMode = 0, /* Piranha stuff */
  79. .xPirConsoleMode = 0,
  80. .xPirDasdMode = 0,
  81. .xLparInstalled = 0,
  82. .xSysPartitioned = 0,
  83. .xHwSyncedTBs = 0,
  84. .xIntProcUtilHmt = 0,
  85. .xSpVpdFormat = 0,
  86. .xIntProcRatio = 0,
  87. .xPlicVrmIndex = 0, /* VRM index of PLIC */
  88. .xMinSupportedSlicVrmInd = 0, /* min supported SLIC */
  89. .xMinCompatableSlicVrmInd = 0, /* min compat SLIC */
  90. .xLoadAreaAddr = 0, /* 64-bit addr of load area */
  91. .xLoadAreaChunks = 0, /* chunks for load area */
  92. .xPaseSysCallCRMask = 0, /* PASE mask */
  93. .xSlicSegmentTablePtr = 0, /* seg table */
  94. .xOldLpQueue = { 0 }, /* Old LP Queue */
  95. .xInterruptHdlr = {
  96. (u64)system_reset_iSeries, /* 0x100 System Reset */
  97. (u64)machine_check_iSeries, /* 0x200 Machine Check */
  98. (u64)data_access_iSeries, /* 0x300 Data Access */
  99. (u64)instruction_access_iSeries, /* 0x400 Instruction Access */
  100. (u64)hardware_interrupt_iSeries, /* 0x500 External */
  101. (u64)alignment_iSeries, /* 0x600 Alignment */
  102. (u64)program_check_iSeries, /* 0x700 Program Check */
  103. (u64)fp_unavailable_iSeries, /* 0x800 FP Unavailable */
  104. (u64)decrementer_iSeries, /* 0x900 Decrementer */
  105. (u64)trap_0a_iSeries, /* 0xa00 Trap 0A */
  106. (u64)trap_0b_iSeries, /* 0xb00 Trap 0B */
  107. (u64)system_call_iSeries, /* 0xc00 System Call */
  108. (u64)single_step_iSeries, /* 0xd00 Single Step */
  109. (u64)trap_0e_iSeries, /* 0xe00 Trap 0E */
  110. (u64)performance_monitor_iSeries,/* 0xf00 Performance Monitor */
  111. 0, /* int 0x1000 */
  112. 0, /* int 0x1010 */
  113. 0, /* int 0x1020 CPU ctls */
  114. (u64)hardware_interrupt_iSeries, /* SC Ret Hdlr */
  115. (u64)data_access_slb_iSeries, /* 0x380 D-SLB */
  116. (u64)instruction_access_slb_iSeries /* 0x480 I-SLB */
  117. }
  118. };
  119. EXPORT_SYMBOL(itLpNaca);
  120. /* May be filled in by the hypervisor so cannot end up in the BSS */
  121. struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
  122. /* May be filled in by the hypervisor so cannot end up in the BSS */
  123. struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
  124. EXPORT_SYMBOL(xItExtVpdPanel);
  125. #define maxPhysicalProcessors 32
  126. struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
  127. {
  128. .xInstCacheOperandSize = 32,
  129. .xDataCacheOperandSize = 32,
  130. .xProcFreq = 50000000,
  131. .xTimeBaseFreq = 50000000,
  132. .xPVR = 0x3600
  133. }
  134. };
  135. /* Space for Main Store Vpd 27,200 bytes */
  136. /* May be filled in by the hypervisor so cannot end up in the BSS */
  137. u64 xMsVpd[3400] __attribute__((__section__(".data")));
  138. /* Space for Recovery Log Buffer */
  139. /* May be filled in by the hypervisor so cannot end up in the BSS */
  140. u64 xRecoveryLogBuffer[32] __attribute__((__section__(".data")));
  141. struct SpCommArea xSpCommArea = {
  142. .xDesc = 0xE2D7C3C2,
  143. .xFormat = 1,
  144. };
  145. /* The LparMap data is now located at offset 0x6000 in head.S
  146. * It was put there so that the HvReleaseData could address it
  147. * with a 32-bit offset as required by the iSeries hypervisor
  148. *
  149. * The Naca has a pointer to the ItVpdAreas. The hypervisor finds
  150. * the Naca via the HvReleaseData area. The HvReleaseData has the
  151. * offset into the Naca of the pointer to the ItVpdAreas.
  152. */
  153. struct ItVpdAreas itVpdAreas = {
  154. .xSlicDesc = 0xc9a3e5c1, /* "ItVA" */
  155. .xSlicSize = sizeof(struct ItVpdAreas),
  156. .xSlicVpdEntries = ItVpdMaxEntries, /* # VPD array entries */
  157. .xSlicDmaEntries = ItDmaMaxEntries, /* # DMA array entries */
  158. .xSlicMaxLogicalProcs = NR_CPUS * 2, /* Max logical procs */
  159. .xSlicMaxPhysicalProcs = maxPhysicalProcessors, /* Max physical procs */
  160. .xSlicDmaToksOffset = offsetof(struct ItVpdAreas, xPlicDmaToks),
  161. .xSlicVpdAdrsOffset = offsetof(struct ItVpdAreas, xSlicVpdAdrs),
  162. .xSlicDmaLensOffset = offsetof(struct ItVpdAreas, xPlicDmaLens),
  163. .xSlicVpdLensOffset = offsetof(struct ItVpdAreas, xSlicVpdLens),
  164. .xSlicMaxSlotLabels = 0, /* max slot labels */
  165. .xSlicMaxLpQueues = 1, /* max LP queues */
  166. .xPlicDmaLens = { 0 }, /* DMA lengths */
  167. .xPlicDmaToks = { 0 }, /* DMA tokens */
  168. .xSlicVpdLens = { /* VPD lengths */
  169. 0,0,0, /* 0 - 2 */
  170. sizeof(xItExtVpdPanel), /* 3 Extended VPD */
  171. sizeof(struct paca_struct), /* 4 length of Paca */
  172. 0, /* 5 */
  173. sizeof(struct ItIplParmsReal),/* 6 length of IPL parms */
  174. 26992, /* 7 length of MS VPD */
  175. 0, /* 8 */
  176. sizeof(struct ItLpNaca),/* 9 length of LP Naca */
  177. 0, /* 10 */
  178. 256, /* 11 length of Recovery Log Buf */
  179. sizeof(struct SpCommArea), /* 12 length of SP Comm Area */
  180. 0,0,0, /* 13 - 15 */
  181. sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */
  182. 0,0,0,0,0,0, /* 17 - 22 */
  183. sizeof(struct hvlpevent_queue), /* 23 length of Lp Queue */
  184. 0,0 /* 24 - 25 */
  185. },
  186. .xSlicVpdAdrs = { /* VPD addresses */
  187. 0,0,0, /* 0 - 2 */
  188. &xItExtVpdPanel, /* 3 Extended VPD */
  189. &paca[0], /* 4 first Paca */
  190. 0, /* 5 */
  191. &xItIplParmsReal, /* 6 IPL parms */
  192. &xMsVpd, /* 7 MS Vpd */
  193. 0, /* 8 */
  194. &itLpNaca, /* 9 LpNaca */
  195. 0, /* 10 */
  196. &xRecoveryLogBuffer, /* 11 Recovery Log Buffer */
  197. &xSpCommArea, /* 12 SP Comm Area */
  198. 0,0,0, /* 13 - 15 */
  199. &xIoHriProcessorVpd, /* 16 Proc Vpd */
  200. 0,0,0,0,0,0, /* 17 - 22 */
  201. &hvlpevent_queue, /* 23 Lp Queue */
  202. 0,0
  203. }
  204. };
  205. struct msChunks msChunks;
  206. EXPORT_SYMBOL(msChunks);
  207. /* Depending on whether this is called from iSeries or pSeries setup
  208. * code, the location of the msChunks struct may or may not have
  209. * to be reloc'd, so we force the caller to do that for us by passing
  210. * in a pointer to the structure.
  211. */
  212. unsigned long
  213. msChunks_alloc(unsigned long mem, unsigned long num_chunks, unsigned long chunk_size)
  214. {
  215. unsigned long offset = reloc_offset();
  216. struct msChunks *_msChunks = PTRRELOC(&msChunks);
  217. _msChunks->num_chunks = num_chunks;
  218. _msChunks->chunk_size = chunk_size;
  219. _msChunks->chunk_shift = __ilog2(chunk_size);
  220. _msChunks->chunk_mask = (1UL<<_msChunks->chunk_shift)-1;
  221. mem = _ALIGN(mem, sizeof(msChunks_entry));
  222. _msChunks->abs = (msChunks_entry *)(mem + offset);
  223. mem += num_chunks * sizeof(msChunks_entry);
  224. return mem;
  225. }