Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: RAMAccessor.vr | |
4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | // | |
7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | // | |
9 | // This program is free software; you can redistribute it and/or modify | |
10 | // it under the terms of the GNU General Public License as published by | |
11 | // the Free Software Foundation; version 2 of the License. | |
12 | // | |
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | // | |
22 | // For the avoidance of doubt, and except that if any non-GPL license | |
23 | // choice is available it will apply instead, Sun elects to use only | |
24 | // the General Public License version 2 (GPLv2) at this time for any | |
25 | // software where a choice of GPL license versions is made | |
26 | // available with the language indicating that GPLv2 or any later version | |
27 | // may be used, or where a choice of which version of the GPL is applied is | |
28 | // otherwise unspecified. | |
29 | // | |
30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | // have any questions. | |
33 | // | |
34 | // ========== Copyright Header End ============================================ | |
35 | #include "report_macros.vri" | |
36 | ||
37 | class RAMAccessor extends AccessorBase { | |
38 | ||
39 | local bit [CSRT_ADDR_OFFSET_WIDTH-1:0] base_address; | |
40 | ||
41 | //================================================= | |
42 | // Constructor | |
43 | //================================================= | |
44 | task new ( CSRState ShadowState, | |
45 | bit [CSRT_ADDR_OFFSET_WIDTH-1:0] input_addr_offset , | |
46 | bit [CSRT_DATA_WIDTH-1:0] input_por_value , | |
47 | bit [CSRT_DATA_WIDTH-1:0] input_rmask , | |
48 | bit [CSRT_DATA_WIDTH-1:0] input_read_only_mask , | |
49 | bit [CSRT_DATA_WIDTH-1:0] input_write_mask , | |
50 | bit [CSRT_DATA_WIDTH-1:0] input_clear_mask , | |
51 | bit [CSRT_DATA_WIDTH-1:0] input_set_mask, | |
52 | bit [CSRT_DATA_WIDTH-1:0] input_toggle_mask , | |
53 | string input_name , | |
54 | integer input_num_fields , | |
55 | CSRAccessMethod input_access_methods[], | |
56 | integer input_access_level[], | |
57 | string input_access_name[], | |
58 | integer input_default_access_method | |
59 | ) { | |
60 | ||
61 | integer ii; | |
62 | ||
63 | super.new ( ShadowState, | |
64 | input_addr_offset, | |
65 | input_por_value, | |
66 | input_rmask, | |
67 | input_read_only_mask, | |
68 | input_write_mask, | |
69 | input_clear_mask, | |
70 | input_set_mask, | |
71 | input_toggle_mask, | |
72 | input_name, | |
73 | input_num_fields); | |
74 | ||
75 | base_address = get_addr_offset(); //This is a base address for a RAM accessor | |
76 | csr_check_enabled = CSRT_CHECK_ENABLED; | |
77 | // csr_write_trans_sem = alloc(SEMAPHORE,0,1,1); | |
78 | ||
79 | set_method_array(input_access_methods, input_access_level, input_access_name); | |
80 | ||
81 | DefaultMethod = input_default_access_method; | |
82 | } // end task new | |
83 | ||
84 | ||
85 | //================================================= | |
86 | // Read function | |
87 | //================================================= | |
88 | function bit [CSRT_DATA_WIDTH-1:0] read (bit [CSRT_ADDR_OFFSET_WIDTH-1:0] offset, | |
89 | integer method = CSRT_USE_DEFAULT_METHOD){ | |
90 | ||
91 | bit [CSRT_ADDR_OFFSET_WIDTH-1:0] effective_addr; | |
92 | ||
93 | if (method == CSRT_USE_DEFAULT_METHOD) | |
94 | method = DefaultMethod; | |
95 | ||
96 | check_method(method); | |
97 | ||
98 | if (method == CSRT_STUB) { | |
99 | QuickReport(CSRReport, RTYP_CSR_DEBUG_1, "RAMAccessor::read: %s register: is stubbed out",get_name()); | |
100 | } | |
101 | else { | |
102 | effective_addr = base_address + offset; | |
103 | QuickReport(CSRReport, RTYP_CSR_DEBUG_1,"RAMAccessor: %s read(): %s register: Addr %0h", | |
104 | get_method_name(method), | |
105 | get_name(), | |
106 | effective_addr); | |
107 | read = access_methods[method].read(effective_addr); | |
108 | } | |
109 | } // end function read | |
110 | ||
111 | ||
112 | //================================================= | |
113 | // Write task | |
114 | //================================================= | |
115 | task write ( bit [CSRT_ADDR_OFFSET_WIDTH-1:0] offset, | |
116 | bit [CSRT_DATA_WIDTH-1:0] csr_data, | |
117 | integer method = CSRT_USE_DEFAULT_METHOD ){ | |
118 | ||
119 | bit [CSRT_ADDR_OFFSET_WIDTH-1:0] effective_addr; | |
120 | ||
121 | if (method == CSRT_USE_DEFAULT_METHOD) | |
122 | method = DefaultMethod; | |
123 | ||
124 | ||
125 | ||
126 | check_method(method); | |
127 | ||
128 | // Perform Hardware Write | |
129 | if (method == CSRT_STUB) { | |
130 | QuickReport(CSRReport, RTYP_CSR_INFO, "RAMAccessor::read: %s register: is stubbed out",get_name()); | |
131 | } | |
132 | else { | |
133 | effective_addr = base_address + offset; | |
134 | ||
135 | QuickReport(CSRReport, RTYP_CSR_DEBUG_1,"RAMAccessor: %s write(): %s register: Addr %0h : data %0h", | |
136 | get_method_name(method), | |
137 | get_name(), | |
138 | effective_addr, | |
139 | csr_data); | |
140 | ||
141 | access_methods[method].write(effective_addr, csr_data); | |
142 | } | |
143 | } // end task write | |
144 | ||
145 | ||
146 | //================================================= | |
147 | // Check Register Function | |
148 | //================================================= | |
149 | // The following change was made on 9/21/01 -RFT | |
150 | // This function should really be based on a wild card match, allowing | |
151 | // a don't care setting for the shadow data. This is necessary for registers | |
152 | // that don't have a specific POR value because they are not connected to | |
153 | // reset. | |
154 | // | |
155 | function integer check_register (integer method = CSRT_USE_DEFAULT_METHOD) { | |
156 | ||
157 | bit [CSRT_DATA_WIDTH-1:0] actual_data; | |
158 | bit [CSRT_DATA_WIDTH-1:0] expected_data; | |
159 | integer index = 0; | |
160 | bit success = 1; | |
161 | ||
162 | QuickReport(CSRReport, RTYP_CSR_ALERT,"%0d:check_register() is not supported for RAMAccessor: %s register.", | |
163 | get_cycle(),get_name()); | |
164 | ||
165 | check_register = CSRT_MISMATCH_RETURN_CODE; | |
166 | ||
167 | } // end function check_register | |
168 | ||
169 | ||
170 | ||
171 | //================================================= | |
172 | // Reset Task | |
173 | //================================================= | |
174 | ||
175 | task reset () { | |
176 | ||
177 | QuickReport(CSRReport, RTYP_CSR_ALERT,"%0d:reset() is not supported for RAMAccessor: %s register.", | |
178 | get_cycle(),get_name()); | |
179 | ||
180 | } // end task reset | |
181 | ||
182 | ||
183 | ||
184 | //================================================= | |
185 | // Read Field Function | |
186 | //================================================= | |
187 | ||
188 | function bit [CSRT_DATA_WIDTH-1:0] read_field (bit [CSRT_ADDR_OFFSET_WIDTH-1:0] offset, | |
189 | integer field_id, | |
190 | integer method = CSRT_USE_DEFAULT_METHOD) { | |
191 | ||
192 | bit [CSRT_DATA_WIDTH-1:0] temp_data; | |
193 | ||
194 | if (method == CSRT_USE_DEFAULT_METHOD) | |
195 | method = DefaultMethod; | |
196 | ||
197 | if (field_id < get_max_num_fields()) { | |
198 | QuickReport(CSRReport, RTYP_CSR_DEBUG_3,"%0d:CSR read_field(): %s register %s field:\t%0h\n", | |
199 | get_cycle(),get_name(),reg_field[field_id].get_field_name(),read_field); | |
200 | ||
201 | temp_data = read(offset,method); | |
202 | temp_data = temp_data & reg_field[field_id].get_field_mask(); | |
203 | temp_data = temp_data >> reg_field[field_id].get_field_position(); | |
204 | read_field = temp_data; | |
205 | } | |
206 | else { | |
207 | QuickReport(CSRReport, RTYP_CSR_ERROR, "RamAccessor::read_field: Invalid field_id %0h",field_id); | |
208 | } | |
209 | } // end function read_field | |
210 | ||
211 | ||
212 | ||
213 | //================================================= | |
214 | // Write Field Task | |
215 | //================================================= | |
216 | ||
217 | task write_field (bit [CSRT_ADDR_OFFSET_WIDTH-1:0] offset, | |
218 | integer field_id, | |
219 | bit [CSRT_DATA_WIDTH-1:0] field_data, | |
220 | integer method = CSRT_USE_DEFAULT_METHOD ) { | |
221 | ||
222 | bit [CSRT_DATA_WIDTH-1:0] curr_data; | |
223 | bit [CSRT_DATA_WIDTH-1:0] revised_data; | |
224 | bit [CSRT_DATA_WIDTH-1:0] field_positioned_data; | |
225 | bit [CSRT_DATA_WIDTH-1:0] zero_field_mask; | |
226 | bit [CSRT_DATA_WIDTH-1:0] refresh_bit_mask; | |
227 | ||
228 | if (method == CSRT_USE_DEFAULT_METHOD) | |
229 | method = DefaultMethod; | |
230 | ||
231 | if (field_id < get_max_num_fields()) { | |
232 | ||
233 | QuickReport(CSRReport, RTYP_CSR_DEBUG_3,"%0d:CSR write_field(): %s register %s field:\t%0h\n", | |
234 | get_cycle(),get_name(),reg_field[field_id].get_field_name(),field_data); | |
235 | semaphore_get (WAIT, ShadowState.csr_write_trans_sem, 1); | |
236 | ||
237 | field_positioned_data = reg_field[field_id].get_field_mask() & (field_data << reg_field[field_id].get_field_position()); | |
238 | curr_data = read(offset, method); | |
239 | zero_field_mask = ~(reg_field[field_id].get_field_mask()); | |
240 | refresh_bit_mask = zero_field_mask & get_write_mask (); | |
241 | revised_data = (curr_data & refresh_bit_mask) | field_positioned_data; | |
242 | access_methods[method].write(offset, revised_data); | |
243 | ||
244 | semaphore_put (ShadowState.csr_write_trans_sem, 1); | |
245 | } | |
246 | else { | |
247 | QuickReport(CSRReport, RTYP_CSR_ERROR, "RamAccessor::write_field: Invalid field_id %0h",field_id); | |
248 | } | |
249 | ||
250 | } // end task write_field | |
251 | ||
252 | ||
253 | //================================================= | |
254 | // Write Fields Task | |
255 | //================================================= | |
256 | task write_fields(bit [CSRT_ADDR_OFFSET_WIDTH-1:0] offset, CSRFieldAggregate field_aggregate, integer method = CSRT_USE_DEFAULT_METHOD) { | |
257 | bit [CSRT_DATA_WIDTH-1:0] curr_data; | |
258 | bit [CSRT_DATA_WIDTH-1:0] revised_data; | |
259 | bit [CSRT_DATA_WIDTH-1:0] field_positioned_data = 0; | |
260 | bit [CSRT_DATA_WIDTH-1:0] zero_field_mask = 0; | |
261 | bit [CSRT_DATA_WIDTH-1:0] refresh_bit_mask = 0; | |
262 | ||
263 | CSRAggregateContainer field_container; | |
264 | ||
265 | zero_field_mask = ~zero_field_mask; | |
266 | ||
267 | if (method == CSRT_USE_DEFAULT_METHOD) | |
268 | method = DefaultMethod; | |
269 | ||
270 | semaphore_get(WAIT, ShadowState.csr_write_trans_sem, 1); | |
271 | ||
272 | field_container = field_aggregate.pop(); | |
273 | ||
274 | while (field_container != null) { | |
275 | if (field_container.field_id < get_max_num_fields()) { | |
276 | ||
277 | // CSRReport.report(RTYP_INFO,"%0d:CSR write_fields(): %s register %s field:\t%0h\n", get_cycle(), get_name(), | |
278 | // reg_field[field_container.field_id].get_field_name(), field_container.field_data); | |
279 | ||
280 | field_positioned_data |= (reg_field[field_container.field_id].get_field_mask() & | |
281 | (field_container.field_data << reg_field[field_container.field_id].get_field_position())); | |
282 | zero_field_mask &= ~(reg_field[field_container.field_id].get_field_mask()); | |
283 | refresh_bit_mask |= zero_field_mask & get_write_mask(); | |
284 | } else { | |
285 | QuickReport(CSRReport, RTYP_CSR_ERROR, "RamAccessor::write_fields: Invalid field_id %0h", field_container.field_id); | |
286 | } | |
287 | field_container = field_aggregate.pop(); | |
288 | } | |
289 | ||
290 | curr_data = read(offset, method); | |
291 | revised_data = (curr_data & refresh_bit_mask) | field_positioned_data; | |
292 | ||
293 | if (curr_data !== revised_data) { | |
294 | QuickReport(CSRReport, RTYP_CSR_INFO,"RAMAccessor: %s write_fields(): %s register: Addr %0h : data %0h", get_method_name(method), get_name(), | |
295 | get_addr_offset(), revised_data); | |
296 | access_methods[method].write(offset, revised_data); | |
297 | } else { | |
298 | QuickReport(CSRReport, RTYP_CSR_DEBUG_1,"RAMAccessor: %s write_fields(): %s register: Addr %0h : data %0h %s", get_method_name(method), | |
299 | get_name(), get_addr_offset(), revised_data, " -- Not writing due to current_data == new_data"); | |
300 | } | |
301 | ||
302 | ||
303 | semaphore_put (ShadowState.csr_write_trans_sem, 1); | |
304 | } // end task write_fields | |
305 | ||
306 | ||
307 | //================================================= | |
308 | ||
309 | task set_shadow_csr(bit [CSRT_DATA_WIDTH-1:0] new_data) { | |
310 | ||
311 | QuickReport(CSRReport, RTYP_CSR_ALERT,"%0d:set_shadow_csr() is not supported for RAMAccessor: %s register.", | |
312 | get_cycle(),get_name()); | |
313 | } // end task set_shadow_csr() | |
314 | ||
315 | //================================================= | |
316 | // Get Shadow CSR Function | |
317 | //================================================= | |
318 | ||
319 | function bit [CSRT_DATA_WIDTH-1:0] get_shadow_csr() { | |
320 | ||
321 | QuickReport(CSRReport, RTYP_CSR_DEBUG_3,"%0d:CSR get_shadow_register(): %s register:\t%0h\n", | |
322 | get_cycle(), get_name(), get_shadow_csr); | |
323 | ||
324 | QuickReport(CSRReport, RTYP_CSR_ALERT,"%0d:get_shadow_csr() is not supported for RAMAccessor: %s register.", | |
325 | get_cycle(),get_name()); | |
326 | ||
327 | get_shadow_csr = get_shadow_data(); | |
328 | } // end function get_shadow_csr() | |
329 | ||
330 | } // end class CSRAccessor | |
331 | ||
332 | ||
333 | ||
334 | ||
335 |