In legion build config, updated path to GNU tools and updated deprecated Sun CC flag...
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_AsiSpace.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: SS_AsiSpace.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#ifndef __SS_AsiSpace_h__
24#define __SS_AsiSpace_h__
25
26#include "SS_Types.h"
27#include "SS_Asi.h"
28
29class SS_Strand;
30class SS_Node;
31class SS_AsiCtrReg;
32class SS_SharedAsiCtrReg;
33
34class SS_AsiSpace
35{
36 public:
37 SS_AsiSpace();
38 ~SS_AsiSpace();
39
40 // merge() this asi space into asi space s (the strand's asi_space (element of asi_map))
41 void merge( SS_AsiSpace& s );
42
43 // set_mask() sets the mask that is applied to address before look up.
44 void set_mask( SS_Vaddr _mask ) { mask = _mask; }
45
46 // get_mask() returns the address mask
47 SS_Vaddr get_mask() { return mask; }
48
49 bool is_empty(SS_Vaddr va) { return size == 0; }
50
51 // Error is a return value for rd/wr asi routines to signal
52 // success or failure. The hardwired values are values exported
53 // outside our code base, so please don't change these.
54
55 enum Error
56 {
57 OK = 0, // Accessed asi is ok and value is correct for load
58 RETRY = 1, // Retry the access, don't advance the pc.
59 NO_ASI, // Asi number does not exist
60 NO_READ, // Register at addr can not be read
61 NO_WRITE, // Register at addr can not be written
62 NO_VALUE, // As OK but value returned can be overwritten by value sync.
63 TRAP_PA, // Failed and trap with privileged action trap
64 TRAP_IA, // Failed and trap with invalid asi trap
65 TRAP_IPE, // Failed and trap with internal processor error trap
66 NOT_INIT // Value is uninitailized internally
67 };
68
69 Error ld64( SS_Strand* s, SS_Vaddr addr, uint64_t* data );
70 Error st64( SS_Strand* s, SS_Vaddr addr, uint64_t data );
71 Error rd64( SS_Strand* s, SS_Vaddr addr, uint64_t* data );
72 Error wr64( SS_Strand* s, SS_Vaddr addr, uint64_t data );
73
74 typedef Error (*Read) ( SS_Node* obj, void* reg, SS_Strand* s, SS_Vaddr, uint64_t* data );
75 typedef Error (*Write)( SS_Node* obj, void* reg, SS_Strand* s, SS_Vaddr, uint64_t data );
76
77 // ToDo this is a bit too much interface ... remove some, probably the top two
78 void add( SS_Vaddr va, SS_Node* obj, SS_AsiCtrReg& reg );
79 void add( SS_Vaddr va, SS_Strand* obj, SS_AsiCtrReg& reg )
80 {
81 add(va, (SS_Node*)obj, reg);
82 }
83 void add( SS_Vaddr va, SS_Node* obj, SS_SharedAsiCtrReg& reg );
84 void add( SS_Vaddr va, SS_Strand* obj, SS_SharedAsiCtrReg& reg )
85 {
86 add(va, (SS_Node*)obj, reg);
87 }
88 void add( SS_Vaddr va, SS_Node* obj, void* reg, Read ld, Write st, Read rd, Write wr );
89 void add( SS_Vaddr va, SS_Strand* obj, void* reg, Read ld, Write st, Read rd, Write wr )
90 {
91 add(va, (SS_Node*)obj, reg, ld, st, rd, wr);
92 }
93 void add( SS_Vaddr lo, SS_Vaddr hi, SS_Node* obj, void* reg, Read ld, Write st, Read rd, Write wr );
94 void add( SS_Vaddr lo, SS_Vaddr hi, SS_Strand* obj, void* reg, Read ld, Write st, Read rd, Write wr )
95 {
96 add(lo, hi, (SS_Node*)obj, reg, ld, st, rd, wr);
97 }
98
99
100 class Range
101 {
102 public:
103 typedef SS_AsiSpace::Read Read;
104 typedef SS_AsiSpace::Write Write;
105
106 Range() : lo(0), hi(0), obj(0), reg(0), ld(0), st(0), rd(0), wr(0) {}
107 Range( SS_Vaddr _lo, SS_Vaddr _hi, SS_Node* _obj, void* _reg, Read _ld, Write _st, Read _rd, Write _wr )
108 : lo(_lo), hi(_hi), obj(_obj), reg(_reg), ld(_ld), st(_st), rd(_rd), wr(_wr) {}
109
110 SS_Vaddr lo;
111 SS_Vaddr hi;
112 SS_Node* obj;
113 void* reg;
114 Read ld;
115 Write st;
116 Read rd;
117 Write wr;
118
119 bool in_range( SS_Vaddr va ) { return (lo <= va) && (va <= hi); }
120 };
121
122 enum { ALLOC = 256 };
123
124 SS_Asi asi; // Set once to this SS_AsiSpace's
125 // asi number in SS_AsiMap constructor.
126 // Used for debugging messages.
127
128
129 protected:
130 static Error no_rd( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t* );
131 static Error no_wr( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t );
132
133 void add( Range* r );
134
135 // find() searches for va in the table of ranges.
136 // If found it returns a pointer to the range that
137 // maps va. When va is not found it returns a pointer
138 // to the fail Range.
139
140 Range* find( SS_Vaddr va )
141 {
142 if (size == 0)
143 return &fail;
144
145 uint_t l = 0;
146 uint_t h = size;
147 uint_t m = size >> 1;
148
149 Range* r = table[m];
150
151 while (l != m)
152 {
153 ((va < r->lo) ? h : l) = m;
154 m = l + ((h - l) >> 1);
155 r = table[m];
156 }
157
158 return r->in_range(va) ? r : &fail;
159 }
160
161 class Block
162 {
163 public:
164 Block( Block* _next=0 ) : next(_next) {}
165
166 SS_AsiSpace::Range page[SS_AsiSpace::ALLOC];
167 Block* next;
168 };
169
170 SS_Vaddr mask;
171 Range fail; // Default for failing accesses (va not found)
172 Range** table; // Sorted table of ranges
173 bool table_copy; // True when the table needs to be copied during merge
174 Block* block; // List of allocated blocks of ranges
175 uint_t free_range_index; // Index in block for free Range
176 uint_t alloc; // Number of allocated ranges
177 uint_t size; // Number of added ranges
178
179};
180
181#endif