* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: sam_piu.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 ============================================
* This is a port from Legions PIU library to SAM, with the intention
* of making as minimal changes as possible to the legion library sources,
* while making it mmi compliant as much as possible.
* Code that is not needed from SAM perspective is deleted.
static int access_piu(uint32_t cpuid
, void* obj
, uint64_t paddr
, mmi_bool_t wr
, uint32_t size
, uint64_t* buf
, uint8_t bytemask
);
int n2piu_ui_cmd(void*, int argc
, char * argv
[]);
void samPiu_1ms_callback(void * piuobj
, void * );
class samPiu
:public Module
, genericPcieDevIf
{
const char *bus
; // pcie bus name on the downstream
mmi_instance_t busMod
; // pcie bus instance
const char * N2_PIU_VERSION
;
pcieBusIf
*busIf
; // pcie bus interface
static const uint64_t PIU_CSR_BASE
= 0x8800000000;
static const uint64_t PIU_CSR_SIZE
= 0x800000; // 8 MB
// this region maps the pcie conf/io/mem32/mem64 regions of
static const uint64_t PIU_PCIE_BASE
= 0xc000000000;
static const uint64_t PIU_PCIE_SIZE
= 0x1000000000; // 64 GB
* PIU CSR space allows only r/w's of 8 bytes.
* pcie config/io space allows r/w' s of 1,2,4 bytes.
* pcie mem32/mem64 allows r/w's of 1,2,4,8 bytes along with
* partial writes, which specify a bytemask.
// some useful offsets into PIU_CSR_BASE
static const uint64_t PIU_DMU_PCIE_CONFREG_OFFSET
= 0x653100;
public: // genericPcieDevIf
bool devif_isBridge(){ return false; }
bool devif_isRootCmplx(){return true; }
// piu does not support CONFIG access as a target
pcieCompleter
devif_confAccess(bool wr
, uint32_t offset
, void * data
, \
uint8_t be
, uint16_t reqId
, addrMd_xactnType
, uint16_t, tlp_X
,SAM_DeviceId
*id
){
return pcieCompleter(CA
);
// piu does not support IO access as a target
pcieCompleter
devif_ioAccess(bool wr
, uint32_t addr
, void * data
,
uint8_t be
, uint16_t reqId
, uint16_t length
, tlp_X args
,SAM_DeviceId
*id
){
return pcieCompleter(CA
);
int devif_getBusNo(){ return secondary_bus_no
; }
int devif_getPriBusNo(){ return primary_bus_no
; }
int devif_getSubBusNo() { return subordinate_bus_no
; }
int devif_getDevice(){ return device
; }
int devif_getFunction(){ return function
; }
const char *devif_getName(){ return Module::getName(); }
const char *devif_getBusName(){ return "N2 PIU internal bus"; }
mmi_instance_t
devif_getInstance(){ return Module::getInstance(); }
void devif_confAccessCb(bool wr
, uint64_t offset
, uint8_t be
){}
pcieCompleter
devif_memAccess(bool wr
, uint64_t addr
, addrMd_xactnType mode
,\
void * data
, uint16_t length
, uint8_t be
, uint16_t reqId
, tlp_X args
,SAM_DeviceId
*id
);
pcieCompleter
devif_msgAccess(uint8_t messageCode
, msgRouting route
, \
uint64_t tarIdOrAddr
, uint16_t reqId
, \
void * data
, uint16_t length
, \
uint16_t vendorId
, uint32_t vendor_data
, tlp_X args
,SAM_DeviceId
*id
);
// intr 0-19 are reserved, 20-23 intx, 24-59 ev q, 62 dmu, 63 peu
typedef list
<int > intxStatus
;
intxStatus intLine
[4]; // 4 lists of pending interrupts, 1 for every device from a bus
pthread_mutex_t intxMutex
;
pthread_mutex_t pendIntMutex
;
pthread_mutex_t piuMutex
;
pthread_mutex_t msiMutex
[36]; // 36 event queues in total
static const int MONDO_INTA
= 20;
pthread_mutex_t ncuMutex
;
typedef list
<VCPU_InterruptRequest
* > irqList
;
uint64_t event_fire_time
;
public: // Module interface
bool parse_arg(const char *);
void module_added(mmi_instance_t
, const char*);
void module_deleted(mmi_instance_t
, const char*);
void *get_interface(const char*);
const char *get_version();
samPiu(const char *modname
, const char *instance_name
);
n2Ncu
* getNcu(){ return ncuIf
; }
uint16_t getReqId(){ return PCIE_REQUESTER_ID(primary_bus_no
,device
,function
); }
void sendMondo(pcie_mondo_t
*);
int handlePio(uint32_t cpuid
,uint64_t paddr
, mmi_bool_t wr
, \
uint32_t size
, uint64_t* buf
, uint8_t bytemask
);
bool setPending(int ino
, bool set
){
pthread_mutex_lock(&pendIntMutex
);
bool ret
= pendingIntr
[ino
];
pthread_mutex_unlock(&pendIntMutex
);
bool getPending(int ino
){
void setIntx(int devid
,int line
, bool set
){
//printf("piu intx line %d set to %d\n",line,set);
pthread_mutex_lock(&intxMutex
);
intLine
[line
].push_back(devid
);
setPending(line
+ MONDO_INTA
, true);
intLine
[line
].remove(devid
);
if(intLine
[line
].empty())
setPending(line
+ MONDO_INTA
, false);
pthread_mutex_unlock(&intxMutex
);
void handle_ui(int argc
, char * argv
[]);
printf("ui format: %s <command> <command args> ... \n",getName());
printf("%s supports following UI commands\n",getName());
printf(" dump [<filename>]\n \
dump the CSR contents to \'filename\' \n \
dump format is: <csr name> <csr physical offset> [<csr index> <csr value>,]+\n \
: pending interrupts (msi event q, intx)\n");
printf(" restore <filename>\n\
restore the CSR contents from \'filename\' \n\
restore file format is same as dump file format\n");
printf(" debug [<level>]\n\
set the debug level for debug prints to \'level\'\n\
if \'level\' not provided, print current debug level\n\
void samPiu::timer_callback();
void dump_piu_csrs(FILE * fp
);
void dump_intr(FILE * fp
);
void dump_irq(FILE * fp
);
void restore_piu_csrs(FILE * fp
);
void restore_intr(FILE * fp
);
void restore_irq(FILE * fp
);