x86.pp 8.3 KB

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