Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / devices / mmi / mmi.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: mmi.c
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23/*
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28#pragma ident "@(#)mmi.c 1.4 06/07/22 SMI"
29
30/*
31 * This file contains the Legion implementation of the MMI APIs.
32 */
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <unistd.h>
37#include <sys/types.h>
38#include <time.h>
39#include <string.h>
40
41#include "basics.h"
42#include "allocate.h"
43#include "lexer.h"
44#include "simcore.h"
45#include "config.h"
46#include "dumpinfo.h"
47#include "fatal.h"
48#include "device.h"
49#include "mmi.h"
50#include "sam_dev.h"
51
52
53mmi_bool_t mmi_register_instance_creator (const char * modname, mmi_instance_creator create_instance)
54{
55 sam_device_t *sam_devp;
56 uint8_t instance;
57 char instance_name[BUFSIZ];
58
59
60 if (create_instance) {
61 sam_devp = sam_get_instance(modname, &instance);
62 ASSERT(sam_devp);
63 if (sam_devp->mmi_datap->instance_name == NULL) {
64 sprintf(instance_name, "%s%d",
65 sam_devp->mmi_datap->modname, instance);
66 sam_devp->mmi_datap->instance_name =
67 strdup(instance_name);
68 }
69 create_instance(sam_devp->mmi_datap->modname,
70 sam_devp->mmi_datap->instance_name);
71 sam_devp->mmi_datap->create_instance = create_instance;
72 return mmi_true;
73 }
74
75 return mmi_false;
76}
77
78void mmi_register_instance_cmd (mmi_instance_t instance, const char * helpstring, mmi_instance_cmd_fn fn)
79{
80 DBGDEV(lprintf(-1, "Warning: mmi_register_instance_cmd is not supported\n"););
81}
82
83mmi_instance_t mmi_register_instance(const char * modname, const char *instance_name,
84 void * instance_data, const char * help)
85{
86 sam_device_t *sam_devp = sam_find_device(instance_name);
87
88 if (!sam_devp) {
89 printf("mmi_register_instance: failed to register instance <%s>\n",
90 instance_name);
91 return NULL;
92 }
93
94 sam_devp->mmi_datap->cb_data = instance_data;
95
96 return (mmi_instance_t) (sam_devp->mmi_datap);
97}
98
99
100mmi_bool_t mmi_register_config_cb(mmi_instance_t instance, mmi_config_cb fn)
101{
102 mmi_data_t *mmi_datap = (mmi_data_t *)instance;
103 sam_device_t *sam_devp;
104 sam_device_t *osam_devp;
105
106 sam_devp = sam_find_device(mmi_datap->instance_name);
107 if (!sam_devp) {
108 printf("mmi_register_config_cb: invalid instance = 0x%llx\n", instance);
109 return mmi_false;
110 }
111
112 sam_devp->mmi_datap->config_cb = fn;
113 osam_devp = sam_dev_list_head;
114
115 while (osam_devp) {
116 fn(sam_devp->mmi_datap->cb_data, (mmi_instance_t) (osam_devp->mmi_datap),
117 osam_devp->mmi_datap->instance_name, MMI_CONFIG_NEW_MODULE);
118 osam_devp = osam_devp->next;
119 }
120 osam_devp = sam_dev_list_head;
121 while (osam_devp) {
122 if (osam_devp->mmi_datap->config_cb && (osam_devp != sam_devp)) {
123 osam_devp->mmi_datap->config_cb(osam_devp->mmi_datap->cb_data, instance,
124 sam_devp->mmi_datap->instance_name, MMI_CONFIG_NEW_MODULE);
125 }
126 osam_devp = osam_devp->next;
127 }
128 fn(sam_devp->mmi_datap->cb_data, instance, sam_devp->mmi_datap->instance_name, MMI_CONFIG_NEW_MODULE);
129
130 return mmi_true;
131}
132
133
134mmi_bool_t mmi_register_interface_cb(mmi_instance_t instance, mmi_interface_cb fn)
135{
136 mmi_data_t *mmi_datap = (mmi_data_t *)instance;
137 sam_device_t *sam_devp;
138
139 sam_devp = sam_find_device(mmi_datap->instance_name);
140 if (!sam_devp) {
141 printf("mmi_register_interface_cb: invalid instance = 0x%llx\n", instance);
142 return mmi_false;
143 }
144
145 sam_devp->mmi_datap->interface_cb = fn;
146
147 return mmi_true;
148}
149
150
151mmi_instance_t mmi_get_instance(const char * instance_name)
152{
153 sam_device_t *sam_devp = sam_find_device(instance_name);
154
155 if (!sam_devp) {
156 printf("mmi_get_instance: failed to get instance <%s>\n",
157 instance_name);
158 return NULL;
159 }
160
161 return (mmi_instance_t) (sam_devp->mmi_datap);
162}
163
164
165void * mmi_get_instance_data(mmi_instance_t instance)
166{
167 mmi_data_t *mmi_datap = (mmi_data_t *)instance;
168 sam_device_t *sam_devp;
169
170 sam_devp = sam_find_device(mmi_datap->instance_name);
171 if (!sam_devp) {
172 printf("mmi_get_instance_data: invalid instance = 0x%llx\n", instance);
173 return NULL;
174 }
175
176 return (sam_devp->mmi_datap->cb_data);
177}
178
179
180int mmi_argc(mmi_instance_t instance)
181{
182 mmi_data_t *mmi_datap = (mmi_data_t *)(instance);
183 sam_device_t *sam_devp;
184
185 sam_devp = sam_find_device(mmi_datap->instance_name);
186 if (!sam_devp) {
187 printf("mmi_argc: invalid instance = 0x%llx\n", instance);
188 return (0);
189 }
190
191 return sam_devp->mmi_datap->argc;
192}
193
194
195char *mmi_argv(mmi_instance_t instance, int index)
196{
197 sam_device_t *sam_devp;
198 mmi_data_t *mmi_datap = (mmi_data_t *)instance;
199
200 sam_devp = sam_find_device(mmi_datap->instance_name);
201 if (!sam_devp) {
202 printf("mmi_argv: invalid instance = 0x%llx\n", instance);
203 return NULL;
204 }
205
206 if (index < 0 || sam_devp->mmi_datap->argc <= index)
207 return NULL;
208
209 return sam_devp->mmi_datap->argv[index];
210}
211
212
213void mmi_memread(uint64_t paddr, uint8_t *data, uint64_t size)
214{
215 sam_mem_access(paddr, data, size, DA_Load);
216}
217
218
219void mmi_memwrite(uint64_t paddr, uint8_t *data, uint64_t size)
220{
221 sam_mem_access(paddr, data, size, DA_Store);
222}
223
224
225int mmi_map_physio(uint64_t base, uint64_t size, void *obj, mmi_access access)
226{
227 mmi_iomap_t *iomap;
228
229 iomap = Xcalloc(1, mmi_iomap_t);
230 iomap->obj = obj;
231 iomap->access = access;
232 iomap->base = base;
233 iomap->size = size;
234 iomap->end = base + size;
235
236 sam_register_iomap(iomap);
237
238 /*
239 * SAM MMI expects a zero value upon successful completion
240 */
241 return mmi_false;
242}
243
244
245int mmi_interrupt_vector(int dest_cpuid, void *src, int src_iscpu, uint32_t vnum, int traptype)
246{
247 sam_device_t *sam_devp = NULL;
248 mmi_data_t *mmi_datap = (mmi_data_t *)src;
249
250 if (src) {
251 sam_devp = sam_find_device(mmi_datap->instance_name);
252 }
253 sam_internal_intr(dest_cpuid, sam_devp, src_iscpu, vnum, traptype);
254 return true;
255}
256
257
258int mmi_interrupt_packet(int dest_cpuid, void *src, int src_iscpu, uint64_t *idata)
259{
260 DBGDEV(lprintf(-1, "Warning: mmi_interrupt_packet is not supported\n"););
261
262 sam_mondo_intr(dest_cpuid, src, src_iscpu, idata);
263
264 return true;
265}
266
267
268void mmi_unmap_physio(uint64_t base, uint64_t size, void* obj)
269{
270 sam_unregister_iomap(base, size, obj);
271}
272
273
274void *mmi_get_interface(mmi_instance_t instance, const char * interface_name)
275{
276 mmi_data_t *mmi_datap = (mmi_data_t *)instance;
277 sam_device_t *sam_devp;
278
279 sam_devp = sam_find_device(mmi_datap->instance_name);
280
281 if (!sam_devp) {
282 printf("mmi_get_interface: invalid instance = 0x%llx\n", instance);
283 return NULL;
284 }
285
286 if (sam_devp->mmi_datap->interface_cb) {
287 return sam_devp->mmi_datap->interface_cb(sam_devp->mmi_datap->cb_data, interface_name);
288 }
289}
290
291mmi_bool_t mmi_register_modinfo_cb(mmi_instance_t this_instance, mmi_modinfo_cb modinfo_fn)
292{
293 DBGDEV(lprintf(-1, "Warning: mmi_register_modinfo_cb not supported\n"););
294 return mmi_true;
295}
296
297void mmi_register_start_stop(mmi_start_stop_cb start_action, mmi_start_stop_cb stop_action, void * userdata)
298{
299 DBGDEV(lprintf(-1, "Warning: mmi_register_start_stop not supported\n"););
300}
301
302mmi_bool_t mmi_register_dump_restore(void * userdata, mmi_dump_cb dump_fn, mmi_restore_cb restore_fn)
303{
304 DBGDEV(lprintf(-1, "Warning: mmi_register_dump_restore not supported\n"););
305 return mmi_true;
306}
307
308void *mmi_register_cb_cycle(mmi_instance_t instance, mmi_event_cycle handler, uint64_t repeat)
309{
310 mmi_data_t *mmi_datap = (mmi_data_t *)instance;
311 sam_device_t *sam_devp;
312 sam_cycle_t *sam_cycle;
313
314 sam_devp = sam_find_device(mmi_datap->instance_name);
315 if (!sam_devp) {
316 printf("mmi_register_cb_cycle: invalid instance = 0x%llx\n", instance);
317 return NULL;
318 }
319 sam_cycle = Xcalloc(1, sam_cycle_t);
320 sam_cycle->handler = handler;
321 sam_cycle->repeat = repeat;
322 sam_cycle->enable = 1;
323 sam_cycle->cb_data = sam_devp->mmi_datap->cb_data;
324 sam_register_cb_cycle(sam_cycle);
325 if (pthread_create(&sam_devp->tid, NULL, sam_start_dma, NULL)) {
326 printf("mmi_register_cb_cycle: failed creating thread \n");
327 return NULL;
328 }
329
330 return(sam_cycle);
331}
332
333mmi_bool_t mmi_register_asi_cb_data (mmi_instance_t instance, void *cb_data)
334{
335 mmi_data_t *mmi_datap = (mmi_data_t *)instance;
336 sam_device_t *sam_devp;
337
338 sam_devp = sam_find_device(mmi_datap->instance_name);
339 if (!sam_devp) {
340 printf("mmi_register_asi_cb_data: invalid instance = 0x%llx\n",
341 instance);
342 return mmi_false;
343 }
344 sam_devp->mmi_datap->asi_cb_data = cb_data;
345 return mmi_true;
346}
347
348void mmi_register_asi_action (mmi_instance_t instance, uint32_t asi, mmi_ld_asi_action ld_handler, mmi_st_asi_action st_handler)
349{
350 mmi_data_t *mmi_datap = (mmi_data_t *)(instance);
351 sam_device_t *sam_devp;
352
353 sam_devp = sam_find_device(mmi_datap->instance_name);
354 if (!sam_devp) {
355 printf("mmi_register_asi_action: invalid instance = 0x%llx\n",
356 instance);
357 return;
358 }
359 if (ld_handler) {
360 mmi_datap->asi_ld_handler = ld_handler;
361 }
362 if (st_handler) {
363 mmi_datap->asi_st_handler = st_handler;
364 }
365 LIST_ADD_PTR (sam_asi_dev_list, sam_device_t, sam_devp);
366}
367
368void mmi_unregister_cb_cycle(mmi_instance_t instance, void * intf)
369{
370 sam_unregister_cb_cycle(intf);
371}
372
373uint64_t mmi_get_cpufreq()
374{
375 DBGDEV(lprintf(-1, "Warning: mmi_get_cpufreq is not supported\n"););
376 return (0);
377}
378
379int mmi_disable_cb_cycle (void * intf)
380{
381 sam_cycle_t *cb_cycle;
382
383 cb_cycle = sam_find_cb_cycle(intf);
384 if (!cb_cycle) {
385 printf("mmi_disable_cb_cycle: invalid intf = 0x%llx\n", intf);
386 return false;
387 }
388 cb_cycle->enable = 0;
389 return (true);
390}
391int mmi_enable_cb_cycle (void * intf, uint64_t repeat)
392{
393 sam_cycle_t *cb_cycle;
394
395 cb_cycle = sam_find_cb_cycle(intf);
396 if (!cb_cycle) {
397 printf("mmi_enable_cb_cycle: invalid intf = 0x%llx\n", intf);
398 return false;
399 }
400 cb_cycle->enable = 1;
401 return (true);
402}