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