From 74d841f78f8f2643ee107861fe8789c47a1faff8 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 22 Jun 2016 23:00:01 -0700 Subject: [PATCH] Remove legacy HTIF implementation; use Debug Module instead --- fesvr/device.h | 1 - fesvr/dtm.cc | 308 ++++++++++++++++++++++++++++++++++++++++ fesvr/dtm.h | 96 +++++++++++++ fesvr/elfloader.cc | 5 +- fesvr/fesvr-eth.cc | 10 -- fesvr/fesvr-rs232.cc | 45 ------ fesvr/fesvr-zedboard.cc | 10 -- fesvr/fesvr.mk.in | 13 +- fesvr/htif.cc | 151 ++------------------ fesvr/htif.h | 31 ++-- fesvr/htif_eth.cc | 281 ------------------------------------ fesvr/htif_eth.h | 53 ------- fesvr/htif_hexwriter.h | 4 +- fesvr/htif_rs232.cc | 64 --------- fesvr/htif_rs232.h | 26 ---- fesvr/htif_zedboard.cc | 58 -------- fesvr/htif_zedboard.h | 28 ---- fesvr/memif.cc | 45 ++---- fesvr/memif.h | 38 +---- fesvr/packet.cc | 49 ------- fesvr/packet.h | 91 ------------ fesvr/rfb.h | 3 +- fesvr/syscall.cc | 29 +++- fesvr/syscall.h | 6 +- 24 files changed, 475 insertions(+), 970 deletions(-) create mode 100644 fesvr/dtm.cc create mode 100644 fesvr/dtm.h delete mode 100644 fesvr/fesvr-eth.cc delete mode 100644 fesvr/fesvr-rs232.cc delete mode 100644 fesvr/fesvr-zedboard.cc delete mode 100644 fesvr/htif_eth.cc delete mode 100644 fesvr/htif_eth.h delete mode 100644 fesvr/htif_rs232.cc delete mode 100644 fesvr/htif_rs232.h delete mode 100644 fesvr/htif_zedboard.cc delete mode 100644 fesvr/htif_zedboard.h delete mode 100644 fesvr/packet.cc delete mode 100644 fesvr/packet.h diff --git a/fesvr/device.h b/fesvr/device.h index e3400e6..2fa56f5 100644 --- a/fesvr/device.h +++ b/fesvr/device.h @@ -1,7 +1,6 @@ #ifndef _DEVICE_H #define _DEVICE_H -#include "packet.h" #include #include #include diff --git a/fesvr/dtm.cc b/fesvr/dtm.cc new file mode 100644 index 0000000..2854b7d --- /dev/null +++ b/fesvr/dtm.cc @@ -0,0 +1,308 @@ +#include "dtm.h" +#include +#include +#include +#include +#include + +#define RV_X(x, s, n) \ + (((x) >> (s)) & ((1 << (n)) - 1)) +#define ENCODE_ITYPE_IMM(x) \ + (RV_X(x, 0, 12) << 20) +#define ENCODE_STYPE_IMM(x) \ + ((RV_X(x, 0, 5) << 7) | (RV_X(x, 5, 7) << 25)) +#define ENCODE_SBTYPE_IMM(x) \ + ((RV_X(x, 1, 4) << 8) | (RV_X(x, 5, 6) << 25) | (RV_X(x, 11, 1) << 7) | (RV_X(x, 12, 1) << 31)) +#define ENCODE_UTYPE_IMM(x) \ + (RV_X(x, 12, 20) << 12) +#define ENCODE_UJTYPE_IMM(x) \ + ((RV_X(x, 1, 10) << 21) | (RV_X(x, 11, 1) << 20) | (RV_X(x, 12, 8) << 12) | (RV_X(x, 20, 1) << 31)) + +#define LOAD(xlen, dst, base, imm) \ + (((xlen) == 64 ? 0x00003003 : 0x00002003) \ + | ((dst) << 7) | ((base) << 15) | (uint32_t)ENCODE_ITYPE_IMM(imm)) +#define STORE(xlen, src, base, imm) \ + (((xlen) == 64 ? 0x00003023 : 0x00002023) \ + | ((src) << 20) | ((base) << 15) | (uint32_t)ENCODE_STYPE_IMM(imm)) +#define JUMP(there, here) (0x6f | (uint32_t)ENCODE_UJTYPE_IMM((there) - (here))) +#define BNE(r1, r2, there, here) (0x1063 | ((r1) << 15) | ((r2) << 20) | (uint32_t)ENCODE_SBTYPE_IMM((there) - (here))) +#define ADDI(dst, src, imm) (0x13 | ((dst) << 7) | ((src) << 15) | (uint32_t)ENCODE_ITYPE_IMM(imm)) +#define SRL(dst, src, sh) (0x5033 | ((dst) << 7) | ((src) << 15) | ((sh) << 20)) +#define FENCE_I 0x100f +#define X0 0 +#define S0 8 +#define S1 9 + +#define WRITE 1 +#define SET 2 +#define CLEAR 3 +#define CSRRx(type, dst, csr, src) (0x73 | ((type) << 12) | ((dst) << 7) | ((src) << 15) | (uint32_t)((csr) << 20)) + +uint64_t dtm_t::do_command(dtm_t::req r) +{ + req_buf = r; + target->switch_to(); + assert(resp_buf.resp == 0); + return resp_buf.data; +} + +uint64_t dtm_t::read(uint32_t addr) +{ + idle_cycles = 0; + return do_command((req){addr, 1, 0}); +} + +uint64_t dtm_t::write(uint32_t addr, uint64_t data) +{ + idle_cycles = 0; + return do_command((req){addr, 2, data}); +} + +void dtm_t::nop() +{ + do_command((req){0, 0, 0}); +} + +uint32_t dtm_t::run_program(const uint32_t program[], size_t n, size_t result) +{ + assert(n <= ram_words()); + assert(result < ram_words()); + + uint64_t interrupt_bit = 0x200000000U; + for (size_t i = 0; i < n; i++) + write(i, program[i] | (i == n-1 ? interrupt_bit : 0)); + + while (true) { + uint64_t rdata = read(result); + if (!(rdata & interrupt_bit)) + return (uint32_t)rdata; + } +} + +size_t dtm_t::chunk_align() +{ + return xlen / 8; +} + +void dtm_t::read_chunk(uint64_t taddr, size_t len, void* dst) +{ + uint32_t prog[ram_words()]; + uint32_t res[ram_words()]; + int result_word = 2 + (len / (xlen/8)) * 2; + int addr_word = result_word; + int prog_words = addr_word + (xlen/32); + + prog[0] = LOAD(xlen, S0, X0, ram_base() + addr_word * 4); + for (size_t i = 0; i < len/(xlen/8); i++) { + prog[2*i+1] = LOAD(xlen, S1, S0, i * (xlen/8)); + prog[2*i+2] = STORE(xlen, S1, X0, ram_base() + (result_word * 4) + (i * (xlen/8))); + } + prog[result_word - 1] = JUMP(rom_ret(), ram_base() + (result_word - 1) * 4); + prog[addr_word] = (uint32_t)taddr; + prog[addr_word + 1] = (uint32_t)(taddr >> 32); + + res[0] = run_program(prog, prog_words, result_word); + for (size_t i = 1; i < len/4; i++) + res[i] = read(result_word + i); + memcpy(dst, res, len); +} + +void dtm_t::write_chunk(uint64_t taddr, size_t len, const void* src) +{ + uint32_t prog[ram_words()]; + int data_word = 2 + (len / (xlen/8)) * 2; + int addr_word = data_word + len/4; + int prog_words = addr_word + (xlen/32); + + prog[0] = LOAD(xlen, S0, X0, ram_base() + addr_word * 4); + for (size_t i = 0; i < len/(xlen/8); i++) { + prog[2*i+1] = LOAD(xlen, S1, X0, ram_base() + (data_word * 4) + (i * (xlen/8))); + prog[2*i+2] = STORE(xlen, S1, S0, i * (xlen/8)); + } + prog[data_word - 1] = JUMP(rom_ret(), ram_base() + (data_word - 1)*4); + memcpy(prog + data_word, src, len); + prog[addr_word] = (uint32_t)taddr; + prog[addr_word + 1] = (uint32_t)(taddr >> 32); + + run_program(prog, prog_words, data_word); +} + +void dtm_t::clear_chunk(uint64_t taddr, size_t len) +{ + uint32_t prog[ram_words()]; + int addr1_word = 6; + int addr2_word = addr1_word + (xlen/32); + int prog_words = addr2_word + (xlen/32); + + if (prog_words + (xlen/32) > ram_words()) + return htif_t::clear_chunk(taddr, len); + + prog[0] = LOAD(xlen, S0, X0, ram_base() + addr1_word * 4); + prog[1] = LOAD(xlen, S1, X0, ram_base() + addr2_word * 4); + prog[2] = STORE(xlen, X0, S0, 0); + prog[3] = ADDI(S0, S0, xlen/8); + prog[4] = BNE(S0, S1, 2*4, 4*4); + prog[5] = JUMP(rom_ret(), ram_base() + 5*4); + prog[addr1_word] = (uint32_t)taddr; + prog[addr1_word + 1] = (uint32_t)(taddr >> 32); + prog[addr2_word] = (uint32_t)(taddr + len); + prog[addr2_word + 1] = (uint32_t)((taddr + len) >> 32); + + run_program(prog, prog_words, 0); +} + +uint64_t dtm_t::write_csr(unsigned which, uint64_t data) +{ + return modify_csr(which, data, WRITE); +} + +uint64_t dtm_t::set_csr(unsigned which, uint64_t data) +{ + return modify_csr(which, data, SET); +} + +uint64_t dtm_t::clear_csr(unsigned which, uint64_t data) +{ + return modify_csr(which, data, CLEAR); +} + +uint64_t dtm_t::read_csr(unsigned which) +{ + return set_csr(which, 0); +} + +uint64_t dtm_t::modify_csr(unsigned which, uint64_t data, uint32_t type) +{ + int data_word = 4; + int prog_words = data_word + xlen/32; + uint32_t prog[ram_words()] = { + LOAD(xlen, S0, X0, ram_base() + data_word * 4), + CSRRx(type, S0, which, S0), + STORE(xlen, S0, X0, ram_base() + data_word * 4), + JUMP(rom_ret(), ram_base() + 12) + }; + + prog[data_word] = (uint32_t)data; + prog[data_word + 1] = (uint32_t)(data >> 32); + + uint64_t res = run_program(prog, prog_words, data_word); + if (xlen == 64) + res |= read(data_word + 1) << 32; + return res; +} + +size_t dtm_t::chunk_max_size() +{ + if (xlen == 32) + return 4 * ((ram_words() - 4) / 3); + else + return 8 * ((ram_words() - 6) / 4); +} + +uint32_t dtm_t::get_xlen() +{ + const uint32_t prog[] = { + CSRRx(SET, S0, 0xF10, X0), + ADDI(S1, X0, 62), + SRL(S0, S0, S1), + STORE(32, S0, X0, ram_base()), + JUMP(rom_ret(), ram_base() + 16) + }; + + uint32_t result = run_program(prog, sizeof(prog)/sizeof(*prog), 0); + if (result < 2) + return 32; + else if (result == 2) + return 64; + abort(); +} + +void dtm_t::fence_i() +{ + const uint32_t prog[] = { + FENCE_I, + JUMP(rom_ret(), ram_base() + 4) + }; + + run_program(prog, sizeof(prog)/sizeof(*prog), 0); +} + +void host_thread_main(void* arg) +{ + ((dtm_t*)arg)->producer_thread(); +} + +void dtm_t::reset() +{ + fence_i(); + // set pc and un-halt + write_csr(0x7b1, 0x80000000U); + clear_csr(0x7b0, 8); +} + +void dtm_t::idle() +{ + while (idle_cycles < max_idle_cycles) + nop(); +} + +void dtm_t::producer_thread() +{ + // halt hart + dminfo = -1U; + xlen = 32; + set_csr(0x7b0, 8); + + // query hart + dminfo = read(0x11); + xlen = get_xlen(); + + htif_t::run(); + + while (true) + nop(); +} + +void dtm_t::start_host_thread() +{ + req_wait = false; + resp_wait = false; + + target = context_t::current(); + host.init(host_thread_main, this); +} + +dtm_t::dtm_t(const std::vector& args) + : htif_t(args) +{ + start_host_thread(); +} + +dtm_t::~dtm_t() +{ +} + +void dtm_t::tick( + bool req_ready, + bool resp_valid, + resp resp_bits) +{ + idle_cycles++; + + if (!resp_wait) { + if (!req_wait) { + req_wait = true; + } else if (req_ready) { + req_wait = false; + resp_wait = true; + } + } + + if (resp_valid) { + assert(resp_wait); + resp_wait = false; + + resp_buf = resp_bits; + host.switch_to(); + } +} diff --git a/fesvr/dtm.h b/fesvr/dtm.h new file mode 100644 index 0000000..26193d9 --- /dev/null +++ b/fesvr/dtm.h @@ -0,0 +1,96 @@ +#ifndef _ROCKET_DTM_H +#define _ROCKET_DTM_H + +#include "htif.h" +#include "context.h" +#include +#include +#include +#include +#include +#include + +// abstract debug transport module +class dtm_t : public htif_t +{ + public: + dtm_t(const std::vector& args); + ~dtm_t(); + + struct req { + uint32_t addr; + uint32_t op; + uint64_t data; + }; + + struct resp { + uint32_t resp; + uint64_t data; + }; + + void tick( + bool req_ready, + bool resp_valid, + resp resp_bits + ); + + bool req_valid() { return req_wait; } + req req_bits() { return req_buf; } + bool resp_ready() { return true; } + + uint64_t read(uint32_t addr); + uint64_t write(uint32_t addr, uint64_t data); + void nop(); + + uint64_t read_csr(unsigned which); + uint64_t write_csr(unsigned which, uint64_t data); + uint64_t clear_csr(unsigned which, uint64_t data); + uint64_t set_csr(unsigned which, uint64_t data); + void fence_i(); + + void producer_thread(); + + private: + context_t host; + context_t* target; + pthread_t producer; + sem_t req_produce; + sem_t req_consume; + sem_t resp_produce; + sem_t resp_consume; + req req_buf; + resp resp_buf; + + uint32_t run_program(const uint32_t program[], size_t n, size_t result); + uint64_t modify_csr(unsigned which, uint64_t data, uint32_t type); + + void read_chunk(addr_t taddr, size_t len, void* dst) override; + void write_chunk(addr_t taddr, size_t len, const void* src) override; + void clear_chunk(addr_t taddr, size_t len) override; + size_t chunk_align() override; + size_t chunk_max_size() override; + void reset() override; + void idle() override; + + bool req_wait; + bool resp_wait; + uint32_t dminfo; + uint32_t xlen; + + int idle_cycles; + static const int max_idle_cycles = 10000; + + size_t ram_base() { return 0x400; } + size_t rom_ret() { return 0x804; } + size_t ram_words() { return ((dminfo >> 10) & 63) + 1; } + uint32_t get_xlen(); + uint64_t do_command(dtm_t::req r); + + void parse_args(const std::vector& args); + void register_devices(); + void start_host_thread(); + + friend class memif_t; +}; + +#endif diff --git a/fesvr/elfloader.cc b/fesvr/elfloader.cc index 37f8f3f..a4567a2 100644 --- a/fesvr/elfloader.cc +++ b/fesvr/elfloader.cc @@ -1,12 +1,13 @@ // See LICENSE for license details. +#include "elf.h" +#include "memif.h" +#include #include #include #include #include #include -#include "elf.h" -#include "memif.h" #include #include #include diff --git a/fesvr/fesvr-eth.cc b/fesvr/fesvr-eth.cc deleted file mode 100644 index 99f7029..0000000 --- a/fesvr/fesvr-eth.cc +++ /dev/null @@ -1,10 +0,0 @@ -// See LICENSE for license details. - -#include "htif_eth.h" - -int main(int argc, char** argv) -{ - std::vector args(argv + 1, argv + argc); - htif_eth_t htif(args); - return htif.run(); -} diff --git a/fesvr/fesvr-rs232.cc b/fesvr/fesvr-rs232.cc deleted file mode 100644 index 5bfeb11..0000000 --- a/fesvr/fesvr-rs232.cc +++ /dev/null @@ -1,45 +0,0 @@ -// See LICENSE for license details. - -#include "htif_rs232.h" - -int main(int argc, char** argv) -{ - std::vector args(argv + 1, argv + argc); - htif_rs232_t htif(args); - return htif.run(); -} - -#if 0 -int poll_tohost(int coreid, addr_t sig_addr, int sig_len) -{ - reg_t tohost; - while ((tohost = htif->read_cr(coreid, 30)) == 0); - if (tohost == 1) - { - if (sig_len != -1) - { - int chunk_size = 16; - assert(sig_addr % chunk_size == 0); - int sig_len_aligned = (sig_len + chunk_size - 1)/chunk_size*chunk_size; - - uint8_t* signature = new uint8_t[sig_len_aligned]; - htif->memif().read(sig_addr, sig_len, signature); - for (int i = sig_len; i < sig_len_aligned; i++) - signature[i] = 0; - - for (int i = 0; i < sig_len_aligned; i += chunk_size) - { - for (int j = chunk_size - 1; j >= 0; j--) - printf("%02x", signature[i+j]); - printf("\n"); - } - delete [] signature; - } - else - - return 0; - } - - return -1; -} -#endif diff --git a/fesvr/fesvr-zedboard.cc b/fesvr/fesvr-zedboard.cc deleted file mode 100644 index 680e4e7..0000000 --- a/fesvr/fesvr-zedboard.cc +++ /dev/null @@ -1,10 +0,0 @@ -// See LICENSE for license details. - -#include "htif_zedboard.h" - -int main(int argc, char** argv) -{ - std::vector args(argv + 1, argv + argc); - htif_zedboard_t htif(args); - return htif.run(); -} diff --git a/fesvr/fesvr.mk.in b/fesvr/fesvr.mk.in index 00497b7..3eb1e0f 100644 --- a/fesvr/fesvr.mk.in +++ b/fesvr/fesvr.mk.in @@ -3,15 +3,12 @@ fesvr_hdrs = \ elf.h \ elfloader.h \ htif.h \ + dtm.h \ memif.h \ syscall.h \ - packet.h \ context.h \ htif_pthread.h \ - htif_rs232.h \ htif_hexwriter.h \ - htif_eth.h \ - htif_zedboard.h \ option_parser.h \ term.h \ device.h \ @@ -20,23 +17,17 @@ fesvr_hdrs = \ fesvr_srcs = \ elfloader.cc \ htif.cc \ - packet.cc \ memif.cc \ + dtm.cc \ syscall.cc \ device.cc \ rfb.cc \ context.cc \ htif_pthread.cc \ - htif_rs232.cc \ htif_hexwriter.cc \ - htif_eth.cc \ - htif_zedboard.cc \ dummy.cc \ option_parser.cc \ term.cc \ fesvr_install_prog_srcs = \ elf2hex.cc \ - fesvr-eth.cc \ - fesvr-rs232.cc \ - fesvr-zedboard.cc \ diff --git a/fesvr/htif.cc b/fesvr/htif.cc index 4622dfa..f72b0f6 100644 --- a/fesvr/htif.cc +++ b/fesvr/htif.cc @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -40,25 +39,9 @@ static void handle_signal(int sig) signal(sig, &handle_signal); } -void htif_t::set_chroot(const char* where) -{ - char buf1[PATH_MAX], buf2[PATH_MAX]; - - if (getcwd(buf1, sizeof(buf1)) == NULL - || chdir(where) != 0 - || getcwd(buf2, sizeof(buf2)) == NULL - || chdir(buf1) != 0) - { - printf("could not chroot to %s\n", chroot.c_str()); - exit(-1); - } - - chroot = buf2; -} - htif_t::htif_t(const std::vector& args) - : exitcode(0), mem(this), seqno(1), started(false), stopped(false), - _num_cores(0), sig_addr(0), sig_len(0), tohost_addr(0), fromhost_addr(0), + : mem(this), _num_cores(0), sig_addr(0), sig_len(0), + tohost_addr(0), fromhost_addr(0), exitcode(0), syscall_proxy(this) { signal(SIGINT, &handle_signal); @@ -84,7 +67,7 @@ htif_t::htif_t(const std::vector& args) else if (arg.find("+signature=") == 0) sig_file = arg.c_str() + strlen("+signature="); else if (arg.find("+chroot=") == 0) - set_chroot(arg.substr(strlen("+chroot=")).c_str()); + syscall_proxy.set_chroot(arg.substr(strlen("+chroot=")).c_str()); } device_list.register_device(&syscall_proxy); @@ -99,55 +82,8 @@ htif_t::~htif_t() delete d; } -packet_t htif_t::read_packet(seqno_t expected_seqno) -{ - while (1) - { - if (read_buf.size() >= sizeof(packet_header_t)) - { - packet_header_t hdr(&read_buf[0]); - if (read_buf.size() >= hdr.get_packet_size()) - { - packet_t p(&read_buf[0]); - switch (p.get_header().cmd) - { - case HTIF_CMD_ACK: - break; - case HTIF_CMD_NACK: - throw packet_error("nack!"); - default: - throw packet_error("illegal command " + std::to_string(p.get_header().cmd)); - } - read_buf.erase(read_buf.begin(), read_buf.begin() + hdr.get_packet_size()); - return p; - } - } - size_t old_size = read_buf.size(); - size_t max_size = sizeof(packet_header_t) + chunk_max_size(); - read_buf.resize(old_size + max_size); - ssize_t this_size = this->read(&read_buf[old_size], max_size); - if (this_size < 0) - throw io_error("read failed"); - read_buf.resize(old_size + this_size); - } -} - -void htif_t::write_packet(const packet_t& p) -{ - for (size_t pos = 0; pos < p.get_size(); ) - { - ssize_t bytes = this->write(p.get_packet() + pos, p.get_size() - pos); - if (bytes < 0) - throw io_error("write failed"); - pos += bytes; - } -} - void htif_t::start() { - assert(!started); - started = true; - config_string = read_config_string(mem.read_uint32(CONFIG_STRING_ADDR)); if (!targs.empty() && targs[0] != "none") @@ -188,15 +124,6 @@ void htif_t::load_program() } } -void htif_t::reset() -{ - for (uint32_t i = 0; i < num_cores(); i++) - { - write_cr(i, CSR_MRESET, 1); - write_cr(i, CSR_MRESET, 0); - } -} - void htif_t::stop() { if (!sig_file.empty() && sig_len) // print final torture test signature @@ -219,73 +146,15 @@ void htif_t::stop() sigs.close(); } - - for (uint32_t i = 0, nc = num_cores(); i < nc; i++) - write_cr(i, CSR_MRESET, 1); - - stopped = true; -} - -void htif_t::read_chunk(addr_t taddr, size_t len, void* dst) -{ - assert(taddr % chunk_align() == 0); - assert(len % chunk_align() == 0 && len <= chunk_max_size()); - - packet_header_t hdr(HTIF_CMD_READ_MEM, seqno, - len/HTIF_DATA_ALIGN, taddr/HTIF_DATA_ALIGN); - write_packet(hdr); - packet_t resp = read_packet(seqno); - seqno++; - - memcpy(dst, resp.get_payload(), len); } -void htif_t::write_chunk(addr_t taddr, size_t len, const void* src) +void htif_t::clear_chunk(addr_t taddr, size_t len) { - assert(taddr % chunk_align() == 0); - assert(len % chunk_align() == 0 && len <= chunk_max_size()); - - bool nonzero = started || !assume0init(); - for (size_t i = 0; i < len && !nonzero; i++) - nonzero |= ((uint8_t*)src)[i] != 0; - - if (nonzero) - { - packet_header_t hdr(HTIF_CMD_WRITE_MEM, seqno, - len/HTIF_DATA_ALIGN, taddr/HTIF_DATA_ALIGN); - write_packet(packet_t(hdr, src, len)); - read_packet(seqno); - seqno++; - } -} - -reg_t htif_t::read_cr(uint32_t coreid, uint16_t regnum) -{ - reg_t addr = (reg_t)coreid << 20 | regnum; - packet_header_t hdr(HTIF_CMD_READ_CONTROL_REG, seqno, 1, addr); - write_packet(hdr); - - packet_t resp = read_packet(seqno); - seqno++; - - reg_t val; - assert(resp.get_payload_size() == sizeof(reg_t)); - memcpy(&val, resp.get_payload(), sizeof(reg_t)); - return val; -} - -reg_t htif_t::write_cr(uint32_t coreid, uint16_t regnum, reg_t val) -{ - reg_t addr = (reg_t)coreid << 20 | regnum; - packet_header_t hdr(HTIF_CMD_WRITE_CONTROL_REG, seqno, 1, addr); - write_packet(packet_t(hdr, &val, sizeof(val))); - - packet_t resp = read_packet(seqno); - seqno++; + char zeros[chunk_max_size()]; + memset(zeros, 0, chunk_max_size()); - assert(resp.get_payload_size() == sizeof(reg_t)); - memcpy(&val, resp.get_payload(), sizeof(reg_t)); - return val; + for (size_t pos = 0; pos < len; pos += chunk_max_size()) + write_chunk(taddr + pos, std::min(len - pos, chunk_max_size()), zeros); } int htif_t::run() @@ -306,6 +175,8 @@ int htif_t::run() mem.write_uint64(tohost_addr, 0); command_t cmd(this, tohost, fromhost_callback); device_list.handle_command(cmd); + } else { + idle(); } device_list.tick(); @@ -356,7 +227,7 @@ uint32_t htif_t::num_cores() bool htif_t::done() { - return stopped; + return exitcode & 1; } int htif_t::exit_code() diff --git a/fesvr/htif.h b/fesvr/htif.h index 8db4584..5c0f0cc 100644 --- a/fesvr/htif.h +++ b/fesvr/htif.h @@ -22,59 +22,46 @@ class htif_t bool done(); int exit_code(); - virtual reg_t read_cr(uint32_t coreid, uint16_t regnum); - virtual reg_t write_cr(uint32_t coreid, uint16_t regnum, reg_t val); - virtual memif_t& memif() { return mem; } virtual uint32_t num_cores(); protected: - virtual void read_chunk(addr_t taddr, size_t len, void* dst); - virtual void write_chunk(addr_t taddr, size_t len, const void* src); + virtual void reset() = 0; + + virtual void read_chunk(addr_t taddr, size_t len, void* dst) = 0; + virtual void write_chunk(addr_t taddr, size_t len, const void* src) = 0; + virtual void clear_chunk(addr_t taddr, size_t len); virtual size_t chunk_align() = 0; virtual size_t chunk_max_size() = 0; - virtual bool assume0init() { return false; } - virtual ssize_t read(void* buf, size_t max_size) = 0; - virtual ssize_t write(const void* buf, size_t size) = 0; + virtual void load_program(); + virtual void idle() {} const std::vector& host_args() { return hargs; } - int exitcode; - - virtual void load_program(); - virtual void reset(); - std::string read_config_string(reg_t addr); std::string config_string; private: memif_t mem; bool writezeros; - seqno_t seqno; - bool started; - bool stopped; uint32_t _num_cores; std::vector hargs; std::vector targs; std::string sig_file; - std::string chroot; addr_t sig_addr; // torture addr_t sig_len; // torture addr_t tohost_addr; addr_t fromhost_addr; + int exitcode; device_list_t device_list; syscall_t syscall_proxy; bcd_t bcd; std::vector dynamic_devices; - std::vector read_buf; - virtual packet_t read_packet(seqno_t expected_seqno); - virtual void write_packet(const packet_t& packet); - - void set_chroot(const char* where); const std::vector& target_args() { return targs; } + std::string read_config_string(reg_t addr); friend class memif_t; friend class syscall_t; diff --git a/fesvr/htif_eth.cc b/fesvr/htif_eth.cc deleted file mode 100644 index 7dee247..0000000 --- a/fesvr/htif_eth.cc +++ /dev/null @@ -1,281 +0,0 @@ -// See LICENSE for license details. - -#include "htif_eth.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __APPLE__ -#include -#endif - -#define debug(...) -//#define debug(...) fprintf(stderr,__VA_ARGS__) - -struct eth_packet_t -{ - char dst_mac[6]; - char src_mac[6]; - unsigned short ethertype; - short pad; - packet_header_t htif_header; - char htif_payload[ETH_MAX_DATA_SIZE]; -}; - -htif_eth_t::htif_eth_t(const std::vector& args) - : htif_t(args), rtlsim(false) -{ - std::string mac_str = "feedfacebeef"; -#ifdef __linux__ - std::string interface = "eth0"; -#elif __APPLE__ - std::string interface = "en0"; -#elif __FreeBSD__ - std::string interface = "em0"; -#endif - for (std::vector::const_iterator a = host_args().begin(); a != host_args().end(); ++a) - { - if (a->substr(0, 4) == "+if=") - interface = a->substr(4); - if (a->substr(0, 5) == "+mac=") - mac_str = a->substr(5), assert(mac_str.length() == 2*sizeof(dst_mac)); - if (*a == "+sim") - rtlsim = true; - } - - #define hexval(c) ((c) >= 'a' ? (c)-'a'+10 : (c) >= 'A' ? (c)-'A'+10 : (c)-'0') - for (size_t i = 0; i < sizeof(dst_mac); i++) - dst_mac[i] = hexval(mac_str[2*i]) << 4 | hexval(mac_str[2*i+1]); - #undef hexval - -#ifdef __linux__ - if(rtlsim) - { - struct sockaddr_un vs_addr, appserver_addr; - - // unlink should fail if nothing is wrong. - std::string client_path = interface + "client"; - if (unlink(client_path.c_str()) == 0) - printf("Warning: removing existing unix domain socket %s\n", client_path.c_str()); - - // Create the socket. - sock = socket(AF_UNIX, SOCK_DGRAM, 0); - - if (sock < 0) - throw std::runtime_error("socket() failed: client unix domain socket"); - - //setup socket address - memset(&vs_addr, 0, sizeof(vs_addr)); - memset(&appserver_addr, 0, sizeof(appserver_addr)); - - vs_addr.sun_family = AF_UNIX; - strcpy(vs_addr.sun_path, interface.c_str()); - - appserver_addr.sun_family = AF_UNIX; - strcpy(appserver_addr.sun_path, client_path.c_str()); - - //bind to client address - if (bind(sock, (struct sockaddr*)&appserver_addr, sizeof(appserver_addr))<0) - { - perror("bind appserver"); - abort(); - } - - if (connect(sock, (struct sockaddr *)&vs_addr, sizeof(vs_addr)) < 0) - throw std::runtime_error("connect() failed: client unix domain socket"); - } - else - { - // setuid root to open a raw socket. - if (seteuid(0) != 0) - throw std::runtime_error("couldn't setuid root"); - - if ((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) - throw std::runtime_error("socket() failed!"); - - if (seteuid(getuid()) != 0) - throw std::runtime_error("couldn't setuid away from root"); - - // get MAC address of local ethernet device - struct ifreq ifr; - strcpy(ifr.ifr_name, interface.c_str()); - if(ioctl(sock, SIOCGIFHWADDR, (char*)&ifr) == -1) - throw std::runtime_error("ioctl() failed!"); - memcpy(&src_mac, &ifr.ifr_ifru.ifru_hwaddr.sa_data, sizeof(src_mac)); - - memset(&src_addr, 0, sizeof(src_addr)); - src_addr.sll_ifindex = if_nametoindex(interface.c_str()); - src_addr.sll_family = AF_PACKET; - - if(bind(sock, (struct sockaddr *)&src_addr, sizeof(src_addr)) == -1) - throw std::runtime_error("bind() failed!"); - - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 50000; - if(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(struct timeval)) == -1) - throw std::runtime_error("setsockopt() failed!"); - } -#elif __APPLE__ - assert(!rtlsim); - - char buf[11]; - for (int i = 0; i < 4; i++) { - sprintf(buf, "/dev/bpf%i", i); - if ((sock = open(buf, O_RDWR)) != -1) - break; - } - if (sock < 0) - throw std::runtime_error("open() failed!"); - - ifaddrs *ifaddr, *ifa; - if (getifaddrs(&ifaddr) == -1) - throw std::runtime_error("getifaddrs() failed"); - for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) - { - if (interface == ifa->ifa_name && ifa->ifa_addr->sa_family == AF_LINK) - { - memcpy(src_mac, LLADDR((sockaddr_dl*)ifa->ifa_addr), sizeof(src_mac)); - break; - } - } - if (ifa == NULL) - throw std::runtime_error("could not locate interface"); - freeifaddrs(ifaddr); - - struct ifreq bound_if; - strcpy(bound_if.ifr_name, interface.c_str()); - if (ioctl(sock, BIOCSETIF, &bound_if) == -1) - throw std::runtime_error("Failed to bind to interface!"); - - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 50000; - if (ioctl(sock, BIOCSRTIMEOUT, &tv) == -1) - throw std::runtime_error("couldn't set socket timeout!"); - - int enable = 1; - if (ioctl(sock, BIOCIMMEDIATE, &enable) == -1) - throw std::runtime_error("setting immediate mode failed!"); - if (ioctl(sock, BIOCGBLEN, &buffer_len) == -1) - throw std::runtime_error("cannot get buffer length!"); -#endif -} - -htif_eth_t::~htif_eth_t() -{ - close(sock); -} - -ssize_t htif_eth_t::read(void* buf, size_t max_size) -{ - ssize_t bytes; - - for(int timeouts = 0; timeouts < 3; ) - { - #ifdef __linux__ - eth_packet_t packet; - - if((bytes = ::read(sock, (char*)&packet, sizeof(packet))) == -1) - { - timeouts++; - debug("read failed (%s)\n",strerror(errno)); - continue; - } - - if (packet.ethertype != htons(HTIF_ETHERTYPE)) - continue; - if (memcmp(packet.dst_mac, src_mac, ETHER_ADDR_LEN)) - continue; - - bytes -= 16; //offsetof(eth_header_t, htif_header) - bytes = std::min(bytes, (ssize_t)(sizeof(packet_header_t) + HTIF_DATA_ALIGN*packet.htif_header.data_size)); - bytes = std::min(bytes, (ssize_t)max_size); - memcpy(buf, &packet.htif_header, bytes); - - debug("read packet\n"); - for(ssize_t i = 0; i < bytes; i++) - debug("%02x ",((unsigned char*)buf)[i]); - debug("\n"); - - return bytes; - #elif __APPLE__ - uint8_t buffer[buffer_len]; - if ((bytes = ::read(sock, buffer, buffer_len)) == -1) { - timeouts++; - debug("read failed (%s)\n",strerror(errno)); - continue; - } - uint8_t* bufp = buffer; - - while (bufp < buffer + bytes) { - struct bpf_hdr *hdr = (struct bpf_hdr *) bufp; - eth_packet_t* packet = (eth_packet_t*)(bufp + hdr->bh_hdrlen); - bufp += BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen); - assert(hdr->bh_caplen == hdr->bh_datalen); - - if (packet->ethertype != htons(HTIF_ETHERTYPE)) - continue; - if (memcmp(packet->dst_mac, src_mac, ETHER_ADDR_LEN)) - continue; - - bytes = hdr->bh_caplen; - bytes -= 16; //offsetof(eth_header_t, htif_header) - bytes = std::min(bytes, (ssize_t)sizeof(packet_header_t) + HTIF_DATA_ALIGN*packet->htif_header.data_size); - bytes = std::min(bytes, (ssize_t)max_size); - memcpy(buf, &packet->htif_header, bytes); - - debug("read packet\n"); - for(ssize_t i = 0; i < bytes; i++) - debug("%02x ",((unsigned char*)buf)[i]); - debug("\n"); - - return bytes; - } - #endif - } - - return -1; -} - -ssize_t htif_eth_t::write(const void* buf, size_t size) -{ - debug("write packet\n"); - for(size_t i = 0; i < size; i++) - debug("%02x ",((const unsigned char*)buf)[i]); - debug("\n"); - - eth_packet_t eth_packet; - memcpy(eth_packet.dst_mac, dst_mac, sizeof(dst_mac)); - memcpy(eth_packet.src_mac, src_mac, sizeof(src_mac)); - eth_packet.ethertype = htons(HTIF_ETHERTYPE); - eth_packet.pad = 0; - memcpy(ð_packet.htif_header, buf, size); - size += 16; //offsetof(eth_packet_t, htif_header) - - #ifdef __linux__ - if(rtlsim) - return ::write(sock, (char*)ð_packet, size); - else - return ::sendto(sock, (char*)ð_packet, size, 0, - (sockaddr*)&src_addr, sizeof(src_addr)); - #elif __APPLE__ - if (rtlsim) - return -1; - else - return ::write(sock, (char*)ð_packet, size); - #endif -} diff --git a/fesvr/htif_eth.h b/fesvr/htif_eth.h deleted file mode 100644 index c4fdf46..0000000 --- a/fesvr/htif_eth.h +++ /dev/null @@ -1,53 +0,0 @@ -// See LICENSE for license details. - -#ifndef __HTIF_ETH_H -#define __HTIF_ETH_H - -#include "htif.h" -#include - -#include -#ifdef __linux__ -#include -typedef struct sockaddr_ll sockaddr_ll_t; -#elif __APPLE__ || __FreeBSD__ -#include -#include -#include -#include -#if __APPLE__ -#include -#endif -typedef struct sockaddr sockaddr_ll_t; -#else -# error unsupported OS -#endif - -const size_t ETH_DATA_ALIGN = 64; -const size_t ETH_MAX_DATA_SIZE = 1472; // largest multiple of 64 <= MTU -const unsigned short HTIF_ETHERTYPE = 0x8888; - -class htif_eth_t : public htif_t -{ -public: - htif_eth_t(const std::vector& args); - virtual ~htif_eth_t(); - - size_t chunk_align() { return ETH_DATA_ALIGN; } - size_t chunk_max_size() { return ETH_MAX_DATA_SIZE; } - -protected: - ssize_t read(void* buf, size_t max_size); - ssize_t write(const void* buf, size_t size); - - int sock; - sockaddr_ll_t src_addr; - char src_mac[6]; - char dst_mac[6]; - - bool rtlsim; - - int buffer_len; -}; - -#endif // __HTIF_ETH_H diff --git a/fesvr/htif_hexwriter.h b/fesvr/htif_hexwriter.h index 3f6d9b7..29ebf1d 100644 --- a/fesvr/htif_hexwriter.h +++ b/fesvr/htif_hexwriter.h @@ -23,9 +23,7 @@ class htif_hexwriter_t : public htif_t size_t chunk_max_size() { return width; } size_t chunk_align() { return width; } - - ssize_t read(void* buf, size_t max_size) { abort(); } - ssize_t write(const void* buf, size_t max_size) { abort(); } + void reset() {} friend std::ostream& operator<< (std::ostream&, const htif_hexwriter_t&); }; diff --git a/fesvr/htif_rs232.cc b/fesvr/htif_rs232.cc deleted file mode 100644 index 58e0959..0000000 --- a/fesvr/htif_rs232.cc +++ /dev/null @@ -1,64 +0,0 @@ -// See LICENSE for license details. - -#include "htif_rs232.h" -#include -#include -#include -#include -#include -#include -#include - -#define debug(...) -//#define debug(...) fprintf(stderr,__VA_ARGS__) - -htif_rs232_t::htif_rs232_t(const std::vector& args) - : htif_t(args) -{ - std::string tty; - for (std::vector::const_iterator a = host_args().begin(); a != host_args().end(); ++a) - if (a->substr(0, 4) == "+if=") - tty = a->substr(4); - assert(tty.length()); - - debug("opening %s\n",tty); - fd = open(tty.c_str(), O_RDWR|O_NOCTTY); - assert(fd != -1); - - struct termios tio; - memset(&tio,0,sizeof(tio)); - - tio.c_cflag = B9600; - tio.c_iflag = IGNPAR; - tio.c_oflag = 0; - tio.c_lflag = 0; - tio.c_cc[VTIME] = 0; - tio.c_cc[VMIN] = 1; // read in 8 byte chunks - - tcflush(fd, TCIOFLUSH); - tcsetattr(fd, TCSANOW, &tio); -} - -htif_rs232_t::~htif_rs232_t() -{ - close(fd); -} - -ssize_t htif_rs232_t::read(void* buf, size_t max_size) -{ - // XXX this is untested! - ssize_t bytes = sizeof(packet_header_t); - for (ssize_t i = 0; i < bytes; i++) - { - if (::read(fd, (char*)buf + i, 1) != 1) - return -1; - if (i == sizeof(packet_header_t)-1) - bytes += ((packet_header_t*)buf)->data_size; - } - return bytes; -} - -ssize_t htif_rs232_t::write(const void* buf, size_t size) -{ - return ::write(fd, buf, size); -} diff --git a/fesvr/htif_rs232.h b/fesvr/htif_rs232.h deleted file mode 100644 index 78ef971..0000000 --- a/fesvr/htif_rs232.h +++ /dev/null @@ -1,26 +0,0 @@ -// See LICENSE for license details. - -#ifndef __HTIF_RS232_H -#define __HTIF_RS232_H - -#include "htif.h" -#include - -class htif_rs232_t : public htif_t -{ - public: - htif_rs232_t(const std::vector& args); - ~htif_rs232_t(); - - protected: - ssize_t read(void* buf, size_t max_size); - ssize_t write(const void* buf, size_t size); - - size_t chunk_max_size() { return 64; } - size_t chunk_align() { return 64; } - - private: - int fd; -}; - -#endif // __HTIF_RS232_H diff --git a/fesvr/htif_zedboard.cc b/fesvr/htif_zedboard.cc deleted file mode 100644 index 6dcb2be..0000000 --- a/fesvr/htif_zedboard.cc +++ /dev/null @@ -1,58 +0,0 @@ -// See LICENSE for license details. - -#include "htif_zedboard.h" -#include -#include -#include -#include -#include - -#define read_reg(r) (dev_vaddr[r]) -#define write_reg(r, v) (dev_vaddr[r] = v) - -htif_zedboard_t::htif_zedboard_t(const std::vector& args) - : htif_t(args) -{ - int fd = open("/dev/mem", O_RDWR|O_SYNC); - assert(fd != -1); - dev_vaddr = (uintptr_t*)mmap(0, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, dev_paddr); - assert(dev_vaddr != MAP_FAILED); - write_reg(31, 0); // reset -} - -htif_zedboard_t::~htif_zedboard_t() -{ -} - -ssize_t htif_zedboard_t::write(const void* buf, size_t size) -{ -// printf("htif_zedboard_t::write(buf, size = %u\n", size); - const uint32_t* x = (const uint32_t*)buf; - assert(size >= sizeof(*x)); - - for (uint32_t i = 0; i < size/sizeof(*x); i++) - write_reg(0, x[i]); -// printf("htif_zedboard_t::write() returning\n"); -// return sizeof(*x); - return size; -} - -ssize_t htif_zedboard_t::read(void* buf, size_t max_size) -{ -// printf("htif_zedboard_t::read(buf, max_size = %u\n", max_size); - uint32_t* x = (uint32_t*)buf; - assert(max_size >= sizeof(*x)); - - // fifo data counter - uintptr_t c = read_reg(0); - uint32_t count = 0; - if (c > 0) - { -// printf("htif_zedboard_t::read() read_reg(0) returned %u\n", c); - for (count=0; count - -class htif_zedboard_t : public htif_t -{ - public: - htif_zedboard_t(const std::vector& args); - ~htif_zedboard_t(); - - protected: - ssize_t read(void* buf, size_t max_size); - ssize_t write(const void* buf, size_t size); - - size_t chunk_max_size() { return 64; } - size_t chunk_align() { return 64; } - - private: - volatile uintptr_t* dev_vaddr; - - const static uintptr_t dev_paddr = 0x43C00000; -}; - -#endif // __HTIF_ZEDBOARD_H diff --git a/fesvr/memif.cc b/fesvr/memif.cc index aa72ee4..1115ffb 100644 --- a/fesvr/memif.cc +++ b/fesvr/memif.cc @@ -1,36 +1,5 @@ // See LICENSE for license details. -/* Author: Andrew S. Waterman - * Parallel Computing Laboratory - * Electrical Engineering and Computer Sciences - * University of California, Berkeley - * - * Copyright (c) 2010, The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the University of California, Berkeley nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS ''AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE REGENTS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - #include #include #include @@ -101,9 +70,17 @@ void memif_t::write(addr_t addr, size_t len, const void* bytes) } // now we're aligned - size_t max_chunk = htif->chunk_max_size(); - for (size_t pos = 0; pos < len; pos += max_chunk) - htif->write_chunk(addr + pos, std::min(max_chunk, len - pos), (char*)bytes + pos); + bool all_zero = len != 0; + for (size_t i = 0; i < len; i++) + all_zero &= ((const char*)bytes)[i] == 0; + + if (all_zero) { + htif->clear_chunk(addr, len); + } else { + size_t max_chunk = htif->chunk_max_size(); + for (size_t pos = 0; pos < len; pos += max_chunk) + htif->write_chunk(addr + pos, std::min(max_chunk, len - pos), (char*)bytes + pos); + } } #define MEMIF_READ_FUNC \ diff --git a/fesvr/memif.h b/fesvr/memif.h index e91a540..706b46c 100644 --- a/fesvr/memif.h +++ b/fesvr/memif.h @@ -1,42 +1,14 @@ // See LICENSE for license details. -/* Author: Andrew S. Waterman - * Parallel Computing Laboratory - * Electrical Engineering and Computer Sciences - * University of California, Berkeley - * - * Copyright (c) 2010, The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the University of California, Berkeley nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS ''AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE REGENTS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - #ifndef __MEMIF_H #define __MEMIF_H -#include "packet.h" #include -#include +#include + +typedef uint64_t reg_t; +typedef int64_t sreg_t; +typedef reg_t addr_t; class htif_t; class memif_t diff --git a/fesvr/packet.cc b/fesvr/packet.cc deleted file mode 100644 index cc0710c..0000000 --- a/fesvr/packet.cc +++ /dev/null @@ -1,49 +0,0 @@ -// See LICENSE for license details. - -#include "packet.h" -#include - -packet_t::packet_t(const packet_header_t& hdr) - : header(hdr) -{ - init(NULL, 0); -} - -packet_t::packet_t(const void* pkt) - : header(pkt) -{ - init((char*)pkt + sizeof(header), get_payload_size()); -} - -packet_t::packet_t(const packet_t& p) - : header(p.header) -{ - init(p.get_payload(), get_payload_size()); -} - -packet_t::packet_t(const packet_header_t& hdr, const void* payload, size_t paysize) - : header(hdr) -{ - init(payload, paysize); -} - -void packet_t::init(const void* pay, size_t paysize) -{ - if (paysize != get_payload_size()) - throw packet_error("bad payload paysize"); - - if (paysize) - { - packet = new uint8_t[sizeof(header) + paysize]; - memcpy(packet, &header, sizeof(header)); - memcpy((char*)packet + sizeof(header), pay, paysize); - } - else - packet = (uint8_t*)&header; -} - -packet_t::~packet_t() -{ - if (packet != (uint8_t*)&header) - delete [] packet; -} diff --git a/fesvr/packet.h b/fesvr/packet.h deleted file mode 100644 index fe9b30b..0000000 --- a/fesvr/packet.h +++ /dev/null @@ -1,91 +0,0 @@ -// See LICENSE for license details. - -#ifndef __HTIF_PACKET_H -#define __HTIF_PACKET_H - -#include -#include -#include -#include -#include - -enum -{ - HTIF_CMD_READ_MEM, - HTIF_CMD_WRITE_MEM, - HTIF_CMD_READ_CONTROL_REG, - HTIF_CMD_WRITE_CONTROL_REG, - HTIF_CMD_ACK, - HTIF_CMD_NACK, -}; - -#define HTIF_DATA_ALIGN 8U - -typedef uint8_t seqno_t; -typedef uint64_t reg_t; -typedef int64_t sreg_t; -typedef reg_t addr_t; - -struct packet_header_t -{ - reg_t cmd : 4; - reg_t data_size : 12; - reg_t seqno : 8; - reg_t addr : 40; - - packet_header_t() - : cmd(0), data_size(0), seqno(0), addr(0) {} - packet_header_t(reg_t c, seqno_t s, reg_t ds, addr_t a) - : cmd(c), data_size(ds), seqno(s), addr(a) {} - packet_header_t(const void* buf) - { - memcpy(this, buf, sizeof(*this)); - } - size_t get_payload_size() const - { - if (cmd == HTIF_CMD_READ_MEM || cmd == HTIF_CMD_READ_CONTROL_REG) - return 0; - return data_size * HTIF_DATA_ALIGN; - } - size_t get_packet_size() const { return sizeof(*this) + get_payload_size(); } -}; - -class packet_t -{ - public: - packet_t(const packet_header_t& hdr); - packet_t(const packet_header_t& hdr, const void* payload, size_t paysize); - packet_t(const void* packet); - packet_t(const packet_t& p); - ~packet_t(); - - packet_header_t get_header() const { return header; } - const uint8_t* get_payload() const { return packet + sizeof(header); } - size_t get_size() const { return header.get_packet_size(); } - const uint8_t* get_packet() const { return packet; } - size_t get_payload_size() const { return header.get_payload_size(); } - - private: - packet_header_t header; - uint8_t* packet; - - void init(const void* payload, size_t payload_size); -}; - -class packet_error : public std::runtime_error -{ -public: - packet_error(const std::string& s) : std::runtime_error(s) {} -}; -class bad_seqno_error : public packet_error -{ -public: - bad_seqno_error() : packet_error("bad seqno") {} -}; -class io_error : public packet_error -{ -public: - io_error(const std::string& s) : packet_error(s) {} -}; - -#endif diff --git a/fesvr/rfb.h b/fesvr/rfb.h index 31cee1e..263663a 100644 --- a/fesvr/rfb.h +++ b/fesvr/rfb.h @@ -2,10 +2,9 @@ #define _RFB_H #include "device.h" +#include "memif.h" #include -class memif_t; - // remote frame buffer class rfb_t : public device_t { diff --git a/fesvr/syscall.cc b/fesvr/syscall.cc index f4c9c17..49d43b2 100644 --- a/fesvr/syscall.cc +++ b/fesvr/syscall.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -85,18 +86,18 @@ syscall_t::syscall_t(htif_t* htif) std::string syscall_t::do_chroot(const char* fn) { - if (!htif->chroot.empty() && *fn == '/') - return htif->chroot + fn; + if (!chroot.empty() && *fn == '/') + return chroot + fn; return fn; } std::string syscall_t::undo_chroot(const char* fn) { - if (htif->chroot.empty()) + if (chroot.empty()) return fn; - if (strncmp(fn, htif->chroot.c_str(), htif->chroot.size()) == 0 - && (htif->chroot.back() == '/' || fn[htif->chroot.size()] == '/')) - return fn + htif->chroot.size() - (htif->chroot.back() == '/'); + if (strncmp(fn, chroot.c_str(), chroot.size()) == 0 + && (chroot.back() == '/' || fn[chroot.size()] == '/')) + return fn + chroot.size() - (chroot.back() == '/'); return "/"; } @@ -375,3 +376,19 @@ int fds_t::lookup(reg_t fd) return AT_FDCWD; return fd >= fds.size() ? -1 : fds[fd]; } + +void syscall_t::set_chroot(const char* where) +{ + char buf1[PATH_MAX], buf2[PATH_MAX]; + + if (getcwd(buf1, sizeof(buf1)) == NULL + || chdir(where) != 0 + || getcwd(buf2, sizeof(buf2)) == NULL + || chdir(buf1) != 0) + { + fprintf(stderr, "could not chroot to %s\n", chroot.c_str()); + exit(-1); + } + + chroot = buf2; +} diff --git a/fesvr/syscall.h b/fesvr/syscall.h index da82a9f..8294696 100644 --- a/fesvr/syscall.h +++ b/fesvr/syscall.h @@ -4,9 +4,9 @@ #define __SYSCALL_H #include "device.h" +#include "memif.h" #include #include -#include class syscall_t; typedef reg_t (syscall_t::*syscall_func_t)(reg_t, reg_t, reg_t, reg_t, reg_t, reg_t, reg_t); @@ -28,6 +28,8 @@ class syscall_t : public device_t { public: syscall_t(htif_t*); + + void set_chroot(const char* where); private: const char* identity() { return "syscall_proxy"; } @@ -39,6 +41,8 @@ class syscall_t : public device_t void handle_syscall(command_t cmd); void dispatch(addr_t mm); + + std::string chroot; std::string do_chroot(const char* fn); std::string undo_chroot(const char* fn);