Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / memsync / src / RieslingInterface.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: RieslingInterface.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21/************************************************************************
22**
23** Copyright (C) 2002, Sun Microsystems, Inc.
24**
25** Sun considers its source code as an unpublished, proprietary
26** trade secret and it is available only under strict license provisions.
27** This copyright notice is placed here only to protect Sun in the event
28** the source is deemed a published work. Disassembly, decompilation,
29** or other means of reducing the object code to human readable form
30** is prohibited by the license agreement under which this code is
31** provided to the user or company in possession of this copy."
32**
33*************************************************************************/
34#include <sstream>
35#include "RieslingInterface.h"
36
37using namespace std;
38
39/* this will be removed once pli-socket files are in place */
40int RieslingInterface::max_strands=256;
41int RieslingInterface::strands_per_core=8;
42int RieslingInterface::cores_per_cpu=8;
43
44uint64_t RieslingInterface::readMemory(uint32_t cid, uint32_t tid, uint64_t addr, uint_t size, int convert)
45{
46 uint64_t data;
47
48 if (convert)
49 addr = convertPA(cid, tid, addr);
50
51 assert(size <= 8);
52 if(size == 1)
53 data = io->peek8u(tid,addr);
54 else if(size == 2)
55 data = io->peek16u(tid,addr);
56 else if(size == 4)
57 data = io->peek32u(tid,addr);
58 else if(size == 8)
59 data = io->peek64(tid,addr);
60
61 MSYNC_DEBUG (1, "ReadMemory tid=%d pa=%#llx data=%#llx size=%d", tid, addr, data, size);
62 return data;
63}
64
65void RieslingInterface::writeMemory(uint32_t cid, uint32_t tid, uint64_t addr, uint64_t data, uint_t size, int convert)
66{
67 if (convert)
68 addr = convertPA(cid, tid, addr);
69
70 switch (size)
71 {
72 case 1: io->poke8( tid,addr,data); break;
73 case 2: io->poke16(tid,addr,data); break;
74 case 4: io->poke32(tid,addr,data); break;
75 case 8: io->poke64(tid,addr,data); break;
76 default: assert(0);
77 }
78
79 MSYNC_DEBUG (1, "WriteMemory tid=%d pa=%#llx data=%#llx size=%d", tid, addr, data, size);
80}
81
82void RieslingInterface::slamMemory(uint32_t cid, uint32_t tid, uint64_t addr, uint64_t data, uint_t size, int convert )
83{
84 if (convert)
85 addr = convertPA(cid, tid, addr);
86
87 switch (size)
88 {
89 case 1: io->poke8( tid,addr,data); break;
90 case 2: io->poke16(tid,addr,data); break;
91 case 4: io->poke32(tid,addr,data); break;
92 case 8: io->poke64(tid,addr,data); break;
93 default: assert(0);
94 }
95
96 MSYNC_DEBUG (1, "WriteMemory tid=%d pa=%#llx data=%#llx size=%d", tid, addr, data, size);
97}
98
99//=============================================================================
100// 16.3.2.4 PCI Express addressing & 24.3
101//
102// #define MEM32_OFFSET_BASE_REG_ADDR 0x80-0000-2000
103// #define MEM32_OFFSET_MASK_REG_ADDR 0x80-0000-2008
104// #define MEM64_OFFSET_BASE_REG_ADDR 0x80-0000-2010
105// #define MEM64_OFFSET_MASK_REG_ADDR 0x80-0000-2018
106// #define MEM64_PCIE_OFFSET_REG_ADDR 0x88-0063-4018
107//
108// match = false;
109// if (PA[39:36] == 0xc) {
110// if ((BASE64[63] == 1) &&
111// ((PA[35:24] & MASK64[35:24]) == BASE64[35:24])) {
112// // 64bit address
113// match = true;
114// newPA = OFFSET64[63:36] |
115// (OFFSET[35:24] | (PA[35:24] & ~MASK64[35:24])) |
116// PA[23:0];
117// }
118// if ((match == false) &&
119// (BASE32[63] == 1) &&
120// ((PA[35:24] & MASK32[35:24]) == BASE32[35:24])) {
121// // 32bit address
122// newPA = PA[31:0] & ~MASK32[35:24];
123// }
124// }
125//
126// maybe we should move this function to N2_System.cc ?
127//---> no, we need it here so that we can match msync address.
128//
129//=============================================================================
130uint64_t
131RieslingInterface::convertPA(int cid, int tid, uint64_t pa)
132{
133 if ((getBits(pa, 39, 36) & 0xf) == 0xc) {
134 //cerr << "DBX: enter convertPA(), pa=0x" << hex << pa << endl;//DBX
135 // looking for 32bit/64bit PCIE PIO address mapping, check 64bit first
136 bool match = false;
137 uint64_t newPa = pa;
138 uint64_t mem64_offset_base = readMemory(cid, tid, 0x8000002010, 8, 0);
139 //cerr << "DBX: RieslingInterface::convertPA: offset64=0x" << hex << mem64_offset_base << endl;//DBX
140 if (getBits(mem64_offset_base, 63, 63) == 0x1) {
141 // 64bit enabled
142 uint64_t mem64_offset_mask = readMemory(cid, tid, 0x8000002018, 8, 0);
143 //cerr << "DBX: RieslingInterface::convertPA: mask64=0x" << hex << mem64_offset_mask << endl;//DBX
144 if ((getBits(pa, 35, 24) & getBits(mem64_offset_mask, 35, 24)) == getBits(mem64_offset_base, 35, 24)) {
145 // match 64bit base
146 match = true;
147 uint64_t pcie_offset = readMemory(cid, tid, 0x8800634018, 8, 0);
148 //cerr << "DBX: RieslingInterface::convertPA: pcie_offset=0x" << hex << pcie_offset << endl;//DBX
149 newPa = getBits(pcie_offset, 63, 36, true) |
150 (getBits(pcie_offset, 35, 24, true) | (getBits(pa, 35, 24, true) & ~(getBits(mem64_offset_mask, 35, 24, true)))) |
151 getBits(pa, 23, 0, true);
152 }
153 }
154 // 64bit has higher priority, check 32bit only if not matching 64bit
155 //TODO 32bit checking is disable for now, 1/6/06
156 if (0 && (match == false)) {
157 uint64_t mem32_offset_base = readMemory(cid, tid, 0x8000002000, 8, 0);
158 //cerr << "DBX: RieslingInterface::convertPA: offset32=0x" << hex << mem32_offset_base << endl;//DBX
159 if (getBits(mem32_offset_base, 63, 63) == 0x1) {
160 // 32bit enabled
161 uint64_t mem32_offset_mask = readMemory(cid, tid, 0x8000002008, 8, 0);
162 //cerr << "DBX: RieslingInterface::convertPA: mask32=0x" << hex << mem32_offset_mask << endl;//DBX
163 if ((getBits(pa, 35, 24) & getBits(mem32_offset_mask, 35, 24)) == getBits(mem32_offset_base, 35, 24)) {
164 // match 32bit base
165 newPa = getBits(pa, 31, 0, true) & ~(getBits(mem32_offset_mask, 35, 24, true));
166 }
167 }
168 }
169 //cerr << "DBX: RieslingInterface::convertPA: pa=0x" << hex << pa << " newPa=0x" << newPa << endl;//DBX
170 return newPa;
171 }
172 else {
173 return pa;
174 }
175}