Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / csr / src / SS_CsrAttribute.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: SS_CsrAttribute.h
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
*
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ========== Copyright Header End ============================================
*/
#ifndef SS_CSR_ATTRIBUTE_H
#define SS_CSR_ATTRIBUTE_H
/************************************************************************
**
** Copyright (C) 2006, Sun Microsystems, Inc.
**
** Sun considers its source code as an unpublished, proprietary
** trade secret and it is available only under strict license provisions.
** This copyright notice is placed here only to protect Sun in the event
** the source is deemed a published work. Disassembly, decompilation,
** or other means of reducing the object code to human readable form
** is prohibited by the license agreement under which this code is
** provided to the user or company in possession of this copy.
**
*************************************************************************/
#include <list>
#include <vector>
#include "SS_Types.h"
class RegisterAttribute;
// a single register content
class RegisterValue
{
public:
RegisterValue() : valid_(false) { }
RegisterValue(SS_Paddr addr,
uint64_t da,
const RegisterAttribute* attr,
int _sid=-1) :
address(addr),
data_(da),
attribute(attr),
valid_(true),
sid(_sid) { }
RegisterValue(const RegisterValue &rhs) :
address(rhs.address),
data_(rhs.data_),
attribute(rhs.attribute),
valid_(rhs.valid_),
sid(rhs.sid) { }
virtual ~RegisterValue() { }
RegisterValue operator= (const RegisterValue &rhs)
{
address = rhs.address;
data_ = rhs.data_;
attribute = rhs.attribute;
valid_ = rhs.valid_;
sid = rhs.sid;
return *this;
}
uint64_t data() const { return data_; }
void set_data(uint64_t da) { valid_ = true; data_ = da; }
bool valid() const { return valid_; }
SS_Paddr address;
const RegisterAttribute* attribute;
// strand-id
int sid;
private:
uint64_t data_;
// whether the object is valid or not
bool valid_;
};
/**
* RW1C:
* old-value input-value new-value
* 0 0 0
* 0 1 0
* 1 0 1
* 1 1 0
*
* RW1S:
* old-value input-value new-value
* 0 0 0
* 0 1 1
* 1 0 1
* 1 1 1
*
* maskRSVD, reserved bits
* maskRO, read-only bits
* maskRW, read-write bits, ~(maskRSVD | maskRO)
* maskRW1C, mask for RW1C, a subset of maskRW
* maskRW1S, mask for RW1S, a subset of maskRW
* maskWarm, mask used for warm reset, if 0x0, then warmReset is used
*
* exclude_maskRW = maskRW & ~(maskRW1C | maskRW1S)
*
* new_data = (input_data & exclude_maskRW) |
* (input_data & maskRW1S) |
* (old_data & ~(exclde_maskRW | (input_data & maskRW1C)))
*/
/**
* a register group's attribute. Each RegisterAttribute object has the
* attribute of (startAddr, endAddr, stride, count), so there can be more
* than one register in a group, an addr belong to a group if
* startAddr <= addr <= endAddr, and (addr % stride) == 0.
*
* For each RegisterAttribute object, "count-1 = (endAddr-startAddr )/stride"
* must always hold true.
*/
class RegisterAttribute {
public:
/**
* Defines the different types of access a field can have:
* read-write (RW), read-only (RO), write-only (WO),
* read/write-1-clear(RW1C), or read/write-1-set(RW1S).
*/
typedef enum { RW, RO, WO, RW1C, RW1S } Protection;
// the address of the first register of the group
SS_Paddr startAddr;
// the address of the last register of the group
SS_Paddr endAddr;
// the register group's address offset
uint64_t stride;
// number of registers in the group
int count;
// power-on-reset value
uint64_t por;
// warm reset value
uint64_t warmReset;
// access type of the register
Protection protect;
// reserved bits
uint64_t maskRSVD;
// read-only bits
uint64_t maskRO;
// read-write bits, ~(maskRSVD | maskRO)
uint64_t maskRW;
// mask for RW1C, a subset of maskRW
uint64_t maskRW1C;
// mask for RW1S, a subset of maskRW
uint64_t maskRW1S;
// mask used for warm reset, if 0x0, then no masking and warmReset value
// is used
uint64_t maskWarm;
// register name
const char* name;
const char* comment;
// take ownership of address space
bool ownAddressSpace;
/**
* find the register entry of a specified (node-id, padd). The 'values'
* represents the vector of the register group that the paddr is in, it
* is a 2-dimension structure, the first dimention has one entry for
* each node (i.e., cpu), and the second dimention has one entry for
* each addr in the register group.
*/
RegisterValue *find(SS_Paddr paddr, std::vector<std::vector<RegisterValue>*> &values, int nid) const
{
// first check if the specified node has its vector
if (values.size() < nid+1)
{
values.resize(nid+1);
}
// make sure the proper structure is allocated
if (values[nid] == NULL)
{
values[nid] = new std::vector<RegisterValue>;
}
// then see if there are enough entries for this register group
// (startAddr, endAddr, count, stride)
if (values[nid]->size() != count)
{
if (count - 1 != (endAddr - startAddr)/stride)
{
fprintf(stderr, "ERROR: RegisterAttribute::find(): Bad count/endAddr %d/%#llx\n", count, endAddr);
return NULL;
}
else
{
values[nid]->resize(count);
}
}
// calculate register index into the vector
uint64_t ndx = (paddr - startAddr)/stride;
if (ndx >= count)
{
fprintf(stderr, "ERROR: RegisterAttribute::find(): Bad count allocation, count=%d, addr=%#llx, ndx=%d\n", count, paddr, (int)ndx);
return NULL;
}
else
{
return &((*values[nid])[ndx]);
}
}
};
#endif // SS_CSR_ATTRIBUTE_H