x86.pp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1997-2004 by the Free Pascal development team
  4. Some x86 specific stuff. Has to be fixed still for *BSD
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY;without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit x86;
  12. interface
  13. {$inline on}
  14. Uses BaseUnix;
  15. function ReadPortB (Port : Longint): Byte;inline;
  16. function ReadPortW (Port : Longint): Word;inline;
  17. function ReadPortL (Port : Longint): Longint;inline;
  18. Procedure ReadPort (Port : Longint; Var Value : Byte);inline;
  19. Procedure ReadPort (Port : Longint; Var Value : Longint);inline;
  20. Procedure ReadPort (Port : Longint; Var Value : Word);inline;
  21. Procedure ReadPortB (Port : Longint; Var Buf; Count: longint);
  22. Procedure ReadPortL (Port : Longint; Var Buf; Count: longint);
  23. Procedure ReadPortW (Port : Longint; Var Buf; Count: longint);
  24. Procedure WritePort (Port : Longint; Value : Byte);inline;
  25. Procedure WritePort (Port : Longint; Value : Longint);inline;
  26. Procedure WritePort (Port : Longint; Value : Word);inline;
  27. Procedure WritePortB (Port : Longint; Value : Byte);inline;
  28. Procedure WritePortB (Port : Longint; Var Buf; Count: longint);
  29. Procedure WritePortL (Port : Longint; Value : Longint);inline;
  30. Procedure WritePortW (Port : Longint; Value : Word);inline;
  31. Procedure WritePortW (Port : Longint; Var Buf; Count: longint);
  32. Procedure WritePortl (Port : Longint; Var Buf; Count: longint);
  33. Function fpIOperm (From,Num : Cardinal; Value : cint) : cint;
  34. Function fpIoPL(Level : cint) : cint;
  35. implementation
  36. {$ASMMODE ATT}
  37. Uses Syscall;
  38. {$IFDEF VER3_0}
  39. { Bootstrapping kludge. Note that these do nothing, but since I/O ports are not
  40. necessary for bootstrapping, these are only added to make the rtl compile
  41. with 3.0.
  42. }
  43. procedure fpc_x86_outportb(p:longint;v:byte); begin end;
  44. procedure fpc_x86_outportw(p:longint;v:word); begin end;
  45. procedure fpc_x86_outportl(p:longint;v:longint); begin end;
  46. function fpc_x86_inportb(p:word):byte; begin fpc_x86_inportb:=0; end;
  47. function fpc_x86_inportw(p:word):word; begin fpc_x86_inportw:=0; end;
  48. function fpc_x86_inportl(p:word):longint; begin fpc_x86_inportl:=0; end;
  49. {$ENDIF VER3_0}
  50. Procedure WritePort (Port : Longint; Value : Byte);inline;
  51. {
  52. Writes 'Value' to port 'Port'
  53. }
  54. begin
  55. fpc_x86_outportb(Port,Value);
  56. end;
  57. Procedure WritePort (Port : Longint; Value : Word);inline;
  58. {
  59. Writes 'Value' to port 'Port'
  60. }
  61. begin
  62. fpc_x86_outportw(Port,Value);
  63. end;
  64. Procedure WritePort (Port : Longint; Value : Longint);inline;
  65. {
  66. Writes 'Value' to port 'Port'
  67. }
  68. begin
  69. fpc_x86_outportl(Port,Value);
  70. end;
  71. Procedure WritePortB (Port : Longint; Value : Byte);inline;
  72. {
  73. Writes 'Value' to port 'Port'
  74. }
  75. begin
  76. fpc_x86_outportb(Port,Value);
  77. end;
  78. Procedure WritePortW (Port : Longint; Value : Word);inline;
  79. {
  80. Writes 'Value' to port 'Port'
  81. }
  82. begin
  83. fpc_x86_outportw(Port,Value);
  84. end;
  85. Procedure WritePortL (Port : Longint; Value : Longint);inline;
  86. {
  87. Writes 'Value' to port 'Port'
  88. }
  89. begin
  90. fpc_x86_outportl(Port,Value);
  91. end;
  92. Procedure WritePortl (Port : Longint; Var Buf; Count: longint);
  93. {
  94. Writes 'Count' longints from 'Buf' to Port
  95. }
  96. begin
  97. asm
  98. {$ifdef CPU386}
  99. movl count,%ecx
  100. movl buf,%esi
  101. movl port,%edx
  102. cld
  103. rep
  104. outsl
  105. {$endif CPU386}
  106. {$ifdef CPUX86_64}
  107. movl count,%ecx
  108. movq buf,%rsi
  109. movl port,%edx
  110. cld
  111. rep
  112. outsl
  113. {$endif CPUX86_64}
  114. end;
  115. end;
  116. Procedure WritePortW (Port : Longint; Var Buf; Count: longint);
  117. {
  118. Writes 'Count' words from 'Buf' to Port
  119. }
  120. begin
  121. asm
  122. {$ifdef CPU386}
  123. movl count,%ecx
  124. movl buf,%esi
  125. movl port,%edx
  126. cld
  127. rep
  128. outsw
  129. {$endif CPU386}
  130. {$ifdef CPUX86_64}
  131. movl count,%ecx
  132. movq buf,%rsi
  133. movl port,%edx
  134. cld
  135. rep
  136. outsw
  137. {$endif CPUX86_64}
  138. end;
  139. end;
  140. Procedure WritePortB (Port : Longint; Var Buf; Count: longint);
  141. {
  142. Writes 'Count' bytes from 'Buf' to Port
  143. }
  144. begin
  145. asm
  146. {$ifdef CPU386}
  147. movl count,%ecx
  148. movl buf,%esi
  149. movl port,%edx
  150. cld
  151. rep
  152. outsb
  153. {$endif CPU386}
  154. {$ifdef CPUX86_64}
  155. movl count,%ecx
  156. movq buf,%rsi
  157. movl port,%edx
  158. cld
  159. rep
  160. outsb
  161. {$endif CPUX86_64}
  162. end;
  163. end;
  164. Procedure ReadPort (Port : Longint; Var Value : Byte);inline;
  165. {
  166. Reads 'Value' from port 'Port'
  167. }
  168. begin
  169. Value:=fpc_x86_inportb(Port);
  170. end;
  171. Procedure ReadPort (Port : Longint; Var Value : Word);inline;
  172. {
  173. Reads 'Value' from port 'Port'
  174. }
  175. begin
  176. Value:=fpc_x86_inportw(Port);
  177. end;
  178. Procedure ReadPort (Port : Longint; Var Value : Longint);inline;
  179. {
  180. Reads 'Value' from port 'Port'
  181. }
  182. begin
  183. Value:=fpc_x86_inportl(Port);
  184. end;
  185. function ReadPortB (Port : Longint): Byte;inline;
  186. {
  187. Reads a byte from port 'Port'
  188. }
  189. begin
  190. ReadPortB:=fpc_x86_inportb(Port);
  191. end;
  192. function ReadPortW (Port : Longint): Word;inline;
  193. {
  194. Reads a word from port 'Port'
  195. }
  196. begin
  197. ReadPortW:=fpc_x86_inportw(Port);
  198. end;
  199. function ReadPortL (Port : Longint): LongInt;inline;
  200. {
  201. Reads a LongInt from port 'Port'
  202. }
  203. begin
  204. ReadPortL:=fpc_x86_inportl(Port);
  205. end;
  206. Procedure ReadPortL (Port : Longint; Var Buf; Count: longint);
  207. {
  208. Reads 'Count' longints from port 'Port' to 'Buf'.
  209. }
  210. begin
  211. asm
  212. {$ifdef CPU386}
  213. movl count,%ecx
  214. movl buf,%edi
  215. movl port,%edx
  216. cld
  217. rep
  218. insl
  219. {$endif CPU386}
  220. {$ifdef CPUX86_64}
  221. movl count,%ecx
  222. movq buf,%rdi
  223. movl port,%edx
  224. cld
  225. rep
  226. insl
  227. {$endif CPUX86_64}
  228. end;
  229. end;
  230. Procedure ReadPortW (Port : Longint; Var Buf; Count: longint);
  231. {
  232. Reads 'Count' words from port 'Port' to 'Buf'.
  233. }
  234. begin
  235. asm
  236. {$ifdef CPU386}
  237. movl count,%ecx
  238. movl buf,%edi
  239. movl port,%edx
  240. cld
  241. rep
  242. insw
  243. {$endif CPU386}
  244. {$ifdef CPUX86_64}
  245. movl count,%ecx
  246. movq buf,%rdi
  247. movl port,%edx
  248. cld
  249. rep
  250. insw
  251. {$endif CPUX86_64}
  252. end;
  253. end;
  254. Procedure ReadPortB (Port : Longint; Var Buf; Count: longint);
  255. {
  256. Reads 'Count' bytes from port 'Port' to 'Buf'.
  257. }
  258. begin
  259. asm
  260. {$ifdef CPU386}
  261. movl count,%ecx
  262. movl buf,%edi
  263. movl port,%edx
  264. cld
  265. rep
  266. insb
  267. {$endif CPU386}
  268. {$ifdef CPUX86_64}
  269. movl count,%ecx
  270. movq buf,%rdi
  271. movl port,%edx
  272. cld
  273. rep
  274. insb
  275. {$endif CPUX86_64}
  276. end;
  277. end;
  278. {$if defined(linux) or defined(android)}
  279. Function fpIOperm (From,Num : Cardinal; Value : cint) : cint;
  280. {
  281. Set permissions on NUM ports starting with port FROM to VALUE
  282. this works ONLY as root.
  283. }
  284. begin
  285. fpIOPerm:=do_Syscall(Syscall_nr_ioperm,TSysParam(From),TSysParam(Num),TSysParam(Value));
  286. end;
  287. {$else}
  288. {$packrecords C}
  289. TYPE uint=CARDINAL;
  290. CONST
  291. I386_GET_LDT =0;
  292. I386_SET_LDT =1;
  293. { I386_IOPL }
  294. I386_GET_IOPERM =3;
  295. I386_SET_IOPERM =4;
  296. { xxxxx }
  297. I386_VM86 =6;
  298. type
  299. { i386_ldt_args = record
  300. int start : longint;
  301. union descriptor *descs;
  302. int num;
  303. end;
  304. }
  305. i386_ioperm_args = record
  306. start : cuint;
  307. length : cuint;
  308. enable : cint;
  309. end;
  310. i386_vm86_args = record
  311. sub_op : cint; { sub-operation to perform }
  312. sub_args : pchar; { args }
  313. end;
  314. sysarch_args = record
  315. op : longint;
  316. parms : pchar;
  317. end;
  318. Function fpIOPerm(From,Num:CARDINAL;Value:cint):cint;
  319. var sg : i386_ioperm_args;
  320. sa : sysarch_args;
  321. begin
  322. sg.start:=From;
  323. sg.length:=Num;
  324. sg.enable:=value;
  325. sa.op:=i386_SET_IOPERM;
  326. sa.parms:=@sg;
  327. fpIOPerm:=do_syscall(syscall_nr_sysarch,TSysParam(@sa));
  328. end;
  329. {$endif}
  330. Function fpIoPL(Level : cint) : cint;
  331. begin
  332. {$ifdef Linux}
  333. fpIOPL:=do_Syscall(Syscall_nr_iopl,TSysParam(Level));
  334. {$else}
  335. fpIOPL:=-1;
  336. FpSetErrNo(ESysENoSys);
  337. {$endif}
  338. end;
  339. end.