riscv_htif.c (65cc5ccf06a74c98de73ec683d9a543baa302a12) riscv_htif.c (66247edc8b6fb36d6b905babcd795068ea989ad5)
1/*
2 * QEMU RISC-V Host Target Interface (HTIF) Emulation
3 *
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2017-2018 SiFive, Inc.
6 *
7 * This provides HTIF device emulation for QEMU. At the moment this allows
8 * for identical copies of bbl/linux to run on both spike and QEMU.

--- 15 unchanged lines hidden (view full) ---

24#include "qapi/error.h"
25#include "qemu/log.h"
26#include "hw/char/riscv_htif.h"
27#include "hw/char/serial.h"
28#include "chardev/char.h"
29#include "chardev/char-fe.h"
30#include "qemu/timer.h"
31#include "qemu/error-report.h"
1/*
2 * QEMU RISC-V Host Target Interface (HTIF) Emulation
3 *
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2017-2018 SiFive, Inc.
6 *
7 * This provides HTIF device emulation for QEMU. At the moment this allows
8 * for identical copies of bbl/linux to run on both spike and QEMU.

--- 15 unchanged lines hidden (view full) ---

24#include "qapi/error.h"
25#include "qemu/log.h"
26#include "hw/char/riscv_htif.h"
27#include "hw/char/serial.h"
28#include "chardev/char.h"
29#include "chardev/char-fe.h"
30#include "qemu/timer.h"
31#include "qemu/error-report.h"
32#include "exec/address-spaces.h"
33#include "sysemu/dma.h"
32
33#define RISCV_DEBUG_HTIF 0
34#define HTIF_DEBUG(fmt, ...) \
35 do { \
36 if (RISCV_DEBUG_HTIF) { \
37 qemu_log_mask(LOG_TRACE, "%s: " fmt "\n", __func__, ##__VA_ARGS__);\
38 } \
39 } while (0)

--- 6 unchanged lines hidden (view full) ---

46
47#define HTIF_SYSTEM_CMD_SYSCALL 0
48#define HTIF_CONSOLE_CMD_GETC 0
49#define HTIF_CONSOLE_CMD_PUTC 1
50
51/* PK system call number */
52#define PK_SYS_WRITE 64
53
34
35#define RISCV_DEBUG_HTIF 0
36#define HTIF_DEBUG(fmt, ...) \
37 do { \
38 if (RISCV_DEBUG_HTIF) { \
39 qemu_log_mask(LOG_TRACE, "%s: " fmt "\n", __func__, ##__VA_ARGS__);\
40 } \
41 } while (0)

--- 6 unchanged lines hidden (view full) ---

48
49#define HTIF_SYSTEM_CMD_SYSCALL 0
50#define HTIF_CONSOLE_CMD_GETC 0
51#define HTIF_CONSOLE_CMD_PUTC 1
52
53/* PK system call number */
54#define PK_SYS_WRITE 64
55
54static uint64_t fromhost_addr, tohost_addr;
56const char *sig_file;
57uint8_t line_size = 16;
55
58
59static uint64_t fromhost_addr, tohost_addr, begin_sig_addr, end_sig_addr;
60
56void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
57 uint64_t st_size)
58{
59 if (strcmp("fromhost", st_name) == 0) {
60 fromhost_addr = st_value;
61 if (st_size != 8) {
62 error_report("HTIF fromhost must be 8 bytes");
63 exit(1);
64 }
65 } else if (strcmp("tohost", st_name) == 0) {
66 tohost_addr = st_value;
67 if (st_size != 8) {
68 error_report("HTIF tohost must be 8 bytes");
69 exit(1);
70 }
61void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
62 uint64_t st_size)
63{
64 if (strcmp("fromhost", st_name) == 0) {
65 fromhost_addr = st_value;
66 if (st_size != 8) {
67 error_report("HTIF fromhost must be 8 bytes");
68 exit(1);
69 }
70 } else if (strcmp("tohost", st_name) == 0) {
71 tohost_addr = st_value;
72 if (st_size != 8) {
73 error_report("HTIF tohost must be 8 bytes");
74 exit(1);
75 }
76 } else if (strcmp("begin_signature", st_name) == 0) {
77 begin_sig_addr = st_value;
78 } else if (strcmp("end_signature", st_name) == 0) {
79 end_sig_addr = st_value;
71 }
72}
73
74/*
75 * Called by the char dev to see if HTIF is ready to accept input.
76 */
77static int htif_can_recv(void *opaque)
78{

--- 79 unchanged lines hidden (view full) ---

158 * 1: Console
159 */
160 if (unlikely(device == HTIF_DEV_SYSTEM)) {
161 /* frontend syscall handler, shutdown and exit code support */
162 if (cmd == HTIF_SYSTEM_CMD_SYSCALL) {
163 if (payload & 0x1) {
164 /* exit code */
165 int exit_code = payload >> 1;
80 }
81}
82
83/*
84 * Called by the char dev to see if HTIF is ready to accept input.
85 */
86static int htif_can_recv(void *opaque)
87{

--- 79 unchanged lines hidden (view full) ---

167 * 1: Console
168 */
169 if (unlikely(device == HTIF_DEV_SYSTEM)) {
170 /* frontend syscall handler, shutdown and exit code support */
171 if (cmd == HTIF_SYSTEM_CMD_SYSCALL) {
172 if (payload & 0x1) {
173 /* exit code */
174 int exit_code = payload >> 1;
175
176 /*
177 * Dump signature data if sig_file is specified and
178 * begin/end_signature symbols exist.
179 */
180 if (sig_file && begin_sig_addr && end_sig_addr) {
181 uint64_t sig_len = end_sig_addr - begin_sig_addr;
182 char *sig_data = g_malloc(sig_len);
183 dma_memory_read(&address_space_memory, begin_sig_addr,
184 sig_data, sig_len, MEMTXATTRS_UNSPECIFIED);
185 FILE *signature = fopen(sig_file, "w");
186 if (signature == NULL) {
187 error_report("Unable to open %s with error %s",
188 sig_file, strerror(errno));
189 exit(1);
190 }
191
192 for (int i = 0; i < sig_len; i += line_size) {
193 for (int j = line_size; j > 0; j--) {
194 if (i + j <= sig_len) {
195 fprintf(signature, "%02x",
196 sig_data[i + j - 1] & 0xff);
197 } else {
198 fprintf(signature, "%02x", 0);
199 }
200 }
201 fprintf(signature, "\n");
202 }
203
204 fclose(signature);
205 g_free(sig_data);
206 }
207
166 exit(exit_code);
167 } else {
168 uint64_t syscall[8];
169 cpu_physical_memory_read(payload, syscall, sizeof(syscall));
170 if (syscall[0] == PK_SYS_WRITE &&
171 syscall[1] == HTIF_DEV_CONSOLE &&
172 syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
173 uint8_t ch;

--- 138 unchanged lines hidden ---
208 exit(exit_code);
209 } else {
210 uint64_t syscall[8];
211 cpu_physical_memory_read(payload, syscall, sizeof(syscall));
212 if (syscall[0] == PK_SYS_WRITE &&
213 syscall[1] == HTIF_DEV_CONSOLE &&
214 syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
215 uint8_t ch;

--- 138 unchanged lines hidden ---