Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
7.6 KiB

  1. /*++
  2. Copyright (c) 1999 Intel Corporation
  3. Module Name:
  4. salpal.c
  5. Abstract:
  6. Functions to make SAL and PAL proc calls
  7. Revision History
  8. --*/
  9. #include "lib.h"
  10. #include "palproc.h"
  11. #include "SalProc.h"
  12. rArg
  13. MakeStaticPALCall (
  14. IN UINT64 PALPROCPtr,
  15. IN UINT64 Arg1,
  16. IN UINT64 Arg2,
  17. IN UINT64 Arg3,
  18. IN UINT64 Arg4
  19. );
  20. rArg
  21. MakeStackedPALCall (
  22. IN UINT64 PALPROCPtr,
  23. IN UINT64 Arg1,
  24. IN UINT64 Arg2,
  25. IN UINT64 Arg3,
  26. IN UINT64 Arg4
  27. );
  28. PLABEL SalProcPlabel;
  29. PLABEL PalProcPlabel;
  30. CALL_SAL_PROC GlobalSalProc;
  31. CALL_PAL_PROC GlobalPalProc;
  32. VOID
  33. LibInitSalAndPalProc (
  34. OUT PLABEL *SalPlabel,
  35. OUT UINT64 *PalEntry
  36. )
  37. {
  38. SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable;
  39. EFI_STATUS Status;
  40. GlobalSalProc = NULL;
  41. GlobalPalProc = NULL;
  42. Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, &SalSystemTable);
  43. if (EFI_ERROR(Status)) {
  44. return;
  45. }
  46. /*
  47. * BugBug: Add code to test checksum on the Sal System Table
  48. */
  49. if (SalSystemTable->Entry0.Type != 0) {
  50. return;
  51. }
  52. SalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.SalProcEntry;
  53. SalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer;
  54. GlobalSalProc = (CALL_SAL_PROC)&SalProcPlabel.ProcEntryPoint;
  55. /*
  56. * Need to check the PAL spec to make sure I'm not responsible for
  57. * storing more state.
  58. * We are passing in a Plabel that should be ignorred by the PAL. Call
  59. * this way will cause use to retore our gp after the PAL returns.
  60. */
  61. PalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.PalProcEntry;
  62. PalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer;
  63. GlobalPalProc = (CALL_PAL_PROC)PalProcPlabel.ProcEntryPoint;
  64. *PalEntry = PalProcPlabel.ProcEntryPoint;
  65. *SalPlabel = SalProcPlabel;
  66. }
  67. EFI_STATUS
  68. LibGetSalIoPortMapping (
  69. OUT UINT64 *IoPortMapping
  70. )
  71. /*++
  72. Get the IO Port Map from the SAL System Table.
  73. DO NOT USE THIS TO DO YOU OWN IO's!!!!!!!!!!!!
  74. Only use this for getting info, or initing the built in EFI IO abstraction.
  75. Always use the EFI Device IO protoocl to access IO space.
  76. --*/
  77. {
  78. SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable;
  79. SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc;
  80. EFI_STATUS Status;
  81. Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, &SalSystemTable);
  82. if (EFI_ERROR(Status)) {
  83. return EFI_UNSUPPORTED;
  84. }
  85. /*
  86. * BugBug: Add code to test checksum on the Sal System Table
  87. */
  88. if (SalSystemTable->Entry0.Type != 0) {
  89. return EFI_UNSUPPORTED;
  90. }
  91. /*
  92. * The SalSystemTable pointer includes the Type 0 entry.
  93. * The SalMemDesc is Type 1 so it comes next.
  94. */
  95. SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1);
  96. while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) {
  97. if (SalMemDesc->MemoryType == SAL_IO_PORT_MAPPING) {
  98. *IoPortMapping = SalMemDesc->PhysicalMemoryAddress;
  99. return EFI_SUCCESS;
  100. }
  101. SalMemDesc++;
  102. }
  103. return EFI_UNSUPPORTED;
  104. }
  105. EFI_STATUS
  106. LibGetSalIpiBlock (
  107. OUT UINT64 *IpiBlock
  108. )
  109. /*++
  110. Get the IPI block from the SAL system table
  111. --*/
  112. {
  113. SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable;
  114. SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc;
  115. EFI_STATUS Status;
  116. Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, &SalSystemTable);
  117. if (EFI_ERROR(Status)) {
  118. return EFI_UNSUPPORTED;
  119. }
  120. /*
  121. * BugBug: Add code to test checksum on the Sal System Table
  122. */
  123. if (SalSystemTable->Entry0.Type != 0) {
  124. return EFI_UNSUPPORTED;
  125. }
  126. /*
  127. * The SalSystemTable pointer includes the Type 0 entry.
  128. * The SalMemDesc is Type 1 so it comes next.
  129. */
  130. SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1);
  131. while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) {
  132. if (SalMemDesc->MemoryType == SAL_SAPIC_IPI_BLOCK ) {
  133. *IpiBlock = SalMemDesc->PhysicalMemoryAddress;
  134. return EFI_SUCCESS;
  135. }
  136. SalMemDesc++;
  137. }
  138. return EFI_UNSUPPORTED;
  139. }
  140. EFI_STATUS
  141. LibGetSalWakeupVector (
  142. OUT UINT64 *WakeVector
  143. )
  144. /*++
  145. Get the wakeup vector from the SAL system table
  146. --*/
  147. {
  148. SAL_ST_AP_WAKEUP_DECRIPTOR *ApWakeUp;
  149. ApWakeUp = LibSearchSalSystemTable (SAL_ST_AP_WAKEUP);
  150. if (!ApWakeUp) {
  151. *WakeVector = -1;
  152. return EFI_UNSUPPORTED;
  153. }
  154. *WakeVector = ApWakeUp->ExternalInterruptVector;
  155. return EFI_SUCCESS;
  156. }
  157. VOID *
  158. LibSearchSalSystemTable (
  159. IN UINT8 EntryType
  160. )
  161. {
  162. EFI_STATUS Status;
  163. UINT8 *SalTableHack;
  164. SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable;
  165. UINT16 EntryCount;
  166. UINT16 Count;
  167. Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, &SalSystemTable);
  168. if (EFI_ERROR(Status)) {
  169. return NULL;
  170. }
  171. EntryCount = SalSystemTable->Header.EntryCount;
  172. if (EntryCount == 0) {
  173. return NULL;
  174. }
  175. /*
  176. * BugBug: Add code to test checksum on the Sal System Table
  177. */
  178. SalTableHack = (UINT8 *)&SalSystemTable->Entry0;
  179. for (Count = 0; Count < EntryCount ;Count++) {
  180. if (*SalTableHack == EntryType) {
  181. return (VOID *)SalTableHack;
  182. }
  183. switch (*SalTableHack) {
  184. case SAL_ST_ENTRY_POINT:
  185. SalTableHack += 48;
  186. break;
  187. case SAL_ST_MEMORY_DESCRIPTOR:
  188. SalTableHack += 32;
  189. break;
  190. case SAL_ST_PLATFORM_FEATURES:
  191. SalTableHack += 16;
  192. break;
  193. case SAL_ST_TR_USAGE:
  194. SalTableHack += 32;
  195. break;
  196. case SAL_ST_PTC:
  197. SalTableHack += 16;
  198. break;
  199. case SAL_ST_AP_WAKEUP:
  200. SalTableHack += 16;
  201. break;
  202. default:
  203. ASSERT(FALSE);
  204. break;
  205. }
  206. }
  207. return NULL;
  208. }
  209. VOID
  210. LibSalProc (
  211. IN UINT64 Arg1,
  212. IN UINT64 Arg2,
  213. IN UINT64 Arg3,
  214. IN UINT64 Arg4,
  215. IN UINT64 Arg5,
  216. IN UINT64 Arg6,
  217. IN UINT64 Arg7,
  218. IN UINT64 Arg8,
  219. OUT rArg *Results OPTIONAL
  220. )
  221. {
  222. rArg ReturnValue;
  223. ReturnValue.p0 = -3; /* SAL status return completed with error */
  224. if (GlobalSalProc) {
  225. ReturnValue = GlobalSalProc(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
  226. }
  227. if (Results) {
  228. CopyMem (Results, &ReturnValue, sizeof(rArg));
  229. }
  230. }
  231. VOID
  232. LibPalProc (
  233. IN UINT64 Arg1, /* Pal Proc index */
  234. IN UINT64 Arg2,
  235. IN UINT64 Arg3,
  236. IN UINT64 Arg4,
  237. OUT rArg *Results OPTIONAL
  238. )
  239. {
  240. rArg ReturnValue;
  241. ReturnValue.p0 = -3; /* PAL status return completed with error */
  242. /*
  243. * check for valid PalProc entry point
  244. */
  245. if (!GlobalPalProc) {
  246. if (Results)
  247. CopyMem (Results, &ReturnValue, sizeof(rArg));
  248. return;
  249. }
  250. /*
  251. * check if index falls within stacked or static register calling conventions
  252. * and call appropriate Pal stub call
  253. */
  254. if (((Arg1 >=255) && (Arg1 <=511)) ||
  255. ((Arg1 >=768) && (Arg1 <=1023))) {
  256. ReturnValue = MakeStackedPALCall((UINT64)GlobalPalProc,Arg1,Arg2,Arg3,Arg4);
  257. }
  258. else {
  259. ReturnValue = MakeStaticPALCall((UINT64)GlobalPalProc,Arg1,Arg2,Arg3,Arg4);
  260. }
  261. if (Results)
  262. CopyMem (Results, &ReturnValue, sizeof(rArg));
  263. return;
  264. }