URL
https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk
Subversion Repositories riscv_vhdl
[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [common/] [debug/] [greth.cpp] - Rev 5
Compare with Previous | Blame | View Log
/** * @file * @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. * @author Sergey Khabarov - sergeykhbr@gmail.com * @brief Ethernet MAC device functional model. */ #include <api_core.h> #include "greth.h" #include "coreservices/isocinfo.h" namespace debugger { /** Class registration in the Core */ REGISTER_CLASS(Greth) Greth::Greth(const char *name) : IService(name) { registerInterface(static_cast<IThread *>(this)); registerInterface(static_cast<IMemoryOperation *>(this)); registerInterface(static_cast<IAxi4NbResponse *>(this)); registerAttribute("IP", &ip_); registerAttribute("MAC", &mac_); registerAttribute("Bus", &bus_); registerAttribute("Transport", &transport_); registerAttribute("SysBusMasterID", &sysBusMasterID_); memset(txbuf_, 0, sizeof(txbuf_)); seq_cnt_ = 35; RISCV_event_create(&event_tap_, "UART_event_tap"); } Greth::~Greth() { RISCV_event_close(&event_tap_); } void Greth::postinitService() { ibus_ = static_cast<IMemoryOperation *>( RISCV_get_service_iface(bus_.to_string(), IFACE_MEMORY_OPERATION)); if (!ibus_) { RISCV_error("Bus interface '%s' not found", bus_.to_string()); return; } itransport_ = static_cast<ILink *>( RISCV_get_service_iface(transport_.to_string(), IFACE_LINK)); if (!itransport_) { RISCV_error("UDP interface '%s' not found", bus_.to_string()); return; } AttributeType clks; RISCV_get_clock_services(&clks); if (clks.size()) { iclk0_ = static_cast<IClock *>(clks[0u].to_iface()); } else { RISCV_error("CPUs not found", NULL); } // Get global settings: const AttributeType *glb = RISCV_get_global_settings(); if ((*glb)["SimEnable"].to_bool()) { if (!run()) { RISCV_error("Can't create thread.", NULL); return; } } } void Greth::busyLoop() { int bytes; uint8_t *tbuf; uint32_t bytes_to_read; UdpEdclCommonType req; RISCV_info("Ethernet thread was started", NULL); trans_.source_idx = sysBusMasterID_.to_int(); while (isEnabled()) { bytes = itransport_->readData(rxbuf_, static_cast<int>(sizeof(rxbuf_))); if (bytes == 0) { continue; } req.control.word = read32(&rxbuf_[2]); req.address = read32(&rxbuf_[6]); if (seq_cnt_ != req.control.request.seqidx) { sendNAK(&req); continue; } trans_.addr = req.address; if (req.control.request.write == 0) { trans_.action = MemAction_Read; trans_.wstrb = 0; tbuf = &txbuf_[10]; bytes = sizeof(UdpEdclCommonType) + req.control.request.len; } else { trans_.action = MemAction_Write; tbuf = &rxbuf_[10]; bytes = sizeof(UdpEdclCommonType); } bytes_to_read = req.control.request.len; while (bytes_to_read) { trans_.xsize = bytes_to_read; if (trans_.xsize > 8) { trans_.xsize = 8; } if (trans_.action == MemAction_Write) { memcpy(trans_.wpayload.b8, tbuf, trans_.xsize); trans_.wstrb = (1 << trans_.xsize) - 1; } RISCV_event_clear(&event_tap_); ibus_->nb_transport(&trans_, this); if (RISCV_event_wait_ms(&event_tap_, 500) != 0) { RISCV_error("CPU queue callback timeout", NULL); } else if (trans_.action == MemAction_Read) { memcpy(tbuf, trans_.rpayload.b8, trans_.xsize); } tbuf += trans_.xsize; trans_.addr += trans_.xsize; bytes_to_read -= trans_.xsize; } req.control.response.nak = 0; req.control.response.seqidx = seq_cnt_; write32(&txbuf_[2], req.control.word); seq_cnt_++; itransport_->sendData(txbuf_, bytes); } } void Greth::nb_response(Axi4TransactionType *trans) { RISCV_event_set(&event_tap_); } ETransStatus Greth::b_transport(Axi4TransactionType *trans) { RISCV_error("ETH Slave registers not implemented", NULL); return TRANS_OK; } void Greth::sendNAK(UdpEdclCommonType *req) { req->control.response.nak = 1; req->control.response.seqidx = seq_cnt_; req->control.response.len = 0; write32(&txbuf_[2], req->control.word); write32(&txbuf_[6], req->address); itransport_->sendData(txbuf_, sizeof(UdpEdclCommonType)); } uint32_t Greth::read32(uint8_t *buf) { return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3] << 0); } void Greth::write32(uint8_t *buf, uint32_t v) { buf[0] = static_cast<char>((v >> 24) & 0xFF); buf[1] = static_cast<char>((v >> 16) & 0xFF); buf[2] = static_cast<char>((v >> 8) & 0xFF); buf[3] = static_cast<char>(v & 0xFF); } } // namespace debugger