Files

70 lines
2.9 KiB
Ada

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;