sparc64: interrupts and tick timers v1
cover sparc64: interrupts and tick timers v1
The following series is a cleanup over previous one.
v0 -> v1: post-review changes
- dropped patch "clear exception_index with -1 val" (applied)
- new patch "change_pstate should have 32bit argument"
- cleanups for coding style and hexadecimal output convention
- wrpil is no-op for CONFIG_USER_ONLY
- restored PIL 15 as non-maskable interrupt level on sparcv8
- check for PSTATE.IE is replaced with call to cpu_interrupts_enabled()
- in patch "sparc64: interrupt trap handling"
cleaned up change in cpu_exec; since sparc64 does not use CPU_INTERRUPT_TIMER now, corresponding code branch is unchanged
---
Igor V. Kovalenko (9):
sparc64: change_pstate should have 32bit argument
sparc64: trace pstate and global register set changes
sparc64: add PIL to cpu state dump
sparc64: use helper_wrpil to check pending irq on write
sparc64: check for pending irq when pil, pstate or softint is changed
sparc64: add macros to deal with softint and timer interrupt
sparc64: move cpu_interrupts_enabled to cpu.h
sparc64: interrupt trap handling
sparc64: reimplement tick timers
cpu-exec.c | 28 +++--- hw/sun4u.c | 225 +++++++++++++++++++++++++++++++++++++--------- target-sparc/cpu.h | 27 ++++++ target-sparc/exec.h | 13 --- target-sparc/helper.c | 1 target-sparc/helper.h | 1 target-sparc/op_helper.c | 81 +++++++++++++++-- target-sparc/translate.c | 5 - 8 files changed, 300 insertions(+), 81 deletions(-)
Signature · 2 lines
Kind regards, Igor V. Kovalenko
PATCH 1/9 sparc64: change_pstate should have 32bit argument
From: Igor V. Kovalenko <[email protected]>
- pstate is 32bit variable, no need to pass 64bit value around
--- target-sparc/op_helper.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
target-sparc/op_helper.c +3 -3
@@ -3240,7 +3240,7 @@ target_ulong helper_popc(target_ulong val)return ctpop64 (val); } -static inline uint64_t *get_gregset (uint64_t pstate) +static inline uint64_t *get_gregset (uint32_t pstate) {switch (pstate) {default :
@@ -3255,9 +3255,9 @@ static inline uint64_t *get_gregset(uint64_t pstate) } } -static inline void change_pstate (uint64_t new_pstate) +static inline void change_pstate (uint32_t new_pstate) { -uint64_t pstate_regs, new_pstate_regs; +uint32_t pstate_regs, new_pstate_regs;uint64_t *src, *dst;if (env->def->features &CPU_FEATURE_GL ) {
PATCH 2/9 sparc64: trace pstate and global register set changes
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
--- target-sparc/op_helper.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)
target-sparc/op_helper.c +20 -0
@@ -11,6 +11,7 @@//#define DEBUG_UNASSIGNED //#define DEBUG_ASI //#define DEBUG_PCALL +//#define DEBUG_PSTATE #ifdef DEBUG_MMU #define DPRINTF_MMU (fmt, ...) \
@@ -31,6 +32,13 @@ do { printf("ASI: " fmt , ## __VA_ARGS__); } while (0)#endif +#ifdef DEBUG_PSTATE +#define DPRINTF_PSTATE (fmt, ...) \ + do { printf("PSTATE: " fmt , ## __VA_ARGS__); } while (0) +#else +#define DPRINTF_PSTATE (fmt, ...) do {} while (0) +#endif +#ifdef TARGET_SPARC64 #ifndef TARGET_ABI32 #define AM_CHECK (env1) ((env1)->pstate & PS_AM)
@@ -3244,6 +3252,12 @@ static inline uint64_t *get_gregset(uint32_t pstate) {switch (pstate) {default : +DPRINTF_PSTATE ("ERROR in get_gregset: active pstate bits=%x%s%s%s\n" , + pstate, + (pstate &PS_IG ) ?" IG" :"" , + (pstate &PS_MG ) ?" MG" :"" , + (pstate &PS_AG ) ?" AG" :"" ); +/* pass through to normal set of global registers */ case 0 :return env->bgregs;case PS_AG :
@@ -3269,12 +3283,18 @@ static inline void change_pstate(uint32_t new_pstate) new_pstate_regs = new_pstate &0xc01 ;if (new_pstate_regs != pstate_regs) { +DPRINTF_PSTATE ("change_pstate: switching regs old=%x new=%x\n" , + pstate_regs, new_pstate_regs);// Switch global register bank src =get_gregset (new_pstate_regs); dst =get_gregset (pstate_regs);memcpy32 (dst, env->gregs);memcpy32 (env->gregs, src); } +else { +DPRINTF_PSTATE ("change_pstate: regs new=%x (unchanged)\n" , + new_pstate_regs); + } env->pstate = new_pstate; }
PATCH 3/9 sparc64: add PIL to cpu state dump
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
--- target-sparc/helper.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
target-sparc/helper.c +1 -0
@@ -1452,6 +1452,7 @@ void cpu_dump_state(CPUState *env, FILE *f,#ifdef TARGET_SPARC64 cpu_fprintf (f,"pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n" , env->pstate,GET_CCR (env), env->asi, env->tl, env->fprs); +cpu_fprintf (f,"pil=%x\n" , env->psrpil); cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d " "cleanwin %d cwp %d\n", env->cansave, env->canrestore, env->otherwin, env->wstate,
PATCH 4/9 sparc64: use helper_wrpil to check pending irq on write
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
--- target-sparc/helper.h | 1 + target-sparc/op_helper.c | 14 ++++++++++++++ target-sparc/translate.c | 5 +---- 3 files changed, 16 insertions(+), 4 deletions(-)
target-sparc/helper.h +1 -0
@@ -5,6 +5,7 @@ DEF_HELPER_0(rett, void) DEF_HELPER_1(wrpsr, void, tl) DEF_HELPER_0(rdpsr, tl)#else +DEF_HELPER_1(wrpil, void, tl) DEF_HELPER_1(wrpstate, void, tl) DEF_HELPER_0(done, void)DEF_HELPER_0 (retry, void)
target-sparc/op_helper.c +14 -0
@@ -3303,6 +3303,20 @@ void helper_wrpstate(target_ulong new_state)change_pstate (new_state &0xf3f ); } +void helper_wrpil (target_ulong new_pil) +{ +#if !defined(CONFIG_USER_ONLY ) +DPRINTF_PSTATE ("helper_wrpil old=%x new=%x\n" , + env->psrpil, (uint32_t )new_pil); + + env->psrpil = new_pil; + +if (cpu_interrupts_enabled (env)) { +cpu_check_irqs (env); + } +#endif +} +void helper_done (void ) {trap_state * tsptr =cpu_tsptr (env);
target-sparc/translate.c +1 -4
@@ -3371,10 +3371,7 @@ static void disas_sparc_insn(DisasContext * dc) offsetof(CPUSPARCState, tl));break ;case 8 :// pil -tcg_gen_trunc_tl_i32 (cpu_tmp32, cpu_tmp0); -tcg_gen_st_i32 (cpu_tmp32, cpu_env, - offsetof(CPUSPARCState , - psrpil)); +gen_helper_wrpil (cpu_tmp0);break ;case 9 :// cwp gen_helper_wrcwp (cpu_tmp0);
PATCH 5/9 sparc64: check for pending irq when pil, pstate or softint is changed
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
--- target-sparc/op_helper.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 files changed, 38 insertions(+), 3 deletions(-)
target-sparc/op_helper.c +38 -3
@@ -3301,6 +3301,12 @@ static inline void change_pstate(uint32_t new_pstate)void helper_wrpstate (target_ulong new_state) {change_pstate (new_state &0xf3f ); + +#if !defined(CONFIG_USER_ONLY ) +if (cpu_interrupts_enabled (env)) { +cpu_check_irqs (env); + } +#endif }void helper_wrpil (target_ulong new_pil)
@@ -3328,6 +3334,14 @@ void helper_done(void)change_pstate ((tsptr->tstate >>8 ) &0xf3f );PUT_CWP64 (env, tsptr->tstate &0xff ); env->tl--; + +DPRINTF_PSTATE ("... helper_done tl=%d\n" , env->tl); + +#if !defined(CONFIG_USER_ONLY ) +if (cpu_interrupts_enabled (env)) { +cpu_check_irqs (env); + } +#endif }void helper_retry (void )
@@ -3341,21 +3355,42 @@ void helper_retry(void)change_pstate ((tsptr->tstate >>8 ) &0xf3f );PUT_CWP64 (env, tsptr->tstate &0xff ); env->tl--; + +DPRINTF_PSTATE ("... helper_retry tl=%d\n" , env->tl); + +#if !defined(CONFIG_USER_ONLY ) +if (cpu_interrupts_enabled (env)) { +cpu_check_irqs (env); + } +#endif +} + +static void do_modify_softint (const char * operation,uint32_t value) +{ +if (env->softint != value) { + env->softint = value; +DPRINTF_PSTATE (": %s new %08x\n" , operation, env->softint); +#if !defined(CONFIG_USER_ONLY ) +if (cpu_interrupts_enabled (env)) { +cpu_check_irqs (env); + } +#endif + } }void helper_set_softint (uint64_t value) { - env->softint |= (uint32_t )value; +do_modify_softint ("helper_set_softint" , env->softint | (uint32_t )value); }void helper_clear_softint (uint64_t value) { - env->softint &= (uint32_t )~value; +do_modify_softint ("helper_clear_softint" , env->softint & (uint32_t )~value); }void helper_write_softint (uint64_t value) { - env->softint = (uint32_t )value; +do_modify_softint ("helper_write_softint" , (uint32_t )value); }#endif
PATCH 6/9 sparc64: add macros to deal with softint and timer interrupt
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
--- hw/sun4u.c | 1 - target-sparc/cpu.h | 4 ++++ 2 files changed, 4 insertions(+), 1 deletions(-)
hw/sun4u.c +0 -1
@@ -73,7 +73,6 @@#define MAX_PILS 16 -#define TICK_INT_DIS 0x8000000000000000ULL#define TICK_MAX 0x7fffffffffffffffULLstruct hwdef {
target-sparc/cpu.h +4 -0
@@ -394,6 +394,8 @@ typedef struct CPUSPARCState {uint64_t fprs;uint64_t tick_cmpr, stick_cmpr;void *tick, *stick; +#define TICK_NPT_MASK 0x8000000000000000ULL +#define TICK_INT_DIS 0x8000000000000000ULLuint64_t gsr;uint32_t gl;// UA2005 /* UA 2005 hyperprivileged registers */
@@ -402,6 +404,8 @@ typedef struct CPUSPARCState {uint32_t softint;#define SOFTINT_TIMER 1#define SOFTINT_STIMER (1 << 16) +#define SOFTINT_INTRMASK (0xFFFE) +#define SOFTINT_REG_MASK (SOFTINT_STIMER|SOFTINT_INTRMASK|SOFTINT_TIMER)#endif sparc_def_t *def; } CPUSPARCState;
PATCH 7/9 sparc64: move cpu_interrupts_enabled to cpu.h
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
- to be used by cpu_check_irqs
--- target-sparc/cpu.h | 13 +++++++++++++ target-sparc/exec.h | 13 ------------- 2 files changed, 13 insertions(+), 13 deletions(-)
target-sparc/cpu.h +13 -0
@@ -564,6 +564,19 @@ static inline int cpu_mmu_index(CPUState *env1)#endif } +static inline int cpu_interrupts_enabled (CPUState *env1) +{ +#if !defined (TARGET_SPARC64 ) +if (env1->psret !=0 ) +return 1 ; +#else +if (env1->pstate &PS_IE ) +return 1 ; +#endif + +return 0 ; +} +static inline int cpu_fpu_enabled (CPUState *env1) {#if defined(CONFIG_USER_ONLY )
target-sparc/exec.h +0 -13
@@ -24,19 +24,6 @@ static inline void regs_to_env(void)/* op_helper.c */ void do_interrupt (CPUState *env); -static inline int cpu_interrupts_enabled (CPUState *env1) -{ -#if !defined (TARGET_SPARC64 ) -if (env1->psret !=0 ) -return 1 ; -#else -if (env1->pstate &PS_IE ) -return 1 ; -#endif - -return 0 ; -} -static inline int cpu_has_work (CPUState *env1) { return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
PATCH 8/9 sparc64: interrupt trap handling
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
cpu_check_irqs
- handle SOFTINT register TICK and STICK timer bits
- only check interrupt levels greater than PIL value
- handle preemption by higher level traps
cpu_exec
- handle CPU_INTERRUPT_HARD only if interrupts are enabled
- PIL 15 is not special level on sparcv9
--- cpu-exec.c | 28 ++++++++++++++-------------- hw/sun4u.c | 48 +++++++++++++++++++++++++++++++++++------------- target-sparc/cpu.h | 10 ++++++++++ 3 files changed, 59 insertions(+), 27 deletions(-)
cpu-exec.c +14 -14
@@ -449,20 +449,20 @@ int cpu_exec(CPUState *env1) next_tb = 0; }#elif defined(TARGET_SPARC) -if ((interrupt_request &CPU_INTERRUPT_HARD ) && -cpu_interrupts_enabled (env)) { -int pil = env->interrupt_index &15 ; -int type = env->interrupt_index &0xf0 ; - -if (((type ==TT_EXTINT ) && - (pil ==15 || pil > env->psrpil)) || - type !=TT_EXTINT ) { - env->interrupt_request &= ~CPU_INTERRUPT_HARD ; - env->exception_index = env->interrupt_index; -do_interrupt (env); - env->interrupt_index =0 ; - next_tb =0 ; - } +if (interrupt_request &CPU_INTERRUPT_HARD ) { +if (cpu_interrupts_enabled (env) && + env->interrupt_index >0 ) { +int pil = env->interrupt_index &0xf ; +int type = env->interrupt_index &0xf0 ; + +if (((type ==TT_EXTINT ) && +cpu_pil_allowed (env, pil)) || + type !=TT_EXTINT ) { + env->exception_index = env->interrupt_index; +do_interrupt (env); + next_tb =0 ; + } + } }else if (interrupt_request &CPU_INTERRUPT_TIMER ) {//do_interrupt(0, 0, 0, 0, 0); env->interrupt_request &= ~CPU_INTERRUPT_TIMER ;
hw/sun4u.c +35 -13
64 lines not on this page · raw message
target-sparc/cpu.h +10 -0
@@ -577,6 +577,16 @@ static inline int cpu_interrupts_enabled(CPUState *env1)return 0 ; } +static inline int cpu_pil_allowed (CPUState *env1,int pil) +{ +#if !defined(TARGET_SPARC64 ) +/* level 15 is non-maskable on sparc v8 */ +return pil ==15 || pil > env1->psrpil; +#else +return pil > env1->psrpil; +#endif +} +static inline int cpu_fpu_enabled (CPUState *env1) {#if defined(CONFIG_USER_ONLY )
PATCH 9/9 sparc64: reimplement tick timers
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
sparc64 timer has tick counter which can be set and read, and tick compare value used as deadline to fire timer interrupt. The timer is not used as periodic timer, instead deadline is set each time new timer interrupt is needed.
This change implements sparc64 timers without periodic timers. It is not complete yet, cpu_tick_set_count does not really set counter value.
--- hw/sun4u.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 146 insertions(+), 30 deletions(-)
hw/sun4u.c +146 -30
@@ -40,6 +40,7 @@//#define DEBUG_IRQ //#define DEBUG_EBUS +//#define DEBUG_TIMER #ifdef DEBUG_IRQ #define CPUIRQ_DPRINTF (fmt, ...) \
@@ -55,6 +56,13 @@#define EBUS_DPRINTF (fmt, ...)#endif +#ifdef DEBUG_TIMER +#define TIMER_DPRINTF (fmt, ...) \ + do { printf("TIMER: " fmt , ## __VA_ARGS__); } while (0) +#else +#define TIMER_DPRINTF (fmt, ...) +#endif +#define KERNEL_LOAD_ADDR 0x00404000#define CMDLINE_ADDR 0x003ff000#define INITRD_LOAD_ADDR 0x00300000
@@ -280,6 +288,12 @@ void cpu_check_irqs(CPUState *env) } } +static void cpu_kick_irq (CPUState *env) +{ + env->halted =0 ; +cpu_check_irqs (env); +} +static void cpu_set_irq (void *opaque,int irq,int level) {CPUState *env = opaque;
@@ -301,6 +315,41 @@ typedef struct ResetData {uint64_t prom_addr; } ResetData; +struct sun4u_timer +{ +const char *name; +uint32_t frequency; +int disabled; +uint64_t disabled_mask; +QEMUTimer *qtimer; +}; + +typedef struct sun4u_timer sun4u_timer ; + +static sun4u_timer *sun4u_timer_create (const char * name,CPUState *env, +QEMUBHFunc *cb,uint32_t frequency, +uint64_t disabled_mask) +{ +sun4u_timer *timer; + + timer =qemu_mallocz (sizeof (sun4u_timer)); + + timer->name = name; + timer->frequency = frequency; + timer->disabled =1 ; + timer->disabled_mask = disabled_mask; + + timer->qtimer =qemu_new_timer (vm_clock, cb, env); + +return timer; +} + +static void sun4u_timer_reset (sun4u_timer *timer) +{ + timer->disabled =1 ; +qemu_del_timer (timer->qtimer); +} +static void main_cpu_reset (void *opaque) {ResetData *s = (ResetData *)opaque;
@@ -308,15 +357,11 @@ static void main_cpu_reset(void *opaque)static unsigned int nr_resets;cpu_reset (env); - env->tick_cmpr =TICK_INT_DIS |0 ; -ptimer_set_limit (env->tick,TICK_MAX ,1 ); -ptimer_run (env->tick,1 ); - env->stick_cmpr =TICK_INT_DIS |0 ; -ptimer_set_limit (env->stick,TICK_MAX ,1 ); -ptimer_run (env->stick,1 ); - env->hstick_cmpr =TICK_INT_DIS |0 ; -ptimer_set_limit (env->hstick,TICK_MAX ,1 ); -ptimer_run (env->hstick,1 ); + +sun4u_timer_reset (env->tick); +sun4u_timer_reset (env->stick); +sun4u_timer_reset (env->hstick); + env->gregs[1 ] =0 ;// Memory start env->gregs[2 ] = ram_size;// Memory size env->gregs[3 ] =0 ;// Machine description XXX
@@ -333,44 +378,114 @@ static void tick_irq(void *opaque) {CPUState *env = opaque; -if (!(env->tick_cmpr &TICK_INT_DIS )) { - env->softint |=SOFTINT_TIMER ; -cpu_interrupt (env,CPU_INTERRUPT_TIMER ); +sun4u_timer * timer = (sun4u_timer *) env->tick; + +if (timer->disabled) { +CPUIRQ_DPRINTF ("tick_irq: softint disabled\n" ); +return ; + }else { +CPUIRQ_DPRINTF ("tick: fire\n" ); } + + env->softint |=SOFTINT_TIMER ; +cpu_kick_irq (env); }static void stick_irq (void *opaque) {CPUState *env = opaque; -if (!(env->stick_cmpr &TICK_INT_DIS )) { - env->softint |=SOFTINT_STIMER ; -cpu_interrupt (env,CPU_INTERRUPT_TIMER ); +sun4u_timer * timer = (sun4u_timer *) env->stick; + +if (timer->disabled) { +CPUIRQ_DPRINTF ("stick_irq: softint disabled\n" ); +return ; + }else { +CPUIRQ_DPRINTF ("stick: fire\n" ); } + + env->softint |=SOFTINT_STIMER ; +cpu_kick_irq (env); }static void hstick_irq (void *opaque) {CPUState *env = opaque; -if (!(env->hstick_cmpr &TICK_INT_DIS )) { -cpu_interrupt (env,CPU_INTERRUPT_TIMER ); +sun4u_timer * timer = (sun4u_timer *) env->hstick; + +if (timer->disabled) { +CPUIRQ_DPRINTF ("hstick_irq: softint disabled\n" ); +return ; + }else { +CPUIRQ_DPRINTF ("hstick: fire\n" ); } + + env->softint |=SOFTINT_STIMER ; +cpu_kick_irq (env); }void cpu_tick_set_count (void *opaque,uint64_t count) { -ptimer_set_count (opaque, -count); +sun4u_timer *timer = opaque; + +uint64_t real_count = count & ~timer->disabled_mask; + timer->disabled = (count & timer->disabled_mask) ?1 :0 ; + +TIMER_DPRINTF ("%s (ignored) set_count count=0x%016lx (%s) p=%p\n" , + timer->name, real_count, timer->disabled?"disabled" :"enabled" , opaque); + +// TODO: save offset in our timer }uint64_t cpu_tick_get_count (void *opaque) { -return -ptimer_get_count (opaque); +sun4u_timer *timer = opaque; + +uint64_t real_count =muldiv64 (qemu_get_clock (vm_clock), timer->frequency, +get_ticks_per_sec ()); + +TIMER_DPRINTF ("%s get_count count=0x%016lx (%s) p=%p\n" , + timer->name, real_count, + timer->disabled?"disabled" :"enabled" , opaque); + +if (timer->disabled) + real_count |= timer->disabled_mask; + +return real_count; }void cpu_tick_set_limit (void *opaque,uint64_t limit) { -ptimer_set_limit (opaque, -limit,0 ); +sun4u_timer *timer = opaque; + +int64_t now =qemu_get_clock (vm_clock); + +int64_t real_limit = limit & ~timer->disabled_mask; +int64_t expires =muldiv64 (now, timer->frequency, +get_ticks_per_sec ()) & ~timer->disabled_mask; +int64_t current_tick = expires; +int64_t delta = real_limit - current_tick; +if (delta <0 ) + delta =1 ; + + timer->disabled = (limit & timer->disabled_mask) ?1 :0 ; + +TIMER_DPRINTF ("%s set_limit limit=0x%016lx (%s) p=%p " +"called with limit=0x%016lx at 0x%016lx (delta=0x%016lx)\n" , + timer->name, real_limit, timer->disabled?"disabled" :"enabled" , + opaque, limit, current_tick, delta); + +if (!real_limit) { +TIMER_DPRINTF ("%s set_limit limit=ZERO - not starting timer\n" , + timer->name); +qemu_del_timer (timer->qtimer); + }else if (timer->disabled) { +qemu_del_timer (timer->qtimer); + }else { +qemu_mod_timer (timer->qtimer, now +muldiv64 (delta,get_ticks_per_sec (), + timer->frequency)); + } } static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
@@ -557,9 +672,12 @@ device_init(ram_register_devices);static CPUState *cpu_devinit (const char *cpu_model,const struct hwdef *hwdef) {CPUState *env; -QEMUBH *bh;ResetData *reset_info; +uint32_t tick_frequency =10 *1000000 ; +uint32_t stick_frequency =10 *1000000 ; +uint32_t hstick_frequency =10 *1000000 ; +if (!cpu_model) cpu_model = hwdef->default_cpu_model; env =cpu_init (cpu_model);
@@ -567,17 +685,15 @@ static CPUState *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)fprintf (stderr,"Unable to find Sparc CPU definition\n" );exit (1 ); } - bh =qemu_bh_new (tick_irq, env); - env->tick =ptimer_init (bh); -ptimer_set_period (env->tick,1ULL ); - bh =qemu_bh_new (stick_irq, env); - env->stick =ptimer_init (bh); -ptimer_set_period (env->stick,1ULL ); + env->tick =sun4u_timer_create ("tick" , env, tick_irq, + tick_frequency,TICK_NPT_MASK ); + + env->stick =sun4u_timer_create ("stick" , env, stick_irq, + stick_frequency,TICK_INT_DIS ); - bh =qemu_bh_new (hstick_irq, env); - env->hstick =ptimer_init (bh); -ptimer_set_period (env->hstick,1ULL ); + env->hstick =sun4u_timer_create ("hstick" , env, hstick_irq, + hstick_frequency,TICK_INT_DIS ); reset_info =qemu_mallocz (sizeof (ResetData)); reset_info->env = env;
Blue Swirl
AppliedThanks, applied all except 9/9.
Quoted 43 lines · Igor V. Kovalenko
The following series is a cleanup over previous one.
v0 -> v1: post-review changes
- dropped patch "clearexception_indexwith -1 val" (applied)
- new patch "change_pstateshould have 32bit argument"
- cleanups for coding style and hexadecimal output convention
- wrpil is no-op forCONFIG_USER_ONLY
- restored PIL 15 as non-maskable interrupt level on sparcv8
- check for PSTATE.IE is replaced with call tocpu_interrupts_enabled()
- in patch "sparc64: interrupt trap handling"
cleaned up change incpu_exec; since sparc64 does not useCPU_INTERRUPT_TIMERnow, corresponding code branch is unchanged---
Igor V. Kovalenko (9):
sparc64:change_pstateshould have 32bit argument
sparc64: trace pstate and global register set changes
sparc64: add PIL to cpu state dump
sparc64: usehelper_wrpilto check pending irq on write
sparc64: check for pending irq when pil, pstate or softint is changed
sparc64: add macros to deal with softint and timer interrupt
sparc64: movecpu_interrupts_enabledtocpu.h
sparc64: interrupt trap handling
sparc64: reimplement tick timerscpu-exec.c | 28 +++---
hw/sun4u.c | 225 +++++++++++++++++++++++++++++++++++++---------target-sparc/cpu.h| 27 ++++++
target-sparc/exec.h | 13 ---
target-sparc/helper.c | 1
target-sparc/helper.h | 1
target-sparc/op_helper.c | 81 +++++++++++++++--target-sparc/translate.c| 5 -8 files changed, 300 insertions(+), 81 deletions(-)--
Kind regards,
Igor V. Kovalenko