Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / ll / ll_mod.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: ll_mod.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21/*
22 * Copyright 2004 by Sun Microsystems, Inc.
23 * All rights reserved.
24 *
25 * W% 04/08/04
26 */
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <sys/types.h>
31#include "types.h"
32#include "mmi.h"
33#include "ll_mod.h"
34//#include "schizo_module.h"
35#include "ll_props.h"
36
37// downstream I/O access
38
39
40pciXactnStatus LL::pciTarget_mem32access(uint64_t offset, bool wr,uint64_t * buf, uint8_t size){
41 debug_info("%s: %s MEM32: offset %llx size %x\n", HERE, wr?"WRITE":"READ ", offset, size);
42
43 int retval = reg_access((char*)buf, offset - pciMem32_base,wr);
44 return SUCCESS;
45}
46
47// one-line help
48const char *
49Module::get_help_string()
50{
51 return "Local Loopback Filesystem";
52}
53
54// factory function
55Module *
56Module::create(const char *_modname, const char *_instance_name)
57{
58 return new LL(_modname, _instance_name);
59}
60// return help string
61const char *
62LL::get_help()
63{
64 return Module::get_help_string();
65}
66
67
68// constructor
69LL::LL(const char *_modname, const char *_instance_name)
70 : Module(_modname, _instance_name),
71 sp(NULL), rdce_head(NULL), rdce_tail(NULL)
72{
73 initialized =FALSE;
74 allocation_obj();
75
76 pciMem32_size = 0x2000;
77
78/*
79 cfg->pci_device_id = 0x1a;
80 cfg->vendor_id = 0x0;
81 cfg->class_code = 0x0;
82*/
83}
84
85// destructor
86LL::~LL()
87{
88 debug_more("%s: destructor\n", instance_name);
89 DR_unregister((void*)this);
90 if (sp)
91 free((void*)sp);
92}
93
94// parse an arg
95bool
96LL::parse_arg(const char *arg)
97{
98
99 if(restore_v4_dump()){
100 if(argval("mem32_base",arg,&pciMem32_base)){
101 debug_more("%s:mem32_base = %llx\n",getName(),pciMem32_base);
102 return true;
103 }else if(argval("mem32_size",arg,&pciMem32_size)){
104 debug_more("%s:mem32_size = %llx\n",getName(),pciMem32_size);
105 return true;
106 }
107 }
108
109 return dev_parse_arg(arg);
110}
111
112// check args for sanity
113bool
114LL::check_args()
115{
116 return dev_check_args();
117}
118
119// called once after blaze has initialized devices and cpu data structs
120void
121LL::init_done()
122{
123 dev_init_done(debug_level);
124 initPci();
125#ifdef V5_FAKEPROM
126 // map in the device. these functions would normally be
127 // performed by the boot prom
128
129 // 1. get the lowest available base address on the bus
130 // if this is a new v5 run
131 if(!DR_is_restoreOP)
132 pciMem32_base = getBase(PCI_MEM32,pciMem32_size);
133 // Map in the address if this is a v4 restore or a new v5 run
134 if(restore_v4_dump() || !restore_v5_dump()){
135 // 2. set the base address 0 register
136 confSpace->confAccessSize(PCI_CONF_BASE0,true,&pciMem32_base,4);
137 // 3. enable the pci mem32 access by setting the command reg.
138 uint64_t command = 2;
139 confSpace->confAccessSize(PCI_CONF_COMM,true,&command,2);
140 }
141
142 get_dev_props();
143 plist->writeToFakeProm();
144 if(Module::debug_level >= 2)
145 plist->print();
146#endif
147}
148
149// called each time a new module instance has been created
150void
151LL::module_added(mmi_instance_t target, const char *target_name)
152{
153 dev_module_added(target_name);
154}
155
156// called each time a new module instance has been unloaded
157void
158LL::module_deleted(mmi_instance_t target, const char *target_name)
159{
160 dev_module_deleted(target_name);
161}
162
163// print interesting info about this module
164void
165LL::modinfo()
166{
167 printf("%s: This is a Local Looback PCI device\n", getName());
168 pciDevInfo();
169}
170
171// return pointer to interface
172void *
173LL::get_interface(const char *name)
174{
175 if (!strcmp(name, PCI_GENERIC_DEV_INTERFACE))
176 return (genericPciDevIf*)this;
177 return NULL;
178}
179
180void
181LL::get_dev_props()
182{
183 ll_props[0].size = strlen(devif_getBusName())+1;
184 ll_props[0].value= strdup(devif_getBusName());
185
186 ll_reg[0].pci_phys_hi = 0x00000000 | devif_getDevice() << 11;
187 ll_reg[0].pci_phys_mid = ll_reg[0].pci_phys_low = 0;
188 ll_reg[0].pci_size_hi = ll_reg[0].pci_size_low = 0;
189
190 //ll_reg[1].pci_phys_hi = 0x82000000 | device << 11;
191 ll_reg[1].pci_phys_hi = 0x02000000 | devif_getDevice() << 11 | devif_getFunction() << 8 | PCI_CONF_BASE0;
192 ll_reg[1].pci_phys_mid = 0;
193 ll_reg[1].pci_phys_low = 0;
194 ll_reg[1].pci_size_hi = 0;
195 ll_reg[1].pci_size_low = pciMem32_size;
196
197 ll_assigned_addr[0].pci_phys_hi = 0x82000000 | devif_getDevice() << 11 | devif_getFunction() << 8 | PCI_CONF_BASE0;
198 ll_assigned_addr[0].pci_phys_mid = 0;
199 ll_assigned_addr[0].pci_phys_low = pciMem32_base;
200 ll_assigned_addr[0].pci_size_hi = 0;
201 ll_assigned_addr[0].pci_size_low = pciMem32_size;
202
203 plist->add_bunch(ll_props);
204
205}
206
207
208
209void LL::initPci(){
210
211 //add the configuration registers - - format is pciConfReg(name, size, por value, write mask, call back data)
212 // call back data defaults to 0.
213 // write mask defines bits that can be written to. a 0 in write mask makes the bit read only.
214
215 // this is a rather simple minded pseudo device. doesn't care about
216 // device id, vendor id etc. the properties required by the driver
217 // need to be added at the 'OK' prompt in case of boot prom. (the obp has
218 // no idea what ll device is !!)
219
220 confSpace->addConfReg(new pciConfReg("LL vendor id",2,0x108e,0x0,0x0),PCI_CONF_VENID);
221 confSpace->addConfReg(new pciConfReg("LL device id",2,0x0,0x0,0x0),PCI_CONF_DEVID);
222 confSpace->addConfReg(new pciCommandReg("LL command reg",(genericPciDev*)this,0x2),PCI_CONF_COMM); // only bit 1 is writable to allow mapping in mem32 space
223 confSpace->addConfReg(new baseAddrReg("LL Base address reg 0",(genericPciDev*)this,pciMem32_size,PCI_MEM32),PCI_CONF_BASE0);
224 // 8KB, relocatable, non prefethable register space in 32 bit memory space
225 // all the other registers would be read-only with value of 0
226}
227
228mmi_instance_t LL::pciDev_getInstance(){ return Module::getInstance();}
229const char * LL::pciDev_getName(){ return Module::getName();}
230void LL::pciDev_confAccessCb(bool_t wr, uint64_t offset, uint8_t size){
231 if(!wr)
232 return;
233
234 if(offset == PCI_CONF_BASE0){
235 assert(size == 4);
236 pciMem32_base = confSpace->readConf(offset) & 0xfffffff0;
237 }
238
239 return;
240}
241
242
243
244