* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: pci_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 _PCI_BUS_NEW_IMPL_H
#define _PCI_BUS_NEW_IMPL_H
class pciBus
:public Module
, pciBusIf
{
pciDevInfo(const char * n
, mmi_instance_t i
, genericPciDevIf
* dI
, uint8_t d
, uint8_t f
= 0){
printf("name <%s>, dev <%d>, fun <%d>\n",name
, device
, function
);
uint64_t end
; // base + size - 1
pciDevInfo
* devInfo
; // pointer to the info struct for this device
pciRange(uint64_t b
, uint64_t e
, pciDevInfo
* 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 , pciRange
*,compare
> pciDevMap
;
typedef map
<uint64_t , pciRange
*,compare
>::iterator pciDevMapIterator
;
pciDevInfo
*searchDevInfoListByName(const char * name
){
list
<pciDevInfo
*>::iterator i
;
for(i
= devInfoList
.begin(); i
!= devInfoList
.end(); i
++)
if(!strcmp(name
, (*i
)->name
))
pciDevInfo
*searchDevInfoListByDevFun(uint8_t dev
, uint8_t fun
){
list
<pciDevInfo
*>::iterator i
;
for(i
= devInfoList
.begin(); i
!= devInfoList
.end(); i
++)
if(((*i
)->device
== dev
) && ((*i
)->function
== fun
))
bool addSpace(pciRange
* pI
,pci_space_t space
){
pciDevMapIterator dmIter
;
dmIter
= pciAddrSpace
[space
].lower_bound(pI
->base
);
for(dmIter
= pciAddrSpace
[space
].begin(); dmIter
!= pciAddrSpace
[space
].end(); dmIter
++){
if(pI
->base
>= dmIter
->second
->base
&& pI
->base
<= dmIter
->second
->end
|| \
pI
->end
>= dmIter
->second
->base
&& pI
->end
<= dmIter
->second
->end
|| \
pI
->base
<= dmIter
->second
->base
&& pI
->end
>= dmIter
->second
->end
){
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
pciAddrSpace
[space
][pI
->base
] = pI
;
bool removeMap(pciDevInfo
* pI
){ //remove all the mappings for device with info struct pI
pciDevMapIterator dmIter
;
for(uint8_t i
= 0; i
< PCI_NSPACES
; i
++)
for(dmIter
= pciAddrSpace
[i
].begin(); dmIter
!= pciAddrSpace
[i
].end(); dmIter
++)
if(dmIter
->second
->devInfo
== pI
){
pciDevMapIterator dmIter1
= ++dmIter
;
pciAddrSpace
[i
].erase(--dmIter
);
bool removeSpace(uint64_t base
, pci_space_t space
){
return pciAddrSpace
[space
].erase(base
);
static const char * pci_space_name(pci_space_t space
){
list
<pciDevInfo
*> devInfoList
; //list of devices present on the pci Bus
pciDevMap pciAddrSpace
[PCI_NSPACES
];
//mmi_instance_t bridgeMod;
mmi_instance_t bridgeMod
;
pciBus(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
);
bool busif_add_device(const char *devname
, uint8_t device
, uint8_t function
);
bool busif_delete_device(const char *devname
);
bool busif_map(const char *devname
, pci_space_t
, uint64_t base
, uint64_t size
);
bool busif_unmap(const char *devname
, pci_space_t
, uint64_t base
);
int busif_add_interrupt(int device
, int dev_type
, int slot_irl
[], bool isMulti
= false);
int busif_free_interrupt(int device
);
bool busif_interrupt_in(bool set
, int dev_number
, int line
, SAM_DeviceId
*samId
);
uint64_t busif_get_lowest_base(pci_space_t
, uint64_t sz
);
pciXactnStatus
busif_dma(bool wr
, uint64_t vaddr
, void *data
, long count
, SAM_DeviceId
*samId
);
pciXactnStatus
busif_special_cycle(uint16_t mssg
, uint16_t data
);
pciXactnStatus
busif_intr_ack(uint64_t * data
);
pciXactnStatus
busif_access_w_size(pci_space_t
, uint64_t paddr
, uint64_t offset
, bool_t wr
, uint64_t* buf
, uint8_t size
, SAM_DeviceId
* samId
);
pciXactnStatus
busif_access_w_byte_enables(pci_space_t
, uint64_t paddr
, uint64_t offset
, bool_t wr
, uint64_t* buf
, uint8_t byte_enable
, SAM_DeviceId
* samId
);
int busif_get_busno(){return bridgeIf
->busif_get_secondary_busno();}