// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: ll_mod.cc
// 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 ============================================
* Copyright 2004 by Sun Microsystems, Inc.
//#include "schizo_module.h"
pciXactnStatus
LL::pciTarget_mem32access(uint64_t offset
, bool wr
,uint64_t * buf
, uint8_t size
){
debug_info("%s: %s MEM32: offset %llx size %x\n", HERE
, wr
?"WRITE":"READ ", offset
, size
);
int retval
= reg_access((char*)buf
, offset
- pciMem32_base
,wr
);
Module::get_help_string()
return "Local Loopback Filesystem";
Module::create(const char *_modname
, const char *_instance_name
)
return new LL(_modname
, _instance_name
);
return Module::get_help_string();
LL::LL(const char *_modname
, const char *_instance_name
)
: Module(_modname
, _instance_name
),
sp(NULL
), rdce_head(NULL
), rdce_tail(NULL
)
cfg->pci_device_id = 0x1a;
debug_more("%s: destructor\n", instance_name
);
DR_unregister((void*)this);
LL::parse_arg(const char *arg
)
if(argval("mem32_base",arg
,&pciMem32_base
)){
debug_more("%s:mem32_base = %llx\n",getName(),pciMem32_base
);
}else if(argval("mem32_size",arg
,&pciMem32_size
)){
debug_more("%s:mem32_size = %llx\n",getName(),pciMem32_size
);
return dev_parse_arg(arg
);
// called once after blaze has initialized devices and cpu data structs
dev_init_done(debug_level
);
// map in the device. these functions would normally be
// performed by the boot prom
// 1. get the lowest available base address on the bus
// if this is a new v5 run
pciMem32_base
= getBase(PCI_MEM32
,pciMem32_size
);
// Map in the address if this is a v4 restore or a new v5 run
if(restore_v4_dump() || !restore_v5_dump()){
// 2. set the base address 0 register
confSpace
->confAccessSize(PCI_CONF_BASE0
,true,&pciMem32_base
,4);
// 3. enable the pci mem32 access by setting the command reg.
confSpace
->confAccessSize(PCI_CONF_COMM
,true,&command
,2);
plist
->writeToFakeProm();
if(Module::debug_level
>= 2)
// called each time a new module instance has been created
LL::module_added(mmi_instance_t target
, const char *target_name
)
dev_module_added(target_name
);
// called each time a new module instance has been unloaded
LL::module_deleted(mmi_instance_t target
, const char *target_name
)
dev_module_deleted(target_name
);
// print interesting info about this module
printf("%s: This is a Local Looback PCI device\n", getName());
// return pointer to interface
LL::get_interface(const char *name
)
if (!strcmp(name
, PCI_GENERIC_DEV_INTERFACE
))
return (genericPciDevIf
*)this;
ll_props
[0].size
= strlen(devif_getBusName())+1;
ll_props
[0].value
= strdup(devif_getBusName());
ll_reg
[0].pci_phys_hi
= 0x00000000 | devif_getDevice() << 11;
ll_reg
[0].pci_phys_mid
= ll_reg
[0].pci_phys_low
= 0;
ll_reg
[0].pci_size_hi
= ll_reg
[0].pci_size_low
= 0;
//ll_reg[1].pci_phys_hi = 0x82000000 | device << 11;
ll_reg
[1].pci_phys_hi
= 0x02000000 | devif_getDevice() << 11 | devif_getFunction() << 8 | PCI_CONF_BASE0
;
ll_reg
[1].pci_phys_mid
= 0;
ll_reg
[1].pci_phys_low
= 0;
ll_reg
[1].pci_size_hi
= 0;
ll_reg
[1].pci_size_low
= pciMem32_size
;
ll_assigned_addr
[0].pci_phys_hi
= 0x82000000 | devif_getDevice() << 11 | devif_getFunction() << 8 | PCI_CONF_BASE0
;
ll_assigned_addr
[0].pci_phys_mid
= 0;
ll_assigned_addr
[0].pci_phys_low
= pciMem32_base
;
ll_assigned_addr
[0].pci_size_hi
= 0;
ll_assigned_addr
[0].pci_size_low
= pciMem32_size
;
plist
->add_bunch(ll_props
);
//add the configuration registers - - format is pciConfReg(name, size, por value, write mask, call back data)
// call back data defaults to 0.
// write mask defines bits that can be written to. a 0 in write mask makes the bit read only.
// this is a rather simple minded pseudo device. doesn't care about
// device id, vendor id etc. the properties required by the driver
// need to be added at the 'OK' prompt in case of boot prom. (the obp has
// no idea what ll device is !!)
confSpace
->addConfReg(new pciConfReg("LL vendor id",2,0x108e,0x0,0x0),PCI_CONF_VENID
);
confSpace
->addConfReg(new pciConfReg("LL device id",2,0x0,0x0,0x0),PCI_CONF_DEVID
);
confSpace
->addConfReg(new pciCommandReg("LL command reg",(genericPciDev
*)this,0x2),PCI_CONF_COMM
); // only bit 1 is writable to allow mapping in mem32 space
confSpace
->addConfReg(new baseAddrReg("LL Base address reg 0",(genericPciDev
*)this,pciMem32_size
,PCI_MEM32
),PCI_CONF_BASE0
);
// 8KB, relocatable, non prefethable register space in 32 bit memory space
// all the other registers would be read-only with value of 0
mmi_instance_t
LL::pciDev_getInstance(){ return Module::getInstance();}
const char * LL::pciDev_getName(){ return Module::getName();}
void LL::pciDev_confAccessCb(bool_t wr
, uint64_t offset
, uint8_t size
){
if(offset
== PCI_CONF_BASE0
){
pciMem32_base
= confSpace
->readConf(offset
) & 0xfffffff0;