1 #include <freehdl/kernel-acl.hh>
2 #include <freehdl/std-vhdl-types.hh>
3 
4 
5 acl *free_acl[MAX_ACL_DEPTH + 1]; // List of acl objects that are currently not in use
6 
7 pacl tmpacl = new(100) acl; // temporary acl instance with 100 elements (should be enough
8 			    // for most cases!
9 pacl tmpacl1 = new(100) acl; // temporary acl instance with 100 elements (should be enough
10                              // for most cases!
11 pacl tmpacl2 = new(100) acl; // temporary acl instance with 100 elements (should be enough
12                              // for most cases!
13 
14 bool
operator ==(const acl & a)15 acl::operator==(const acl &a) {
16   if (this == NULL)
17     return a.end();
18   int i = 0;
19   while (!end() && !a.end()) {
20     if (get(i) != ACL_RANGE) {
21       if (get(i) != a.get(i)) return false;
22       i++;
23     } else {
24       if (a.get(i) != ACL_RANGE) return false;
25       int low1 = get(i+2) == to? get(i+1) : get(i+3);
26       int high1 = get(i+2) == to? get(i+3) : get(i+1);
27       int low2 = a.get(i+2) == to? a.get(i+1) : a.get(i+3);
28       int high2 = a.get(i+2) == to? a.get(i+3) : a.get(i+1);
29       if (low1 != low2 || high1 != high2) return false;
30       i += 3;
31     }
32   }
33   return true;
34 }
35 
36 
37 // *****************************************************************
38 // Some function  which are used only within kernel code. Usually,
39 // these function would be defined as methods of the acl class.
40 // However, as they are used by kernel modules only we define
41 // them as normal functions keeping the acl class as slim as
42 // possible.
43 // *****************************************************************
44 
45 
46 // Count levels an acl consists of. Note that a range is counted as a
47 // single level.
48 int
count_levels(const pacl a)49 count_levels(const pacl a)
50 {
51   int levels = 0;
52   pacl ac = a;
53 
54   while (!ac->end()) {
55     if (ac->get() == ACL_RANGE)
56       ac += 3;
57     ac++;
58     levels++;
59   }
60 
61   return levels;
62 }
63 
64 
65 // Get acl pointer associated with level "level". Note that a range is
66 // counted as a single level.
67 pacl
get_level(const pacl a,const int level)68 get_level(const pacl a, const int level)
69 {
70   pacl ac = a;
71   int level_counter = level;
72   while (--level_counter > 0) {
73     if (ac->get() == ACL_RANGE)
74       ac += 3;
75     ac++;
76   }
77   return ac;
78 }
79 
80 
81 // Creates a new acl containing levels begin to end (not included)
82 // from original acl a
83 pacl
clone_levels(const pacl a,const int begin,const int end)84 clone_levels(const pacl a, const int begin, const int end)
85 {
86   pacl first = get_level(a, begin);
87   pacl last = get_level(a, end - 1);
88   pacl new_aclp = new(last - first + 1) acl;
89   for (pacl iter = first; iter != last; iter++)
90     *new_aclp << iter->get();
91 
92   return new_aclp;
93 }
94 
95 
96 
97 // Returns current acl entry in left, dir and right. A single number
98 // is converted into a range "number" to "number". If no range or
99 // index is specified then a null range 1 to 0 is returned. Function
100 // returns a pointer to the next acl entry.
101 pacl
get_entry_data(pacl a,int & left,range_direction & dir,int & right)102 get_entry_data(pacl a, int &left, range_direction &dir, int &right)
103 {
104   if (a->end()) {
105     left = 1;
106     dir = to;
107     right = 0;
108     return a;
109   }
110 
111   left = (a++)->get();
112   if (left == ACL_RANGE) {
113     left = (a++)->get();
114     dir = (a++)->get() == 0? to : downto;
115     right = (a++)->get();
116   } else {
117     dir = to;
118     right = left;
119   }
120   return a;
121 }
122