target: e2k: Reord pcsp.

This commit is contained in:
Denis Drakhnia 2020-11-26 18:31:25 +02:00
parent 008b9b53e0
commit d44b82eba3
7 changed files with 54 additions and 104 deletions

View File

@ -118,8 +118,7 @@ void cpu_loop(CPUE2KState *env)
void target_cpu_copy_regs(CPUE2KState *env, struct target_pt_regs *regs)
{
env->ip = regs->ip;
env->pcsp_lo = regs->pcsp_lo;
env->pcsp_hi = regs->pcsp_hi;
env->pcsp = regs->pcsp;
env->psp = regs->psp;
env->usd_lo = regs->usd_lo;
env->usd_hi = regs->usd_hi;

View File

@ -28,6 +28,7 @@ struct target_pt_regs {
// uint64_t tr; // current type register
E2KPcsState pcsp;
E2KPsState psp;
uint32_t psr; // Processor State Register (PSR)

View File

@ -1520,18 +1520,17 @@ static inline abi_ulong e2k_mmap(abi_ulong size)
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
abi_ulong pcsp;
abi_ulong pcs_size = TARGET_PAGE_SIZE;
abi_ulong stack_size = infop->start_stack - infop->stack_limit;
regs->ip = infop->entry;
regs->usd_hi = stack_size << 32;
regs->usd_lo = (0x1800UL << 48) | infop->start_stack;
/* FIXME: mmap to 0xc2e000003000 */
pcsp = e2k_mmap(pcs_size);
regs->pcsp_lo = (3UL << 59) | pcsp;
regs->pcsp_hi = pcs_size << 32;
regs->pcsp.is_readable = true;
regs->pcsp.is_writable = true;
regs->pcsp.index = 0;
regs->pcsp.size = TARGET_PAGE_SIZE;
regs->pcsp.base = (void *) e2k_mmap(regs->pcsp.size);
regs->psp.is_readable = true;
regs->psp.is_writable = true;

View File

@ -124,10 +124,10 @@ void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
unsigned int i;
qemu_fprintf(f, "ip: " TARGET_FMT_lx "\n", env->ip);
qemu_fprintf(f, "pcsp_hi: %016lx, pcsp_lo: %016lx\n",
env->pcsp_hi, env->pcsp_lo);
qemu_fprintf(f, "psp_hi: %016lx, psp_lo: %016lx\n",
e2k_state_psp_hi(env), e2k_state_psp_lo(env));
qemu_fprintf(f, "pcsp_lo: %016lx\n", e2k_state_pcsp_lo(env));
qemu_fprintf(f, "pcsp_hi: %016lx\n", e2k_state_pcsp_hi(env));
qemu_fprintf(f, "psp_lo: %016lx\n", e2k_state_psp_lo(env));
qemu_fprintf(f, "psp_hi: %016lx\n", e2k_state_psp_hi(env));
qemu_fprintf(f, "PF: %016lx\n", env->pf);
qemu_fprintf(f, "cr1_hi: %016lx, cr1_lo: %016lx\n",
env->cr1_hi, env->cr1_lo);

View File

@ -53,35 +53,20 @@ void e2k_tcg_initialize(void);
#define WD_FX_OFF 48
#define WD_FX_BIT (1UL << WD_FX_OFF)
#define PCSP_HI_IND_OFF 0 /* index for SPILL */
#define PCSP_HI_IND_END 31
#define PCSP_HI_IND_LEN (PCSP_HI_IND_END - PCSP_HI_IND_OFF + 1)
#define PCSP_HI_SIZE_OFF 32
#define PCSP_HI_SIZE_END 63 /* procedure stack chain size */
#define PCSP_HI_SIZE_LEN (PCSP_HI_SIZE_END - PCSP_HI_SIZE_OFF + 1)
#define DESC_HI_IND_OFF 0 /* index for SPILL */
#define DESC_HI_IND_END 31
#define DESC_HI_IND_LEN (DESC_HI_IND_END - DESC_HI_IND_OFF + 1)
#define DESC_HI_SIZE_OFF 32 /* stack size */
#define DESC_HI_SIZE_END 63
#define DESC_HI_SIZE_LEN (DESC_HI_SIZE_END - DESC_HI_SIZE_OFF + 1)
#define PCSP_LO_BASE_OFF 0 /* procedure stack chain address */
#define PCSP_LO_BASE_END 47
#define PCSP_LO_BASE_LEN (PCSP_LO_BASE_END - PCSP_LO_BASE_OFF + 1)
#define PCSP_LO_READ_OFF 59
#define PCSP_LO_READ_BIT (1UL << PCSP_LO_READ_OFF)
#define PCSP_LO_WRITE_OFF 60
#define PCSP_LO_WRITE_BIT (1UL << PCSP_LO_WRITE_OFF)
#define PSP_HI_IND_OFF 0 /* index for SPILL */
#define PSP_HI_IND_END 31
#define PSP_HI_IND_LEN (PSP_HI_IND_END - PSP_HI_IND_OFF + 1)
#define PSP_HI_SIZE_OFF 32
#define PSP_HI_SIZE_END 63 /* procedure stack size */
#define PSP_HI_SIZE_LEN (PSP_HI_SIZE_END - PSP_HI_SIZE_OFF + 1)
#define PSP_LO_BASE_OFF 0 /* procedure stack address */
#define PSP_LO_BASE_END 47
#define PSP_LO_BASE_LEN (PSP_LO_BASE_END - PSP_LO_BASE_OFF + 1)
#define PSP_LO_READ_OFF 59
#define PSP_LO_READ_BIT (1UL << PSP_LO_READ_OFF)
#define PSP_LO_WRITE_OFF 60
#define PSP_LO_WRITE_BIT (1UL << PSP_LO_WRITE_OFF)
#define DESC_LO_BASE_OFF 0 /* stack address */
#define DESC_LO_BASE_END 47
#define DESC_LO_BASE_LEN (DESC_LO_BASE_END - DESC_LO_BASE_OFF + 1)
#define DESC_LO_READ_OFF 59
#define DESC_LO_READ_BIT (1UL << DESC_LO_READ_OFF)
#define DESC_LO_WRITE_OFF 60
#define DESC_LO_WRITE_BIT (1UL << DESC_LO_WRITE_OFF)
#define PSHTP_IND_OFF 0
#define PSHTP_IND_END 11
@ -250,7 +235,7 @@ typedef struct {
uint32_t size;
bool is_readable;
bool is_writable;
} E2KPsState;
} E2KDescState, E2KPsState, E2KPcsState;
typedef struct {
/* register file */
@ -259,8 +244,7 @@ typedef struct {
uint64_t *wptr;
/* Procedure chain info = cr0_lo, cr0_hi, cr1_lo, cr1_hi */
uint64_t pcsp_lo;
uint64_t pcsp_hi;
E2KPcsState pcsp;
uint64_t pcshtp;
uint32_t br;
@ -353,61 +337,34 @@ int e2k_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
#define cpu_signal_handler e2k_cpu_signal_handler
static inline target_ulong e2k_state_pcs_base_get(CPUE2KState *env)
{
return GET_FIELD(env->pcsp_lo, PCSP_LO_BASE_OFF, PCSP_LO_BASE_LEN);
}
static inline void e2k_state_pcs_base_set(CPUE2KState *env, target_ulong pcsp)
{
env->pcsp_lo = SET_FIELD(env->pcsp_lo, pcsp, PCSP_LO_BASE_OFF,
PCSP_LO_BASE_LEN);
}
static inline size_t e2k_state_pcs_index_get(CPUE2KState *env)
{
return GET_FIELD(env->pcsp_hi, PCSP_HI_IND_OFF, PCSP_HI_IND_LEN);
}
static inline void e2k_state_pcs_index_set(CPUE2KState *env, size_t ind)
{
env->pcsp_hi = SET_FIELD(env->pcsp_hi, ind, PCSP_HI_IND_OFF,
PCSP_HI_IND_LEN);
}
static inline size_t e2k_state_pcs_size_get(CPUE2KState *env)
{
return GET_FIELD(env->pcsp_hi, PCSP_HI_SIZE_OFF, PCSP_HI_SIZE_LEN);
}
static inline void e2k_state_pcs_size_set(CPUE2KState *env, size_t size)
{
env->pcsp_hi = SET_FIELD(env->pcsp_hi, size, PCSP_HI_SIZE_OFF,
PCSP_HI_SIZE_LEN);
}
static inline uint64_t e2k_state_psp_lo(CPUE2KState *env)
static inline uint64_t e2k_state_desc_lo(E2KDescState *desc)
{
uint64_t lo = 0;
lo = deposit64(lo, PSP_LO_BASE_OFF, PSP_LO_BASE_LEN,
(uint64_t) env->psp.base);
lo = deposit64(lo, PSP_LO_READ_OFF, 1, env->psp.is_readable);
lo = deposit64(lo, PSP_LO_WRITE_OFF, 1, env->psp.is_writable);
lo = deposit64(lo, DESC_LO_BASE_OFF, DESC_LO_BASE_LEN,
(uint64_t) desc->base);
lo = deposit64(lo, DESC_LO_READ_OFF, 1, desc->is_readable);
lo = deposit64(lo, DESC_LO_WRITE_OFF, 1, desc->is_writable);
return lo;
}
static inline uint64_t e2k_state_psp_hi(CPUE2KState *env)
static inline uint64_t e2k_state_desc_hi(E2KDescState *env)
{
uint64_t hi = 0;
hi = deposit64(hi, PSP_HI_IND_OFF, PSP_HI_IND_LEN, env->psp.index);
hi = deposit64(hi, PSP_HI_SIZE_OFF, PSP_HI_SIZE_OFF, env->psp.size);
hi = deposit64(hi, DESC_HI_IND_OFF, DESC_HI_IND_LEN, env->index);
hi = deposit64(hi, DESC_HI_SIZE_OFF, DESC_HI_SIZE_OFF, env->size);
return hi;
}
#define e2k_state_pcsp_lo(env) e2k_state_desc_lo(&(env)->pcsp)
#define e2k_state_pcsp_hi(env) e2k_state_desc_hi(&(env)->pcsp)
#define e2k_state_psp_lo(env) e2k_state_desc_lo(&(env)->psp)
#define e2k_state_psp_hi(env) e2k_state_desc_hi(&(env)->psp)
static inline int e2k_state_cr1_wbs_get(CPUE2KState *env)
{
return GET_FIELD(env->cr1_lo, CR1_LO_WBS_OFF, CR1_LO_WBS_LEN);

View File

@ -65,8 +65,8 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
case 54: return gdb_get_reg64(mem_buf, env->cr1_lo); // cr1_lo
case 55: return gdb_get_reg64(mem_buf, env->cr1_hi); // cr1_hi
case 56: return gdb_get_reg64(mem_buf, 0); // cwd
case 57: return gdb_get_reg64(mem_buf, env->pcsp_lo); // pcsp_lo
case 58: return gdb_get_reg64(mem_buf, env->pcsp_hi); // pcsp_hi
case 57: return gdb_get_reg64(mem_buf, e2k_state_pcsp_lo(env)); // pcsp_lo
case 58: return gdb_get_reg64(mem_buf, e2k_state_pcsp_hi(env)); // pcsp_hi
case 59: return gdb_get_reg64(mem_buf, env->pcshtp); // pcshtp
case 60: return gdb_get_reg64(mem_buf, 0); // cud_lo
case 61: return gdb_get_reg64(mem_buf, 0); // cud_hi

View File

@ -51,40 +51,34 @@ static inline void restore_br_state(CPUE2KState *env)
static void pcs_push(CPUE2KState *env, int wbs)
{
size_t size = e2k_state_pcs_size_get(env);
size_t offset = e2k_state_pcs_index_get(env);
void *pcsp = (void*) e2k_state_pcs_base_get(env) + offset;
size_t size = sizeof(env->proc_chain);
if (offset + 32 > size) {
/* TODO: allocate more memory */
abort();
if (env->pcsp.size < (env->pcsp.index + size)) {
helper_raise_exception(env, E2K_EXCP_MAPERR);
return;
}
save_br_state(env);
e2k_state_cr1_wpsz_set(env, env->wd_psize / 2);
memcpy(pcsp, &env->proc_chain[0], 32);
memcpy(env->pcsp.base + env->pcsp.index, env->proc_chain, size);
e2k_state_cr1_wbs_set(env, wbs);
e2k_state_pcs_index_set(env, offset + 32);
env->pcsp.index += size;
}
static void pcs_pop(CPUE2KState *env)
{
size_t offset = e2k_state_pcs_index_get(env);
void *pcsp = (void*) e2k_state_pcs_base_get(env) + offset - 32;
size_t size = sizeof(env->proc_chain);
if (offset < 32) {
/* TODO: SIGKILL */
abort();
if (env->pcsp.index < size) {
helper_raise_exception(env, E2K_EXCP_MAPERR);
return;
}
memcpy(&env->proc_chain[0], pcsp, 32);
// TODO: restore wbs (after pshtp implemented)
env->pcsp.index -= size;
memcpy(env->proc_chain, env->pcsp.base + env->pcsp.index, size);
env->wd_psize = e2k_state_cr1_wpsz_get(env) * 2;
restore_br_state(env);
e2k_state_pcs_index_set(env, offset - 32);
}
static void ps_push_nfx(CPUE2KState *env, unsigned int base, size_t len)