Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / ras / src / SS_AsiArray.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: SS_AsiArray.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_AsiArray_h__
24#define __SS_AsiArray_h__
25
26#include "BL_BoundedArray.h"
27#include "BL_Mutex.h"
28#include "SS_AsiSpace.h"
29
30// SS_AsiArray template creates an array of Asi control
31// registers with the machinery to easily add them to an SS_AsiSpace.
32// The elements of the array are intended to be SS_AsiCtrReg's
33// extended with a valid bit to detect whether an element has been
34// initialized.
35//
36// Additionally, there is an get() method which takes either an
37// SS_Vaddr or a specialized type for constructing addresses (usually
38// another SS_AsiCtrReg). These get() routines index the array of Asi
39// elements with the virtual and return a reference to the
40// corresponding element.
41
42// The template takes a class name, AsiType, which must have
43// the following class members:
44//
45// typedef <addressing type> ADDR_TYPE;
46// const static ASI = <array's asi number>;
47// const static SIZE = <number of elements in the array>;
48// const static SHIFT = <log2(vaddr stride between elements)>;
49//
50// The base address of the array must be the value of produced by the
51// default constructor of ADDR_TYPE.
52//
53// SS_AsiArray provides methods to add all its elements to the
54// asi space AsiType::ASI by calling add_asi_map().
55
56class SS_Node;
57
58
59// The SS_AsiArray template class creates an array of asi registers.
60
61template<class AsiType> class SS_AsiArray {
62 public:
63 int lock() { return _mutex.lock(); }
64 int unlock() { return _mutex.unlock(); }
65 int trylock() { return _mutex.trylock(); }
66
67 // Get an asi element by virtual address
68 AsiType& get(SS_Vaddr va) {
69 return array[(va >> AsiType::SHIFT) % AsiType::SIZE];
70 }
71
72 // Get an asi element by specialized virtual address class
73 AsiType& get(typename AsiType::ADDR_TYPE va) {
74 return get(va.get());
75 }
76
77 // Add this Asi array to a SS_Node.
78 void add_asi_map(SS_Node* node, SS_Vaddr base_offset = 0)
79 {
80 AsiType::ADDR_TYPE base_addr;
81 for (SS_Vaddr ndx = 0 ; ndx < AsiType::SIZE; ++ndx)
82 node->asi_map[AsiType::ASI].add(base_addr.get() +
83 (ndx << AsiType::SHIFT) + base_offset,
84 node,
85 (void*)&array[ndx],
86 SS_AsiCtrReg::ld64,
87 SS_AsiCtrReg::st64,
88 SS_AsiCtrReg::rd64,
89 SS_AsiCtrReg::wr64);
90 }
91
92 // Add this Asi array to a SS_Node.
93 void add_asi_map(SS_Node* node, SS_AsiSpace::Read ld64,
94 SS_AsiSpace::Write st64,
95 SS_AsiSpace::Read rd64,
96 SS_AsiSpace::Write wr64,
97 SS_Vaddr base_offset = 0)
98 {
99 AsiType::ADDR_TYPE base_addr;
100 for (SS_Vaddr ndx = 0 ; ndx < AsiType::SIZE; ++ndx)
101 node->asi_map[AsiType::ASI].add(base_addr.get() +
102 (ndx << AsiType::SHIFT) + base_offset,
103 node,
104 (void*)&array[ndx],
105 ld64, st64, rd64, wr64);
106 }
107
108 // Add this Asi array to a SS_Strand.
109 void add_asi_map(SS_Strand* strand)
110 {
111 AsiType::ADDR_TYPE base_addr;
112 for (SS_Vaddr ndx = 0 ; ndx < AsiType::SIZE; ++ndx)
113 strand->asi_map[AsiType::ASI].add(base_addr.get() +
114 (ndx << AsiType::SHIFT),
115 (SS_Node*)strand,
116 SS_AsiCtrReg::ld64,
117 SS_AsiCtrReg::st64,
118 SS_AsiCtrReg::rd64,
119 SS_AsiCtrReg::wr64)
120
121 }
122
123 private:
124 BL_BoundedArray<AsiType, AsiType::SIZE> array;
125
126 BL_Mutex _mutex;
127};
128
129
130
131#endif /* __SS_AsiArray_h__ */