Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / system / tracemod / tm_mmi.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: tm_mmi.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 (C) 1991, 2001 Sun Microsystems, Inc.
23 * All rights reserved.
24 */
25#pragma ident "@(#)1.4 01/11/06 tm_mmi.cc"
26
27/*
28 * Copyright (c) 1989, Sun Microsystems, Inc. All Rights Reserved. Sun
29 * considers its source code as an unpublished, proprietary trade secret, and
30 * it is available only under strict license provisions. This copyright
31 * notice is placed here only to protect Sun in the event the source is
32 * deemed a published work. Disassembly, decompilation, or other means of
33 * reducing the object code to human readable form is prohibited by the
34 * license agreement under which this code is provided to the user or company
35 * in possession of this copy
36 *
37 * RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the
38 * Government is subject to restrictions as set forth in subparagraph
39 * (c) (1) (ii) of the Rights in Technical Data and Computer Software clause
40 * at DFARS 52.227-7013 and in similar clauses in the FAR and NASA FAR
41 * Supplement
42 */
43
44//
45//
46
47#include <sys/types.h>
48#include <assert.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <unistd.h>
52#include <string.h>
53#include <synch.h>
54#include <dlfcn.h>
55#include <ctype.h>
56#include <limits.h>
57
58#include "types.h"
59#include "blaze_globals.h"
60#include "ui.h"
61
62//#include "cpu.h"
63#include "cpu_interface.h"
64
65#include "vtracer.h"
66#include "vtracer_async_queue.h"
67
68#include "system.h"
69#include "dr.h"
70
71
72typedef void* TM_OPAQUE_DATA;
73#include "tracemod.h"
74#include "mmi.h"
75#include "mmi-blaze.h"
76
77#include "tm_impl.h"
78#include "dev_props.h"
79
80void ldm_delete_head_spec ();
81
82volatile bool config_is_done;
83int bdt_verbose = 0;
84
85/////////////////////////////////////////////////////////////
86
87MmiVarNode *pMmiVarList = NULL;
88
89mmi_dr_s * mmi_dr_list = NULL;
90int mmi_dr_list_sz = 0;
91int mmi_dr_list_count = 0;
92
93struct property_list *plist = NULL;
94uint64_t fkprom_dtinbuf_pa = 0x50;
95int fkprom_dtinbuf_offset = 0; // offset at which to write device property data
96
97/////////////////////////////////////////////////////////////
98
99mmi_bool_t mmi_register_instance_creator (const char * modname, mmi_instance_creator fn)
100{
101 // In order to register an instance creator, add the module's name
102 // into the module list to show it is here.
103 // ldm_add_spec ((char *)modname, 0); // for module dependency
104
105 tracemod_t *tm = TM_self_register_spec (modname, NULL);
106 struct ldm_t *pldm;
107
108 if (tm == NULL) {
109 return mmi_false;
110 }
111 pldm = (struct ldm_t *) tm;
112 TM_set_mode (tm, TM_EXT_IO);
113 TM_set_type_ext (tm, TM_TYPE_EXT_DEVICE);
114 pldm->create_instance = fn;
115 return mmi_true;
116} // mmi_register_instance_creator
117
118/////////////////////////////////////////////////////////////
119
120mmi_bool_t mmi_unregister_instance_creator (mmi_instance_t mod)
121{
122 Ldm* pldm = (Ldm *)mod;
123 if (!TM_verify (pldm)) {
124 return mmi_false;
125 }
126 TM_invalidate (pldm);
127 TM_clean_mod_spec();
128 TM_clean_mod();
129 return mmi_true;
130}
131
132/////////////////////////////////////////////////////////////
133
134int mmi_register_cb_data (module_t *mod, void *cb_data)
135{
136 Ldm* pldm = (Ldm *)mod;
137 if (!TM_verify (pldm)) {
138 return (-1);
139 }
140 TM_register_client_data(pldm, cb_data);
141 return 0;
142}
143
144mmi_bool_t mmi_register_asi_cb_data (mmi_instance_t instance, void *cb_data)
145{
146 Ldm* pldm = (Ldm *)instance;
147 if (!TM_verify (pldm)) {
148 return mmi_false;
149 }
150 TM_register_asi_client_data (pldm, cb_data);
151 return mmi_true;
152}
153
154
155/////////////////////////////////////////////////////////////
156
157void* mmi_get_cb_data (module_t *mod)
158{
159 return mod->client_data;
160}
161
162void* mmi_get_asi_cb_data (module_t *mod)
163{
164 return mod->asi_client_data;
165}
166
167/////////////////////////////////////////////////////////////
168
169void* mmi_register_cb_cycle (mmi_instance_t instance, mmi_event_cycle handler, uint64_t repeat)
170{
171 void *cb_data = TM_get_client_data(instance);
172 return TM_register_time_intf ((Ldm*)instance, cb_data, handler, repeat);
173}
174
175/////////////////////////////////////////////////////////////
176
177void mmi_unregister_cb_cycle (mmi_instance_t mod, void * intf)
178{
179 TM_unregister_time_intf ((Ldm*)mod, intf);
180}
181
182/////////////////////////////////////////////////////////////
183
184int mmi_disable_cb_cycle (void * intf)
185{
186 TM_disable_time_intf (intf);
187 return 0;
188}
189
190/////////////////////////////////////////////////////////////
191
192int mmi_enable_cb_cycle (void * intf, blaze_cycle_t repeat )
193{
194 TM_enable_time_intf (intf, repeat);
195 return 0;
196}
197
198/////////////////////////////////////////////////////////////
199
200/* MMI UI command interface */
201void mmi_register_module_cmd(mmi_module_t mod, const char * helpstring, mmi_module_cmd_fn fn)
202{
203 Ldm * pldm = (Ldm *)mod;
204 char * modname = strdup(pldm->name);
205
206 TM_ui_register_2(pldm, modname, helpstring, helpstring, fn);
207
208} // void mmi_register_module_cmd(mmi_module_t mod, const char * helpstring, mmi_module_cmd_fn fn)
209
210
211void mmi_register_instance_cmd(mmi_instance_t instance, const char * helpstring, mmi_instance_cmd_fn fn)
212{
213 Ldm * pldm = (Ldm *) instance;
214 char * instancename = strdup(pldm->name);
215
216 TM_ui_register_2(pldm, instancename, helpstring, helpstring, fn);
217
218} // void mmi_register_instance_cmd(mmi_instance_t instance, const char * helpstring, mmi_instance_cmd_fn fn)
219
220
221
222/////////////////////////////////////////////////////////////
223
224extern bool_t add_asi_module (tracemod_t* mod, uint32_t asi, mmi_ld_asi_action ld_handler,
225 mmi_st_asi_action st_handler);
226
227/////////////////////////////////////////////////////////////
228
229void
230mmi_register_asi_action (mmi_instance_t instance, uint32_t asi,
231 mmi_ld_asi_action ld_handler, mmi_st_asi_action st_handler)
232{
233
234 AsiHandlerNode *pnode = AsiHandlerNode::CreateInstance("ASI handler list");
235 AsiHandlerT *ph;
236 struct ldm_t *pldm = (struct ldm_t *)instance;
237
238 if (pnode == NULL) {
239 ui->error("MMI: Unable to create ASI interceptor for ASI = 0x%x\n", asi);
240 return;
241 }
242
243 ph = pnode->GetData ();
244 ph->asi = asi;
245 ph->vaddr = 0;
246 ph->mmi_ld_action = ld_handler;
247 ph->mmi_st_action = st_handler;
248
249 if (add_asi_module(pldm, asi, ld_handler, st_handler)) {
250 AsiHandlerNode::AddHead ((AsiHandlerNode**)&pldm->headAsi, pnode);
251 } else {
252 ui->error("MMI: unable to register ASI interceptor\n");
253 }
254}
255
256/////////////////////////////////////////////////////////////
257int mmi_argc(mmi_instance_t instance)
258{
259 return ((module_t *)instance)->argc;
260}
261
262char *mmi_argv(mmi_instance_t instance, int index)
263{
264 module_t * mod = (module_t *) instance;
265 if (index < 0 || mod->argc <= index)
266 return NULL;
267 return mod->argv[index];
268}
269
270/////////////////////////////////////////////////////////////
271void set_module_args(Ldm *pldm, int argc, char **argv)
272{
273 int i;
274 if (pldm->argv) {
275 for (i = 0; i < pldm->argc; i++)
276 free(pldm->argv[i]);
277 free(pldm->argv);
278 }
279 pldm->argc = argc;
280 pldm->argv = (char**) calloc (argc, sizeof(char*));
281 for (i = 0; i < argc; i++)
282 pldm->argv[i] = (char*)strdup(argv[i]);
283}
284
285/////////////////////////////////////////////////////////////
286
287static Ldm *load_module(char *modname, char * pathp, char *soname)
288{
289 Ldm *pldm = NULL;
290
291
292 pldm = ldm_add_spec (modname, soname);
293 if (pldm == NULL) {
294 return NULL;
295 }
296
297 pldm->so_handle = mod_dlopen (pathp, soname, RTLD_LAZY|RTLD_GLOBAL|RTLD_PARENT);
298
299 if (pldm->so_handle == NULL) {
300 ldm_delete_head_spec();
301 return NULL;
302 }
303
304 if (!pldm->valid) {
305 TM_clean_mod_spec ();
306 return NULL;
307 }
308
309 return pldm;
310}
311
312/////////////////////////////////////////////////////////////
313
314int ldm_cmd_action(int argc, char **argv)
315{
316 Ldm *pldm = NULL;
317
318 // ldm <modname> <instance> [<XX.so>]
319
320 if (argc == 4) {
321 pldm = load_module(argv[1], NULL, argv[3]);
322 if (pldm) {
323 set_module_args(pldm, argc, argv);
324 if (pldm->create_instance) {
325 pldm->create_instance (argv[1], argv[2]);
326 }
327 else {
328 ui->error("LDM: MMI device module - instance creator not found !! \n");
329 return 0;
330 }
331 }
332 }
333
334 else if (argc == 3) {
335 // ldm <modname> <instance>
336 Ldm *pmod = TM_find_mod_spec (argv[1]);
337 if (pmod == NULL) {
338 ui->error("LDM: MMI device module <%s> not found \n", argv[1]);
339 return 0;
340 }
341 if (pmod->create_instance) {
342 pmod->create_instance (argv[1], argv[2]);
343 }
344 else {
345 ui->error("LDM: MMI device module - instance creator not found !! \n");
346 return 0;
347 }
348 }
349
350 return 1;
351}
352
353/////////////////////////////////////////////////////////////
354int sysconf_usage(const char *msg)
355{
356 ui->error("sysconf: %s\n", msg);
357 ui->error("usage: sysconf [-p <modpath> ] <modname> [ <instance_name> [ args... ] ]\n");
358 return -1;
359}
360
361/////////////////////////////////////////////////////////////
362extern Vcpu * init_cpu ( char *path, int argc, char **argv );
363
364
365int sysconf_cmd_action(int argc, char **argv)
366{
367 Ldm *pldm = NULL;
368 char modname[64], libname[1024];
369 static char path[512] = {"."};
370
371 /* arg to load_module, if null the searchlist */
372 /* with $ORIGIN in it is used, if not this explicit path is used */
373 char * pathp = NULL;
374
375
376 // sysconf [-p <modpath> ] <modname> [ <instance_name> [ args... ] ]
377
378 if (argc < 2)
379 return sysconf_usage("missing args");
380
381 if (strcmp (argv[1], "-p") == 0) {
382 if (argc == 2)
383 return sysconf_usage("missing args");
384 if (argc == 3) {
385 mod_addpath (argv[2]); /* add to generic search path */
386 return 1;
387 }
388 /* otherwise, this is a module specific path prefix, handle below */
389 }
390
391 // XXX should remove it completely
392 if ( (strcmp(argv[1], "done") == 0) && (argc == 2) ) {
393 // complete_initialization();
394 return 1;
395 }
396
397 if ( strcmp ( argv[1], "cpu" ) == 0 )
398 {
399 // cpu module
400
401 // create a new cpu instance;
402 // keep a pointer in a global array;
403 // skip first two args: "sysconf" and "cpu";
404 // we really do only pass pathp here,
405 // the fname is derived from the cpu-type attribute
406 Vcpu *vcpu = init_cpu (pathp, argc-2, argv+2);
407
408 // configure cpu params in fakeprom;
409 VCPU_Config &config_info = vcpu->config;
410
411#ifdef V5_FAKEPROM
412 // cpu clock frequency
413 memwrite64s_nl(mm1, 0x20, config_info.cpufreq);
414
415 // system clock frequency
416 memwrite64s_nl(mm1, 0x28, the_arch.stick_freq);
417
418 // number of cpu's
419 memwrite32u_nl(mm1, 0x14, g_nvcpu);
420#endif
421 // keep a global copy
422 // TODO: the_arch maybe soon obsolete
423 the_arch.cpu_freq = config_info.cpufreq;
424 // read stickfreq from conf suplied value
425 config_info.stickfreq = the_arch.stick_freq;
426 the_arch.numcpus = g_nvcpu;
427
428
429 return 1;
430 }
431
432
433 for (int i = 1; i < argc; i++) {
434 if (strcmp(argv[i], "-p") == 0) {
435 if (++i >= argc)
436 return sysconf_usage("missing -p <modpath>");
437 strlcpy(path, argv[i], sizeof path);
438 pathp = &path[0]; /* override the searchlist */
439 }
440 else if (argv[i][0] == '-') {
441 return sysconf_usage(argv[i]);
442 }
443 else if (!pldm) {
444 strlcpy(modname, argv[i], sizeof modname);
445 sprintf (libname, "%s.so", modname);
446
447 pldm = TM_find_mod_spec(modname);
448 if (!pldm)
449 pldm = load_module (modname, pathp, libname);
450
451 assert(pldm != NULL);
452 if (!pldm)
453 return sysconf_usage("can't load the module");
454 }
455 else {
456 if (TM_find_mod_spec(argv[i]))
457 return sysconf_usage("module instance already exists");
458 mmi_instance_t ins = mmi_register_instance (modname, argv[i], NULL, argv[i]);
459 if (!ins)
460 return sysconf_usage("failed to create module instance");
461 set_module_args((module_t *)ins, argc-(i+1), &argv[i+1]);
462
463 if (pldm->create_instance) {
464 pldm->create_instance (modname, argv[i]);
465 }
466 return 0;
467 }
468 }
469
470 return 1;
471}
472
473/////////////////////////////////////////////////////////////
474void modinfo_list_modules()
475{
476 Ldm *pldm;
477 LdmNode *pnode;
478
479 for (pnode=head_spec_ldm; pnode!=NULL; pnode = pnode->Next()) {
480 pldm = pnode->GetData ();
481 if (!pldm->parent)
482 ui->output("<%s>\n", pldm->name);
483 }
484 for (pnode=head_spec_ldm; pnode!=NULL; pnode=pnode->Next()) {
485 pldm = pnode->GetData ();
486 if (pldm->parent)
487 ui->output("<%s> parent=<%s>\n", pldm->name, pldm->parent->name);
488 }
489}
490
491void modinfo_print_info(char *name)
492{
493 Ldm *pldm;
494 LdmNode *pnode;
495
496 if (!name)
497 return;
498
499 for (pnode=head_spec_ldm; pnode!=NULL; pnode=pnode->Next()) {
500 pldm = pnode->GetData ();
501 if (!strcmp(pldm->name, name)) {
502 if (pldm->modinfo_cb)
503 pldm->modinfo_cb(pldm->client_data);
504 return;
505 }
506 }
507 ui->error("%s is not loaded\n", name);
508}
509
510int modinfo_cmd_action(int argc, char **argv)
511{
512 if (argc < 2) {
513/* modinfo_list_modules();
514 }
515 else if (!strcmp(argv[1], "all") && argc == 2) { */
516 Ldm *pldm;
517 LdmNode *pnode;
518 for (pnode=head_spec_ldm; pnode!=NULL; pnode=pnode->Next()) {
519 pldm = pnode->GetData ();
520 if (pldm->help)
521 ui->output("%s: %s\n", pldm->name, pldm->help);
522 if (pldm->modinfo_cb)
523 pldm->modinfo_cb(pldm->client_data);
524 }
525 }
526 else {
527 for (int i = 1; i < argc; i++)
528 modinfo_print_info(argv[i]);
529 }
530 return 0;
531}
532
533/////////////////////////////////////////////////////////////
534
535int mmi_cmd_action (void*, int argc, char **argv)
536{
537 if (SYSTEM_is_running ()) {
538 ui->error("mmi_cmd_action(%s) called while in run state!!!\n", argv[0]);
539 }
540
541 if (strcmp (argv[0], "uldm") == NULL) {
542 ui->error("uldm has been deprecated. config specifications are not UI commands\n");
543 }
544
545 else if (strcmp (argv[0], "ioa") == NULL) {
546
547 if (argc < 4) {
548 ui->error("UI:usage : ioa <instance name> <ADDR1> <ADDR2>\n");
549 return 0;
550 }
551 uint64_t baddr, eaddr;
552 sscanf (argv[2], "%lli", &baddr);
553 sscanf (argv[3], "%lli", &eaddr);
554 assert(0);
555 return false;
556 }
557
558 else if (strcmp(argv[0], "ldm") == NULL) {
559 return ldm_cmd_action(argc, argv);
560 }
561
562 else if (!strcmp(argv[0], "cfg") || !strcmp(argv[0], "sysconf")) {
563 return sysconf_cmd_action(argc, argv);
564 }
565
566 else if (!strcmp(argv[0], "modinfo")) {
567 return modinfo_cmd_action(argc, argv);
568 }
569
570 return 1;
571}
572
573/////////////////////////////////////////////////////////////
574
575mmi_instance_t mmi_register_instance (const char * modname, const char *instance_name, void * instance_data, const char * help)
576{
577 // parent module must exist
578 Ldm *pmod = TM_find_mod_spec ((char*)modname);
579 if (pmod == NULL) {
580 ui->error("MMI: module <%s> not found \n", modname);
581 return NULL;
582 }
583
584 // create instance, unless already done
585 Ldm *pseudo_mod = TM_find_mod_spec_instance(pmod, (char*)instance_name);
586
587 if (pseudo_mod) {
588 pseudo_mod->help = strdup(help);
589 }
590 else {
591 pseudo_mod = TM_self_pseudomod_spec (pmod, (char*)instance_name, help, NULL);
592
593 if (pseudo_mod) {
594 TM_set_mode (pseudo_mod, TM_EXT_IO);
595 TM_set_type_ext (pseudo_mod, TM_TYPE_EXT_DEVICE);
596 }
597 }
598
599 mmi_register_cb_data(pseudo_mod, instance_data);
600 return (mmi_instance_t) pseudo_mod;
601} // mmi_register_instance()
602
603
604void * mmi_get_instance_data(mmi_instance_t instance)
605{
606 return mmi_get_cb_data((module_t *) instance);
607}
608
609
610/////////////////////////////////////////////////////////////
611void TM_module_init()
612{
613 Ldm *pldm;
614 LdmNode *pnode;
615
616 for (pnode=head_spec_ldm; pnode!=NULL; pnode=pnode->Next()) {
617 pldm = pnode->GetData ();
618 if (pldm->config_cb)
619 (pldm->config_cb)(pldm->client_data, pldm, pldm->name, MMI_CONFIG_INIT_DONE);
620 }
621
622 // register the atexit function
623 atexit(TM_run_atexit_cb);
624
625 config_is_done = true;
626}
627
628/////////////////////////////////////////////////////////////
629// call the config_cb callback of each registered module with
630// the event MMI_CONFIG_DELETE_MODULE. The modules checks to see
631// if the deleted module is itself, in which case it calls delete
632// on itself
633void TM_run_atexit_cb(){
634 Ldm *pldm;
635 LdmNode *pnode;
636
637 for (pnode=head_spec_ldm; pnode!=NULL; pnode=pnode->Next()) {
638 pldm = pnode->GetData ();
639 if (pldm->config_cb)
640 (pldm->config_cb)(pldm->client_data, pldm, pldm->name, MMI_CONFIG_DELETE_MODULE);
641 }
642}
643/////////////////////////////////////////////////////////////
644
645
646void TM_run_config_cb (tracemod_t *mod, int ev)
647{
648 Ldm *pldm;
649 LdmNode *pnode;
650
651 // tell other mods first
652 for (pnode=head_spec_ldm; pnode!=NULL; pnode=pnode->Next()) {
653 pldm = pnode->GetData ();
654 if (pldm->config_cb && pldm != mod)
655 (pldm->config_cb)(pldm->client_data, mod, mod->name, (mmi_config_t)ev);
656 }
657
658 // run this mod last, in case it is going away
659 if (mod->config_cb)
660 (mod->config_cb)(mod->client_data, mod, mod->name, (mmi_config_t)ev);
661}
662
663/////////////////////////////////////////////////////////////
664
665int mmi_unregister_module (module_t *mod)
666{
667 Ldm* pldm = (Ldm *)mod;
668
669 if (!TM_verify (pldm)) {
670 return (-1);
671 }
672
673 // clean out timer callbacks
674 TM_unregister_time_intf(pldm, NULL);
675
676 if (pldm->so_handle) { // delete instances first
677 Ldm* instance;
678 while ((instance = TM_find_mod_spec_instance(pldm, NULL)) != NULL)
679 mmi_unregister_module(instance);
680 }
681 TM_run_config_cb (mod, MMI_CONFIG_DELETE_MODULE);
682 TM_invalidate (pldm);
683 TM_clean_mod_spec();
684 TM_clean_mod();
685 return 0;
686}
687
688/////////////////////////////////////////////////////////////
689
690module_t *mmi_get_instance_pointer (const char *modname, const char *instance_name)
691{
692 Ldm * pldm = TM_find_mod_spec ((char*)modname);
693
694 if (instance_name == NULL) {
695 return (module_t*)pldm;
696 }
697
698 if (pldm == NULL)
699 return NULL;
700 pldm = TM_find_mod_spec_instance (pldm, (char*)instance_name);
701 return (module_t*)pldm;
702}
703
704/////////////////////////////////////////////////////////////
705
706module_t *mmi_get_module (const char *modname)
707{
708 char * s = strdup(modname);
709 module_t * module = TM_find_mod_spec(s);
710 free(s);
711 return module;
712}
713
714
715mmi_instance_t mmi_get_instance(const char * instancename)
716{
717 char * s = strdup(instancename);
718 mmi_instance_t instance = TM_find_mod_spec(s);
719 free(s);
720 return instance;
721}
722
723/////////////////////////////////////////////////////////////
724
725mmi_bool_t mmi_register_interface_cb (mmi_instance_t instance, mmi_interface_cb fn)
726{
727 module_t * mod = (module_t *) instance;
728 if (!TM_verify (mod))
729 return mmi_false;
730 mod->interface_cb = fn;
731 return mmi_true;
732}
733
734/////////////////////////////////////////////////////////////
735
736mmi_bool_t mmi_register_modinfo_cb (mmi_instance_t instance, mmi_modinfo_cb fn)
737{
738 module_t * mod = (module_t *) instance;
739 if (!TM_verify (mod))
740 return mmi_false;
741 mod->modinfo_cb = fn;
742 return mmi_true;
743}
744
745/////////////////////////////////////////////////////////////
746
747mmi_bool_t
748mmi_register_config_cb (mmi_instance_t instance, mmi_config_cb fn)
749{
750 module_t *mod = (module_t *) instance;
751 if (!TM_verify (mod))
752 return mmi_false;
753
754 mod->config_cb = fn;
755
756 // report the modules that exist
757 {
758 Ldm *pldm;
759 LdmNode *pnode;
760
761 for (pnode=head_spec_ldm; pnode!=NULL; pnode=pnode->Next()) {
762 pldm = pnode->GetData ();
763 fn(mod->client_data, pldm, pldm->name, MMI_CONFIG_NEW_MODULE);
764 }
765 }
766
767 // report this module to the others that exist
768 TM_run_config_cb(mod, MMI_CONFIG_NEW_MODULE);
769
770 return mmi_true;
771}
772
773/////////////////////////////////////////////////////////////
774
775void *
776mmi_get_interface (mmi_instance_t instance, const char *name)
777{
778 module_t *mod = (module_t *) instance;
779 if (!TM_verify (mod))
780 return NULL;
781 if (mod->interface_cb)
782 return mod->interface_cb(mod->client_data, name);
783 if (mod->parent && mod->parent->interface_cb)
784 return mod->parent->interface_cb(mod->client_data, name);
785 return NULL;
786}
787
788/////////////////////////////////////////////////////////////
789void mmi_memread(uint64_t paddr, uint8_t * data, uint64_t size,SAM_DeviceId sam_id)
790{
791 assert((size>>32) == 0); // FIXME: need to fix this in Memory::block_read(). 2007.10.23
792 mm1->block_read(paddr,data,(int)size);
793 TRACE_DMA(/*is_write?*/ 0, size, paddr, sam_id);
794} // void mmi_memread(uint64_t paddr, uint8_t * data, uint64_t size, SAM_DeviceId sam_id)
795
796
797
798/////////////////////////////////////////////////////////////
799void mmi_memwrite(uint64_t paddr, const uint8_t * data, uint64_t size,SAM_DeviceId sam_id)
800{
801
802 assert((size>>32) == 0); // FIXME: need to fix this in Memory::block_write(). 2007.10.23
803 mm1->block_write(paddr,data,(int)size);
804 TRACE_DMA(/*is_write?*/ 1, size, paddr, sam_id);
805} // void mmi_memwrite(uint64_t paddr, const uint8_t * data, uint64_t size, SAM_DeviceId sam_id)
806
807
808/////////////////////////////////////////////////////////////
809void mmi_register_start_stop(mmi_start_stop_cb start_action, mmi_start_stop_cb stop_action, void * userdata)
810{
811 SYSTEM_ss_register((ss_action)stop_action, (ss_action) start_action, userdata);
812} // void mmi_register_start_stop(mmi_start_stop_cb start_action, mmi_start_stop_cb stop_action, void * userdata)
813
814/////////////////////////////////////////////////////////////
815bool_t tm_mmi_dump(DR_OPAQUE drh) {
816 int i; char file_name[PATH_MAX];
817 for (i=0; i<mmi_dr_list_count; i++) {
818 ui->output("Dumping <%s> ...\n", mmi_dr_list[i].name);
819 snprintf(file_name, PATH_MAX, "%s/%s.dmp", DR_get_dir(), mmi_dr_list[i].name);
820 if (! mmi_dr_list[i].dump_fn(mmi_dr_list[i].userdata, file_name)) {
821 ui->error("dump failed\n");
822 return FALSE;
823 }
824 ui->output("done\n");
825 }
826 return TRUE;
827} // mmi_dump()
828
829/////////////////////////////////////////////////////////////
830bool_t tm_mmi_restore(DR_OPAQUE drh) {
831 int i; char file_name[PATH_MAX];
832
833 for (i=0; i<mmi_dr_list_count; i++) {
834 ui->output("Restoring <%s> ...", mmi_dr_list[i].name);
835 snprintf(file_name, PATH_MAX, "%s/%s.dmp", DR_get_rdir(drh), mmi_dr_list[i].name);
836 if (!mmi_dr_list[i].restore_fn(mmi_dr_list[i].userdata, file_name)) {
837 ui->error("restore failed\n");
838 return FALSE;
839 }
840 ui->output("done\n");
841 }
842 return TRUE;
843} // mmi_restore()
844
845/////////////////////////////////////////////////////////////
846mmi_bool_t mmi_register_dump_restore(const char *name, mmi_dump_cb dump_fn, mmi_restore_cb restore_fn, void *userdata)
847{
848 if (mmi_dr_list == NULL) {
849 mmi_dr_list_sz = 32;
850 mmi_dr_list = new mmi_dr_s [mmi_dr_list_sz];
851 mmi_dr_list_count = 0;
852
853 DR_register("MMI:DR", tm_mmi_dump, tm_mmi_restore, NULL);
854 }
855 if (mmi_dr_list_count == mmi_dr_list_sz) {
856 int newsz = 2*mmi_dr_list_sz;
857 mmi_dr_s * newlist = new mmi_dr_s[newsz];
858 size_t nbytes = mmi_dr_list_sz*sizeof(mmi_dr_s);
859 memcpy(newlist, mmi_dr_list, nbytes);
860 memset(newlist + mmi_dr_list_sz, 0, nbytes);
861
862 delete [] mmi_dr_list;
863
864 mmi_dr_list = newlist;
865 mmi_dr_list_sz = newsz;
866 }
867
868 mmi_dr_list[mmi_dr_list_count].userdata = userdata;
869 mmi_dr_list[mmi_dr_list_count].name = strdup(name);
870 mmi_dr_list[mmi_dr_list_count].dump_fn = dump_fn;
871 mmi_dr_list[mmi_dr_list_count].restore_fn = restore_fn;
872 mmi_dr_list_count++;
873
874 return mmi_true;
875} // mmi_bool_t mmi_register_dump_restore(void * userdata, mmi_dump_cb dump_fn, mmi_restore_cb restore_fn)
876
877
878/////////////////////////////////////////////////////////////
879
880
881
882int64_t mmi_get_time() // simulated microseconds, since boot
883{
884 return SYSTEM_get_time(TW_CURRENT);
885}
886
887 // event-queue based internal synchonization
888mmi_bool_t mmi_register_event (int64_t when,
889 mmi_event_cb event_fn, void * userdata1, void * userdata2)
890{
891 SYSTEM_register_event (when, (EventFunc_T*)event_fn, userdata1, userdata2,
892 (UnloadFunc_T*)NULL, "mmi-unknown");
893 return mmi_true;
894}
895
896
897
898/////////////////////////////////////////////////////////////
899
900int mmi_register_cb_instr (module_t *mod, fn_event_cpu handler)
901{
902 ui->error("SAM MMI: mmi_register_cb_instr no longer supported (called from module %s)\n", mod->name);
903 return -1;
904}
905
906/////////////////////////////////////////////////////////////
907
908int mmi_register_cb_memop (module_t *mod, fn_event_cpu handler)
909{
910 ui->error("SAM MMI: mmi_register_cb_memop no longer supported (called from module %s)\n", mod->name);
911 return -1;
912}
913
914/////////////////////////////////////////////////////////////
915
916int mmi_register_cb_trap (module_t *mod, fn_event_cpu handler)
917{
918 ui->error("SAM MMI: mmi_register_cb_trap no longer supported (called from module %s)\n", mod->name);
919 return -1;
920}
921
922/////////////////////////////////////////////////////////////
923
924int mmi_register_cb_trapexit (module_t *mod, fn_event_cpu handler)
925{
926 ui->error("SAM MMI: mmi_register_cb_trapexit no longer supported (called from module %s)\n", mod->name);
927 return -1;
928}
929
930/////////////////////////////////////////////////////////////
931
932int mmi_register_cb_tlb (module_t *mod, fn_event_cpu handler)
933{
934 ui->error("SAM MMI: mmi_register_cb_tlb no longer supported (called from module %s)\n", mod->name);
935 return -1;
936}
937
938/////////////////////////////////////////////////////////////
939
940int mmi_register_cb_cpustate (module_t *mod, fn_event_cpu handler)
941{
942 ui->error("SAM MMI: mmi_register_cb_cpustate no longer supported (called from module %s)\n", mod->name);
943 return -1;
944}
945
946/////////////////////////////////////////////////////////////
947
948int mmi_register_cb_dma (module_t *mod, fn_event_dma handler)
949{
950 ui->error("SAM MMI: mmi_register_cb_dma no longer supported (called from module %s)\n", mod->name);
951 return -1;
952}
953
954/////////////////////////////////////////////////////////////
955
956int mmi_set_cb_mask (module_t *mod, uint32_t mask)
957{
958 ui->error("SAM MMI: mmi_set_cb_mask no longer supported (called from module %s)\n", mod->name);
959 return -1;
960}
961
962/////////////////////////////////////////////////////////////
963
964/*OBSOLETE*/
965int mmi_register_io_action (module_t *mod, mmi_io_action ld_handler, mmi_io_action st_handler)
966{
967 if ((mod == 0) || (ld_handler == 0) || (st_handler == 0))
968 return (-1);
969
970 TM_register_io_mmi_action ((tracemod_t*)mod, (fn_misc)ld_handler, (fn_misc)st_handler);
971 return 0;
972}
973
974/////////////////////////////////////////////////////////////
975/////////////////////////////////////////////////////////////
976/////////////////////////////////////////////////////////////
977
978
979mem_t* mmi_get_memobj (cpu_t *)
980{
981 return mm1; //memobj ();
982}
983
984/////////////////////////////////////////////////////////////
985
986//
987// TODO : Might be a subject of MODULE REDIRECTION itself
988//
989
990int mmi_iommu_va2pa (module_t *, int is_read, uint64_t va, uint64_t *)
991{
992
993 uint64_t local_pa;
994 assert(0);
995 return local_pa ? 0 : (-1);
996}
997
998
999/////////////////////////////////////////////////////////////
1000//
1001// review of Sun4u Mondo interrupts:
1002// sender receiver
1003// ------ --------
1004//
1005// cpu-to-cpu:
1006// data => IDDR
1007// (tgt_AgentID<<14) => IDCR--->---IRSR => bits-<5:0> = src_AgentID
1008// IRDR => data
1009// schizo-to-cpu:
1010// (tgt_AgentID<<26 | src_AgentID<<6 | dev_INO) =>...
1011// ...=> INR--->---IRSR => bits-<5:0> = src_AgentID
1012// (*) IRDR => bits-<10:0> = (AID<<6) | INO
1013// *
1014// *-> idata[0] must be supplied by schizo HW _!!!_
1015//
1016int mmi_interrupt_packet (int dst_aid, int src_aid, uint64_t *idata)
1017{
1018 intrT intr; // recently typedef'ed to "cpu_lib_intf.h"/InterruptRequest
1019
1020 intr.isid = src_aid;
1021 intr.itid = dst_aid;
1022 intr.data[0] = idata[0];
1023 intr.data[1] = idata[1];
1024 intr.data[2] = idata[2]; // data[3..7] not part of original mondo spec
1025 // and never referenced by solaris :-!.
1026
1027 SYSTEM_interrupt_by_sid (dst_aid, src_aid, &intr);
1028
1029 return 0;
1030}
1031
1032/////////////////////////////////////////////////////////////
1033//
1034// Sun4v ??? interrupt
1035//
1036int mmi_interrupt_vector (int dest_cpuid, void *src, int src_iscpu, uint32_t vnum, int traptype)
1037{
1038
1039 intrT intr;
1040
1041 intr.isid = 0xF00 | traptype; // Patch - to distinguish between
1042 intr.itid = dest_cpuid;
1043 intr.data[0] = vnum;
1044
1045 SYSTEM_interrupt_by_sid (dest_cpuid, 0, &intr);
1046 return 0;
1047
1048}
1049
1050/////////////////////////////////////////////////////////////
1051
1052int mmi_reset (cpu_t *, void *, resettype_t )
1053{
1054 ui->error("MMI: RESET is not implemented yet \n");
1055 return (-1);
1056}
1057
1058/////////////////////////////////////////////////////////////
1059
1060int mmi_get_ncpu ()
1061{
1062 return SYSTEM_get_ncpu ();
1063}
1064
1065
1066
1067int mmi_get_cpu_sid (cpu_t *sp)
1068{
1069 return sp->id();
1070}
1071
1072cpu_t *mmi_get_cpuptr_by_sid (int id)
1073{
1074 return get_vcpu(id);
1075}
1076uint64_t mmi_get_cpufreq ()
1077{
1078 return SYSTEM_get_cpufreq();
1079}
1080
1081char *mmi_get_comment_string (void *, objtype_t )
1082{
1083 return (char*)strdup("unimplemented");
1084}
1085
1086int mmi_complete_delayed_load (cpu_t *, uint64_t )
1087{
1088 ui->error("MMI: complete delayed load is not implemented yet \n");
1089 return -1;
1090}
1091
1092int mmi_delay_execution (cpu_t *sp, blaze_cycle_t delay)
1093{
1094 SYSTEM_cycle_delay (sp->id(), (uint32_t)delay);
1095 return 0;
1096}
1097
1098
1099//////////////////////////////////////////////////
1100
1101int mmi_register_ui_variable (module_t *module, const char *varname,
1102 vartype_t vartype, void *varptr, int writable, fn_setvar writer)
1103
1104{
1105
1106 MmiVar *pvar;
1107 MmiVarNode *pnode = MmiVarNode::CreateInstance ("MMI Varlist");
1108
1109 if (pnode == NULL) {
1110 ui->error("MMI:Unable to register UI VARIABLE <%s>\n", varname);
1111 return -1;
1112 }
1113 if (module == 0) {
1114 return -1;
1115 }
1116
1117 switch (vartype) {
1118 case VAR_INT:
1119 case VAR_LONG_INT:
1120 case VAR_STRING:
1121 case VAR_BOOL:
1122 break;
1123 default :
1124 ui->error("MMI: Uknown variable type <%d> \n", vartype);
1125 return -1;
1126
1127 }
1128
1129
1130 pvar = pnode->GetData ();
1131 pvar->name = (const char*)strdup(varname);
1132 pvar->vtype = vartype;
1133 pvar->writable = writable;
1134 pvar->action = writer;
1135 pvar->module = module;
1136 pvar->varptr = varptr;
1137
1138 MmiVarNode::AddHead (&pMmiVarList, pnode);
1139 return 0;
1140}
1141
1142//////////////////////////////////////////////////
1143
1144int mmi_set_ui_variable (module_t *module, const char *varname, void *val)
1145{
1146
1147 MmiVar *pvar;
1148 MmiVarNode *pnode = pMmiVarList;
1149 char **pq;
1150
1151 for (;pnode; pnode = pnode->Next()) {
1152 pvar = pnode->GetData ();
1153 if (strcmp (varname, pvar->name) == NULL) {
1154 if (module == pvar->module) {
1155 if (pvar->writable && pvar->action) {
1156 void *cb_data = TM_get_client_data ((void *)module);
1157 pvar->action(cb_data, val);
1158 return 0;
1159 }
1160 else if (pvar->writable) {
1161 switch (pvar->vtype) {
1162 case VAR_INT:
1163 *((uint32_t*) pvar->varptr) = *( (uint32_t*) val);
1164 break;
1165 case VAR_LONG_INT:
1166 *((uint64_t*) pvar->varptr) = *( (uint64_t*) val);
1167 break;
1168 case VAR_STRING:
1169 pq = (char**)&(pvar->varptr);
1170 *pq = (char*)strdup((char*)val);
1171 break;
1172 case VAR_BOOL:
1173 *((uint8_t*) pvar->varptr) = *( (uint8_t*) val);
1174 break;
1175 default :
1176 return -1;
1177 }
1178 return 0;
1179 }
1180 }
1181 }
1182 }
1183
1184 return -1;
1185}
1186
1187//////////////////////////////////////////////////
1188
1189/////////////////////////////////
1190// FlexConfig-related additions
1191/////////////////////////////////
1192
1193char *ldm_get_instanceof(char *modname) {
1194 Ldm* pldm;
1195 LdmNode *pnode = head_spec_ldm;
1196 while(pnode) {
1197 pldm = pnode->GetData();
1198 if ( strstr(pldm->name, modname) )
1199 return pldm->name;
1200 pnode = pnode->Next();
1201 }
1202 return NULL;
1203}
1204
1205
1206