1 // See LICENSE for license details. 2 3 #ifndef __HTIF_H 4 #define __HTIF_H 5 6 #include "memif.h" 7 #include "syscall.h" 8 #include "device.h" 9 #include "byteorder.h" 10 #include <string.h> 11 #include <map> 12 #include <vector> 13 #include <assert.h> 14 15 class htif_t : public chunked_memif_t 16 { 17 public: 18 htif_t(); 19 htif_t(int argc, char** argv); 20 htif_t(const std::vector<std::string>& args); 21 virtual ~htif_t(); 22 23 virtual void start(); 24 virtual void stop(); 25 26 int run(); 27 bool done(); 28 int exit_code(); 29 memif()30 virtual memif_t& memif() { return mem; } 31 from_target(target_endian<T> n)32 template<typename T> inline T from_target(target_endian<T> n) const 33 { 34 #ifdef RISCV_ENABLE_DUAL_ENDIAN 35 memif_endianness_t endianness = get_target_endianness(); 36 assert(endianness == memif_endianness_little || endianness == memif_endianness_big); 37 38 return endianness == memif_endianness_big? n.from_be() : n.from_le(); 39 #else 40 return n.from_le(); 41 #endif 42 } 43 to_target(T n)44 template<typename T> inline target_endian<T> to_target(T n) const 45 { 46 #ifdef RISCV_ENABLE_DUAL_ENDIAN 47 memif_endianness_t endianness = get_target_endianness(); 48 assert(endianness == memif_endianness_little || endianness == memif_endianness_big); 49 50 return endianness == memif_endianness_big? target_endian<T>::to_be(n) : target_endian<T>::to_le(n); 51 #else 52 return target_endian<T>::to_le(n); 53 #endif 54 } 55 56 protected: 57 virtual void reset() = 0; 58 59 virtual void read_chunk(addr_t taddr, size_t len, void* dst) = 0; 60 virtual void write_chunk(addr_t taddr, size_t len, const void* src) = 0; 61 virtual void clear_chunk(addr_t taddr, size_t len); 62 63 virtual size_t chunk_align() = 0; 64 virtual size_t chunk_max_size() = 0; 65 66 virtual std::map<std::string, uint64_t> load_payload(const std::string& payload, reg_t* entry); 67 virtual void load_program(); idle()68 virtual void idle() {} 69 host_args()70 const std::vector<std::string>& host_args() { return hargs; } 71 get_entry_point()72 reg_t get_entry_point() { return entry; } 73 74 // indicates that the initial program load can skip writing this address 75 // range to memory, because it has already been loaded through a sideband is_address_preloaded(addr_t taddr,size_t len)76 virtual bool is_address_preloaded(addr_t taddr, size_t len) { return false; } 77 78 // Given an address, return symbol from addr2symbol map 79 const char* get_symbol(uint64_t addr); 80 81 private: 82 void parse_arguments(int argc, char ** argv); 83 void register_devices(); 84 void usage(const char * program_name); 85 86 memif_t mem; 87 reg_t entry; 88 bool writezeros; 89 std::vector<std::string> hargs; 90 std::vector<std::string> targs; 91 std::string sig_file; 92 unsigned int line_size; 93 addr_t sig_addr; // torture 94 addr_t sig_len; // torture 95 addr_t tohost_addr; 96 addr_t fromhost_addr; 97 int exitcode; 98 bool stopped; 99 100 device_list_t device_list; 101 syscall_t syscall_proxy; 102 bcd_t bcd; 103 std::vector<device_t*> dynamic_devices; 104 std::vector<std::string> payloads; 105 target_args()106 const std::vector<std::string>& target_args() { return targs; } 107 108 std::map<uint64_t, std::string> addr2symbol; 109 110 friend class memif_t; 111 friend class syscall_t; 112 }; 113 114 /* Alignment guide for emulator.cc options: 115 -x, --long-option Description with max 80 characters --------------->\n\ 116 +plus-arg-equivalent\n\ 117 */ 118 #define HTIF_USAGE_OPTIONS \ 119 "HOST OPTIONS\n\ 120 -h, --help Display this help and exit\n\ 121 +h, +help\n\ 122 +permissive The host will ignore any unparsed options up until\n\ 123 +permissive-off (Only needed for VCS)\n\ 124 +permissive-off Stop ignoring options. This is mandatory if using\n\ 125 +permissive (Only needed for VCS)\n\ 126 --rfb=DISPLAY Add new remote frame buffer on display DISPLAY\n\ 127 +rfb=DISPLAY to be accessible on 5900 + DISPLAY (default = 0)\n\ 128 --signature=FILE Write torture test signature to FILE\n\ 129 +signature=FILE\n\ 130 --signature-granularity=VAL Size of each line in signature.\n\ 131 +signature-granularity=VAL\n\ 132 --chroot=PATH Use PATH as location of syscall-servicing binaries\n\ 133 +chroot=PATH\n\ 134 --payload=PATH Load PATH memory as an additional ELF payload\n\ 135 +payload=PATH\n\ 136 \n\ 137 HOST OPTIONS (currently unsupported)\n\ 138 --disk=DISK Add DISK device. Use a ramdisk since this isn't\n\ 139 +disk=DISK supported\n\ 140 \n\ 141 TARGET (RISC-V BINARY) OPTIONS\n\ 142 These are the options passed to the program executing on the emulated RISC-V\n\ 143 microprocessor.\n" 144 145 #define HTIF_LONG_OPTIONS_OPTIND 1024 146 #define HTIF_LONG_OPTIONS \ 147 {"help", no_argument, 0, 'h' }, \ 148 {"rfb", optional_argument, 0, HTIF_LONG_OPTIONS_OPTIND }, \ 149 {"disk", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 1 }, \ 150 {"signature", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 2 }, \ 151 {"chroot", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 3 }, \ 152 {"payload", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 4 }, \ 153 {"signature-granularity", optional_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 5 }, \ 154 {0, 0, 0, 0} 155 156 #endif // __HTIF_H 157