Merge zizzer.eecs.umich.edu:/bk/m5
[gem5.git] / dev / pciconfigall.cc
1 /*
2 * Copyright (c) 2003 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /* @file
30 * PCI Configspace implementation
31 */
32
33 #include <deque>
34 #include <string>
35 #include <vector>
36
37 #include "base/trace.hh"
38 #include "cpu/exec_context.hh"
39 #include "dev/scsi_ctrl.hh"
40 #include "dev/pciconfigall.hh"
41 #include "dev/pcidev.hh"
42 #include "dev/tsunamireg.h"
43 #include "dev/tsunami.hh"
44 #include "mem/functional_mem/memory_control.hh"
45 #include "sim/builder.hh"
46 #include "sim/system.hh"
47
48 using namespace std;
49
50 PCIConfigAll::PCIConfigAll(const string &name, Tsunami *t,
51 Addr addr, Addr mask, MemoryController *mmu)
52 : MmapDevice(name, addr, mask, mmu), tsunami(t)
53 {
54 // Put back pointer in tsunami
55 tsunami->pciconfig = this;
56
57 // Make all the pointers to devices null
58 for(int x=0; x < MAX_PCI_DEV; x++)
59 for(int y=0; y < MAX_PCI_FUNC; y++)
60 devices[x][y] = NULL;
61 }
62
63 Fault
64 PCIConfigAll::read(MemReqPtr &req, uint8_t *data)
65 {
66 DPRINTF(PCIConfigAll, "read va=%#x size=%d\n",
67 req->vaddr, req->size);
68
69 Addr daddr = (req->paddr & addr_mask);
70
71 int device = (daddr >> 11) & 0x1F;
72 int func = (daddr >> 8) & 0x7;
73 int reg = daddr & 0xFF;
74
75 if (devices[device][func] == NULL) {
76 switch (req->size) {
77 // case sizeof(uint64_t):
78 // *(uint64_t*)data = 0xFFFFFFFFFFFFFFFF;
79 // return No_Fault;
80 case sizeof(uint32_t):
81 *(uint32_t*)data = 0xFFFFFFFF;
82 return No_Fault;
83 case sizeof(uint16_t):
84 *(uint16_t*)data = 0xFFFF;
85 return No_Fault;
86 case sizeof(uint8_t):
87 *(uint8_t*)data = 0xFF;
88 return No_Fault;
89 default:
90 panic("invalid access size(?) for PCI configspace!\n");
91 }
92 } else {
93 switch (req->size) {
94 case sizeof(uint32_t):
95 case sizeof(uint16_t):
96 case sizeof(uint8_t):
97 devices[device][func]->ReadConfig(reg, req->size, data);
98 return No_Fault;
99 default:
100 panic("invalid access size(?) for PCI configspace!\n");
101 }
102 }
103
104 DPRINTFN("Tsunami PCI Configspace ERROR: read daddr=%#x size=%d\n",
105 daddr, req->size);
106
107 return No_Fault;
108 }
109
110 Fault
111 PCIConfigAll::write(MemReqPtr &req, const uint8_t *data)
112 {
113 Addr daddr = (req->paddr & addr_mask);
114
115 int device = (daddr >> 11) & 0x1F;
116 int func = (daddr >> 8) & 0x7;
117 int reg = daddr & 0xFF;
118
119 union {
120 uint8_t byte_value;
121 uint16_t half_value;
122 uint32_t word_value;
123 };
124
125 if (devices[device][func] == NULL)
126 panic("Attempting to write to config space on non-existant device\n");
127 else {
128 switch (req->size) {
129 case sizeof(uint8_t):
130 byte_value = *(uint8_t*)data;
131 break;
132 case sizeof(uint16_t):
133 half_value = *(uint16_t*)data;
134 break;
135 case sizeof(uint32_t):
136 word_value = *(uint32_t*)data;
137 break;
138 default:
139 panic("invalid access size(?) for PCI configspace!\n");
140 }
141 }
142
143 DPRINTF(PCIConfigAll, "write - va=%#x size=%d data=%#x\n",
144 req->vaddr, req->size, word_value);
145
146 devices[device][func]->WriteConfig(reg, req->size, word_value);
147
148 return No_Fault;
149 }
150
151 void
152 PCIConfigAll::serialize(std::ostream &os)
153 {
154 // code should be written
155 }
156
157 void
158 PCIConfigAll::unserialize(Checkpoint *cp, const std::string &section)
159 {
160 //code should be written
161 }
162
163 #ifndef DOXYGEN_SHOULD_SKIP_THIS
164
165 BEGIN_DECLARE_SIM_OBJECT_PARAMS(PCIConfigAll)
166
167 SimObjectParam<Tsunami *> tsunami;
168 SimObjectParam<MemoryController *> mmu;
169 Param<Addr> addr;
170 Param<Addr> mask;
171
172 END_DECLARE_SIM_OBJECT_PARAMS(PCIConfigAll)
173
174 BEGIN_INIT_SIM_OBJECT_PARAMS(PCIConfigAll)
175
176 INIT_PARAM(tsunami, "Tsunami"),
177 INIT_PARAM(mmu, "Memory Controller"),
178 INIT_PARAM(addr, "Device Address"),
179 INIT_PARAM(mask, "Address Mask")
180
181 END_INIT_SIM_OBJECT_PARAMS(PCIConfigAll)
182
183 CREATE_SIM_OBJECT(PCIConfigAll)
184 {
185 return new PCIConfigAll(getInstanceName(), tsunami, addr, mask, mmu);
186 }
187
188 REGISTER_SIM_OBJECT("PCIConfigAll", PCIConfigAll)
189
190 #endif // DOXYGEN_SHOULD_SKIP_THIS