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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [common/] [debug/] [dsu.cpp] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      Debug Support Unit (DSU) functional model.
6
 */
7
 
8
#include <api_core.h>
9
#include "dsu.h"
10
 
11
namespace debugger {
12
 
13
DSU::DSU(const char *name)  : IService(name) {
14
    registerInterface(static_cast<IMemoryOperation *>(this));
15
    registerInterface(static_cast<IDbgNbResponse *>(this));
16
    registerInterface(static_cast<IDsuGeneric *>(this));
17
    registerAttribute("CPU", &cpu_);
18
    registerAttribute("Bus", &bus_);
19
 
20
    memset(&info_, 0, sizeof(info_));
21
    soft_reset_ = 0x0;  // Active LOW
22
}
23
 
24
DSU::~DSU() {
25
}
26
 
27
void DSU::postinitService() {
28
    icpu_ = static_cast<ICpuGeneric *>(
29
        RISCV_get_service_iface(cpu_.to_string(), IFACE_CPU_GENERIC));
30
    if (!icpu_) {
31
        RISCV_error("Can't find ICpuGeneric interface %s", cpu_.to_string());
32
    }
33
    icpurst_ = static_cast<IResetListener *>(
34
        RISCV_get_service_iface(cpu_.to_string(), IFACE_RESET_LISTENER));
35
    if (!icpurst_) {
36
        RISCV_error("Can't find IResetListener interface %s",
37
                    cpu_.to_string());
38
    }
39
    ibus_ = static_cast<IMemoryOperation *>(
40
        RISCV_get_service_iface(bus_.to_string(), IFACE_MEMORY_OPERATION));
41
    if (!ibus_) {
42
        RISCV_error("Can't find IBus interface %s", bus_.to_string());
43
    }
44
}
45
 
46
ETransStatus DSU::b_transport(Axi4TransactionType *trans) {
47
    uint64_t mask = (length_.to_uint64() - 1);
48
    uint64_t off64 = (trans->addr - getBaseAddress()) & mask;
49
    if (!icpu_) {
50
        trans->response = MemResp_Error;
51
        return TRANS_ERROR;
52
    }
53
    uint64_t region = (off64 >> 15) & 0x3;
54
 
55
    if (region < 3) {
56
        RISCV_error("b_transport() to debug port NOT SUPPORTED", NULL);
57
        trans->response = MemResp_Error;
58
        return TRANS_ERROR;
59
    }
60
 
61
    if (trans->action == MemAction_Read) {
62
        readLocal(off64 & 0x7fff, trans);
63
    } else {
64
        writeLocal(off64 & 0x7fff, trans);
65
    }
66
 
67
    trans->response = MemResp_Valid;
68
    // @todo Memory mapped registers not related to debug port
69
    return TRANS_OK;
70
}
71
 
72
ETransStatus DSU::nb_transport(Axi4TransactionType *trans,
73
                               IAxi4NbResponse *cb) {
74
    uint64_t mask = (length_.to_uint64() - 1);
75
    uint64_t off64 = (trans->addr - getBaseAddress()) & mask;
76
    if (!icpu_) {
77
        trans->response = MemResp_Error;
78
        cb->nb_response(trans);
79
        return TRANS_ERROR;
80
    }
81
 
82
    nb_trans_.p_axi_trans = trans;
83
    nb_trans_.iaxi_cb = cb;
84
 
85
    nb_trans_.dbg_trans.write = 0;
86
    nb_trans_.dbg_trans.bytes = trans->xsize;
87
    if (trans->action == MemAction_Write) {
88
        nb_trans_.dbg_trans.write = 1;
89
        nb_trans_.dbg_trans.wdata = trans->wpayload.b64[0];
90
    }
91
 
92
    ETransStatus ret = TRANS_OK;
93
    nb_trans_.dbg_trans.addr = off64 & 0x7FFF;
94
    nb_trans_.dbg_trans.region = (off64 >> 15) & 0x3;
95
    if (nb_trans_.dbg_trans.region == 3) {
96
        ret = b_transport(trans);
97
        cb->nb_response(trans);
98
    } else {
99
        icpu_->nb_transport_debug_port(&nb_trans_.dbg_trans, this);
100
    }
101
    return ret;
102
}
103
 
104
void DSU::nb_response_debug_port(DebugPortTransactionType *trans) {
105
    nb_trans_.p_axi_trans->response = MemResp_Valid;
106
    nb_trans_.p_axi_trans->rpayload.b64[0] = trans->rdata;
107
    nb_trans_.iaxi_cb->nb_response(nb_trans_.p_axi_trans);
108
}
109
 
110
void DSU::readLocal(uint64_t off, Axi4TransactionType *trans) {
111
    switch (off >> 3) {
112
    case 0:
113
        trans->rpayload.b64[0] = soft_reset_;
114
        break;
115
    case 8:
116
        trans->rpayload.b64[0] = info_[0].w_cnt;
117
        break;
118
    case 9:
119
        trans->rpayload.b64[0] = info_[0].r_cnt;
120
        break;
121
    case 12:
122
        trans->rpayload.b64[0] = info_[2].w_cnt;
123
        break;
124
    case 13:
125
        trans->rpayload.b64[0] = info_[2].r_cnt;
126
        break;
127
    default:
128
        trans->rpayload.b64[0] = 0;
129
    }
130
    if (trans->xsize == 4 && (off & 0x4) == 0x4) {
131
        trans->rpayload.b64[0] >>= 32;
132
    }
133
}
134
 
135
void DSU::writeLocal(uint64_t off, Axi4TransactionType *trans) {
136
    if (trans->xsize == 4) {
137
        if ((off & 0x4) == 0) {
138
            wdata64_ = trans->wpayload.b32[0];
139
            return;
140
        } else {
141
            wdata64_ |= static_cast<uint64_t>(trans->wpayload.b32[0]) << 32;
142
        }
143
    } else {
144
        wdata64_ = trans->wpayload.b64[0];
145
    }
146
    switch (off >> 3) {
147
    case 0:     // soft reset
148
        if (wdata64_ & 0x1) {
149
            icpurst_->reset(true);
150
        } else {
151
            icpurst_->reset(false);
152
        }
153
        soft_reset_ = wdata64_;
154
        break;
155
    default:;
156
    }
157
}
158
 
159
void DSU::incrementRdAccess(int mst_id) {
160
    info_[mst_id].r_cnt++;
161
}
162
 
163
void DSU::incrementWrAccess(int mst_id) {
164
    info_[mst_id].w_cnt++;
165
}
166
 
167
}  // namespace debugger
168
 

powered by: WebSVN 2.1.0

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