Commit | Line | Data |
---|---|---|
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 | ||
40 | pciXactnStatus 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 | |
48 | const char * | |
49 | Module::get_help_string() | |
50 | { | |
51 | return "Local Loopback Filesystem"; | |
52 | } | |
53 | ||
54 | // factory function | |
55 | Module * | |
56 | Module::create(const char *_modname, const char *_instance_name) | |
57 | { | |
58 | return new LL(_modname, _instance_name); | |
59 | } | |
60 | // return help string | |
61 | const char * | |
62 | LL::get_help() | |
63 | { | |
64 | return Module::get_help_string(); | |
65 | } | |
66 | ||
67 | ||
68 | // constructor | |
69 | LL::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 | |
86 | LL::~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 | |
95 | bool | |
96 | LL::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 | |
113 | bool | |
114 | LL::check_args() | |
115 | { | |
116 | return dev_check_args(); | |
117 | } | |
118 | ||
119 | // called once after blaze has initialized devices and cpu data structs | |
120 | void | |
121 | LL::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 | |
150 | void | |
151 | LL::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 | |
157 | void | |
158 | LL::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 | |
164 | void | |
165 | LL::modinfo() | |
166 | { | |
167 | printf("%s: This is a Local Looback PCI device\n", getName()); | |
168 | pciDevInfo(); | |
169 | } | |
170 | ||
171 | // return pointer to interface | |
172 | void * | |
173 | LL::get_interface(const char *name) | |
174 | { | |
175 | if (!strcmp(name, PCI_GENERIC_DEV_INTERFACE)) | |
176 | return (genericPciDevIf*)this; | |
177 | return NULL; | |
178 | } | |
179 | ||
180 | void | |
181 | LL::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 | ||
209 | void 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 | ||
228 | mmi_instance_t LL::pciDev_getInstance(){ return Module::getInstance();} | |
229 | const char * LL::pciDev_getName(){ return Module::getName();} | |
230 | void 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 |