Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / bridge / include / bridge.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: bridge.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 _PCIE2PCI_BRIDGE_
#define _PCIE2PCI_BRIDGE_
#include "pci.h"
#include "pcie.h"
#include "module.h"
#include "arg.h"
#include "pci_bridge.h"
#include "dr.h"
#include <list>
#define PCI_BCNF_BCNF 0x40
#define PCI_BCNF_MTT 0x42
#define PCI_BCNF_PCLKC 0x43
#define PCI_BCNF_EXP_CAPID 0x44
#define PCI_BCNF_EXP_NXTP 0x45
#define PCI_BCNF_EXP_CAP 0x46
#define PCI_BCNF_EXP_DCAP 0x48
#define PCI_BCNF_EXP_DCTL 0x4c
#define PCI_BCNF_EXP_DSTS 0x4e
#define PCI_BCNF_EXP_LCAP 0x50
extern "C"{
int pcieToPciBridge_ui_cmd(void*, int argc, char * argv[]);
}
class pcieToPciBridge: public genericPcieDev, public pciBridgeIf, public Module{
// pciBridgeIf is exported to the downstream pci Bus.
pciBusIf *secBusIf; // pci bus intf on the downstream/secondary interface
const char * secBusName;
// pcie bus intf on the primary side is member of genericPcieDev
uint32_t mem32_base, mem32_limit, io_base, io_limit;
uint64_t mem64_base, mem64_limit;
pciExpMsgCode map_pin_vpin(int device, int line, bool ast);
uint32_t pcie_eh1_pci0_translation(uint32_t addr);
bridgeCommandReg * bCR;
bool io_mapped() {return bCR->io_mapped();}
bool mem_mapped() {return bCR->mem_mapped();}
bool pendingIntr[4];
typedef std::list<int > intxStatus;
intxStatus intLine[4]; // 4 lists of pending Intx interrupts,
// indexed with INT[A|B|C|D] type.
// Holds the downstream device #
// As long as there is an entry, an Intx
// message is pended to upstream bridge,
// otherwise a deassertIntx is send.
pthread_mutex_t intMutex;
// route the received Intx message to upstream bridge.
pcieCompleter assertIntx(pciExpMsgCode messageCode, int device, SAM_DeviceId *id){
assert(messageCode >= MSG_Assert_INTA && messageCode <= MSG_Assert_INTD);
int line = messageCode - MSG_Assert_INTA;
assert(0 <= line && line <= 3);
pthread_mutex_lock(&intMutex);
intLine[line].push_back(device);
intLine[line].sort();
intLine[line].unique();
if(pendingIntr[line]){
debug_more("%s: asserting Intr%c from device %d - line already asserted\n",getName(),'A' + line, device);
pthread_mutex_unlock(&intMutex);
return pcieCompleter(SC,getId());
}
pendingIntr[line] = true;
pthread_mutex_unlock(&intMutex);
debug_more("%s: asserting Intr%c from device %d\n",getName(),'A' + line, device);
return busIf->busif_msgAccess((uint8_t)messageCode, msgDB->msgCode2Routing(messageCode), getId(),id);
}
pcieCompleter deassertIntx(pciExpMsgCode messageCode, int device, SAM_DeviceId *id){
assert(messageCode >= MSG_Deassert_INTA && messageCode <= MSG_Deassert_INTD);
int line = messageCode - MSG_Deassert_INTA;
assert(0 <= line && line <= 3);
pthread_mutex_lock(&intMutex);
intLine[line].remove(device);
if(!intLine[line].empty()){
debug_more("%s: deasserting Intr%c from device %d - line still asserted\n",getName(),'A' + line, device);
pthread_mutex_unlock(&intMutex);
return pcieCompleter(SC,getId());
}
pendingIntr[line] = false;
pthread_mutex_unlock(&intMutex);
debug_more("%s: Deasserting Intr%c from device %d\n",getName(),'A' + line, device);
return busIf->busif_msgAccess((uint8_t)messageCode, msgDB->msgCode2Routing(messageCode), getId(),id);
}
const char * dump_version1_0;
const char * current_dump_version;
public:
bool devif_isBridge(){return true;}
pcieToPciBridge(const char* modname, const char * instance_name);
~pcieToPciBridge();
void initPci();
void init_regs();
void map_pci(pci_space_t space, uint64_t mask, uint64_t match,uint64_t size);
mmi_instance_t devif_getInstance() {return Module::instance;}
const char *devif_getName() {return Module::getName();}
void devif_confAccessCb(bool wr, uint64_t offset, uint8_t be=0xf);
// Module functions
const char *get_help();
bool parse_arg(const char *);
bool check_args();
void init_done();
void module_added(mmi_instance_t, const char*);
void module_deleted(mmi_instance_t, const char*);
void modinfo();
void *get_interface(const char*);
// genericPcieDev virtual/unimplemented functions
// or functions that need to be overridden eg
// devif_memAccess, devif_ioAccess, etc.
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_confAccess(bool wr, uint32_t offset, void * data, \
uint8_t be,uint16_t reqId, addrMd_xactnType tType, uint16_t length, tlp_X args, SAM_DeviceId *id);
pcieCompleter devif_ioAccess(bool wr, uint64_t addr, void * data, uint8_t be, \
uint16_t reqId, uint16_t length, 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);
int devif_getBusNo() {return (confSpace->readConf(PCI_BCNF_SECBUS) & 0xff);}
int devif_getSubBusNo() {return (confSpace->readConf(PCI_BCNF_SUBBUS) & 0xff);}
// implement pciBridgeIf functions as applicable.
int busif_add_interrupt(mmi_instance_t busMod,int device,int dev_type, int slot_irl[],bool isMulti);
int busif_free_interrupt(mmi_instance_t busMod, int dev_number);
int busif_interrupt_in(bool set,mmi_instance_t busMod, int device, int line, SAM_DeviceId *id);
int busif_dma_out(uint64_t vaddr, void *data, long count, mmi_instance_t caller,uint16_t requesterId,SAM_DeviceId *id);
int busif_dma_in(uint64_t vaddr, void *data, long count, mmi_instance_t
caller,uint16_t requesterId, SAM_DeviceId *id);
int busif_get_secondary_busno() {return (confSpace->readConf(PCI_BCNF_SECBUS) & 0xff);}
// XXX NOTE : we may need to implement some functions in pciTargetIf as well
// to support all the possible accesses from downstream devices. I am still
// looking into the possible cases.
pciXactnStatus pciTarget_mem32access(uint64_t offset, bool wr,uint64_t * buf, uint8_t size){return SIM_INTERNAL_ERROR;}
pciXactnStatus pciTarget_mem64access(uint64_t offset, bool wr,uint64_t * buf, uint8_t size){return SIM_INTERNAL_ERROR;}
pciXactnStatus pciTarget_ioaccess(uint64_t offset, bool wr,uint64_t * buf, uint8_t size){return SIM_INTERNAL_ERROR;}
pciXactnStatus pciTarget_special_cycle(uint16_t mssg, uint16_t data){return SIM_INTERNAL_ERROR;}
pciXactnStatus pciTarget_intr_ack(uint64_t *data){return SIM_INTERNAL_ERROR;}
bool dump(FILE *fp);
bool restore(FILE *fp);
void handle_ui(int, char**);
void ui_cmd_usage(){
printf("ui format: %s <command> <command args> ... \n",getName());
printf("%s supports following UI commands\n",getName());
printf(" debug [<level>]\n\
set the debug level for debug prints to \'level\'\n\
if \'level\' not provided, print current debug level\n\
\'level\' = [0|1|2]\n");
printf(" dump [<filename>]\n \
dump the PCIE CSR contents to <filename>.pci in cwd\n \
default is stderr\n \
dump format is: <csr pciconf offset> <csr value> <csr r/w mask> <csr size> <csr name>\n");
printf(" restore <filename>\n\
restore the PCIE CSR contents from <filename>.pci in cwd \n\
restore file format is same as dump file format\n");
}
};
#endif