Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: mmi.h | |
5 | * Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
6 | * 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
7 | * | |
8 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License as published by | |
12 | * the Free Software Foundation; version 2 of the License. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
22 | * | |
23 | * For the avoidance of doubt, and except that if any non-GPL license | |
24 | * choice is available it will apply instead, Sun elects to use only | |
25 | * the General Public License version 2 (GPLv2) at this time for any | |
26 | * software where a choice of GPL license versions is made | |
27 | * available with the language indicating that GPLv2 or any later version | |
28 | * may be used, or where a choice of which version of the GPL is applied is | |
29 | * otherwise unspecified. | |
30 | * | |
31 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
32 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
33 | * have any questions. | |
34 | * | |
35 | * | |
36 | * ========== Copyright Header End ============================================ | |
37 | */ | |
38 | /* | |
39 | * ========== Copyright Header Begin ========================================== | |
40 | * | |
41 | * OpenSPARC T2 Processor File: mmi.h | |
42 | * Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
43 | * 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
44 | * | |
45 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
46 | * | |
47 | * This program is free software; you can redistribute it and/or modify | |
48 | * it under the terms of the GNU General Public License as published by | |
49 | * the Free Software Foundation; version 2 of the License. | |
50 | * | |
51 | * This program is distributed in the hope that it will be useful, | |
52 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
53 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
54 | * GNU General Public License for more details. | |
55 | * | |
56 | * You should have received a copy of the GNU General Public License | |
57 | * along with this program; if not, write to the Free Software | |
58 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
59 | * | |
60 | * For the avoidance of doubt, and except that if any non-GPL license | |
61 | * choice is available it will apply instead, Sun elects to use only | |
62 | * the General Public License version 2 (GPLv2) at this time for any | |
63 | * software where a choice of GPL license versions is made | |
64 | * available with the language indicating that GPLv2 or any later version | |
65 | * may be used, or where a choice of which version of the GPL is applied is | |
66 | * otherwise unspecified. | |
67 | * | |
68 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
69 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
70 | * have any questions. | |
71 | * | |
72 | * | |
73 | * ========== Copyright Header End ============================================ | |
74 | */ | |
75 | /* | |
76 | * mmi.h | |
77 | * SAM device-model API | |
78 | * | |
79 | * Copyright (C) 2001-2005 Sun Microsystems, Inc. | |
80 | * All rights reserved. | |
81 | */ | |
82 | #ifndef _SAM_MMI_H | |
83 | #define _SAM_MMI_H | |
84 | ||
85 | #pragma ident "@(#)1.26 03/12/05 SAM-mmi.h" | |
86 | ||
87 | #include <sys/types.h> | |
88 | ||
89 | #ifdef __cplusplus | |
90 | extern "C" { | |
91 | #endif | |
92 | #if 0 | |
93 | } | |
94 | #endif | |
95 | ||
96 | ||
97 | /* opaque type definitions for MMI device models */ | |
98 | typedef void * mmi_instance_t; | |
99 | typedef void * mmi_module_t; | |
100 | ||
101 | typedef enum {mmi_false=0, mmi_true=1} mmi_bool_t; | |
102 | ||
103 | typedef uint64_t SAM_DeviceId; | |
104 | ||
105 | ||
106 | /* device operation in SAM | |
107 | * | |
108 | * 1. The simulator reads in the simulation configuration file containing "sysconf" lines at startup | |
109 | * 2. Each sysconf line specifies a module-type name, an instance name and a set of properties in the form name=value | |
110 | * For example: | |
111 | * sysconf mydev dev0 baseaddr=0xffc00040 parent=bus0 debug=true logfile=mydev.0.log | |
112 | * 3. The sysconf parser loads the mydev.so object (unless it is already loaded) | |
113 | * 4. The sysconf parser calls the instance creator function in mydev.so to create the "dev0" instance | |
114 | * 5. The dev0 instance creator retrieves its sysconf arguments using mmi_argc and mmi_argv calls and processes them | |
115 | * 6. The dev0 instance creator maps its device registers into the SAM address space using mmi_map_physio | |
116 | */ | |
117 | ||
118 | /* An MMI device model is a shared object loaded using dlopen(). | |
119 | * In SAM, this mechanism requires an _init function in the shared object: | |
120 | * | |
121 | * extern "C" void _init() | |
122 | * | |
123 | * This function must be defined. For example: | |
124 | * | |
125 | * extern "C" void _init() { | |
126 | * // mmi initialization code goes here | |
127 | * } | |
128 | ||
129 | * There are alternative means of automatically invoking an initialization function in a shared object | |
130 | * For example, the constructor of a static object in the shared object written using C++ | |
131 | * | |
132 | * In any event, SAM does not explicitly call a function in the shared object after dlopen(). | |
133 | * The _init() function is implicitly invoked by dlopen(). | |
134 | */ | |
135 | ||
136 | /* Functions returning mmi_bool_t return an SUCCESS status (true=no error). | |
137 | * An error typically indicates invalid arguments are being passed | |
138 | */ | |
139 | ||
140 | /* Devices are instantiated by SAM when specified in the config file. | |
141 | * For each device instance, the device model needs to provide an INSTANCE CREATOR function | |
142 | * which performs the instantiation. | |
143 | * | |
144 | * The instance creator function is invoked from SAM | |
145 | * with the modname (device class name) and the instance-name | |
146 | */ | |
147 | ||
148 | typedef void (*mmi_instance_creator) (const char *modname, const char *instance_name); | |
149 | ||
150 | mmi_bool_t mmi_register_instance_creator(const char * modname, mmi_instance_creator creatorfn); | |
151 | ||
152 | /* the instance_creator function can retrieve its own handle (mmi_instance_t) by calling the mmi_register_instance | |
153 | * function. In addition, the device-model can register it's implementation-specific instance data. This can be | |
154 | * retrieved (eg in the modinfo, config and interface callbacks) using the mmi_get_instance_data call. | |
155 | * The help string is displayed in response to UI commands for listing all device nodes. | |
156 | * | |
157 | * Putting the mmi_instance_t handle in the instance_data structure can be convenient | |
158 | */ | |
159 | ||
160 | mmi_instance_t mmi_register_instance(const char * modname, const char * instancename, void * instance_data, const char * short_help); | |
161 | ||
162 | void * mmi_get_instance_data(mmi_instance_t instance); | |
163 | ||
164 | ||
165 | ||
166 | /* Register a function that can respond to the modinfo UI command by printing out relevant module instance information */ | |
167 | typedef void (*mmi_modinfo_cb) (mmi_instance_t cb_instance); | |
168 | ||
169 | mmi_bool_t mmi_register_modinfo_cb(mmi_instance_t this_instance, mmi_modinfo_cb modinfo_fn); | |
170 | ||
171 | ||
172 | ||
173 | /* These calls use the mmi_instance_t handle provided by the mmi_register_instance function above. | |
174 | * They return the arguments specified on the sysconf line for this device instance | |
175 | */ | |
176 | int mmi_argc(mmi_instance_t this_instance); | |
177 | char * mmi_argv(mmi_instance_t this_instance, int index); | |
178 | ||
179 | ||
180 | ||
181 | /* A function of type mmi_access needs to be provided by the device model to handle accesses (load/store) to | |
182 | * device registers in response to instructions executed by the simulated CPU. | |
183 | * | |
184 | * The mmi_map_physio function is used to register this function with the simulator. The device-model provides a pointer | |
185 | * to user data which is returned in the call to the access function. This function should return an error indication (0 for success, some non-zero value for failure | |
186 | */ | |
187 | typedef int (*mmi_access) (uint32_t cpuid, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf, uint8_t bytemask); | |
188 | ||
189 | /* These calls lets the instance map/unmap its registers onto the physical address space of the simulated CPUs */ | |
190 | int mmi_map_physio (uint64_t base, uint64_t size, void* obj, mmi_access access_fn); | |
191 | void mmi_unmap_physio(uint64_t base, uint64_t size, void* obj); | |
192 | ||
193 | ||
194 | ||
195 | /* Memory access functions for devices: devices can do block read/write into simulated memory using mmi_memread and mmi_memwrite calls */ | |
196 | void mmi_memread(uint64_t paddr, uint8_t * data, uint64_t size,SAM_DeviceId sam_id = -1); | |
197 | void mmi_memwrite(uint64_t paddr, const uint8_t * data, uint64_t size,SAM_DeviceId sam_id = -1); | |
198 | ||
199 | ||
200 | /* interrupts: interrupts are not directly delivered to CPUs by devices. Instead, | |
201 | * they are passed on up the device hierarchy through a bus and/or a bridge. The bridge model | |
202 | * implements interrupt delivery to the appropriate CPU. We do not address this in MMI | |
203 | */ | |
204 | ||
205 | ||
206 | ||
207 | /* start/stop functions | |
208 | * device operation can be synchronous (in response to a sparc-cpu action and within a cpu simulation thread) | |
209 | * or asynchronous (within a separate thread). A network controller thread listening on a socket for simulated | |
210 | * network connections is an example of an asynchronous device model. | |
211 | * | |
212 | * When a run or stop command is issued at the UI prompt, an asynchronous thread needs to start/stop in response | |
213 | * (eg start=>create thread; stop=>kill thread). | |
214 | * The start/stop functions provide a way for SAM to communicate these changes in run state to asynchronous devices | |
215 | * | |
216 | * These functions are not needed for synchronous devices (devices that do not create their own simulation threads) | |
217 | */ | |
218 | typedef void (*mmi_start_stop_cb) (void * userdata); | |
219 | void mmi_register_start_stop(mmi_start_stop_cb start_action, mmi_start_stop_cb stop_action, void * userdata); | |
220 | ||
221 | ||
222 | /* checkpointing functions | |
223 | * SAM has a checkpointing feature (dump/restore) which allows a user to dump current simulator state | |
224 | * or to restore (at init-time) from a previous checkpoint. | |
225 | * A module needs to register dump and restore functions with SAM to respond to dump/restore UI actions. | |
226 | * SAM calls the dump and restore functions with the directory in which the device instance should create/find | |
227 | * its state dump. The name of the dump file is <instancename>.dmp | |
228 | * These functions should return a success indication (true=success, false=failure) | |
229 | */ | |
230 | typedef mmi_bool_t (*mmi_dump_cb)(void * userdata, const char * dirname); | |
231 | typedef mmi_bool_t (*mmi_restore_cb)(void * userdata, const char * dirname); | |
232 | ||
233 | mmi_bool_t mmi_register_dump_restore( const char *name, mmi_dump_cb dump_fn, mmi_restore_cb restore_fn, void * userdata); | |
234 | ||
235 | ||
236 | ||
237 | /* time-related functions | |
238 | * A device may want to model a delay or a periodic process (eg device latency or device internal clock) | |
239 | * | |
240 | * SAM and the MMI interface support a delayed event callback mechanism. The chosen unit of time is | |
241 | * microseconds of simulated time. | |
242 | * | |
243 | * The device model | |
244 | * defines a callback function (void function with two void * parameters) | |
245 | * gets the current time using the mmi_get_time() function. | |
246 | * adds the desired delay to the current time | |
247 | * registers a delayed callback using the mmi_register_event function | |
248 | * | |
249 | * For periodic processes, the event callback function should register itself at time=current+period | |
250 | */ | |
251 | typedef void (*mmi_event_cb) (void * userdata1, void * userdata2); | |
252 | int64_t mmi_get_time(); // current simulated time in microseconds since reboot | |
253 | mmi_bool_t mmi_register_event(int64_t when, mmi_event_cb event_fn, void * userdata1, void * userdata2); | |
254 | ||
255 | ||
256 | /* Interacting with other devices */ | |
257 | ||
258 | /* | |
259 | * When a device is instantiated/deleted in response to a sysconf directive, | |
260 | * a device module can receive about this config change by registering a config callback | |
261 | * function. | |
262 | * | |
263 | * A config event can be of the type: instance-added, instance-deleted and config-init-done | |
264 | * config-init-done refers to simulated system being initialized and ready to execute instructions. | |
265 | * instance_deleted is deprecated and obsolete. Simulator should not delete a device instance. | |
266 | ||
267 | * registering a config callback results in the callback function | |
268 | * being called for config events that have occurred in the past as | |
269 | * well as those that occur subsequently. | |
270 | */ | |
271 | ||
272 | typedef enum {MMI_CONFIG_NEW_MODULE, MMI_CONFIG_DELETE_MODULE, MMI_CONFIG_INIT_DONE} mmi_config_t; | |
273 | typedef void (*mmi_config_cb) (void *callback_data, mmi_instance_t target, const char * target_name, mmi_config_t); | |
274 | mmi_bool_t mmi_register_config_cb(mmi_instance_t this_instance, mmi_config_cb config_fn); | |
275 | ||
276 | // get a device-instance handle by name | |
277 | mmi_instance_t mmi_get_instance(const char * instancename); | |
278 | ||
279 | // register a call-back function with the simulator to respond to mmi_get_interface calls from other modules | |
280 | typedef void* (*mmi_interface_cb) (void *callback_data, const char *name); | |
281 | mmi_bool_t mmi_register_interface_cb(mmi_instance_t this_instance, mmi_interface_cb); | |
282 | ||
283 | // get a named interface from another device instance (eg pcie_device from pcie_bus). | |
284 | // the return value should be typecast to the mutually-agreed-upon interface type | |
285 | void * mmi_get_interface(mmi_instance_t instance, const char * interface_name); | |
286 | ||
287 | ||
288 | ||
289 | ||
290 | /* for non-peripheral "devices" that implement ASIs */ | |
291 | /* register call back functions for asi load/store for a particular asi */ | |
292 | typedef int (*mmi_ld_asi_action) (void *cbd, uint32_t asi, uint64_t vaddr, uint64_t *buf, int size,uint32_t cpuid); | |
293 | typedef int (*mmi_st_asi_action) (void *cbd, uint32_t asi, uint64_t vaddr, uint64_t buf, int size,uint32_t cpuid); | |
294 | void mmi_register_asi_action (mmi_instance_t instance, uint32_t asi, mmi_ld_asi_action ld_handler, mmi_st_asi_action st_handler); | |
295 | ||
296 | /* register the call back data that will passed thro' the asi load/store callback function (eg: the object pointer that handles the asi) */ | |
297 | mmi_bool_t mmi_register_asi_cb_data (mmi_instance_t instance, void *cb_data); | |
298 | ||
299 | ||
300 | /* UI commands in MMI objects | |
301 | * A user interface command can be module-specific or instance-specific | |
302 | * A module writer can choose to implement module-specific or instance-specific commands (or both) | |
303 | * A module-specific command has the module name as its first word, while the instance-specific command | |
304 | * starts with the instance-name as its first word. For example, if the simulator is configured with 2 | |
305 | * instances of a device called mydev: | |
306 | * | |
307 | * sysconf mydev dev1 ... | |
308 | * sysconf mydev dev2 ... | |
309 | * | |
310 | * Then a module-specific ui command might look like this: | |
311 | * | |
312 | * mydev show-flags | |
313 | * | |
314 | * while an instance-specific ui command might look like this: | |
315 | * | |
316 | * dev1 report-stats -all | |
317 | * | |
318 | * At instantiation, a module (or instance) registers its UI command handler with the simulation framework | |
319 | * A UI command is intercepted by the simulator, and the module/instance function corresponding to the | |
320 | * command is called. | |
321 | * | |
322 | * When the instance function is called, it is passed the | |
323 | * instance-data pointer that was provided by the instance creator to | |
324 | * the mmi_register_instance() function. | |
325 | * | |
326 | * The handler functions should return an error code (0 if no error). | |
327 | * NOTE: the error code is currently not read by SAM | |
328 | */ | |
329 | ||
330 | typedef int (*mmi_module_cmd_fn) (void * nullptr, int argc, char **argv); | |
331 | void mmi_register_module_cmd(mmi_module_t mod, const char * helpstring, mmi_module_cmd_fn fn); | |
332 | ||
333 | typedef int (*mmi_instance_cmd_fn) (void * instancedata, int argc, char **argv); | |
334 | void mmi_register_instance_cmd(mmi_instance_t instance, const char * helpstring, mmi_instance_cmd_fn fn); | |
335 | ||
336 | ||
337 | ||
338 | ||
339 | /* old mmi functions (for backwards compatibility - eg the SN sync-device model) */ | |
340 | mmi_bool_t mmi_unregister_instance_creator(mmi_instance_t instance); | |
341 | ||
342 | /* these have been deprecated in favor of mmi_map_physio (see above) */ | |
343 | ||
344 | ||
345 | typedef int (*mmi_io_action) (void *cb_data, uint64_t paddr, uint64_t *buf, int size, uint8_t bytemask, void *cpuptr); | |
346 | int mmi_register_io_action (mmi_module_t *module, mmi_io_action ld_handler, mmi_io_action st_handler); | |
347 | ||
348 | ||
349 | /* interrupt functions - these are described in the MMI documentation */ | |
350 | #if 0 // this wont work for io devices.!... | |
351 | int mmi_interrupt_packet (int dest_cpuid, void *src, int src_iscpu, uint64_t *idata); | |
352 | #else | |
353 | int mmi_interrupt_packet (int dst_aid, int src_aid, uint64_t *idata); | |
354 | //int mmi_interrupt_packet (int dest_cpuid, void *src, int src_iscpu, uint64_t *idata); | |
355 | #endif | |
356 | int mmi_interrupt_vector (int dest_cpuid, void *src, int src_iscpu, uint32_t vnum, int traptype); | |
357 | ||
358 | typedef void (*mmi_event_cycle)(void * instance_data, uint64_t repeat); | |
359 | void* mmi_register_cb_cycle (mmi_instance_t instance, mmi_event_cycle handler, uint64_t repeat); | |
360 | void mmi_unregister_cb_cycle(mmi_instance_t instance, void * intf); | |
361 | int mmi_disable_cb_cycle (void * intf); | |
362 | int mmi_enable_cb_cycle (void * intf, uint64_t repeat); | |
363 | ||
364 | ||
365 | uint64_t mmi_get_cpufreq(); | |
366 | ||
367 | #if 0 | |
368 | { | |
369 | #endif | |
370 | #ifdef __cplusplus | |
371 | } // extern "C" | |
372 | #endif | |
373 | ||
374 | ||
375 | #endif // _SAM_MMI_H |