x86.pp 8.8 KB

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