OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [libdbg64g/] [api_core.cpp] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      Core API methods implementation.
6
 */
7
 
8
#include <string>
9
#include "api_core.h"
10
#include "api_types.h"
11
#include "iclass.h"
12
#include "ihap.h"
13
#include "coreservices/ithread.h"
14
#include "coreservices/iclock.h"
15
 
16
namespace debugger {
17
 
18
static AttributeType Config_;
19
static AttributeType listClasses_(Attr_List);
20
static AttributeType listHap_(Attr_List);
21
static AttributeType listPlugins_(Attr_List);
22
extern mutex_def mutex_printf;
23
extern mutex_def mutexDefaultConsoles_;
24
 
25
extern void _load_plugins(AttributeType *list);
26
extern void _unload_plugins(AttributeType *list);
27
 
28
class CoreService : public IService {
29
public:
30
    CoreService(const char *name) : IService("CoreService") {
31
        active_ = 1;
32
        RISCV_mutex_init(&mutex_printf);
33
        RISCV_mutex_init(&mutexDefaultConsoles_);
34
        RISCV_event_create(&mutexExiting_, "mutexExiting_");
35
        //logLevel_.make_int64(LOG_DEBUG);  // default = LOG_ERROR
36
    }
37
    virtual ~CoreService() {
38
        RISCV_event_close(&mutexExiting_);
39
    }
40
 
41
    int isActive() { return active_; }
42
    void shutdown() { active_ = 0; }
43
    bool isExiting() { return mutexExiting_.state; }
44
    void setExiting() { RISCV_event_set(&mutexExiting_); }
45
private:
46
    int active_;
47
    event_def mutexExiting_;
48
};
49
static CoreService core_("core");
50
 
51
 
52
IFace *getInterface(const char *name) {
53
    return core_.getInterface(name);
54
}
55
 
56
 
57
extern "C" int RISCV_init() {
58
#if defined(_WIN32) || defined(__CYGWIN__)
59
    WSADATA wsaData;
60
    if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
61
        RISCV_error("Can't initialize sockets library", NULL);
62
    }
63
#endif
64
 
65
    _load_plugins(&listPlugins_);
66
    return 0;
67
}
68
 
69
extern "C" void RISCV_cleanup() {
70
    IClass *icls;
71
 
72
    // Pre-deletion
73
    for (unsigned i = 0; i < listClasses_.size(); i++) {
74
        icls = static_cast<IClass *>(listClasses_[i].to_iface());
75
        icls->predeleteServices();
76
    }
77
 
78
#if defined(_WIN32) || defined(__CYGWIN__)
79
    WSACleanup();
80
#endif
81
 
82
    _unload_plugins(&listPlugins_);
83
    RISCV_mutex_lock(&mutex_printf);
84
    RISCV_mutex_destroy(&mutex_printf);
85
    RISCV_mutex_lock(&mutexDefaultConsoles_);
86
    RISCV_mutex_destroy(&mutexDefaultConsoles_);
87
    RISCV_disable_log();
88
}
89
 
90
extern "C" int RISCV_set_configuration(AttributeType *cfg) {
91
    IClass *icls;
92
    IService *iserv;
93
 
94
    Config_.clone(cfg);
95
    if (!Config_.is_dict()) {
96
        RISCV_error("Wrong configuration.", NULL);
97
        return -1;
98
    }
99
 
100
    AttributeType &Services = Config_["Services"];
101
    if (Services.is_list()) {
102
        for (unsigned i = 0; i < Services.size(); i++) {
103
            icls = static_cast<IClass *>(
104
                RISCV_get_class(Services[i]["Class"].to_string()));
105
            if (icls == NULL) {
106
                RISCV_error("Class %s not found",
107
                             Services[i]["Class"].to_string());
108
                return -1;
109
            }
110
            /** Special global setting for the GUI class: */
111
            if (strcmp(icls->getClassName(), "GuiPluginClass") == 0) {
112
                if (!Config_["GlobalSettings"]["GUI"].to_bool()) {
113
                    RISCV_info("%s", "GUI disabled");
114
                    continue;
115
                }
116
            }
117
 
118
            AttributeType &Instances = Services[i]["Instances"];
119
            for (unsigned n = 0; n < Instances.size(); n++) {
120
                iserv = icls->createService(Instances[n]["Name"].to_string());
121
                iserv->initService(&Instances[n]["Attr"]);
122
            }
123
        }
124
    }
125
 
126
    // Post initialization
127
    for (unsigned i = 0; i < listClasses_.size(); i++) {
128
        icls = static_cast<IClass *>(listClasses_[i].to_iface());
129
        icls->postinitServices();
130
    }
131
 
132
    RISCV_printf(getInterface(IFACE_SERVICE), 0, "%s",
133
    "\n**********************************************************\n"
134
    "  RISC-V debugger\n"
135
    "  Author: Sergey Khabarov - sergeykhbr@gmail.com\n"
136
    "  Copyright 2016 GNSS Sensor Ltd. All right reserved.\n"
137
    "**********************************************************");
138
 
139
    IHap *ihap;
140
    for (unsigned i = 0; i < listHap_.size(); i++) {
141
        ihap = static_cast<IHap *>(listHap_[i].to_iface());
142
        if (ihap->getType() == HAP_ConfigDone) {
143
            ihap->hapTriggered(getInterface(IFACE_SERVICE),
144
                        HAP_ConfigDone, "Initial config done");
145
        }
146
    }
147
    return 0;
148
}
149
 
150
extern "C" const char *RISCV_get_configuration() {
151
    IClass *icls;
152
    AttributeType ret(Attr_Dict);
153
    ret["GlobalSettings"] = Config_["GlobalSettings"];
154
    ret["Services"].make_list(0);
155
    for (unsigned i = 0; i < listClasses_.size(); i++) {
156
        icls = static_cast<IClass *>(listClasses_[i].to_iface());
157
        AttributeType val = icls->getConfiguration();
158
        ret["Services"].add_to_list(&val);
159
    }
160
    return ret.to_config();
161
}
162
 
163
extern "C" const AttributeType *RISCV_get_global_settings() {
164
    return &Config_["GlobalSettings"];
165
}
166
 
167
extern "C" void RISCV_register_class(IFace *icls) {
168
    AttributeType item(icls);
169
    listClasses_.add_to_list(&item);
170
}
171
 
172
extern "C" void RISCV_register_hap(IFace *ihap) {
173
    AttributeType item(ihap);
174
    listHap_.add_to_list(&item);
175
}
176
 
177
extern "C" void RISCV_trigger_hap(IFace *isrc, int type,
178
                                  const char *descr) {
179
    IHap *ihap;
180
    EHapType etype = static_cast<EHapType>(type);
181
    for (unsigned i = 0; i < listHap_.size(); i++) {
182
        ihap = static_cast<IHap *>(listHap_[i].to_iface());
183
        if (ihap->getType() == etype) {
184
            ihap->hapTriggered(isrc, etype, descr);
185
        }
186
    }
187
}
188
 
189
 
190
extern "C" IFace *RISCV_get_class(const char *name) {
191
    IClass *icls;
192
    for (unsigned i = 0; i < listClasses_.size(); i++) {
193
        icls = static_cast<IClass *>(listClasses_[i].to_iface());
194
        if (strcmp(name, icls->getClassName()) == 0) {
195
            return icls;
196
        }
197
    }
198
    return NULL;
199
}
200
 
201
extern "C" IFace *RISCV_create_service(IFace *iclass, const char *name,
202
                                        AttributeType *args) {
203
    IClass *icls = static_cast<IClass *>(iclass);
204
    IService *iobj = icls->createService(name);
205
    iobj->initService(args);
206
    iobj->postinitService();
207
    return iobj;
208
}
209
 
210
extern "C" IFace *RISCV_get_service(const char *name) {
211
    IClass *icls;
212
    IService *iserv;
213
    for (unsigned i = 0; i < listClasses_.size(); i++) {
214
        icls = static_cast<IClass *>(listClasses_[i].to_iface());
215
        if ((iserv = icls->getInstance(name)) != NULL) {
216
            return iserv;
217
        }
218
    }
219
    return NULL;
220
}
221
 
222
extern "C" IFace *RISCV_get_service_iface(const char *servname,
223
                                          const char *facename) {
224
    IService *iserv = static_cast<IService *>(RISCV_get_service(servname));
225
    if (iserv == NULL) {
226
        RISCV_error("Service '%s' not found.", servname);
227
        return NULL;
228
    }
229
    return iserv->getInterface(facename);
230
}
231
 
232
extern "C" void RISCV_get_services_with_iface(const char *iname,
233
                                             AttributeType *list) {
234
    IClass *icls;
235
    IService *iserv;
236
    IFace *iface;
237
    const AttributeType *tlist;
238
    list->make_list(0);
239
 
240
    for (unsigned i = 0; i < listClasses_.size(); i++) {
241
        icls = static_cast<IClass *>(listClasses_[i].to_iface());
242
        tlist = icls->getInstanceList();
243
        if (tlist->size()) {
244
            iserv = static_cast<IService *>((*tlist)[0u].to_iface());
245
            iface = iserv->getInterface(iname);
246
            if (iface) {
247
                AttributeType t1(iserv);
248
                list->add_to_list(&t1);
249
            }
250
        }
251
    }
252
}
253
 
254
extern "C" void RISCV_get_clock_services(AttributeType *list) {
255
    IService *iserv;
256
    RISCV_get_services_with_iface(IFACE_CLOCK, list);
257
    for (unsigned i = 0; i < list->size(); i++) {
258
        iserv = static_cast<IService *>((*list)[i].to_iface());
259
        (*list)[i].make_iface(iserv->getInterface(IFACE_CLOCK));
260
    }
261
}
262
 
263
static thread_return_t safe_exit_thread(void *args) {
264
    AttributeType t1, t2;
265
    IService *iserv;
266
    IThread *ith;
267
    RISCV_get_services_with_iface(IFACE_THREAD, &t1);
268
 
269
    for (unsigned i = 0; i < t1.size(); i++) {
270
        iserv = static_cast<IService *>(t1[i].to_iface());
271
        ith = static_cast<IThread *>(iserv->getInterface(IFACE_THREAD));
272
        printf("Stopping thread service '%s'. . .", iserv->getObjName());
273
        ith->stop();
274
        printf("Stopped\n");
275
    }
276
 
277
    RISCV_trigger_hap(getInterface(IFACE_SERVICE),
278
                      HAP_BreakSimulation, "Exiting");
279
    printf("All threads were stopped!\n");
280
    core_.shutdown();
281
    return 0;
282
}
283
 
284
extern "C" void RISCV_break_simulation() {
285
    if (core_.isExiting()) {
286
        return;
287
    }
288
    core_.setExiting();
289
    LibThreadType data;
290
    data.func = reinterpret_cast<lib_thread_func>(safe_exit_thread);
291
    data.args = 0;
292
    RISCV_thread_create(&data);
293
}
294
 
295
extern "C" int RISCV_is_active() {
296
    return core_.isActive();
297
}
298
 
299
}  // namespace debugger

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.