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.

467 lines
8.9 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. ioaccess.h
  5. Abstract:
  6. Definitions of function prototypes for accessing I/O ports and
  7. memory on I/O adapters from display drivers.
  8. Cloned from parts of nti386.h.
  9. Author:
  10. --*/
  11. //
  12. // Note: IA64 is for 64 bits Merced. Under Merced compiler option, we don't have
  13. // _X86_, instead, we use _IA64_. Same thing, _AXP64_ is for 64 bits compiler
  14. // option for ALPHA
  15. //
  16. #if defined(_MIPS_) || defined(_X86_) || defined(_AMD64_)
  17. //
  18. // Memory barriers on X86 and MIPS are not required since the Io
  19. // Operations are always garanteed to be executed in order
  20. //
  21. #define MEMORY_BARRIER() 0
  22. #elif defined(_IA64_)
  23. //
  24. // Itanium requires memory barriers
  25. //
  26. void __mf();
  27. #define MEMORY_BARRIER() __mf()
  28. #elif defined(_PPC_)
  29. //
  30. // A memory barrier function is provided by the PowerPC Enforce
  31. // In-order Execution of I/O instruction (eieio).
  32. //
  33. #if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000)
  34. void __emit( unsigned const __int32 );
  35. #define __builtin_eieio() __emit( 0x7C0006AC )
  36. #else
  37. void __builtin_eieio(void);
  38. #endif
  39. #define MEMORY_BARRIER() __builtin_eieio()
  40. #elif defined(_ALPHA_) || (_AXP64_)
  41. //
  42. // ALPHA requires memory barriers
  43. //
  44. #define MEMORY_BARRIER() __MB()
  45. #endif
  46. #ifndef NO_PORT_MACROS
  47. //
  48. // I/O space read and write macros.
  49. //
  50. // The READ/WRITE_REGISTER_* calls manipulate MEMORY registers.
  51. // (Use x86 move instructions, with LOCK prefix to force correct behavior
  52. // w.r.t. caches and write buffers.)
  53. //
  54. // The READ/WRITE_PORT_* calls manipulate I/O ports.
  55. // (Use x86 in/out instructions.)
  56. //
  57. //
  58. // inp(),inpw(), inpd(), outp(), outpw(), outpd() are X86 specific intrinsic
  59. // inline functions. So for IA64, we have to put READ_PORT_USHORT() etc. back
  60. // to it's supposed to be, defined in sdk\inc\wdm.h
  61. //
  62. #if defined(_IA64_)
  63. #define READ_REGISTER_UCHAR(Register) (*(volatile UCHAR *)(Register))
  64. #define READ_REGISTER_USHORT(Register) (*(volatile USHORT *)(Register))
  65. #define READ_REGISTER_ULONG(Register) (*(volatile ULONG *)(Register))
  66. #define WRITE_REGISTER_UCHAR(Register, Value) (*(volatile UCHAR *)(Register) = (Value))
  67. #define WRITE_REGISTER_USHORT(Register, Value) (*(volatile USHORT *)(Register) = (Value))
  68. #define WRITE_REGISTER_ULONG(Register, Value) (*(volatile ULONG *)(Register) = (Value))
  69. __declspec(dllimport)
  70. UCHAR
  71. READ_PORT_UCHAR(
  72. PVOID Port
  73. );
  74. __declspec(dllimport)
  75. USHORT
  76. READ_PORT_USHORT(
  77. PVOID Port
  78. );
  79. __declspec(dllimport)
  80. ULONG
  81. READ_PORT_ULONG(
  82. PVOID Port
  83. );
  84. //
  85. // All these function prototypes take a ULONG as a parameter so that
  86. // we don't force an extra typecast in the code (which will cause
  87. // the X86 to generate bad code).
  88. //
  89. __declspec(dllimport)
  90. VOID
  91. WRITE_PORT_UCHAR(
  92. PVOID Port,
  93. ULONG Value
  94. );
  95. __declspec(dllimport)
  96. VOID
  97. WRITE_PORT_USHORT(
  98. PVOID Port,
  99. ULONG Value
  100. );
  101. __declspec(dllimport)
  102. VOID
  103. WRITE_PORT_ULONG(
  104. PVOID Port,
  105. ULONG Value
  106. );
  107. #elif defined(_X86_)
  108. #define READ_REGISTER_UCHAR(Register) (*(volatile UCHAR *)(Register))
  109. #define READ_REGISTER_USHORT(Register) (*(volatile USHORT *)(Register))
  110. #define READ_REGISTER_ULONG(Register) (*(volatile ULONG *)(Register))
  111. #define WRITE_REGISTER_UCHAR(Register, Value) (*(volatile UCHAR *)(Register) = (Value))
  112. #define WRITE_REGISTER_USHORT(Register, Value) (*(volatile USHORT *)(Register) = (Value))
  113. #define WRITE_REGISTER_ULONG(Register, Value) (*(volatile ULONG *)(Register) = (Value))
  114. #define READ_PORT_UCHAR(Port) (UCHAR)(inp (Port))
  115. #define READ_PORT_USHORT(Port) (USHORT)(inpw (Port))
  116. #define READ_PORT_ULONG(Port) (ULONG)(inpd (Port))
  117. #define WRITE_PORT_UCHAR(Port, Value) outp ((Port), (Value))
  118. #define WRITE_PORT_USHORT(Port, Value) outpw ((Port), (Value))
  119. #define WRITE_PORT_ULONG(Port, Value) outpd ((Port), (Value))
  120. #elif defined(_PPC_) || defined(_MIPS_)
  121. #define READ_REGISTER_UCHAR(x) (*(volatile UCHAR * const)(x))
  122. #define READ_REGISTER_USHORT(x) (*(volatile USHORT * const)(x))
  123. #define READ_REGISTER_ULONG(x) (*(volatile ULONG * const)(x))
  124. #define WRITE_REGISTER_UCHAR(x, y) (*(volatile UCHAR * const)(x) = (y))
  125. #define WRITE_REGISTER_USHORT(x, y) (*(volatile USHORT * const)(x) = (y))
  126. #define WRITE_REGISTER_ULONG(x, y) (*(volatile ULONG * const)(x) = (y))
  127. #define READ_PORT_UCHAR(x) READ_REGISTER_UCHAR(x)
  128. #define READ_PORT_USHORT(x) READ_REGISTER_USHORT(x)
  129. #define READ_PORT_ULONG(x) READ_REGISTER_ULONG(x)
  130. //
  131. // All these macros take a ULONG as a parameter so that we don't
  132. // force an extra typecast in the code (which will cause the X86 to
  133. // generate bad code).
  134. //
  135. #define WRITE_PORT_UCHAR(x, y) WRITE_REGISTER_UCHAR(x, (UCHAR) (y))
  136. #define WRITE_PORT_USHORT(x, y) WRITE_REGISTER_USHORT(x, (USHORT) (y))
  137. #define WRITE_PORT_ULONG(x, y) WRITE_REGISTER_ULONG(x, (ULONG) (y))
  138. #elif defined(_ALPHA_) || (_AXP64_)
  139. //
  140. // READ/WRITE_PORT/REGISTER_UCHAR_USHORT_ULONG are all functions that
  141. // go to the HAL on ALPHA
  142. //
  143. // So we only put the prototypes here
  144. //
  145. __declspec(dllimport)
  146. UCHAR
  147. READ_REGISTER_UCHAR(
  148. PVOID Register
  149. );
  150. __declspec(dllimport)
  151. USHORT
  152. READ_REGISTER_USHORT(
  153. PVOID Register
  154. );
  155. __declspec(dllimport)
  156. ULONG
  157. READ_REGISTER_ULONG(
  158. PVOID Register
  159. );
  160. __declspec(dllimport)
  161. VOID
  162. WRITE_REGISTER_UCHAR(
  163. PVOID Register,
  164. UCHAR Value
  165. );
  166. __declspec(dllimport)
  167. VOID
  168. WRITE_REGISTER_USHORT(
  169. PVOID Register,
  170. USHORT Value
  171. );
  172. __declspec(dllimport)
  173. VOID
  174. WRITE_REGISTER_ULONG(
  175. PVOID Register,
  176. ULONG Value
  177. );
  178. __declspec(dllimport)
  179. UCHAR
  180. READ_PORT_UCHAR(
  181. PVOID Port
  182. );
  183. __declspec(dllimport)
  184. USHORT
  185. READ_PORT_USHORT(
  186. PVOID Port
  187. );
  188. __declspec(dllimport)
  189. ULONG
  190. READ_PORT_ULONG(
  191. PVOID Port
  192. );
  193. //
  194. // All these function prototypes take a ULONG as a parameter so that
  195. // we don't force an extra typecast in the code (which will cause
  196. // the X86 to generate bad code).
  197. //
  198. __declspec(dllimport)
  199. VOID
  200. WRITE_PORT_UCHAR(
  201. PVOID Port,
  202. ULONG Value
  203. );
  204. __declspec(dllimport)
  205. VOID
  206. WRITE_PORT_USHORT(
  207. PVOID Port,
  208. ULONG Value
  209. );
  210. __declspec(dllimport)
  211. VOID
  212. WRITE_PORT_ULONG(
  213. PVOID Port,
  214. ULONG Value
  215. );
  216. #elif defined(_AMD64_)
  217. UCHAR
  218. __inbyte (
  219. IN USHORT Port
  220. );
  221. USHORT
  222. __inword (
  223. IN USHORT Port
  224. );
  225. ULONG
  226. __indword (
  227. IN USHORT Port
  228. );
  229. VOID
  230. __outbyte (
  231. IN USHORT Port,
  232. IN UCHAR Data
  233. );
  234. VOID
  235. __outword (
  236. IN USHORT Port,
  237. IN USHORT Data
  238. );
  239. VOID
  240. __outdword (
  241. IN USHORT Port,
  242. IN ULONG Data
  243. );
  244. #pragma intrinsic(__inbyte)
  245. #pragma intrinsic(__inword)
  246. #pragma intrinsic(__indword)
  247. #pragma intrinsic(__outbyte)
  248. #pragma intrinsic(__outword)
  249. #pragma intrinsic(__outdword)
  250. LONG
  251. _InterlockedOr (
  252. IN OUT LONG volatile *Target,
  253. IN LONG Set
  254. );
  255. #pragma intrinsic(_InterlockedOr)
  256. __inline
  257. UCHAR
  258. READ_REGISTER_UCHAR (
  259. PVOID Register
  260. )
  261. {
  262. return *(UCHAR volatile *)Register;
  263. }
  264. __inline
  265. USHORT
  266. READ_REGISTER_USHORT (
  267. PVOID Register
  268. )
  269. {
  270. return *(USHORT volatile *)Register;
  271. }
  272. __inline
  273. ULONG
  274. READ_REGISTER_ULONG (
  275. PVOID Register
  276. )
  277. {
  278. return *(ULONG volatile *)Register;
  279. }
  280. __inline
  281. VOID
  282. WRITE_REGISTER_UCHAR (
  283. PVOID Register,
  284. UCHAR Value
  285. )
  286. {
  287. LONG Synch;
  288. *(UCHAR volatile *)Register = Value;
  289. _InterlockedOr(&Synch, 1);
  290. return;
  291. }
  292. __inline
  293. VOID
  294. WRITE_REGISTER_USHORT (
  295. PVOID Register,
  296. USHORT Value
  297. )
  298. {
  299. LONG Synch;
  300. *(USHORT volatile *)Register = Value;
  301. _InterlockedOr(&Synch, 1);
  302. return;
  303. }
  304. __inline
  305. VOID
  306. WRITE_REGISTER_ULONG (
  307. PVOID Register,
  308. ULONG Value
  309. )
  310. {
  311. LONG Synch;
  312. *(ULONG volatile *)Register = Value;
  313. _InterlockedOr(&Synch, 1);
  314. return;
  315. }
  316. __inline
  317. UCHAR
  318. READ_PORT_UCHAR (
  319. PVOID Port
  320. )
  321. {
  322. return __inbyte((USHORT)((ULONG64)Port));
  323. }
  324. __inline
  325. USHORT
  326. READ_PORT_USHORT (
  327. PVOID Port
  328. )
  329. {
  330. return __inword((USHORT)((ULONG64)Port));
  331. }
  332. __inline
  333. ULONG
  334. READ_PORT_ULONG (
  335. PVOID Port
  336. )
  337. {
  338. return __indword((USHORT)((ULONG64)Port));
  339. }
  340. __inline
  341. VOID
  342. WRITE_PORT_UCHAR (
  343. PVOID Port,
  344. UCHAR Value
  345. )
  346. {
  347. __outbyte((USHORT)((ULONG64)Port), Value);
  348. return;
  349. }
  350. __inline
  351. VOID
  352. WRITE_PORT_USHORT (
  353. PVOID Port,
  354. USHORT Value
  355. )
  356. {
  357. __outword((USHORT)((ULONG64)Port), Value);
  358. return;
  359. }
  360. __inline
  361. VOID
  362. WRITE_PORT_ULONG (
  363. PVOID Port,
  364. ULONG Value
  365. )
  366. {
  367. __outdword((USHORT)((ULONG64)Port), Value);
  368. return;
  369. }
  370. #endif // NO_PORT_MACROS
  371. #endif