with Interfaces; use Interfaces; with System.Machine_Code; use System.Machine_Code; with Agila_Ports; use Agila_Ports; procedure Boot_Main (Magic : Unsigned_32) is State : Manager; Handle, Replacement : Word; Result : Status; Item : Message; procedure Out_Byte (Port : Unsigned_16; Value : Unsigned_8) is begin Asm ("outb %0, %1", Inputs => (Unsigned_8'Asm_Input ("a", Value), Unsigned_16'Asm_Input ("Nd", Port)), Volatile => True); end Out_Byte; function In_Byte (Port : Unsigned_16) return Unsigned_8 is Value : Unsigned_8; begin Asm ("inb %1, %0", Outputs => Unsigned_8'Asm_Output ("=a", Value), Inputs => Unsigned_16'Asm_Input ("Nd", Port), Volatile => True); return Value; end In_Byte; procedure Line (Text : String) is Full_Text : constant String := Text & ASCII.CR & ASCII.LF; begin for C of Full_Text loop for Attempt in 1 .. 10_000 loop exit when (In_Byte (16#3FD#) and 16#20#) /= 0; end loop; Out_Byte (16#3F8#, Unsigned_8 (Character'Pos (C))); end loop; end Line; procedure Finish (Success : Boolean) with No_Return; procedure Finish (Success : Boolean) is Code : constant Unsigned_32 := (if Success then 16#10# else 16#11#); begin if Success then Line ("AGILA_BOOT_OK"); else Line ("AGILA_BOOT_FAILED"); end if; Asm ("outl %0, %1", Inputs => (Unsigned_32'Asm_Input ("a", Code), Unsigned_16'Asm_Input ("Nd", 16#F4#)), Volatile => True); loop Asm ("cli; hlt", Volatile => True); end loop; end Finish; procedure Check (Condition : Boolean) is begin if not Condition then Finish (False); end if; end Check; begin Out_Byte (16#3F9#, 0); Out_Byte (16#3FB#, 16#80#); Out_Byte (16#3F8#, 3); Out_Byte (16#3F9#, 0); Out_Byte (16#3FB#, 3); Out_Byte (16#3FA#, 16#C7#); Out_Byte (16#3FC#, 16#0B#); Line ("OPEN_AGILA_X86_64_ADA"); Check (Magic = 16#2BADB002#); Create (State, 10, Handle, Result); Check (Result = Ok); Send (State, Handle, 20, 42, Result); Check (Result = Permission_Denied); Allow_Sender (State, Handle, 10, 20, Result); Check (Result = Ok); for I in 1 .. Queue_Capacity loop Send (State, Handle, 20, Word (I), Result); Check (Result = Ok); end loop; Send (State, Handle, 20, 99, Result); Check (Result = Full); for I in 1 .. Queue_Capacity loop Receive (State, Handle, 10, Item, Result); Check (Result = Ok and Item.Value = Word (I) and Item.Sender = 20); end loop; Receive (State, Handle, 10, Item, Result); Check (Result = Empty); Close (State, Handle, 10, Result); Check (Result = Ok); Create (State, 30, Replacement, Result); Check (Result = Ok and Replacement /= Handle); Send (State, Handle, 10, 1, Result); Check (Result = Invalid_Handle); Line ("ADA_PORTS_BOOT_TESTS_OK"); Line ("Boot milestone: one address space; no user services or desktop yet."); Finish (True); end Boot_Main;