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] - Diff between revs 2 and 4

Show entire file | Details | Blame | View Log

Rev 2 Rev 4
Line 1... Line 1...
/**
/*
 * @file
 *  Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
 *
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
 *  Licensed under the Apache License, Version 2.0 (the "License");
 * @brief      System Bus class declaration (AMBA or whatever).
 *  you may not use this file except in compliance with the License.
 
 *  You may obtain a copy of the License at
 
 *
 
 *      http://www.apache.org/licenses/LICENSE-2.0
 
 *
 
 *  Unless required by applicable law or agreed to in writing, software
 
 *  distributed under the License is distributed on an "AS IS" BASIS,
 
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 *  See the License for the specific language governing permissions and
 
 *  limitations under the License.
 */
 */
 
 
#include "api_core.h"
#include <api_core.h>
#include "bus.h"
#include "bus.h"
#include "coreservices/icpuriscv.h"
#include "coreservices/icpugen.h"
 
 
namespace debugger {
namespace debugger {
 
 
/** Class registration in the Core */
/** Class registration in the Core */
REGISTER_CLASS(Bus)
REGISTER_CLASS(Bus)
 
 
Bus::Bus(const char *name)
Bus::Bus(const char *name)
    : IService(name) {
    : IService(name) {
    registerInterface(static_cast<IBus *>(this));
    registerInterface(static_cast<IMemoryOperation *>(this));
    registerAttribute("MapList", &listMap_);
    registerAttribute("DSU", &dsu_);
 
 
    listMap_.make_list(0);
 
    imap_.make_list(0);
 
    RISCV_mutex_init(&mutexBAccess_);
    RISCV_mutex_init(&mutexBAccess_);
    RISCV_mutex_init(&mutexNBAccess_);
    RISCV_mutex_init(&mutexNBAccess_);
    memset(info_, 0, sizeof(info_));
    idsu_ = 0;
}
}
 
 
Bus::~Bus() {
Bus::~Bus() {
    RISCV_mutex_destroy(&mutexBAccess_);
    RISCV_mutex_destroy(&mutexBAccess_);
    RISCV_mutex_destroy(&mutexNBAccess_);
    RISCV_mutex_destroy(&mutexNBAccess_);
}
}
 
 
void Bus::postinitService() {
void Bus::postinitService() {
 
    if (dsu_.is_string()) {
 
        idsu_ = static_cast<IDsuGeneric *>(
 
            RISCV_get_service_iface(dsu_.to_string(), IFACE_DSU_GENERIC));
 
        if (!idsu_) {
 
            RISCV_debug("Can't find IDsuGeneric interface %s",
 
                        dsu_.to_string());
 
        }
 
    }
 
 
    IMemoryOperation *imem;
    IMemoryOperation *imem;
    for (unsigned i = 0; i < listMap_.size(); i++) {
    for (unsigned i = 0; i < listMap_.size(); i++) {
 
        const AttributeType &dev = listMap_[i];
 
        if (dev.is_string()) {
        imem = static_cast<IMemoryOperation *>(RISCV_get_service_iface(
        imem = static_cast<IMemoryOperation *>(RISCV_get_service_iface(
                listMap_[i].to_string(), IFACE_MEMORY_OPERATION));
                    dev.to_string(), IFACE_MEMORY_OPERATION));
 
            if (imem == 0) {
 
                RISCV_error("Can't find slave device %s", dev.to_string());
 
                continue;
 
            }
 
            map(imem);
 
        } else if (dev.is_list() && dev.size() == 2) {
 
            const AttributeType &devname = dev[0u];
 
            const AttributeType &portname = dev[1];
 
            imem = static_cast<IMemoryOperation *>(
 
                RISCV_get_service_port_iface(devname.to_string(),
 
                                             portname.to_string(),
 
                                             IFACE_MEMORY_OPERATION));
        if (imem == 0) {
        if (imem == 0) {
            RISCV_error("Can't find slave device %s", listMap_[i].to_string());
                RISCV_error("Can't find slave device %s:%s",
 
                    dev[0u].to_string(), dev[1].to_string());
            continue;
            continue;
        }
        }
        map(imem);
        map(imem);
    }
    }
 
    }
 
 
    AttributeType clks;
    AttributeType clks;
    RISCV_get_clock_services(&clks);
    RISCV_get_clock_services(&clks);
    if (clks.size()) {
    if (clks.size()) {
        iclk0_ = static_cast<IClock *>(clks[0u].to_iface());
        iclk0_ = static_cast<IClock *>(clks[0u].to_iface());
    } else {
    } else {
        RISCV_error("CPUs not found", NULL);
        RISCV_error("CPUs not found", NULL);
    }
    }
}
}
 
 
void Bus::map(IMemoryOperation *imemop) {
 
    AttributeType t1(imemop);
 
    imap_.add_to_list(&t1);
 
}
 
 
 
ETransStatus Bus::b_transport(Axi4TransactionType *trans) {
ETransStatus Bus::b_transport(Axi4TransactionType *trans) {
    IMemoryOperation *imem;
 
    bool unmapped = true;
 
    ETransStatus ret = TRANS_OK;
    ETransStatus ret = TRANS_OK;
 
    uint32_t sz;
 
    IMemoryOperation *memdev = 0;
 
 
    RISCV_mutex_lock(&mutexBAccess_);
    RISCV_mutex_lock(&mutexBAccess_);
 
 
    for (unsigned i = 0; i < imap_.size(); i++) {
    getMapedDevice(trans, &memdev, &sz);
        imem = static_cast<IMemoryOperation *>(imap_[i].to_iface());
 
        if (imem->getBaseAddress() <= trans->addr
 
            && trans->addr < (imem->getBaseAddress() + imem->getLength())) {
 
 
 
            imem->b_transport(trans);
    if (memdev == 0) {
            unmapped = false;
        RISCV_error("[%" RV_PRI64 "d] Blocking request to unmapped address "
            break;
 
            /// @todo Check memory overlapping
 
        }
 
    }
 
 
 
    if (unmapped) {
 
        RISCV_error("[%" RV_PRI64 "d] Read from unmapped address "
 
                    "%08" RV_PRI64 "x", iclk0_->getStepCounter(), trans->addr);
                    "%08" RV_PRI64 "x", iclk0_->getStepCounter(), trans->addr);
        memset(trans->rpayload.b8, 0xFF, trans->xsize);
        memset(trans->rpayload.b8, 0xFF, trans->xsize);
        ret = TRANS_ERROR;
        ret = TRANS_ERROR;
    } else {
    } else {
 
        memdev->b_transport(trans);
        RISCV_debug("[%08" RV_PRI64 "x] => [%08x %08x]",
        RISCV_debug("[%08" RV_PRI64 "x] => [%08x %08x]",
            trans->addr,
            trans->addr,
            trans->rpayload.b32[1], trans->rpayload.b32[0]);
            trans->rpayload.b32[1], trans->rpayload.b32[0]);
    }
    }
 
 
    // Update Bus utilization counters:
    // Update Bus utilization counters:
 
    if (idsu_) {
    if (trans->action == MemAction_Read) {
    if (trans->action == MemAction_Read) {
        info_[trans->source_idx].r_cnt++;
            idsu_->incrementRdAccess(trans->source_idx);
    } else if (trans->action == MemAction_Write) {
    } else if (trans->action == MemAction_Write) {
        info_[trans->source_idx].w_cnt++;
            idsu_->incrementWrAccess(trans->source_idx);
 
        }
    }
    }
    RISCV_mutex_unlock(&mutexBAccess_);
    RISCV_mutex_unlock(&mutexBAccess_);
    return ret;
    return ret;
}
}
 
 
ETransStatus Bus::nb_transport(Axi4TransactionType *trans,
ETransStatus Bus::nb_transport(Axi4TransactionType *trans,
                               IAxi4NbResponse *cb) {
                               IAxi4NbResponse *cb) {
    IMemoryOperation *imem;
 
    bool unmapped = true;
 
    ETransStatus ret = TRANS_OK;
    ETransStatus ret = TRANS_OK;
 
    IMemoryOperation *memdev = 0;
 
    uint32_t sz;
 
 
    RISCV_mutex_lock(&mutexNBAccess_);
    RISCV_mutex_lock(&mutexNBAccess_);
 
 
    for (unsigned i = 0; i < imap_.size(); i++) {
    getMapedDevice(trans, &memdev, &sz);
        imem = static_cast<IMemoryOperation *>(imap_[i].to_iface());
 
        if (imem->getBaseAddress() <= trans->addr
 
            && trans->addr < (imem->getBaseAddress() + imem->getLength())) {
 
 
 
            imem->nb_transport(trans, cb);
 
            unmapped = false;
 
            break;
 
        }
 
    }
 
 
 
    if (unmapped) {
    if (memdev == 0) {
        RISCV_error("[%" RV_PRI64 "d] Non-blocking request to unmapped address "
        RISCV_error("[%" RV_PRI64 "d] Non-blocking request to unmapped address "
                    "%08" RV_PRI64 "x", iclk0_->getStepCounter(), trans->addr);
                    "%08" RV_PRI64 "x", iclk0_->getStepCounter(), trans->addr);
        memset(trans->rpayload.b8, 0xFF, trans->xsize);
        memset(trans->rpayload.b8, 0xFF, trans->xsize);
        trans->response = MemResp_Error;
        trans->response = MemResp_Error;
        cb->nb_response(trans);
        cb->nb_response(trans);
        ret = TRANS_ERROR;
        ret = TRANS_ERROR;
    } else {
    } else {
 
        memdev->nb_transport(trans, cb);
        RISCV_debug("Non-blocking request to [%08" RV_PRI64 "x]",
        RISCV_debug("Non-blocking request to [%08" RV_PRI64 "x]",
                    trans->addr);
                    trans->addr);
    }
    }
 
 
    // Update Bus utilization counters:
    // Update Bus utilization counters:
 
    if (idsu_) {
    if (trans->action == MemAction_Read) {
    if (trans->action == MemAction_Read) {
        info_[trans->source_idx].r_cnt++;
            idsu_->incrementRdAccess(trans->source_idx);
    } else if (trans->action == MemAction_Write) {
    } else if (trans->action == MemAction_Write) {
        info_[trans->source_idx].w_cnt++;
            idsu_->incrementWrAccess(trans->source_idx);
 
        }
    }
    }
    RISCV_mutex_unlock(&mutexNBAccess_);
    RISCV_mutex_unlock(&mutexNBAccess_);
    return ret;
    return ret;
}
}
 
 
BusUtilType *Bus::bus_utilization() {
void Bus::getMapedDevice(Axi4TransactionType *trans,
    return info_;
                         IMemoryOperation **pdev, uint32_t *sz) {
 
    IMemoryOperation *imem;
 
    uint64_t bar, barsz;
 
    *pdev = 0;
 
    *sz = 0;
 
    for (unsigned i = 0; i < imap_.size(); i++) {
 
        imem = static_cast<IMemoryOperation *>(imap_[i].to_iface());
 
        bar = imem->getBaseAddress();
 
        barsz = imem->getLength();
 
        if (bar <= trans->addr && trans->addr < (bar + barsz)) {
 
            if (!(*pdev) || imem->getPriority() > (*pdev)->getPriority()) {
 
                *pdev = imem;
 
            }
 
        }
 
    }
}
}
 
 
}  // namespace debugger
}  // namespace debugger
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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