int UdpService::sendData(const uint8_t *msg, int len) { int tx_bytes = sendto(hsock_, reinterpret_cast<const char *>(msg), len, 0, reinterpret_cast<struct sockaddr *>(&remote_sockaddr_ipv4_), static_cast<int>(sizeof(remote_sockaddr_ipv4_))); if (tx_bytes < 0) { #if defined(_WIN32) || defined(__CYGWIN__) RISCV_error("sendto() failed with error: %d\n", WSAGetLastError()); #else RISCV_error("sendto() failed\n", NULL); #endif return 1; } else if (logLevel_.to_int() >= LOG_DEBUG) { char dbg[1024]; int pos = RISCV_sprintf(dbg, sizeof(dbg), "send %d bytes to %s:%d: ", tx_bytes, inet_ntoa(remote_sockaddr_ipv4_.sin_addr), ntohs(remote_sockaddr_ipv4_.sin_port)); if (tx_bytes < 64) { for (int i = 0; i < len; i++) { pos += RISCV_sprintf(&dbg[pos], sizeof(dbg) - pos, "%02x", msg[i] & 0xFF); } } RISCV_debug("%s", dbg); } return tx_bytes; }
extern "C" void RISCV_set_configuration(AttributeType *cfg) { IClass *icls; IService *iserv; Config_.clone(cfg); if (!Config_.is_dict()) { RISCV_error("Wrong configuration.", NULL); return; } AttributeType &Services = Config_["Services"]; if (Services.is_list()) { for (unsigned i = 0; i < Services.size(); i++) { icls = static_cast<IClass *>( RISCV_get_class(Services[i]["Class"].to_string())); if (icls == NULL) { RISCV_error("Class %s not found", Services[i]["Class"].to_string()); continue; } AttributeType &Instances = Services[i]["Instances"]; for (unsigned n = 0; n < Instances.size(); n++) { iserv = icls->createService(Instances[n]["Name"].to_string()); iserv->initService(&Instances[n]["Attr"]); } } } // Post initialization for (unsigned i = 0; i < listClasses_.size(); i++) { icls = static_cast<IClass *>(listClasses_[i].to_iface()); icls->postinitServices(); } RISCV_printf(getInterface(IFACE_SERVICE), 0, "%s", "\n**********************************************************\n" " RISC-V debugger\n" " Author: Sergey Khabarov - [email protected]\n" " Copyright 2016 GNSS Sensor Ltd. All right reserved.\n" "**********************************************************"); IHap *ihap; for (unsigned i = 0; i < listHap_.size(); i++) { ihap = static_cast<IHap *>(listHap_[i].to_iface()); if (ihap->getType() == HAP_ConfigDone) { ihap->hapTriggered(HAP_ConfigDone); } } }
/** * prv-1.9.1 page 29 * * An interrupt i will be taken if bit i is set in both mip and mie, * and if interrupts are globally enabled. By default, M-mode interrupts * are globally enabled if the hart’s current privilege mode is less than M, * or if the current privilege mode is M and the MIE bit in the mstatus * register is set. * If bit i in mideleg is set, however, interrupts are considered to be * globally enabled if the hart’s current privilege mode equals the delegated * privilege mode (H, S, or U) and that mode’s interrupt enable bit * (HIE, SIE or UIE in mstatus) is set, or if the current privilege mode is * less than the delegated privilege mode. */ void CpuRiscV_Functional::raiseSignal(int idx) { CpuContextType *pContext = getpContext(); csr_mstatus_type mstatus; mstatus.value = pContext->csr[CSR_mstatus]; switch (idx) { case CPU_SIGNAL_RESET: pContext->reset = false; // Active LOW break; case CPU_SIGNAL_EXT_IRQ: if (pContext->reset) { break; } if (mstatus.bits.MIE == 0 && pContext->cur_prv_level == PRV_M) { // External Interrupt controller pending bit pContext->interrupt_pending = 1; break; } /// @todo delegate interrupt to non-machine privilege level. csr_mcause_type cause; cause.value = 0; cause.bits.irq = 1; cause.bits.code = 11; // 11 = Machine external interrupt pContext->csr[CSR_mcause] = cause.value; pContext->interrupt = 1; break; default: RISCV_error("Unsupported signalRaise(%d)", idx); } }
void UART::postinitService() { iwire_ = static_cast<IWire *>( RISCV_get_service_iface(irqctrl_.to_string(), IFACE_WIRE)); if (!iwire_) { RISCV_error("Can't find IWire interface %s", irqctrl_.to_string()); } }
extern "C" int RISCV_init() { RISCV_mutex_init(&mutex_printf); #if defined(_WIN32) || defined(__CYGWIN__) WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData)) { RISCV_error("Can't initialize sockets library", NULL); } #endif return 0; }
int UdpService::readData(const uint8_t *buf, int maxlen) { int sockerr; addr_size_t sockerr_len = sizeof(sockerr); addr_size_t addr_sz = sizeof(sockaddr_ipv4_); int res = recvfrom(hsock_, rcvbuf, sizeof(rcvbuf), 0, (struct sockaddr *)&sockaddr_ipv4_, &addr_sz); getsockopt(hsock_, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &sockerr_len); if (res < 0 && sockerr < 0) { RISCV_error("Socket error %x", sockerr); res = -1; } else if (res < 0 && sockerr == 0) { // Timeout: res = 0; } else if (res > 0) { if (maxlen < res) { res = maxlen; RISCV_error("Receiver's buffer overflow maxlen = %d", maxlen); } memcpy(const_cast<uint8_t *>(buf), rcvbuf, res); if (logLevel_.to_int() >= LOG_DEBUG) { char dbg[1024]; int pos = RISCV_sprintf(dbg, sizeof(dbg), "received %d Bytes: ", res); if (res < 64) { for (int i = 0; i < res; i++) { pos += RISCV_sprintf(&dbg[pos], sizeof(dbg) - pos, "%02x", rcvbuf[i] & 0xFF); } } RISCV_debug("%s", dbg); } } return res; }
void CpuRiscV_Functional::lowerSignal(int idx) { CpuContextType *pContext = getpContext(); switch (idx) { case CPU_SIGNAL_RESET: pContext->reset = true; // Active LOW break; case CPU_SIGNAL_EXT_IRQ: pContext->interrupt = 0; pContext->interrupt_pending = 0; break; default: RISCV_error("Unsupported lowerSignal(%d)", idx); } }
void CpuRiscV_Functional::executeInstruction(IInstruction *instr, uint32_t *rpayload) { CpuContextType *pContext = getpContext(); if (pContext->reg_trace_file) { /** Save previous reg values to find modification after exec() */ for (int i = 0; i < Reg_Total; i++) { iregs_prev[i] = pContext->regs[i]; } } instr->exec(cacheline_, pContext); #if 0 //if (pContext->pc >= 0x10000000) { //if ((pContext->pc >= 0x100000b4 && pContext->pc <= 0x10000130) //|| (pContext->pc >= 0x10001ef4) //) { //if (pContext->pc >= 0x10001928 && pContext->pc <= 0x10001960) { RISCV_debug("[%" RV_PRI64 "d] %08x: %08x \t %4s <prv=%d; mstatus=%016" RV_PRI64 "x; mcause=%016" RV_PRI64 "x; ra=%016" RV_PRI64 "x; sp=%016" RV_PRI64 "x; tp=%016" RV_PRI64 "x>", getStepCounter(), static_cast<uint32_t>(pContext->pc), rpayload[0], instr->name(), pContext->cur_prv_level, pContext->csr[CSR_mstatus], pContext->csr[CSR_mcause], pContext->regs[Reg_ra], pContext->regs[Reg_sp], pContext->regs[Reg_tp] ); } #endif if (pContext->reg_trace_file) { int sz; sz = RISCV_sprintf(tstr, sizeof(tstr),"%8I64d [%08x] %08x: ", pContext->step_cnt, static_cast<uint32_t>(pContext->pc), rpayload[0]); bool reg_changed = false; for (int i = 0; i < 32; i++) { if (iregs_prev[i] != pContext->regs[i]) { reg_changed = true; sz += RISCV_sprintf(&tstr[sz], sizeof(tstr) - sz, "%3s <= %016I64x\n", IREGS_NAMES[i], pContext->regs[i]); } } if (!reg_changed) { sz += RISCV_sprintf(&tstr[sz], sizeof(tstr) - sz, "%s", "-\n"); } (*pContext->reg_trace_file) << tstr; pContext->reg_trace_file->flush(); } if (generateRegTraceFile_.to_bool()) { char msg[16]; int msg_len = 0; IService *uart = NULL; switch (pContext->step_cnt) { case 6000: uart = static_cast<IService *>(RISCV_get_service("uart0")); msg[0] = 'h'; msg[1] = 'i'; msg_len = 2; break; case 6500: uart = static_cast<IService *>(RISCV_get_service("uart0")); msg[0] = 'g'; msg[1] = 'h'; msg[2] = 't'; msg_len = 3; break; case 8200: uart = static_cast<IService *>(RISCV_get_service("uart0")); msg[0] = 'i'; msg[1] = 'c'; msg_len = 2; break; case 8300: uart = static_cast<IService *>(RISCV_get_service("uart0")); msg[0] = 'k'; msg[1] = 's'; msg[2] = '\r'; msg[3] = '\n'; msg_len = 4; break; default:; } if (uart) { ISerial *iserial = static_cast<ISerial *>( uart->getInterface(IFACE_SERIAL)); //iserial->writeData("pnp\r\n", 6); //iserial->writeData("highticks\r\n", 11); iserial->writeData(msg, msg_len); } } if (pContext->regs[0] != 0) { RISCV_error("Register x0 was modificated (not equal to zero)", NULL); } }
int UdpService::createDatagramSocket() { char hostName[256]; if(gethostname(hostName, sizeof(hostName)) < 0) { return -1; } struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; /** * Check availability of IPv4 address assigned via attribute 'hostIP'. * If it woudn't be found use the last avaialble IP address. */ bool host_ip_found = false; int retval; struct addrinfo *result = NULL; struct addrinfo *ptr = NULL; retval = getaddrinfo(hostName, "0", &hints, &result); if (retval != 0) { return -1; } for (ptr = result; ptr != NULL; ptr = ptr->ai_next) { // Find only IPV4 address, ignore others. if (ptr->ai_family != AF_INET) { continue; } sockaddr_ipv4_ = *((struct sockaddr_in *)ptr->ai_addr); RISCV_sprintf(sockaddr_ipv4_str_, sizeof(sockaddr_ipv4_str_), "%s", inet_ntoa(sockaddr_ipv4_.sin_addr)); if (strcmp(inet_ntoa(sockaddr_ipv4_.sin_addr), hostIP_.to_string()) == 0) { host_ip_found = true; break; } } if (!host_ip_found) { RISCV_info("Selected IPv4 %s", inet_ntoa(sockaddr_ipv4_.sin_addr)); } else { #if 1 /** jrkk proposal to hardcode IP address in a such way. No difference. */ memset(&sockaddr_ipv4_, 0, sizeof (sockaddr_ipv4_)); sockaddr_ipv4_.sin_family = AF_INET; inet_pton(AF_INET, hostIP_.to_string(), &(sockaddr_ipv4_.sin_addr)); #endif } hsock_ = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (hsock_ < 0) { RISCV_error("%s", "Error: socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)"); return -1; } int res = bind(hsock_, (struct sockaddr *)&sockaddr_ipv4_, sizeof(sockaddr_ipv4_)); if (res != 0) { RISCV_error("Error: bind(hsock_, \"%s\", ...)", hostIP_.to_string()); return -1; } addr_size_t addr_sz = sizeof(sockaddr_ipv4_); res = getsockname(hsock_, (struct sockaddr *)&sockaddr_ipv4_, &addr_sz); sockaddr_ipv4_port_ = ntohs(sockaddr_ipv4_.sin_port); RISCV_info("\tIPv4 address %s:%d . . . opened", sockaddr_ipv4_str_, sockaddr_ipv4_port_); return 0; }