diff options
author | Fabien Chouteau <chouteau@adacore.com> | 2011-09-13 04:00:32 +0000 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2011-10-06 09:48:09 +0200 |
commit | ddd1055b07fdfe488a22c2275adaca75f4206d30 (patch) | |
tree | 562b06cea9452d0bdfca3e5a0928eefe736265c9 /target-ppc | |
parent | 94135e813c14bac3f967e6b5aa35b9d617737e68 (diff) |
PPC: booke timers
While working on the emulation of the freescale p2010 (e500v2) I realized that
there's no implementation of booke's timers features. Currently mpc8544 uses
ppc_emb (ppc_emb_timers_init) which is close but not exactly like booke (for
example booke uses different SPR).
Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/cpu.h | 27 | ||||
-rw-r--r-- | target-ppc/translate_init.c | 39 |
2 files changed, 66 insertions, 0 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 3f4af22397..3f77e308a6 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1018,8 +1018,35 @@ struct CPUPPCState { #if !defined(CONFIG_USER_ONLY) void *load_info; /* Holds boot loading state. */ #endif + + /* booke timers */ + + /* Specifies bit locations of the Time Base used to signal a fixed timer + * exception on a transition from 0 to 1. (watchdog or fixed-interval timer) + * + * 0 selects the least significant bit. + * 63 selects the most significant bit. + */ + uint8_t fit_period[4]; + uint8_t wdt_period[4]; }; +#define SET_FIT_PERIOD(a_, b_, c_, d_) \ +do { \ + env->fit_period[0] = (a_); \ + env->fit_period[1] = (b_); \ + env->fit_period[2] = (c_); \ + env->fit_period[3] = (d_); \ + } while (0) + +#define SET_WDT_PERIOD(a_, b_, c_, d_) \ +do { \ + env->wdt_period[0] = (a_); \ + env->wdt_period[1] = (b_); \ + env->wdt_period[2] = (c_); \ + env->wdt_period[3] = (d_); \ + } while (0) + #if !defined(CONFIG_USER_ONLY) /* Context used internally during MMU translations */ typedef struct mmu_ctx_t mmu_ctx_t; diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index d09c7ca98b..ca0d8525c8 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -3266,6 +3266,9 @@ static void init_proc_401 (CPUPPCState *env) env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 401x2 */ @@ -3304,6 +3307,9 @@ static void init_proc_401x2 (CPUPPCState *env) env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 401x3 */ @@ -3337,6 +3343,9 @@ static void init_proc_401x3 (CPUPPCState *env) env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(16, 20, 24, 28); } /* IOP480 */ @@ -3375,6 +3384,9 @@ static void init_proc_IOP480 (CPUPPCState *env) env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(8, 12, 16, 20); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 403 */ @@ -3405,6 +3417,9 @@ static void init_proc_403 (CPUPPCState *env) env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(8, 12, 16, 20); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 403 GCX */ @@ -3455,6 +3470,9 @@ static void init_proc_403GCX (CPUPPCState *env) env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(8, 12, 16, 20); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 405 */ @@ -3504,6 +3522,9 @@ static void init_proc_405 (CPUPPCState *env) env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(8, 12, 16, 20); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 440 EP */ @@ -3586,6 +3607,9 @@ static void init_proc_440EP (CPUPPCState *env) env->dcache_line_size = 32; env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* PowerPC 440 GP */ @@ -3650,6 +3674,9 @@ static void init_proc_440GP (CPUPPCState *env) env->dcache_line_size = 32; env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* PowerPC 440x4 */ @@ -3714,6 +3741,9 @@ static void init_proc_440x4 (CPUPPCState *env) env->dcache_line_size = 32; env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* PowerPC 440x5 */ @@ -3795,6 +3825,9 @@ static void init_proc_440x5 (CPUPPCState *env) env->dcache_line_size = 32; env->icache_line_size = 32; ppc40x_irq_init(env); + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* PowerPC 460 (guessed) */ @@ -3883,6 +3916,9 @@ static void init_proc_460 (CPUPPCState *env) env->dcache_line_size = 32; env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* PowerPC 460F (guessed) */ @@ -3974,6 +4010,9 @@ static void init_proc_460F (CPUPPCState *env) env->dcache_line_size = 32; env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* Freescale 5xx cores (aka RCPU) */ |