blob: ad396fdb72df984ff82b5571f335dca746bfd789 [file] [log] [blame]
Nico Huberfda2d6e2017-07-09 16:47:52 +02001with Ada.Unchecked_Conversion;
Nico Huber1d0abe42017-03-05 14:14:09 +01002with Ada.Command_Line;
3with Interfaces.C;
4
Nico Huber1d0abe42017-03-05 14:14:09 +01005with HW.Debug;
Nico Huberfda2d6e2017-07-09 16:47:52 +02006with HW.PCI.Dev;
7with HW.MMIO_Range;
Nico Huber1d0abe42017-03-05 14:14:09 +01008with HW.GFX.GMA;
9with HW.GFX.GMA.Display_Probing;
10
Nico Huberfda2d6e2017-07-09 16:47:52 +020011package body HW.GFX.GMA.GFX_Test
12is
13 pragma Disable_Atomic_Synchronization;
Nico Huber1d0abe42017-03-05 14:14:09 +010014
Nico Huberfda2d6e2017-07-09 16:47:52 +020015 package Dev is new PCI.Dev (PCI.Address'(0, 2, 0));
Nico Huber1d0abe42017-03-05 14:14:09 +010016
17 type Pixel_Type is record
18 Red : Byte;
19 Green : Byte;
20 Blue : Byte;
21 Alpha : Byte;
22 end record;
23
24 for Pixel_Type use record
25 Blue at 0 range 0 .. 7;
26 Green at 1 range 0 .. 7;
27 Red at 2 range 0 .. 7;
28 Alpha at 3 range 0 .. 7;
29 end record;
30
Nico Huberfda2d6e2017-07-09 16:47:52 +020031 function Pixel_To_Word (P : Pixel_Type) return Word32
32 with
33 SPARK_Mode => Off
34 is
35 function To_Word is new Ada.Unchecked_Conversion (Pixel_Type, Word32);
36 begin
37 return To_Word (P);
38 end Pixel_To_Word;
39
Nico Huber1d0abe42017-03-05 14:14:09 +010040 Max_W : constant := 4096;
41 Max_H : constant := 2160;
42 FB_Align : constant := 16#0004_0000#;
Nico Huberfda2d6e2017-07-09 16:47:52 +020043 subtype Screen_Index is Natural range
44 0 .. 3 * (Max_W * Max_H + FB_Align / 4) - 1;
45 type Screen_Type is array (Screen_Index) of Word32;
Nico Huber1d0abe42017-03-05 14:14:09 +010046
Nico Huberfda2d6e2017-07-09 16:47:52 +020047 package Screen is new MMIO_Range (0, Word32, Screen_Index, Screen_Type);
Nico Huber1d0abe42017-03-05 14:14:09 +010048
49 Pipes : GMA.Pipe_Configs;
50
51 function Fill
52 (X, Y : Natural;
53 Framebuffer : Framebuffer_Type;
54 Pipe : GMA.Pipe_Index)
55 return Pixel_Type
56 is
57 use type HW.Byte;
58
59 Xp : constant Natural := X * 256 / Natural (Framebuffer.Width);
60 Yp : constant Natural := Y * 256 / Natural (Framebuffer.Height);
61 Xn : constant Natural := 255 - Xp;
62 Yn : constant Natural := 255 - Yp;
63
64 function Map (X, Y : Natural) return Byte is
65 begin
66 return Byte (X * Y / 255);
67 end Map;
68 begin
69 return
70 (case Pipe is
71 when GMA.Primary => (Map (Xn, Yn), Map (Xp, Yn), Map (Xp, Yp), 255),
72 when GMA.Secondary => (Map (Xn, Yp), Map (Xn, Yn), Map (Xp, Yn), 255),
73 when GMA.Tertiary => (Map (Xp, Yp), Map (Xn, Yp), Map (Xn, Yn), 255));
74 end Fill;
75
76 procedure Test_Screen
77 (Framebuffer : Framebuffer_Type;
78 Pipe : GMA.Pipe_Index)
79 is
Nico Huber1d0abe42017-03-05 14:14:09 +010080 P : Pixel_Type;
81 -- We have pixel offset wheras the framebuffer has a byte offset
82 Offset_Y : Natural := Natural (Framebuffer.Offset / 4);
83 Offset : Natural;
84 begin
85 for Y in 0 .. Natural (Framebuffer.Height) - 1 loop
86 Offset := Offset_Y;
87 for X in 0 .. Natural (Framebuffer.Width) - 1 loop
88 if Y mod 16 = 0 or X mod 16 = 0 then
89 P := (0, 0, 0, 0);
90 else
91 P := Fill (X, Y, Framebuffer, Pipe);
92 end if;
Nico Huberfda2d6e2017-07-09 16:47:52 +020093 Screen.Write (Offset, Pixel_To_Word (P));
Nico Huber1d0abe42017-03-05 14:14:09 +010094 Offset := Offset + 1;
95 end loop;
96 Offset_Y := Offset_Y + Natural (Framebuffer.Stride);
97 end loop;
98 end Test_Screen;
99
100 procedure Calc_Framebuffer
101 (FB : out Framebuffer_Type;
102 Mode : in Mode_Type;
103 Offset : in out Word32)
104 is
Nico Huber1d0abe42017-03-05 14:14:09 +0100105 begin
106 Offset := (Offset + FB_Align - 1) and not (FB_Align - 1);
107 FB :=
108 (Width => Width_Type (Mode.H_Visible),
109 Height => Height_Type (Mode.V_Visible),
110 BPC => 8,
111 Stride => Width_Type ((Word32 (Mode.H_Visible) + 15) and not 15),
112 Offset => Offset);
113 Offset := Offset + Word32 (FB.Stride * FB.Height * 4);
114 end Calc_Framebuffer;
115
116 procedure Prepare_Configs
117 is
118 use type HW.GFX.GMA.Port_Type;
119
Nico Huberfda2d6e2017-07-09 16:47:52 +0200120 Offset : Word32 := 0;
Nico Huber1d0abe42017-03-05 14:14:09 +0100121 begin
122 GMA.Display_Probing.Scan_Ports (Pipes);
123
124 for Pipe in GMA.Pipe_Index loop
125 if Pipes (Pipe).Port /= GMA.Disabled then
126 Calc_Framebuffer
127 (FB => Pipes (Pipe).Framebuffer,
128 Mode => Pipes (Pipe).Mode,
129 Offset => Offset);
130 end if;
131 end loop;
132
133 GMA.Dump_Configs (Pipes);
134 end Prepare_Configs;
135
Nico Huber1d0abe42017-03-05 14:14:09 +0100136 procedure Main
137 is
Nico Huber1d0abe42017-03-05 14:14:09 +0100138 use type HW.GFX.GMA.Port_Type;
Nico Huberfda2d6e2017-07-09 16:47:52 +0200139 use type HW.Word64;
Nico Huber1d0abe42017-03-05 14:14:09 +0100140 use type Interfaces.C.int;
141
Nico Huberfda2d6e2017-07-09 16:47:52 +0200142 Res_Addr : Word64;
143
144 Dev_Init,
Nico Huber1d0abe42017-03-05 14:14:09 +0100145 Initialized : Boolean;
146
147 function iopl (level : Interfaces.C.int) return Interfaces.C.int;
148 pragma Import (C, iopl, "iopl");
149 begin
Nico Huber1d0abe42017-03-05 14:14:09 +0100150 if iopl (3) /= 0 then
151 Debug.Put_Line ("Failed to change i/o privilege level.");
152 return;
153 end if;
154
Nico Huberfda2d6e2017-07-09 16:47:52 +0200155 Dev.Initialize (Dev_Init);
156 if not Dev_Init then
157 Debug.Put_Line ("Failed to map PCI config.");
Nico Huber1d0abe42017-03-05 14:14:09 +0100158 return;
159 end if;
160
Nico Huberfda2d6e2017-07-09 16:47:52 +0200161 Dev.Map (Res_Addr, PCI.Res2, WC => True);
162 if Res_Addr = 0 then
163 Debug.Put_Line ("Failed to map PCI resource2.");
164 return;
165 end if;
166 Screen.Set_Base_Address (Res_Addr);
167
Nico Huber1d0abe42017-03-05 14:14:09 +0100168 GMA.Initialize
Nico Huber2b6f6992017-07-09 18:11:34 +0200169 (Clean_State => True,
Nico Huber1d0abe42017-03-05 14:14:09 +0100170 Success => Initialized);
171
172 if Initialized then
173 Prepare_Configs;
174
175 GMA.Update_Outputs (Pipes);
176
177 for Pipe in GMA.Pipe_Index loop
178 if Pipes (Pipe).Port /= GMA.Disabled then
179 Test_Screen
180 (Framebuffer => Pipes (Pipe).Framebuffer,
181 Pipe => Pipe);
182 end if;
183 end loop;
184 end if;
185 end Main;
186
Nico Huberfda2d6e2017-07-09 16:47:52 +0200187end HW.GFX.GMA.GFX_Test;