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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [socsim_plugin/] [irqctrl.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      Interrupt controller functional model.
6
 */
7
 
8
#include "api_core.h"
9
#include "irqctrl.h"
10
 
11
namespace debugger {
12
 
13
IrqController::IrqController(const char *name)  : IService(name) {
14
    registerInterface(static_cast<IMemoryOperation *>(this));
15
    registerInterface(static_cast<IWire *>(this));
16
    registerAttribute("BaseAddress", &baseAddress_);
17
    registerAttribute("Length", &length_);
18
    registerAttribute("CPU", &cpu_);
19
    registerAttribute("CSR_MIPI", &mipi_);
20
    registerAttribute("IrqTotal", &irqTotal_);
21
 
22
    baseAddress_.make_uint64(0);
23
    mipi_.make_uint64(0x783);
24
    length_.make_uint64(0);
25
    cpu_.make_string("");
26
    irqTotal_.make_uint64(4);
27
 
28
    memset(&regs_, 0, sizeof(regs_));
29
    regs_.irq_mask = ~0;
30
    regs_.irq_lock = 1;
31
    irq_wait_unlock = 0;
32
}
33
 
34
IrqController::~IrqController() {
35
}
36
 
37
void IrqController::postinitService() {
38
    icpu_ = static_cast<ICpuRiscV *>(
39
        RISCV_get_service_iface(cpu_.to_string(), IFACE_CPU_RISCV));
40
    if (!icpu_) {
41
        RISCV_error("Can't find ICpuRiscV interface %s", cpu_.to_string());
42
    }
43
}
44
 
45
void IrqController::b_transport(Axi4TransactionType *trans) {
46
    uint64_t mask = (length_.to_uint64() - 1);
47
    uint64_t off = ((trans->addr - getBaseAddress()) & mask) / 4;
48
    uint32_t t1;
49
    trans->response = MemResp_Valid;
50
    if (trans->action == MemAction_Write) {
51
        for (uint64_t i = 0; i < trans->xsize/4; i++) {
52
            if (((trans->wstrb >> 4*i) & 0xFF) == 0) {
53
                continue;
54
            }
55
 
56
            switch (off + i) {
57
            case 0:
58
                regs_.irq_mask = trans->wpayload.b32[i];
59
                RISCV_info("Set irq_mask = %08x", trans->wpayload.b32[i]);
60
                break;
61
            case 1:
62
                regs_.irq_pending = trans->wpayload.b32[i];
63
                RISCV_info("Set irq_pending = %08x", trans->wpayload.b32[i]);
64
                break;
65
            case 2:
66
                t1 = regs_.irq_pending;
67
                regs_.irq_pending &= ~trans->wpayload.b32[i];
68
                if (t1 && !regs_.irq_pending) {
69
                    icpu_->lowerSignal(CPU_SIGNAL_EXT_IRQ);
70
                }
71
                RISCV_info("Set irq_clear = %08x", trans->wpayload.b32[i]);
72
                break;
73
            case 3:
74
                regs_.irq_pending |= trans->wpayload.b32[i];
75
                RISCV_info("Set irq_rise = %08x", trans->wpayload.b32[i]);
76
                break;
77
            case 4:
78
                regs_.isr_table &= ~0xFFFFFFFFLL;
79
                regs_.isr_table |= trans->wpayload.b32[i];
80
                RISCV_info("Set irq_handler[31:0] = %08x",
81
                            trans->wpayload.b32[i]);
82
                break;
83
            case 5:
84
                regs_.isr_table &= ~0xFFFFFFFF00000000LL;
85
                regs_.isr_table |=
86
                    (static_cast<uint64_t>(trans->wpayload.b32[i]) << 32);
87
                RISCV_info("Set irq_handler[63:32] = %08x",
88
                            trans->wpayload.b32[i]);
89
                break;
90
            case 6:
91
                regs_.dbg_cause &= ~0xFFFFFFFFLL;
92
                regs_.dbg_cause |= trans->wpayload.b32[i];
93
                RISCV_info("Set dbg_cause[31:0] = %08x",
94
                            trans->wpayload.b32[i]);
95
                break;
96
            case 7:
97
                regs_.dbg_cause &= ~0xFFFFFFFF00000000LL;
98
                regs_.dbg_cause |=
99
                    (static_cast<uint64_t>(trans->wpayload.b32[i]) << 32);
100
                RISCV_info("Set dbg_cause[63:32] = %08x",
101
                            trans->wpayload.b32[i]);
102
                break;
103
            case 8:
104
                regs_.dbg_epc &= ~0xFFFFFFFFLL;
105
                regs_.dbg_epc |= trans->wpayload.b32[i];
106
                RISCV_info("Set dbg_epc[31:0] = %08x", trans->wpayload.b32[i]);
107
                break;
108
            case 9:
109
                regs_.dbg_epc &= ~0xFFFFFFFF00000000LL;
110
                regs_.dbg_epc |=
111
                    (static_cast<uint64_t>(trans->wpayload.b32[i]) << 32);
112
                RISCV_info("Set dbg_epc[63:32] = %08x",
113
                            trans->wpayload.b32[i]);
114
                break;
115
            case 10:
116
                regs_.irq_lock = trans->wpayload.b32[i];
117
                RISCV_info("Set irq_ena = %08x", trans->wpayload.b32[i]);
118
                if (regs_.irq_lock == 0 && (regs_.irq_pending ||irq_wait_unlock)) {
119
                    regs_.irq_pending |= irq_wait_unlock;
120
                    icpu_->raiseSignal(CPU_SIGNAL_EXT_IRQ);
121
                    irq_wait_unlock = 0;
122
                } else if (regs_.irq_lock == 1 && regs_.irq_pending) {
123
                    icpu_->lowerSignal(CPU_SIGNAL_EXT_IRQ);
124
                }
125
                break;
126
            case 11:
127
                regs_.irq_cause_idx = trans->wpayload.b32[i];
128
                RISCV_info("Set irq_cause_idx = %08x", trans->wpayload.b32[i]);
129
                break;
130
            default:;
131
            }
132
        }
133
    } else {
134
        for (uint64_t i = 0; i < trans->xsize/4; i++) {
135
            switch (off + i) {
136
            case 0:
137
                trans->rpayload.b32[i] = regs_.irq_mask;
138
                RISCV_info("Get irq_mask = %08x", trans->rpayload.b32[i]);
139
                break;
140
            case 1:
141
                trans->rpayload.b32[i] = regs_.irq_pending;
142
                RISCV_info("Get irq_pending = %08x", trans->rpayload.b32[i]);
143
                break;
144
            case 2:
145
                trans->rpayload.b32[i] = 0;
146
                RISCV_info("Get irq_clear = %08x", trans->rpayload.b32[i]);
147
                break;
148
            case 3:
149
                trans->rpayload.b32[i] = 0;
150
                RISCV_info("Get irq_rise = %08x", trans->rpayload.b32[i]);
151
                break;
152
            case 4:
153
                trans->rpayload.b32[i] =
154
                    static_cast<uint32_t>(regs_.isr_table);
155
                RISCV_info("Get irq_handler[31:0] = %08x",
156
                            trans->rpayload.b32[i]);
157
                break;
158
            case 5:
159
                trans->rpayload.b32[i]
160
                    = static_cast<uint32_t>(regs_.isr_table >> 32);
161
                RISCV_info("Get irq_handler[63:32] = %08x",
162
                            trans->rpayload.b32[i]);
163
                break;
164
            case 6:
165
                trans->rpayload.b32[i] =
166
                    static_cast<uint32_t>(regs_.dbg_cause);
167
                RISCV_info("Get dbg_cause[31:0] = %08x",
168
                            trans->rpayload.b32[i]);
169
                break;
170
            case 7:
171
                trans->rpayload.b32[i] =
172
                    static_cast<uint32_t>(regs_.dbg_cause >> 32);
173
                RISCV_info("Get dbg_cause[63:32] = %08x",
174
                            trans->rpayload.b32[i]);
175
                break;
176
            case 8:
177
                trans->rpayload.b32[i] = static_cast<uint32_t>(regs_.dbg_epc);
178
                RISCV_info("Get dbg_epc[31:0] = %08x",
179
                            trans->rpayload.b32[i]);
180
                break;
181
            case 9:
182
                trans->rpayload.b32[i] =
183
                    static_cast<uint32_t>(regs_.dbg_epc >> 32);
184
                RISCV_info("Get dbg_epc[63:32] = %08x",
185
                            trans->rpayload.b32[i]);
186
                break;
187
            case 10:
188
                trans->rpayload.b32[i] = regs_.irq_lock;
189
                RISCV_info("Get irq_ena = %08x",
190
                            trans->rpayload.b32[i]);
191
                break;
192
            case 11:
193
                trans->rpayload.b32[i] = regs_.irq_cause_idx;
194
                RISCV_info("Get irq_cause_idx = %08x",
195
                            trans->rpayload.b32[i]);
196
                break;
197
            default:
198
                trans->rpayload.b32[i] = ~0;
199
            }
200
        }
201
    }
202
}
203
 
204
void IrqController::raiseLine(int idx) {
205
    if (regs_.irq_lock) {
206
        irq_wait_unlock |= (~regs_.irq_mask & (1 << idx));
207
        return;
208
    }
209
    if ((regs_.irq_mask & (0x1 << idx)) == 0) {
210
        regs_.irq_pending |= (0x1 << idx);
211
        icpu_->raiseSignal(CPU_SIGNAL_EXT_IRQ);   // PLIC interrupt (external)
212
        RISCV_info("Raise interrupt", NULL);
213
    }
214
}
215
 
216
}  // namespace debugger
217
 

powered by: WebSVN 2.1.0

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