Leaked source code of windows server 2003
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.

351 lines
10 KiB

  1. /*++
  2. Copyright (c) 1999 Intel Corporation
  3. Module Name:
  4. io.c
  5. Abstract:
  6. Revision History
  7. --*/
  8. #include "shelle.h"
  9. typedef enum {
  10. EfiMemory,
  11. EFIMemoryMappedIo,
  12. EfiIo,
  13. EfiPciConfig
  14. } EFI_ACCESS_TYPE;
  15. EFI_STATUS
  16. DumpIoModify (
  17. IN EFI_HANDLE ImageHandle,
  18. IN EFI_SYSTEM_TABLE *SystemTable
  19. );
  20. VOID
  21. ReadMem (
  22. IN EFI_IO_WIDTH Width,
  23. IN UINT64 Address,
  24. IN UINTN Size,
  25. IN VOID *Buffer
  26. );
  27. VOID
  28. WriteMem (
  29. IN EFI_IO_WIDTH Width,
  30. IN UINT64 Address,
  31. IN UINTN Size,
  32. IN VOID *Buffer
  33. );
  34. EFI_DRIVER_ENTRY_POINT(DumpIoModify)
  35. EFI_STATUS
  36. DumpIoModify (
  37. IN EFI_HANDLE ImageHandle,
  38. IN EFI_SYSTEM_TABLE *SystemTable
  39. )
  40. /*+++
  41. iomod Address [Width] [;[MEM | MMIO | IO | PCI]] [:Value]
  42. if no Width 1 byte is default, 1|2|4|8 supported byte widths
  43. if no ; then default access type is memory (MEM)
  44. After a ; ;MEM = Memory, ;MMIO = Memmory Mapped IO, ;IO = in/out, PCI = PCI Config space
  45. --*/
  46. {
  47. EFI_STATUS Status;
  48. EFI_HANDLE Handle;
  49. EFI_DEVICE_PATH *DevicePath;
  50. EFI_DEVICE_IO_INTERFACE *IoDev;
  51. UINT64 Address;
  52. UINT64 Value;
  53. EFI_IO_WIDTH Width;
  54. EFI_ACCESS_TYPE AccessType;
  55. UINT64 Buffer;
  56. UINTN Index;
  57. UINTN Size;
  58. CHAR16 *AddressStr, *WidthStr, *p, *ValueStr;
  59. BOOLEAN Done;
  60. CHAR16 InputStr[80];
  61. BOOLEAN Interactive;
  62. InstallInternalShellCommand (
  63. ImageHandle, SystemTable, DumpIoModify,
  64. L"mm", /* command */
  65. L"mm Address [Width] [;Type]", /* command syntax */
  66. L"Memory Modify: Mem, MMIO, IO, PCI", /* 1 line descriptor */
  67. NULL /* command help page */
  68. );
  69. /*
  70. * The End Device Path represents the Root of the tree, thus get the global IoDev
  71. * for the system
  72. */
  73. InitializeShellApplication (ImageHandle, SystemTable);
  74. Width = IO_UINT8;
  75. Size = 1;
  76. AccessType = EfiMemory;
  77. AddressStr = WidthStr = NULL;
  78. ValueStr = NULL;
  79. Interactive = TRUE;
  80. for (Index = 1; Index < SI->Argc; Index += 1) {
  81. p = SI->Argv[Index];
  82. if (*p == ';') {
  83. switch (p[1]) {
  84. case 'I':
  85. case 'i':
  86. AccessType = EfiIo;
  87. continue;
  88. case 'P':
  89. case 'p':
  90. AccessType = EfiPciConfig;
  91. continue;
  92. default:
  93. case 'M':
  94. case 'm':
  95. if (p[2] == 'E' || p[2] == 'e') {
  96. AccessType = EfiMemory;
  97. }
  98. if (p[2] == 'M' || p[2] == 'm') {
  99. AccessType = EFIMemoryMappedIo;
  100. }
  101. continue;
  102. }
  103. } else if (*p == ':') {
  104. ValueStr = &p[1];
  105. Value = xtoi(ValueStr);
  106. continue;
  107. } else if (*p == '-') {
  108. switch (p[1]) {
  109. case 'n':
  110. case 'N': Interactive = FALSE;
  111. break;
  112. case 'h':
  113. case 'H':
  114. case '?':
  115. default:
  116. goto UsageError;
  117. };
  118. continue;
  119. }
  120. if (!AddressStr) {
  121. AddressStr = p;
  122. Address = xtoi(AddressStr);
  123. continue;
  124. }
  125. if (!WidthStr) {
  126. WidthStr = p;
  127. switch (xtoi(WidthStr)) {
  128. case 2:
  129. Width = IO_UINT16;
  130. Size = 2;
  131. continue;
  132. case 4:
  133. Width = IO_UINT32;
  134. Size = 4;
  135. continue;
  136. case 8:
  137. Width = IO_UINT64;
  138. Size = 8;
  139. continue;
  140. case 1:
  141. default:
  142. Width = IO_UINT8;
  143. Size = 1;
  144. continue;
  145. }
  146. }
  147. }
  148. if (!AddressStr) {
  149. goto UsageError;
  150. }
  151. if ((Address & (Size - 1)) != 0) {
  152. goto UsageError;
  153. }
  154. if (AccessType != EfiMemory) {
  155. DevicePath = EndDevicePath;
  156. Status = BS->LocateDevicePath (&DeviceIoProtocol, &DevicePath, &Handle);
  157. if (!EFI_ERROR(Status)) {
  158. Status = BS->HandleProtocol (Handle, &DeviceIoProtocol, (VOID*)&IoDev);
  159. }
  160. if (EFI_ERROR(Status)) {
  161. Print (L"%E - handle protocol error %r%N", Status);
  162. return Status;
  163. }
  164. }
  165. if (ValueStr) {
  166. if (AccessType == EFIMemoryMappedIo) {
  167. IoDev->Mem.Write (IoDev, Width, Address, 1, &Value);
  168. } else if (AccessType == EfiIo) {
  169. IoDev->Io.Write (IoDev, Width, Address, 1, &Value);
  170. } else if (AccessType == EfiPciConfig) {
  171. IoDev->Pci.Write (IoDev, Width, Address, 1, &Value);
  172. } else {
  173. WriteMem (Width, Address, 1, &Value);
  174. }
  175. return EFI_SUCCESS;
  176. }
  177. if (Interactive == FALSE) {
  178. Buffer = 0;
  179. if (AccessType == EFIMemoryMappedIo) {
  180. Print (L"%HMMIO%N");
  181. IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
  182. } else if (AccessType == EfiIo) {
  183. Print (L"%HIO%N");
  184. IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
  185. } else if (AccessType == EfiPciConfig) {
  186. Print (L"%HPCI%N");
  187. IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
  188. } else {
  189. Print (L"%HMEM%N");
  190. ReadMem (Width, Address, 1, &Buffer);
  191. }
  192. Print (L" 0x%016lx : 0x", Address);
  193. if (Size == 1) {
  194. Print (L"%02x", Buffer);
  195. } else if (Size == 2) {
  196. Print (L"%04x", Buffer);
  197. } else if (Size == 4) {
  198. Print (L"%08x", Buffer);
  199. } else if (Size == 8) {
  200. Print (L"%016lx", Buffer);
  201. }
  202. Print(L"\n");
  203. return EFI_SUCCESS;
  204. }
  205. Done = FALSE;
  206. do {
  207. Buffer = 0;
  208. if (AccessType == EFIMemoryMappedIo) {
  209. Print (L"%HMMIO%N");
  210. IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
  211. } else if (AccessType == EfiIo) {
  212. Print (L"%HIO%N");
  213. IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
  214. } else if (AccessType == EfiPciConfig) {
  215. Print (L"%HPCI%N");
  216. IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
  217. } else {
  218. Print (L"%HMEM%N");
  219. ReadMem (Width, Address, 1, &Buffer);
  220. }
  221. Print (L" 0x%016lx : 0x", Address);
  222. if (Size == 1) {
  223. Print (L"%02x", Buffer);
  224. } else if (Size == 2) {
  225. Print (L"%04x", Buffer);
  226. } else if (Size == 4) {
  227. Print (L"%08x", Buffer);
  228. } else if (Size == 8) {
  229. Print (L"%016lx", Buffer);
  230. }
  231. Input (L" > ", InputStr, sizeof(InputStr));
  232. if (*InputStr == '.' || *InputStr == 'e' || *InputStr == 'q' || *InputStr == 'E' || *InputStr == 'Q' ) {
  233. Done = TRUE;
  234. } else if (*InputStr != 0x00) {
  235. Buffer = xtoi(InputStr);
  236. if (AccessType == EFIMemoryMappedIo) {
  237. IoDev->Mem.Write (IoDev, Width, Address, 1, &Buffer);
  238. } else if (AccessType == EfiIo) {
  239. IoDev->Io.Write (IoDev, Width, Address, 1, &Buffer);
  240. } else if (AccessType == EfiPciConfig) {
  241. IoDev->Pci.Write (IoDev, Width, Address, 1, &Buffer);
  242. } else {
  243. WriteMem (Width, Address, 1, &Buffer);
  244. }
  245. }
  246. Address += Size;
  247. Print (L"\n");
  248. } while (!Done);
  249. return EFI_SUCCESS;
  250. UsageError:
  251. Print (L"\n%Hmm%N %HAddress%N [%HWidth%N 1|2|4|8] [%H;MMIO | ;MEM | ;IO | ;PCI%N] [%H:Value%N] [%H-n%N]\n");
  252. Print (L" Default access is %HMEM%N of width 1 byte with interactive mode off\n");
  253. Print (L" Address must be aligned on a %HWidth%N boundary\n");
  254. Print (L" %HMEM%N - Memory Address 0 - 0xffffffff_ffffffff\n");
  255. Print (L" %HMMIO%N - Memory Mapped IO Address 0 - 0xffffffff_ffffffff\n");
  256. Print (L" %HIO%N - IO Address 0 - 0xffff\n");
  257. Print (L" %HPCI%N - PCI Config Address 0x000000%Hss%Nbb%Hdd%Nff%Hrr%N\n");
  258. Print (L" %Hss%N-> _SEG bb-> bus %Hdd%N-> Device ff-> Func %Hrr%N-> Register\n");
  259. Print (L" [%H-n%N] - Interactive Mode Off\n");
  260. return EFI_SUCCESS;
  261. }
  262. VOID
  263. ReadMem (
  264. IN EFI_IO_WIDTH Width,
  265. IN UINT64 Address,
  266. IN UINTN Size,
  267. IN VOID *Buffer
  268. )
  269. {
  270. do {
  271. if (Width == IO_UINT8) {
  272. *(UINT8 *)Buffer = *(UINT8 *)Address;
  273. Address -= 1;
  274. } else if (Width == IO_UINT16) {
  275. *(UINT16 *)Buffer = *(UINT16 *)Address;
  276. Address -= 2;
  277. } else if (Width == IO_UINT32) {
  278. *(UINT32 *)Buffer = *(UINT32 *)Address;
  279. Address -= 4;
  280. } else if (Width == IO_UINT64) {
  281. *(UINT64 *)Buffer = *(UINT64 *)Address;
  282. Address -= 8;
  283. } else {
  284. ASSERT(FALSE);
  285. }
  286. Size--;
  287. } while (Size > 0);
  288. }
  289. VOID
  290. WriteMem (
  291. IN EFI_IO_WIDTH Width,
  292. IN UINT64 Address,
  293. IN UINTN Size,
  294. IN VOID *Buffer
  295. )
  296. {
  297. do {
  298. if (Width == IO_UINT8) {
  299. *(UINT8 *)Address = *(UINT8 *)Buffer;
  300. Address += 1;
  301. } else if (Width == IO_UINT16) {
  302. *(UINT16 *)Address = *(UINT16 *)Buffer;
  303. Address += 2;
  304. } else if (Width == IO_UINT32) {
  305. *(UINT32 *)Address = *(UINT32 *)Buffer;
  306. Address += 4;
  307. } else if (Width == IO_UINT64) {
  308. *(UINT64 *)Address = *(UINT64 *)Buffer;
  309. Address += 8;
  310. } else {
  311. ASSERT(FALSE);
  312. }
  313. Size--;
  314. } while (Size > 0);
  315. }