* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: pcie_bus.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 _PCIE_BUS_NEW_IMPL_H
#define _PCIE_BUS_NEW_IMPL_H
class pcieBus
:public Module
, public pcieBusIf
{
genericPcieDevIf
* devIf
;
pcieDevInfo(const char * n
, mmi_instance_t i
, genericPcieDevIf
* dI
, int d
, int f
= 0){
printf("name <%s>, dev <%d>, fun <%d>",name
, device
, function
);
uint64_t end
; // base + size - 1
pcieDevInfo
* devInfo
; // pointer to the info struct for this device
pcieRange(uint64_t b
, uint64_t e
, pcieDevInfo
* di
){
base
= b
; end
= e
; devInfo
= di
;
printf(" base <%llx> end <%llx>\n", base
, end
);
//comparison function (reverse than normal default case)
bool operator()(uint64_t key1
, uint64_t key2
)const{
typedef map
<uint64_t , pcieRange
*,compare
> pcieDevMap
;
typedef map
<uint64_t , pcieRange
*,compare
>::iterator pcieDevMapIterator
;
pcieDevInfo
*searchDevInfoListByName(const char * name
){
list
<pcieDevInfo
*>::iterator i
;
for(i
= devInfoList
.begin(); i
!= devInfoList
.end(); i
++)
if(!strcmp(name
, (*i
)->name
))
pcieDevInfo
*searchDevInfoListByDevFun(int dev
, int fun
){
list
<pcieDevInfo
*>::iterator i
;
for(i
= devInfoList
.begin(); i
!= devInfoList
.end(); i
++)
if(((*i
)->device
== dev
) && ((*i
)->function
== fun
))
bool addSpace(pcieRange
* pI
,pcie_space space
){
pcieDevMapIterator dmIter
;
for(dmIter
= pcieAddrSpace
[space
].begin(); dmIter
!= pcieAddrSpace
[space
].end(); dmIter
++){
if(pI
->base
>= dmIter
->second
->base
&& pI
->base
<= dmIter
->second
->end
|| // pI base within dmIter
pI
->end
>= dmIter
->second
->base
&& pI
->end
<= dmIter
->second
->end
|| // pI end within dmIter
pI
->base
<= dmIter
->second
->base
&& pI
->end
>= dmIter
->second
->end
){ // pI encloses dmIter
if(strcmp(pI
->devInfo
->name
,dmIter
->second
->devInfo
->name
)){
printf("%s add Space error : Conflicting ranges\n",getName());
printf("Existing device -->"); dmIter
->second
->print();
printf("Conflicting device -->"); pI
->print();
return false; //range conflict
pcieAddrSpace
[space
][pI
->base
] = pI
;
bool removeMap(pcieDevInfo
* pI
){ //remove all the mappings for device with info struct pI
pcieDevMapIterator dmIter
;
for(uint8_t i
= 0; i
< PCI_NSPACES
; i
++)
for(dmIter
= pcieAddrSpace
[i
].begin(); dmIter
!= pcieAddrSpace
[i
].end(); dmIter
++)
if(dmIter
->second
->devInfo
== pI
){
pcieDevMapIterator dmIter1
= ++dmIter
;
pcieAddrSpace
[i
].erase(--dmIter
);
bool removeSpace(uint64_t base
, pcie_space space
){
return pcieAddrSpace
[space
].erase(base
);
static const char * pcie_space_name(pcie_space space
){
return "Unknow Pcie Space!!";
list
<pcieDevInfo
*> devInfoList
; //list of devices present on the pci Bus
pcieDevMap pcieAddrSpace
[3]; // map in only PCIE_CFG, PCIE_IO, PCIE_MEM
mmi_instance_t bridgeMod
;
genericPcieDevIf
* bridgeIf
;
uint16_t getBridgeId(){ return PCIE_REQUESTER_ID(bridgeIf
->devif_getPriBusNo(),\
bridgeIf
->devif_getDevice(),bridgeIf
->devif_getFunction());}
pcieBus(const char *_modname
, const char *_instance_name
);
bool parse_arg(const char *arg
);
void module_added(mmi_instance_t
, const char *target_name
);
void module_deleted(mmi_instance_t
, const char *target_name
);
void * get_interface(const char *name
);
void setBridgeIf(genericPcieDevIf
* i
){bridgeIf
= i
;}
bool busif_addDevice(const char *devname
, int device
, int function
);
bool busif_deleteDevice(const char *devname
);
bool busif_map(const char *devname
, pcie_space
, uint64_t base
, uint64_t size
);
bool busif_unmap(const char *devname
, pcie_space
, uint64_t base
);
bool dump(const char * dir
, const char* file
){return true;}
bool restore(const char * dir
, const char* file
){return true;}
// get the mmi instance based upon device and function
mmi_instance_t
getDevInstance(int dev
,int fun
);
// access the mem, io, conf space addresses under this bus hierarchy.
pcieCompleter
busif_access(pcie_space
, bool wr
, uint64_t addr
, void * data
, \
uint16_t length
, uint8_t be
, uint16_t reqId
, addrMd_xactnType
, SAM_DeviceId
*samId
, tlp_X args
);
// addr is a 64 bit flat address into one of the mem/io/conf spaces.
// the bus would call one of the devif functions based upon the space.
pcieCompleter
busif_msgAccess(uint8_t messageCode
, msgRouting route
,uint16_t reqId
, SAM_DeviceId
*samId
,\
uint64_t tarIdOrAddr
, /*msg tlp*/ \
void * data
, uint16_t length
, /* msgd tlp*/ \
uint16_t vendor
, uint32_t vendor_data
, tlp_X args
= dont_care_attrs
); /* vendor defined msg*/