Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_AddressMap.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: SS_AddressMap.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23
24#ifndef __SS_AddressMap_h__
25#define __SS_AddressMap_h__
26
27#include "BL_BitUtility.h"
28#include "SS_Types.h"
29#include "SS_Access.h"
30
31class SS_AddressMap
32{
33 public:
34 SS_AddressMap();
35 ~SS_AddressMap();
36
37 // Address is the type that describes how objects registered
38 // with the SS_AddressMap should be addressed. Two modes are
39 // available: relative or absolute. Relative addressed objects
40 // can have only one add (one lo to hi range). Absolute objects
41 // can have multiple add's. Relative addressed objects are in
42 // general reusable objects, absolute addressed object are far
43 // more limited in their reuse, however, can be registers at
44 // multiple address ranges.
45
46 enum Addressing
47 {
48 REL, // Registered object is base relative addressed
49 ABS // Registered object is absolute addressed
50 };
51
52 // add() maps a object obj in the address range from lo to hi inclusive.
53 // The cpu argument is for strand (cpu) access. The extra usr agrument is
54 // for optinally different behaviour by frontend (usr) access.
55 // If usr is not given then it defaults to cpu. The rel flags indicated
56 // whether obj needs to be addressed relative or absolute.
57
58 void add( SS_Paddr lo, SS_Paddr hi, void* obj, Addressing rel,
59 SS_Access::Func cpu, SS_Access::Func usr=0 );
60
61 // overwrite the default range_object_not_found routine
62 void set_fail( void* obj, SS_Access::Func cpu, SS_Access::Func usr=0 )
63 {
64 SS_AddressMap::fail->obj = obj;
65 SS_AddressMap::fail->fun_cpu = cpu;
66 SS_AddressMap::fail->fun_usr = usr ? usr : cpu;
67 }
68
69 protected:
70 // The ld(), st(), rd() and wr() access methods expect to get size
71 // arguments that are a power of two, and the pa to be aligned to
72 // the size. When addresses, the object sees the relative address:
73 // e.g. pa - lo (lo is the low address provided to add()).
74
75 void cpu( uint_t sid, SS_Access::Type type, SS_Paddr pa, uint_t size, uint64_t* data )
76 {
77 assert(SS_Access::ok(type,pa,size));
78 find(pa)->cpu(sid,type,pa,size,data);
79 }
80 void usr( uint_t sid, SS_Access::Type type, SS_Paddr pa, uint_t size, uint64_t* data )
81 {
82 assert(SS_Access::ok(type,pa,size));
83 find(pa)->usr(sid,type,pa,size,data);
84 }
85
86 class Range
87 {
88 public:
89 Range()
90 :
91 lo(0),
92 hi(0),
93 obj(0),
94 rel(SS_AddressMap::REL),
95 fun_cpu(0),
96 fun_usr(0)
97 {}
98 Range( SS_Paddr _lo, SS_Paddr _hi, void* _obj, SS_AddressMap::Addressing _rel,
99 SS_Access::Func _cpu, SS_Access::Func _usr )
100 :
101 lo(_lo),
102 hi(_hi),
103 rel(_rel),
104 obj(_obj),
105 fun_cpu(_cpu),
106 fun_usr(_usr)
107 {}
108
109 SS_Paddr lo;
110 SS_Paddr hi;
111 void* obj;
112 SS_AddressMap::Addressing rel;
113 SS_Access::Func fun_cpu;
114 SS_Access::Func fun_usr;
115
116 bool in_range( SS_Paddr pa ) { return (lo <= pa) && (pa <= hi); }
117
118 void cpu( uint_t sid, SS_Access::Type type, SS_Paddr pa, uint_t size, uint64_t* data )
119 {
120 (fun_cpu)(obj,sid,type,(rel == SS_AddressMap::REL) ? (pa - lo) : pa,size,data);
121 }
122 void usr( uint_t sid, SS_Access::Type type, SS_Paddr pa, uint_t size, uint64_t* data )
123 {
124 (fun_usr)(obj,sid,type,(rel == SS_AddressMap::REL) ? (pa - lo) : pa,size,data);
125 }
126 };
127
128 static void no_access( void*, uint_t, SS_Access::Type, SS_Paddr, uint_t size, uint64_t* data );
129
130 Range* find( SS_Paddr pa )
131 {
132 if (_size == 0)
133 return SS_AddressMap::fail;
134
135 uint_t l = 0;
136 uint_t h = _size;
137 uint_t m = _size >> 1;
138
139 Range* r = &table[m];
140
141 while (l != m)
142 {
143 ((pa < r->lo) ? h : l) = m;
144 m = l + ((h - l) >> 1);
145 r = &table[m];
146 }
147
148 return r->in_range(pa) ? r : SS_AddressMap::fail;
149 }
150
151 enum { ALLOC = 16 };
152
153 static Range* fail; // Default for failing accesses (pa not found)
154
155 Range* table; // Sorted table of ranges
156 uint_t alloc; // Number of allocated ranges
157 uint_t _size; // Number of added ranges
158};
159
160#endif
161
162
163