MEM: Introduce the master/slave port sub-classes in C++
[gem5.git] / src / python / swig / pyobject.cc
1 /*
2 * Copyright (c) 2006 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 * Authors: Nathan Binkert
29 */
30
31 #include <Python.h>
32
33 #include <string>
34
35 #include "base/inifile.hh"
36 #include "base/output.hh"
37 #include "dev/etherdevice.hh"
38 #include "dev/etherint.hh"
39 #include "dev/etherobject.hh"
40 #include "mem/mem_object.hh"
41 #include "mem/port.hh"
42 #include "sim/full_system.hh"
43 #include "sim/sim_object.hh"
44
45 using namespace std;
46
47 EtherInt *
48 lookupEthPort(SimObject *so, const std::string &name, int i)
49 {
50 EtherObject *eo = dynamic_cast<EtherObject *>(so);
51 EtherDevice *ed = dynamic_cast<EtherDevice *>(so);
52 if (eo == NULL && ed == NULL) {
53 warn("error casting SimObject %s", so->name());
54 return NULL;
55 }
56
57 EtherInt *p = NULL;
58 if (eo)
59 p = eo->getEthPort(name, i);
60 else
61 p = ed->getEthPort(name, i);
62 return p;
63 }
64
65 /**
66 * Connect the described MemObject ports. Called from Python via SWIG.
67 * The indices i1 & i2 will be -1 for regular ports, >= 0 for vector ports.
68 * SimObject1 is the master, and SimObject2 is the slave
69 */
70 int
71 connectPorts(SimObject *o1, const std::string &name1, int i1,
72 SimObject *o2, const std::string &name2, int i2)
73 {
74 if (FullSystem) {
75 EtherObject *eo1, *eo2;
76 EtherDevice *ed1, *ed2;
77 eo1 = dynamic_cast<EtherObject*>(o1);
78 ed1 = dynamic_cast<EtherDevice*>(o1);
79 eo2 = dynamic_cast<EtherObject*>(o2);
80 ed2 = dynamic_cast<EtherDevice*>(o2);
81
82 if ((eo1 || ed1) && (eo2 || ed2)) {
83 EtherInt *p1 = lookupEthPort(o1, name1, i1);
84 EtherInt *p2 = lookupEthPort(o2, name2, i2);
85
86 if (p1 != NULL && p2 != NULL) {
87
88 p1->setPeer(p2);
89 p2->setPeer(p1);
90
91 return 1;
92 }
93 }
94 }
95 MemObject *mo1, *mo2;
96 mo1 = dynamic_cast<MemObject*>(o1);
97 mo2 = dynamic_cast<MemObject*>(o2);
98
99 if(mo1 == NULL || mo2 == NULL) {
100 panic ("Error casting SimObjects %s and %s to MemObject", o1->name(),
101 o2->name());
102 }
103
104 // generic master/slave port connection
105 MasterPort& masterPort = mo1->getMasterPort(name1, i1);
106 SlavePort& slavePort = mo2->getSlavePort(name2, i2);
107
108 masterPort.bind(slavePort);
109
110 return 1;
111 }
112
113 inline IniFile &
114 inifile()
115 {
116 static IniFile inifile;
117 return inifile;
118 }
119
120 /**
121 * Convert a pointer to the Python object that SWIG wraps around a C++
122 * SimObject pointer back to the actual C++ pointer. See main.i.
123 */
124 extern "C" SimObject *convertSwigSimObjectPtr(PyObject *);
125
126 // Python.h is notoriously not const-correct (for 2.4, anyway)... make
127 // a little define here to reduce the noise and make it easier to
128 // #ifdef away if Python.h gets fixed. Note there are a couple of
129 // these in sim/main.cc as well that are handled without this define.
130 #define PCC(s) const_cast<char *>(s)
131
132
133 SimObject *
134 resolveSimObject(const string &name)
135 {
136 PyObject *module = PyImport_ImportModule(PCC("m5.SimObject"));
137 if (module == NULL)
138 panic("Could not import m5.SimObject");
139
140 PyObject *resolver =
141 PyObject_GetAttrString(module, PCC("resolveSimObject"));
142 if (resolver == NULL) {
143 PyErr_Print();
144 panic("resolveSimObject: failed to find resolveSimObject");
145 }
146
147 PyObject *ptr = PyObject_CallFunction(resolver, PCC("(s)"), name.c_str());
148 if (ptr == NULL) {
149 PyErr_Print();
150 panic("resolveSimObject: failure on call to Python for %s", name);
151 }
152
153 SimObject *obj = convertSwigSimObjectPtr(ptr);
154 if (obj == NULL)
155 panic("resolveSimObject: failure on pointer conversion for %s", name);
156
157 Py_DECREF(module);
158 Py_DECREF(resolver);
159 Py_DECREF(ptr);
160
161 return obj;
162 }