x86.pp 8.5 KB

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