* ========== 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_
#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
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
// 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
);
bool io_mapped() {return bCR
->io_mapped();}
bool mem_mapped() {return bCR
->mem_mapped();}
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
);
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
;
bool devif_isBridge(){return true;}
pcieToPciBridge(const char* modname
, const char * instance_name
);
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);
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*);
// 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
;}
void handle_ui(int, char**);
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\
printf(" dump [<filename>]\n \
dump the PCIE CSR contents to <filename>.pci in cwd\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");