> compile NEMU
ysyx_22040000 李心杨 Linux calcite 6.1.75 #1-NixOS SMP PREEMPT_DYNAMIC Thu Jan 25 23:27:52 UTC 2024 x86_64 GNU/Linux 20:46:44 up 6:22, 2 users, load average: 0.45, 0.42, 0.45
This commit is contained in:
parent
3a604683b0
commit
3d280fbe0b
3 changed files with 85 additions and 70 deletions
|
@ -48,4 +48,6 @@
|
||||||
|
|
||||||
#define TODO() panic("please implement me")
|
#define TODO() panic("please implement me")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,6 +31,7 @@ static uint64_t g_timer = 0; // unit: us
|
||||||
static bool g_print_step = false;
|
static bool g_print_step = false;
|
||||||
|
|
||||||
void device_update();
|
void device_update();
|
||||||
|
void wp_eval_all();
|
||||||
|
|
||||||
static void trace_and_difftest(Decode *_this, vaddr_t dnpc) {
|
static void trace_and_difftest(Decode *_this, vaddr_t dnpc) {
|
||||||
#ifdef CONFIG_ITRACE_COND
|
#ifdef CONFIG_ITRACE_COND
|
||||||
|
@ -113,6 +114,8 @@ void cpu_exec(uint64_t n) {
|
||||||
uint64_t timer_end = get_time();
|
uint64_t timer_end = get_time();
|
||||||
g_timer += timer_end - timer_start;
|
g_timer += timer_end - timer_start;
|
||||||
|
|
||||||
|
wp_eval_all();
|
||||||
|
|
||||||
switch (nemu_state.state) {
|
switch (nemu_state.state) {
|
||||||
case NEMU_RUNNING: nemu_state.state = NEMU_STOP; break;
|
case NEMU_RUNNING: nemu_state.state = NEMU_STOP; break;
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
***************************************************************************************/
|
***************************************************************************************/
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "sdb.h"
|
#include "sdb.h"
|
||||||
|
#include <common.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define NR_WP 32
|
#define NR_WP 32
|
||||||
|
@ -27,8 +27,8 @@ typedef struct watchpoint {
|
||||||
} WP;
|
} WP;
|
||||||
|
|
||||||
static WP wp_pool[NR_WP] = {};
|
static WP wp_pool[NR_WP] = {};
|
||||||
static WP *head = NULL, *tail = NULL, *free_ = NULL;
|
static WP *head = NULL, *free_ = NULL;
|
||||||
static int wp_count = 0;
|
// static int wp_count = 0;
|
||||||
|
|
||||||
void init_wp_pool() {
|
void init_wp_pool() {
|
||||||
int i;
|
int i;
|
||||||
|
@ -41,77 +41,87 @@ void init_wp_pool() {
|
||||||
free_ = wp_pool;
|
free_ = wp_pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
WP *wp_new() {
|
// static WP *wp_new() {
|
||||||
if (free_ == NULL) {
|
// if (free_ == NULL) {
|
||||||
Error("wp_pool: Watchpoint pool not initialized or is full.");
|
// Error("wp_pool: Watchpoint pool not initialized or is full.");
|
||||||
return NULL;
|
// return NULL;
|
||||||
}
|
// }
|
||||||
|
|
||||||
WP *ret = free_;
|
// WP *ret = free_;
|
||||||
free_ = free_->next;
|
// free_ = free_->next;
|
||||||
|
|
||||||
ret->NO = 0;
|
// ret->NO = 0;
|
||||||
ret->next = NULL;
|
// ret->next = NULL;
|
||||||
return ret;
|
// return ret;
|
||||||
}
|
|
||||||
|
|
||||||
void wp_delete(WP *wp) {
|
|
||||||
assert(wp);
|
|
||||||
wp->next = free_;
|
|
||||||
free_ = wp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wp_add(char * expr) {
|
|
||||||
WP *wp = wp_new();
|
|
||||||
if (wp == NULL) {
|
|
||||||
Error("watchpoint: Failed to add watchpoint, pool is full.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
wp->NO = wp_count++;
|
|
||||||
if (tail == NULL) {
|
|
||||||
head = wp;
|
|
||||||
tail = wp;
|
|
||||||
} else {
|
|
||||||
tail->next = wp;
|
|
||||||
tail = wp;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wp_remove_by_number(int number) {
|
|
||||||
WP *target_prev;
|
|
||||||
// Find previous node of target number
|
|
||||||
for (target_prev = head; target_prev != NULL && target_prev->next->NO != number; target_prev = target_prev->next) ;
|
|
||||||
if (target_prev == NULL) {
|
|
||||||
Error("Watchpoint not found, you can check current watchpoints with `info w`");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
WP *target = target_prev->next;
|
|
||||||
target_prev->next = target->next;
|
|
||||||
if (target == head) {
|
|
||||||
head = target->next;
|
|
||||||
} else if (target == tail) {
|
|
||||||
tail = target_prev;
|
|
||||||
}
|
|
||||||
wp_delete(target);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// int wp_eval(WP* wp) {
|
|
||||||
// bool success = false;
|
|
||||||
// word_t result;
|
|
||||||
|
|
||||||
// result = parse_expr(wp->expr, &success);
|
|
||||||
// if (!success) {
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// static void wp_delete(WP *wp) {
|
||||||
|
// assert(wp);
|
||||||
|
// wp->next = free_;
|
||||||
|
// free_ = wp;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static int wp_add(char * expr) {
|
||||||
|
// WP *wp = wp_new();
|
||||||
|
// if (wp == NULL) {
|
||||||
|
// Error("watchpoint: Failed to add watchpoint, pool is full.");
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// wp->NO = wp_count++;
|
||||||
|
// if (tail == NULL) {
|
||||||
|
// head = wp;
|
||||||
|
// tail = wp;
|
||||||
|
// } else {
|
||||||
|
// tail->next = wp;
|
||||||
|
// tail = wp;
|
||||||
|
// }
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static int wp_remove_by_number(int number) {
|
||||||
|
// WP *target_prev;
|
||||||
|
// // Find previous node of target number
|
||||||
|
// for (target_prev = head; target_prev != NULL && target_prev->next->NO != number; target_prev = target_prev->next) ;
|
||||||
|
// if (target_prev == NULL) {
|
||||||
|
// Error("Watchpoint not found, you can check current watchpoints with `info w`");
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
// WP *target = target_prev->next;
|
||||||
|
// target_prev->next = target->next;
|
||||||
|
// if (target == head) {
|
||||||
|
// head = target->next;
|
||||||
|
// } else if (target == tail) {
|
||||||
|
// tail = target_prev;
|
||||||
|
// }
|
||||||
|
// wp_delete(target);
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
static bool wp_check_change(WP* wp) {
|
||||||
|
bool success = false;
|
||||||
|
word_t result;
|
||||||
|
|
||||||
|
result = parse_expr(wp->expr, &success);
|
||||||
|
if (!success) {
|
||||||
|
panic("Failed to evaluate %s", wp->expr);
|
||||||
|
}
|
||||||
|
if (result != wp->val) {
|
||||||
|
wp->val = result;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if watchpoint value changed after execution
|
Check if watchpoint value changed after execution
|
||||||
*/
|
*/
|
||||||
// int wp_eval_all() {
|
void wp_eval_all() {
|
||||||
// }
|
WP *wp;
|
||||||
|
for (wp = head; wp != NULL; wp = wp->next) {
|
||||||
/* TODO: Implement the functionality of watchpoint */
|
int prev_val = wp->val;
|
||||||
|
if (wp_check_change(wp)) {
|
||||||
|
printf("Watchpoint %d: %s\n %u -> %u\n", wp->NO, wp->expr, prev_val, wp->val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue