gma pcode: Move and revise mailbox handling
Unify the PCODE mailbox implementations (Linux' i915 uses the same
implementation since Sandy Bridge, too) and add `Wait` and `Success`
parameters so we can act correctly if something failed. This adds
a lot of boilerplate. But we keep it contained in the new package
`PCode` and the code outside it looks cleaner and handles errors
more gracefully.
In GNATprove, we track state of the mailbox' readiness in a ghost
variable `Mailbox_Ready`. This allows us to skip the initial wait
loop if we know that we already waited at the end of a previous
call. The first call to a mailbox procedure has to be made with
`Wait_Ready => True`.
Also, start to experiment with a `use` clause for the `Register`
package. It allows us to write a little more condensed code, with-
out sacrificing much (in this program we can expect that `Read`/
`Write` means register access?) So far it looks good?
Change-Id: I5daa3effb7ab774e4a35bd8794b0f67f57e4caa4
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/libgfxinit/+/35710
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb
index 15d234a..dbdee5c 100644
--- a/common/hw-gfx-gma.adb
+++ b/common/hw-gfx-gma.adb
@@ -21,6 +21,7 @@
with HW.GFX.GMA.Config;
with HW.GFX.GMA.Config_Helpers;
with HW.GFX.GMA.Registers;
+with HW.GFX.GMA.PCode;
with HW.GFX.GMA.Power_And_Clocks;
with HW.GFX.GMA.Panel;
with HW.GFX.GMA.PLLs;
@@ -39,6 +40,7 @@
(State =>
(Dev.Address_State,
Registers.Address_State,
+ PCode.Mailbox_Ready,
PLLs.State, Panel.Panel_State,
Cur_Configs, Allocated_PLLs,
HPD_Delay, Wait_For_HPD,
@@ -376,6 +378,7 @@
(Config.Variable,
Dev.Address_State,
Registers.Address_State,
+ PCode.Mailbox_Ready,
PLLs.State, Panel.Panel_State,
Cur_Configs, Allocated_PLLs,
HPD_Delay, Wait_For_HPD,
@@ -435,6 +438,7 @@
pragma Debug (Debug.Set_Register_Write_Delay (Write_Delay));
Linear_FB_Base := 0;
+ PCode.Mailbox_Ready := False;
Wait_For_HPD := HPD_Type'(others => False);
HPD_Delay := HPD_Delay_Type'(others => Now);
Allocated_PLLs := (others => PLLs.Invalid);