diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2011-09-06 03:55:48 +0400 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2011-09-10 16:57:39 +0000 |
commit | b994e91b00cce463bfd306482dfe21630e11bf68 (patch) | |
tree | 097173c01d0e318e0201f30c877927193fce0e57 /target-xtensa/cpu.h | |
parent | 1ddeaa5d4277af76679d02bc59b08657c357aee6 (diff) | |
download | qemu-b994e91b00cce463bfd306482dfe21630e11bf68.zip qemu-b994e91b00cce463bfd306482dfe21630e11bf68.tar.gz qemu-b994e91b00cce463bfd306482dfe21630e11bf68.tar.bz2 |
target-xtensa: implement interrupt option
See ISA, 4.4.6 (interrupt option), 4.4.7 (high priority interrupt
option) and 4.4.8 (timer interrupt option) for details.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-xtensa/cpu.h')
-rw-r--r-- | target-xtensa/cpu.h | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 1283fd9..474466c 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -116,10 +116,16 @@ enum { WINDOW_START = 73, EPC1 = 177, DEPC = 192, + EPS2 = 194, EXCSAVE1 = 209, + INTSET = 226, + INTCLEAR = 227, + INTENABLE = 228, PS = 230, EXCCAUSE = 232, + CCOUNT = 234, EXCVADDR = 238, + CCOMPARE = 240, }; #define PS_INTLEVEL 0xf @@ -141,6 +147,10 @@ enum { #define PS_WOE 0x40000 #define MAX_NAREG 64 +#define MAX_NINTERRUPT 32 +#define MAX_NLEVEL 6 +#define MAX_NNMI 1 +#define MAX_NCCOMPARE 3 enum { /* Static vectors */ @@ -190,6 +200,17 @@ enum { COPROCESSOR0_DISABLED = 32, }; +typedef enum { + INTTYPE_LEVEL, + INTTYPE_EDGE, + INTTYPE_NMI, + INTTYPE_SOFTWARE, + INTTYPE_TIMER, + INTTYPE_DEBUG, + INTTYPE_WRITE_ERR, + INTTYPE_MAX +} interrupt_type; + typedef struct XtensaConfig { const char *name; uint64_t options; @@ -197,6 +218,18 @@ typedef struct XtensaConfig { int excm_level; int ndepc; uint32_t exception_vector[EXC_MAX]; + unsigned ninterrupt; + unsigned nlevel; + uint32_t interrupt_vector[MAX_NLEVEL + MAX_NNMI + 1]; + uint32_t level_mask[MAX_NLEVEL + MAX_NNMI + 1]; + uint32_t inttype_mask[INTTYPE_MAX]; + struct { + uint32_t level; + interrupt_type inttype; + } interrupt[MAX_NINTERRUPT]; + unsigned nccompare; + uint32_t timerint[MAX_NCCOMPARE]; + uint32_t clock_freq_khz; } XtensaConfig; typedef struct CPUXtensaState { @@ -207,6 +240,12 @@ typedef struct CPUXtensaState { uint32_t uregs[256]; uint32_t phys_regs[MAX_NAREG]; + int pending_irq_level; /* level of last raised IRQ */ + void **irq_inputs; + QEMUTimer *ccompare_timer; + uint32_t wake_ccount; + int64_t halt_clock; + int exception_taken; CPU_COMMON @@ -222,6 +261,10 @@ CPUXtensaState *cpu_xtensa_init(const char *cpu_model); void xtensa_translate_init(void); int cpu_xtensa_exec(CPUXtensaState *s); void do_interrupt(CPUXtensaState *s); +void check_interrupts(CPUXtensaState *s); +void xtensa_irq_init(CPUState *env); +void xtensa_advance_ccount(CPUState *env, uint32_t d); +void xtensa_timer_irq(CPUState *env, uint32_t id, uint32_t active); int cpu_xtensa_signal_handler(int host_signum, void *pinfo, void *puc); void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf); void xtensa_sync_window_from_phys(CPUState *env); @@ -298,7 +341,7 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, static inline int cpu_has_work(CPUState *env) { - return 1; + return env->pending_irq_level; } static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |