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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [libdbg64g/] [services/] [bus/] [bus.cpp] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 sergeykhbr
/*
2
 *  Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
3
 *
4
 *  Licensed under the Apache License, Version 2.0 (the "License");
5
 *  you may not use this file except in compliance with the License.
6
 *  You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *  Unless required by applicable law or agreed to in writing, software
11
 *  distributed under the License is distributed on an "AS IS" BASIS,
12
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *  See the License for the specific language governing permissions and
14
 *  limitations under the License.
15
 */
16
 
17
#include <api_core.h>
18
#include "bus.h"
19
#include "coreservices/icpugen.h"
20
 
21
namespace debugger {
22
 
23
/** Class registration in the Core */
24
REGISTER_CLASS(Bus)
25
 
26
Bus::Bus(const char *name)
27
    : IService(name) {
28
    registerInterface(static_cast<IMemoryOperation *>(this));
29
    registerAttribute("DSU", &dsu_);
30
    RISCV_mutex_init(&mutexBAccess_);
31
    RISCV_mutex_init(&mutexNBAccess_);
32
    idsu_ = 0;
33
}
34
 
35
Bus::~Bus() {
36
    RISCV_mutex_destroy(&mutexBAccess_);
37
    RISCV_mutex_destroy(&mutexNBAccess_);
38
}
39
 
40
void Bus::postinitService() {
41
    if (dsu_.is_string()) {
42
        idsu_ = static_cast<IDsuGeneric *>(
43
            RISCV_get_service_iface(dsu_.to_string(), IFACE_DSU_GENERIC));
44
        if (!idsu_) {
45
            RISCV_debug("Can't find IDsuGeneric interface %s",
46
                        dsu_.to_string());
47
        }
48
    }
49
 
50
    IMemoryOperation *imem;
51
    for (unsigned i = 0; i < listMap_.size(); i++) {
52
        const AttributeType &dev = listMap_[i];
53
        if (dev.is_string()) {
54
            imem = static_cast<IMemoryOperation *>(RISCV_get_service_iface(
55
                    dev.to_string(), IFACE_MEMORY_OPERATION));
56
            if (imem == 0) {
57
                RISCV_error("Can't find slave device %s", dev.to_string());
58
                continue;
59
            }
60
            map(imem);
61
        } else if (dev.is_list() && dev.size() == 2) {
62
            const AttributeType &devname = dev[0u];
63
            const AttributeType &portname = dev[1];
64
            imem = static_cast<IMemoryOperation *>(
65
                RISCV_get_service_port_iface(devname.to_string(),
66
                                             portname.to_string(),
67
                                             IFACE_MEMORY_OPERATION));
68
            if (imem == 0) {
69
                RISCV_error("Can't find slave device %s:%s",
70
                    dev[0u].to_string(), dev[1].to_string());
71
                continue;
72
            }
73
            map(imem);
74
        }
75
    }
76
 
77
    AttributeType clks;
78
    RISCV_get_clock_services(&clks);
79
    if (clks.size()) {
80
        iclk0_ = static_cast<IClock *>(clks[0u].to_iface());
81
    } else {
82
        RISCV_error("CPUs not found", NULL);
83
    }
84
}
85
 
86
ETransStatus Bus::b_transport(Axi4TransactionType *trans) {
87
    ETransStatus ret = TRANS_OK;
88
    uint32_t sz;
89
    IMemoryOperation *memdev = 0;
90
 
91
    RISCV_mutex_lock(&mutexBAccess_);
92
 
93
    getMapedDevice(trans, &memdev, &sz);
94
 
95
    if (memdev == 0) {
96
        RISCV_error("[%" RV_PRI64 "d] Blocking request to unmapped address "
97
                    "%08" RV_PRI64 "x", iclk0_->getStepCounter(), trans->addr);
98
        memset(trans->rpayload.b8, 0xFF, trans->xsize);
99
        ret = TRANS_ERROR;
100
    } else {
101
        memdev->b_transport(trans);
102
        RISCV_debug("[%08" RV_PRI64 "x] => [%08x %08x]",
103
            trans->addr,
104
            trans->rpayload.b32[1], trans->rpayload.b32[0]);
105
    }
106
 
107
    // Update Bus utilization counters:
108
    if (idsu_) {
109
        if (trans->action == MemAction_Read) {
110
            idsu_->incrementRdAccess(trans->source_idx);
111
        } else if (trans->action == MemAction_Write) {
112
            idsu_->incrementWrAccess(trans->source_idx);
113
        }
114
    }
115
    RISCV_mutex_unlock(&mutexBAccess_);
116
    return ret;
117
}
118
 
119
ETransStatus Bus::nb_transport(Axi4TransactionType *trans,
120
                               IAxi4NbResponse *cb) {
121
    ETransStatus ret = TRANS_OK;
122
    IMemoryOperation *memdev = 0;
123
    uint32_t sz;
124
 
125
    RISCV_mutex_lock(&mutexNBAccess_);
126
 
127
    getMapedDevice(trans, &memdev, &sz);
128
 
129
    if (memdev == 0) {
130
        RISCV_error("[%" RV_PRI64 "d] Non-blocking request to unmapped address "
131
                    "%08" RV_PRI64 "x", iclk0_->getStepCounter(), trans->addr);
132
        memset(trans->rpayload.b8, 0xFF, trans->xsize);
133
        trans->response = MemResp_Error;
134
        cb->nb_response(trans);
135
        ret = TRANS_ERROR;
136
    } else {
137
        memdev->nb_transport(trans, cb);
138
        RISCV_debug("Non-blocking request to [%08" RV_PRI64 "x]",
139
                    trans->addr);
140
    }
141
 
142
    // Update Bus utilization counters:
143
    if (idsu_) {
144
        if (trans->action == MemAction_Read) {
145
            idsu_->incrementRdAccess(trans->source_idx);
146
        } else if (trans->action == MemAction_Write) {
147
            idsu_->incrementWrAccess(trans->source_idx);
148
        }
149
    }
150
    RISCV_mutex_unlock(&mutexNBAccess_);
151
    return ret;
152
}
153
 
154
void Bus::getMapedDevice(Axi4TransactionType *trans,
155
                         IMemoryOperation **pdev, uint32_t *sz) {
156
    IMemoryOperation *imem;
157
    uint64_t bar, barsz;
158
    *pdev = 0;
159
    *sz = 0;
160
    for (unsigned i = 0; i < imap_.size(); i++) {
161
        imem = static_cast<IMemoryOperation *>(imap_[i].to_iface());
162
        bar = imem->getBaseAddress();
163
        barsz = imem->getLength();
164
        if (bar <= trans->addr && trans->addr < (bar + barsz)) {
165
            if (!(*pdev) || imem->getPriority() > (*pdev)->getPriority()) {
166
                *pdev = imem;
167
            }
168
        }
169
    }
170
}
171
 
172
}  // namespace debugger

powered by: WebSVN 2.1.0

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