Commit e57ec0168ce21cdda48ddf45d77b76185667d9e6
1 parent
aae9366a
ARMv7-M SysTick fix.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3727 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
9 additions
and
11 deletions
hw/arm-misc.h
| @@ -27,6 +27,7 @@ void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename, | @@ -27,6 +27,7 @@ void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename, | ||
| 27 | int board_id, target_phys_addr_t loader_start); | 27 | int board_id, target_phys_addr_t loader_start); |
| 28 | 28 | ||
| 29 | /* armv7m_nvic.c */ | 29 | /* armv7m_nvic.c */ |
| 30 | +int system_clock_scale; | ||
| 30 | qemu_irq *armv7m_nvic_init(CPUState *env); | 31 | qemu_irq *armv7m_nvic_init(CPUState *env); |
| 31 | 32 | ||
| 32 | #endif /* !ARM_MISC_H */ | 33 | #endif /* !ARM_MISC_H */ |
hw/arm_gic.c
| @@ -638,7 +638,7 @@ static void gic_reset(gic_state *s) | @@ -638,7 +638,7 @@ static void gic_reset(gic_state *s) | ||
| 638 | s->cpu_enabled[i] = 0; | 638 | s->cpu_enabled[i] = 0; |
| 639 | #endif | 639 | #endif |
| 640 | } | 640 | } |
| 641 | - for (i = 0; i < 15; i++) { | 641 | + for (i = 0; i < 16; i++) { |
| 642 | GIC_SET_ENABLED(i); | 642 | GIC_SET_ENABLED(i); |
| 643 | GIC_SET_TRIGGER(i); | 643 | GIC_SET_TRIGGER(i); |
| 644 | } | 644 | } |
hw/armv7m_nvic.c
| @@ -48,14 +48,15 @@ typedef struct { | @@ -48,14 +48,15 @@ typedef struct { | ||
| 48 | #define SYSTICK_CLKSOURCE (1 << 2) | 48 | #define SYSTICK_CLKSOURCE (1 << 2) |
| 49 | #define SYSTICK_COUNTFLAG (1 << 16) | 49 | #define SYSTICK_COUNTFLAG (1 << 16) |
| 50 | 50 | ||
| 51 | -/* Conversion factor from qemu timer to SysTick frequencies. | ||
| 52 | - QEMU uses a base of 1GHz, so these give 20MHz and 1MHz for core and | ||
| 53 | - reference frequencies. */ | 51 | +/* Multiplication factor to convert from system clock ticks to qemu timer |
| 52 | + ticks. */ | ||
| 53 | +int system_clock_scale; | ||
| 54 | 54 | ||
| 55 | +/* Conversion factor from qemu timer to SysTick frequencies. */ | ||
| 55 | static inline int64_t systick_scale(nvic_state *s) | 56 | static inline int64_t systick_scale(nvic_state *s) |
| 56 | { | 57 | { |
| 57 | if (s->systick.control & SYSTICK_CLKSOURCE) | 58 | if (s->systick.control & SYSTICK_CLKSOURCE) |
| 58 | - return 50; | 59 | + return system_clock_scale; |
| 59 | else | 60 | else |
| 60 | return 1000; | 61 | return 1000; |
| 61 | } | 62 | } |
hw/stellaris.c
| @@ -42,10 +42,6 @@ typedef const struct { | @@ -42,10 +42,6 @@ typedef const struct { | ||
| 42 | 42 | ||
| 43 | /* General purpose timer module. */ | 43 | /* General purpose timer module. */ |
| 44 | 44 | ||
| 45 | -/* Multiplication factor to convert from GPTM timer ticks to qemu timer | ||
| 46 | - ticks. */ | ||
| 47 | -static int stellaris_clock_scale; | ||
| 48 | - | ||
| 49 | typedef struct gptm_state { | 45 | typedef struct gptm_state { |
| 50 | uint32_t config; | 46 | uint32_t config; |
| 51 | uint32_t mode[2]; | 47 | uint32_t mode[2]; |
| @@ -90,7 +86,7 @@ static void gptm_reload(gptm_state *s, int n, int reset) | @@ -90,7 +86,7 @@ static void gptm_reload(gptm_state *s, int n, int reset) | ||
| 90 | /* 32-bit CountDown. */ | 86 | /* 32-bit CountDown. */ |
| 91 | uint32_t count; | 87 | uint32_t count; |
| 92 | count = s->load[0] | (s->load[1] << 16); | 88 | count = s->load[0] | (s->load[1] << 16); |
| 93 | - tick += (int64_t)count * stellaris_clock_scale; | 89 | + tick += (int64_t)count * system_clock_scale; |
| 94 | } else if (s->config == 1) { | 90 | } else if (s->config == 1) { |
| 95 | /* 32-bit RTC. 1Hz tick. */ | 91 | /* 32-bit RTC. 1Hz tick. */ |
| 96 | tick += ticks_per_sec; | 92 | tick += ticks_per_sec; |
| @@ -480,7 +476,7 @@ static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value) | @@ -480,7 +476,7 @@ static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value) | ||
| 480 | s->int_status |= (1 << 6); | 476 | s->int_status |= (1 << 6); |
| 481 | } | 477 | } |
| 482 | s->rcc = value; | 478 | s->rcc = value; |
| 483 | - stellaris_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1); | 479 | + system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1); |
| 484 | break; | 480 | break; |
| 485 | case 0x100: /* RCGC0 */ | 481 | case 0x100: /* RCGC0 */ |
| 486 | s->rcgc[0] = value; | 482 | s->rcgc[0] = value; |