blob: acd23ec700c4f53230c530c55bed1363dc5364e0 [file] [log] [blame]
Nico Huber5e9b1b52016-10-08 22:09:33 +02001--
2-- Copyright (C) 2016 secunet Security Networks AG
3--
4-- This program is free software; you can redistribute it and/or modify
5-- it under the terms of the GNU General Public License as published by
Nico Huberaab715f2016-10-18 00:22:25 +02006-- the Free Software Foundation; either version 2 of the License, or
7-- (at your option) any later version.
Nico Huber5e9b1b52016-10-08 22:09:33 +02008--
9-- This program is distributed in the hope that it will be useful,
10-- but WITHOUT ANY WARRANTY; without even the implied warranty of
11-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-- GNU General Public License for more details.
13--
14
15package body HW.MMIO_Regs
16is
17
18 generic
19 type Word_T is mod <>;
20 procedure Read_G (Value : out Word_T; Idx : Subs_P.Index_T);
21
22 procedure Read_G (Value : out Word_T; Idx : Subs_P.Index_T)
23 is
24 Off : constant Range_P.Index_T := Range_P.Index_T
25 ((Byte_Offset + Regs (Idx).Byte_Offset) / (Range_P.Element_T'Size / 8));
26 pragma Warnings
27 (GNAT, Off, """Mask"" is not modified, could be declared constant",
28 Reason => "Ada RM forbids making it constant.");
29 Mask : Word64 := Shift_Left (1, Regs (Idx).MSB + 1 - Regs (Idx).LSB) - 1;
30 pragma Warnings
31 (GNAT, On, """Mask"" is not modified, could be declared constant");
32 Temp : Range_P.Element_T;
33 begin
34 Range_P.Read (Temp, Off);
35 Value := Word_T (Shift_Right (Word64 (Temp), Regs (Idx).LSB) and Mask);
36 end Read_G;
37
38 procedure Read_I is new Read_G (Word8);
39 procedure Read (Value : out Word8; Idx : Subs_P.Index_T) renames Read_I;
40
41 procedure Read_I is new Read_G (Word16);
42 procedure Read (Value : out Word16; Idx : Subs_P.Index_T) renames Read_I;
43
44 procedure Read_I is new Read_G (Word32);
45 procedure Read (Value : out Word32; Idx : Subs_P.Index_T) renames Read_I;
46
47 procedure Read_I is new Read_G (Word64);
48 procedure Read (Value : out Word64; Idx : Subs_P.Index_T) renames Read_I;
49
50 ----------------------------------------------------------------------------
51
52 generic
53 type Word_T is mod <>;
54 procedure Write_G (Idx : Subs_P.Index_T; Value : Word_T);
55
56 procedure Write_G (Idx : Subs_P.Index_T; Value : Word_T)
57 is
58 Off : constant Range_P.Index_T := Range_P.Index_T
59 ((Byte_Offset + Regs (Idx).Byte_Offset) / (Range_P.Element_T'Size / 8));
60 pragma Warnings
61 (GNAT, Off, """Mask"" is not modified, could be declared constant",
62 Reason => "Ada RM forbids making it constant.");
63 Mask : Word64 :=
64 Shift_Left (1, Regs (Idx).MSB + 1) - Shift_Left (1, Regs (Idx).LSB);
65 pragma Warnings
66 (GNAT, On, """Mask"" is not modified, could be declared constant");
67 Temp : Range_P.Element_T;
68 begin
69 if Regs (Idx).MSB - Regs (Idx).LSB + 1 = Range_P.Element_T'Size then
70 Range_P.Write (Off, Range_P.Element_T (Value));
71 else
72 -- read/modify/write
73 Range_P.Read (Temp, Off);
74 Temp := Range_P.Element_T
75 ((Word64 (Temp) and not Mask) or
76 (Shift_Left (Word64 (Value), Regs (Idx).LSB)));
77 Range_P.Write (Off, Temp);
78 end if;
79 end Write_G;
80
81 procedure Write_I is new Write_G (Word8);
82 procedure Write (Idx : Subs_P.Index_T; Value : Word8) renames Write_I;
83
84 procedure Write_I is new Write_G (Word16);
85 procedure Write (Idx : Subs_P.Index_T; Value : Word16) renames Write_I;
86
87 procedure Write_I is new Write_G (Word32);
88 procedure Write (Idx : Subs_P.Index_T; Value : Word32) renames Write_I;
89
90 procedure Write_I is new Write_G (Word64);
91 procedure Write (Idx : Subs_P.Index_T; Value : Word64) renames Write_I;
92
93end HW.MMIO_Regs;