[GAP] Low level port access?
Jorge Real
jorge at disca.upv.es
Wed Sep 20 20:47:56 CEST 2006
Hi Peter.
In windows, you need a DLL to access the port address map. I found one
on the web when I needed it. There's info in the gnat manual on how to
generate the DLL's corresponding ".a" file - I can't remember the
details now.
Then you have to write an Ada program to interface with the DLL.
In our case, we used the following code:
--------------------------------------
with Byte_Operations; use Byte_Operations;
package Port_IO is
pragma linker_options("-linput_output32");
procedure Out32(Port:in word; Value: in Byte);
pragma Import(StdCall, Out32, "Out32");
function Inp32(Port: word) return Byte;
pragma Import(StdCall, Inp32, "Inp32");
end Port_IO;
----------------------------------------
The imported package Byte_Operations simply defines the subtypes used:
subtype Word is Unsigned_16;
subtype Byte is Unsigned_8;
The DLL is "input_output32.dll" and the names of the functions are those
exported by the DLL. We did the Windows experiment just to compare with
the Linux/RTLinux performance, so we abandoned this platform immediately :-)
For Linux, you'll need the following 4 files:
common_types.ads
--------------------------------------
-- Common Types
-- Defines types common to Port_IO and Pendulum_IO
--
-- Jorge Real.- September 2005
with Interfaces; use Interfaces;
package Common_Types is
subtype Word is Unsigned_16;
subtype Byte is Unsigned_8;
end Common_Types;
--------------------------------------
port_io_linux.ads
--------------------------------------
with Common_Types; use Common_Types;
package Port_IO_Linux is
procedure PortOut(Port : in Word; Data : in Byte);
function PortIn(Port : in Word) return Byte;
end Port_IO_Linux;
--------------------------------------
port_io_linux.adb
--------------------------------------
with System.Machine_Code; use System.Machine_Code;
package body Port_Io_Linux is
function PortIn(Port : in Word) return Byte is
Tmp : Byte;
begin
Asm ("inb %%dx, %0",
Byte'Asm_Output ("=a", Tmp),
Word'Asm_Input ("d", Port),
"edx",
True);
return Tmp;
end PortIn;
pragma Inline (PortIn);
procedure PortOut(Port : in Word; Data : in Byte) is
begin
Asm ("outb %0, %%dx",
No_Output_Operands,
(Byte'Asm_Input ("a", Data),
Word'Asm_Input ("d", Port)),
"edx", True);
end PortOut;
pragma Inline (PortOut);
-- This one is only for initialisation of the pakage
procedure Get_IOPL;
pragma Import(C,Get_IOPL,"get_iopl_3");
pragma Linker_Options("get_iopl_3.o");
begin
Get_IOPL;
end Port_Io_Linux;
--------------------------------
get_iopl.c
--------------------------------
void get_iopl_3 (void) {
iopl(3);
}
--------------------------------
You must be root to execute code using the Port_IO_Linux package.
In RTLinux, you don't need to acquire iopl(3) since you run in the
kernel space. The rest is the same as for Linux.
I hope this helps.
Jorge.
Peter C. Chapin escribió:
> On Wed, 20 Sep 2006, Jorge Real wrote:
>
>
>>it depends on your underlying OS. I have three different versions for
>>Linux, RTLinux and Windows. What's your case?
>
>
> Sorry, I should have mentioned that before. I'm interested primarily in
> Windows right now... although perhaps Linux in the future. Thanks for your
> reply!
>
> Peter
>
> _______________________________________________
> GAP mailing list
> GAP at gnat.info
> /no-more-mailman.html
> To unsubscribe from this list, please contact the GAP GNAT Tracker administrator
> within your organization.
>
More information about the GAP
mailing list