Loading hw/sun4m.c +3 −3 Original line number Diff line number Diff line Loading @@ -404,7 +404,7 @@ static void sun4m_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, qemu_register_reset(secondary_cpu_reset, env); env->halted = 1; } register_savevm("cpu", i, 3, cpu_save, cpu_load, env); register_savevm("cpu", i, 4, cpu_save, cpu_load, env); cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); env->prom_addr = hwdef->slavio_base; } Loading Loading @@ -579,7 +579,7 @@ static void sun4c_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, cpu_sparc_set_id(env, 0); qemu_register_reset(main_cpu_reset, env); register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); register_savevm("cpu", 0, 4, cpu_save, cpu_load, env); cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS); env->prom_addr = hwdef->slavio_base; Loading Loading @@ -1391,7 +1391,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, qemu_register_reset(secondary_cpu_reset, env); env->halted = 1; } register_savevm("cpu", i, 3, cpu_save, cpu_load, env); register_savevm("cpu", i, 4, cpu_save, cpu_load, env); cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); env->prom_addr = hwdef->slavio_base; } Loading hw/sun4u.c +1 −1 Original line number Diff line number Diff line Loading @@ -260,7 +260,7 @@ static void sun4u_init(ram_addr_t RAM_size, int vga_ram_size, bh = qemu_bh_new(hstick_irq, env); env->hstick = ptimer_init(bh); ptimer_set_period(env->hstick, 1ULL); register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); register_savevm("cpu", 0, 4, cpu_save, cpu_load, env); qemu_register_reset(main_cpu_reset, env); main_cpu_reset(env); Loading linux-user/main.c +14 −14 Original line number Diff line number Diff line Loading @@ -626,11 +626,11 @@ void cpu_loop(CPUARMState *env) can be found at http://www.sics.se/~psm/sparcstack.html */ static inline int get_reg_index(CPUSPARCState *env, int cwp, int index) { index = (index + cwp * 16) & (16 * NWINDOWS - 1); index = (index + cwp * 16) % (16 * env->nwindows); /* wrap handling : if cwp is on the last window, then we use the registers 'after' the end */ if (index < 8 && env->cwp == (NWINDOWS - 1)) index += (16 * NWINDOWS); if (index < 8 && env->cwp == env->nwindows - 1) index += 16 * env->nwindows; return index; } Loading @@ -656,12 +656,12 @@ static void save_window(CPUSPARCState *env) { #ifndef TARGET_SPARC64 unsigned int new_wim; new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) & ((1LL << NWINDOWS) - 1); save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) & ((1LL << env->nwindows) - 1); save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2)); env->wim = new_wim; #else save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2)); env->cansave++; env->canrestore--; #endif Loading @@ -672,11 +672,11 @@ static void restore_window(CPUSPARCState *env) unsigned int new_wim, i, cwp1; abi_ulong sp_ptr; new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) & ((1LL << NWINDOWS) - 1); new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) & ((1LL << env->nwindows) - 1); /* restore the invalid window */ cwp1 = (env->cwp + 1) & (NWINDOWS - 1); cwp1 = cpu_cwp_inc(env, env->cwp + 1); sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; #if defined(DEBUG_WIN) printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n", Loading @@ -690,7 +690,7 @@ static void restore_window(CPUSPARCState *env) env->wim = new_wim; #ifdef TARGET_SPARC64 env->canrestore++; if (env->cleanwin < NWINDOWS - 1) if (env->cleanwin < env->nwindows - 1) env->cleanwin++; env->cansave--; #endif Loading @@ -703,14 +703,14 @@ static void flush_windows(CPUSPARCState *env) offset = 1; for(;;) { /* if restore would invoke restore_window(), then we can stop */ cwp1 = (env->cwp + offset) & (NWINDOWS - 1); cwp1 = cpu_cwp_inc(env, env->cwp + offset); if (env->wim & (1 << cwp1)) break; save_window_offset(env, cwp1); offset++; } /* set wim so that restore will reload the registers */ cwp1 = (env->cwp + 1) & (NWINDOWS - 1); cwp1 = cpu_cwp_inc(env, env->cwp + 1); env->wim = 1 << cwp1; #if defined(DEBUG_WIN) printf("flush_windows: nb=%d\n", offset - 1); Loading target-sparc/TODO +0 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ CPU common: slot next page) - Atomical instructions - CPU features should match real CPUs (also ASI selection) - Allow choosing of NWINDOWS (CPU model specific and as a CPU feature) - Optimizations/improvements: - Condition code/branch handling like x86, also for FPU? - Remove remaining explicit alignment checks Loading target-sparc/cpu.h +27 −6 Original line number Diff line number Diff line Loading @@ -170,8 +170,9 @@ #define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT) #define PG_CACHE_MASK (1 << PG_CACHE_BIT) /* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */ #define NWINDOWS 8 /* 3 <= NWINDOWS <= 32. */ #define MIN_NWINDOWS 3 #define MAX_NWINDOWS 32 #if !defined(TARGET_SPARC64) #define NB_MMU_MODES 2 Loading Loading @@ -222,8 +223,9 @@ typedef struct CPUSPARCState { uint32_t mmu_cxr_mask; uint32_t mmu_sfsr_mask; uint32_t mmu_trcr_mask; uint32_t nwindows; /* NOTE: we allow 8 more registers to handle wrapping */ target_ulong regbase[NWINDOWS * 16 + 8]; target_ulong regbase[MAX_NWINDOWS * 16 + 8]; CPU_COMMON Loading Loading @@ -330,6 +332,20 @@ void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); #ifndef NO_CPU_IO_DEFS void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); static inline int cpu_cwp_inc(CPUSPARCState *env1, int cwp) { if (unlikely(cwp >= env1->nwindows)) cwp -= env1->nwindows; return cwp; } static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp) { if (unlikely(cwp < 0)) cwp += env1->nwindows; return cwp; } #endif #define PUT_PSR(env, val) do { int _tmp = val; \ Loading @@ -348,9 +364,14 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); env->xcc = (_tmp >> 4) << 20; \ env->psr = (_tmp & 0xf) << 20; \ } while (0) #define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp) #define PUT_CWP64(env, val) \ cpu_set_cwp(env, NWINDOWS - 1 - ((val) & (NWINDOWS - 1))) #define GET_CWP64(env) (env->nwindows - 1 - (env)->cwp) static inline void PUT_CWP64(CPUSPARCState *env1, int cwp) { if (unlikely(cwp >= env1->nwindows || cwp < 0)) cwp = 0; cpu_set_cwp(env1, env1->nwindows - 1 - cwp); } #endif Loading Loading
hw/sun4m.c +3 −3 Original line number Diff line number Diff line Loading @@ -404,7 +404,7 @@ static void sun4m_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, qemu_register_reset(secondary_cpu_reset, env); env->halted = 1; } register_savevm("cpu", i, 3, cpu_save, cpu_load, env); register_savevm("cpu", i, 4, cpu_save, cpu_load, env); cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); env->prom_addr = hwdef->slavio_base; } Loading Loading @@ -579,7 +579,7 @@ static void sun4c_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, cpu_sparc_set_id(env, 0); qemu_register_reset(main_cpu_reset, env); register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); register_savevm("cpu", 0, 4, cpu_save, cpu_load, env); cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS); env->prom_addr = hwdef->slavio_base; Loading Loading @@ -1391,7 +1391,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, qemu_register_reset(secondary_cpu_reset, env); env->halted = 1; } register_savevm("cpu", i, 3, cpu_save, cpu_load, env); register_savevm("cpu", i, 4, cpu_save, cpu_load, env); cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); env->prom_addr = hwdef->slavio_base; } Loading
hw/sun4u.c +1 −1 Original line number Diff line number Diff line Loading @@ -260,7 +260,7 @@ static void sun4u_init(ram_addr_t RAM_size, int vga_ram_size, bh = qemu_bh_new(hstick_irq, env); env->hstick = ptimer_init(bh); ptimer_set_period(env->hstick, 1ULL); register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); register_savevm("cpu", 0, 4, cpu_save, cpu_load, env); qemu_register_reset(main_cpu_reset, env); main_cpu_reset(env); Loading
linux-user/main.c +14 −14 Original line number Diff line number Diff line Loading @@ -626,11 +626,11 @@ void cpu_loop(CPUARMState *env) can be found at http://www.sics.se/~psm/sparcstack.html */ static inline int get_reg_index(CPUSPARCState *env, int cwp, int index) { index = (index + cwp * 16) & (16 * NWINDOWS - 1); index = (index + cwp * 16) % (16 * env->nwindows); /* wrap handling : if cwp is on the last window, then we use the registers 'after' the end */ if (index < 8 && env->cwp == (NWINDOWS - 1)) index += (16 * NWINDOWS); if (index < 8 && env->cwp == env->nwindows - 1) index += 16 * env->nwindows; return index; } Loading @@ -656,12 +656,12 @@ static void save_window(CPUSPARCState *env) { #ifndef TARGET_SPARC64 unsigned int new_wim; new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) & ((1LL << NWINDOWS) - 1); save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) & ((1LL << env->nwindows) - 1); save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2)); env->wim = new_wim; #else save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2)); env->cansave++; env->canrestore--; #endif Loading @@ -672,11 +672,11 @@ static void restore_window(CPUSPARCState *env) unsigned int new_wim, i, cwp1; abi_ulong sp_ptr; new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) & ((1LL << NWINDOWS) - 1); new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) & ((1LL << env->nwindows) - 1); /* restore the invalid window */ cwp1 = (env->cwp + 1) & (NWINDOWS - 1); cwp1 = cpu_cwp_inc(env, env->cwp + 1); sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; #if defined(DEBUG_WIN) printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n", Loading @@ -690,7 +690,7 @@ static void restore_window(CPUSPARCState *env) env->wim = new_wim; #ifdef TARGET_SPARC64 env->canrestore++; if (env->cleanwin < NWINDOWS - 1) if (env->cleanwin < env->nwindows - 1) env->cleanwin++; env->cansave--; #endif Loading @@ -703,14 +703,14 @@ static void flush_windows(CPUSPARCState *env) offset = 1; for(;;) { /* if restore would invoke restore_window(), then we can stop */ cwp1 = (env->cwp + offset) & (NWINDOWS - 1); cwp1 = cpu_cwp_inc(env, env->cwp + offset); if (env->wim & (1 << cwp1)) break; save_window_offset(env, cwp1); offset++; } /* set wim so that restore will reload the registers */ cwp1 = (env->cwp + 1) & (NWINDOWS - 1); cwp1 = cpu_cwp_inc(env, env->cwp + 1); env->wim = 1 << cwp1; #if defined(DEBUG_WIN) printf("flush_windows: nb=%d\n", offset - 1); Loading
target-sparc/TODO +0 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ CPU common: slot next page) - Atomical instructions - CPU features should match real CPUs (also ASI selection) - Allow choosing of NWINDOWS (CPU model specific and as a CPU feature) - Optimizations/improvements: - Condition code/branch handling like x86, also for FPU? - Remove remaining explicit alignment checks Loading
target-sparc/cpu.h +27 −6 Original line number Diff line number Diff line Loading @@ -170,8 +170,9 @@ #define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT) #define PG_CACHE_MASK (1 << PG_CACHE_BIT) /* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */ #define NWINDOWS 8 /* 3 <= NWINDOWS <= 32. */ #define MIN_NWINDOWS 3 #define MAX_NWINDOWS 32 #if !defined(TARGET_SPARC64) #define NB_MMU_MODES 2 Loading Loading @@ -222,8 +223,9 @@ typedef struct CPUSPARCState { uint32_t mmu_cxr_mask; uint32_t mmu_sfsr_mask; uint32_t mmu_trcr_mask; uint32_t nwindows; /* NOTE: we allow 8 more registers to handle wrapping */ target_ulong regbase[NWINDOWS * 16 + 8]; target_ulong regbase[MAX_NWINDOWS * 16 + 8]; CPU_COMMON Loading Loading @@ -330,6 +332,20 @@ void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); #ifndef NO_CPU_IO_DEFS void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); static inline int cpu_cwp_inc(CPUSPARCState *env1, int cwp) { if (unlikely(cwp >= env1->nwindows)) cwp -= env1->nwindows; return cwp; } static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp) { if (unlikely(cwp < 0)) cwp += env1->nwindows; return cwp; } #endif #define PUT_PSR(env, val) do { int _tmp = val; \ Loading @@ -348,9 +364,14 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); env->xcc = (_tmp >> 4) << 20; \ env->psr = (_tmp & 0xf) << 20; \ } while (0) #define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp) #define PUT_CWP64(env, val) \ cpu_set_cwp(env, NWINDOWS - 1 - ((val) & (NWINDOWS - 1))) #define GET_CWP64(env) (env->nwindows - 1 - (env)->cwp) static inline void PUT_CWP64(CPUSPARCState *env1, int cwp) { if (unlikely(cwp >= env1->nwindows || cwp < 0)) cwp = 0; cpu_set_cwp(env1, env1->nwindows - 1 - cwp); } #endif Loading