1 | ARM queue for 2.10: all M profile bugfixes... | 1 | Arm queue; bugfixes only. |
---|---|---|---|
2 | 2 | ||
3 | thanks | 3 | thanks |
4 | -- PMM | 4 | -- PMM |
5 | 5 | ||
6 | The following changes since commit 25dd0e77898c3e10796d4cbeb35e8af5ba6ce975: | 6 | The following changes since commit 48aa8f0ac536db3550a35c295ff7de94e4c33739: |
7 | 7 | ||
8 | Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-fetch' into staging (2017-07-31 11:27:43 +0100) | 8 | Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2020-11-16' into staging (2020-11-17 11:07:00 +0000) |
9 | 9 | ||
10 | are available in the git repository at: | 10 | are available in the Git repository at: |
11 | 11 | ||
12 | git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170731 | 12 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201117 |
13 | 13 | ||
14 | for you to fetch changes up to 89cbc3778a3d61761e2231e740269218c9a8a41d: | 14 | for you to fetch changes up to ab135622cf478585bdfcb68b85e4a817d74a0c42: |
15 | 15 | ||
16 | hw/mps2_scc: fix incorrect properties (2017-07-31 13:11:56 +0100) | 16 | tmp105: Correct handling of temperature limit checks (2020-11-17 12:56:33 +0000) |
17 | 17 | ||
18 | ---------------------------------------------------------------- | 18 | ---------------------------------------------------------------- |
19 | target-arm queue: | 19 | target-arm queue: |
20 | * fix broken properties on MPS2 SCC device | 20 | * hw/arm/virt: ARM_VIRT must select ARM_GIC |
21 | * fix MPU trace handling of write vs exec | 21 | * exynos: Fix bad printf format specifiers |
22 | * fix MPU M profile bugs: | 22 | * hw/input/ps2.c: Remove remnants of printf debug |
23 | - not handling system space or PPB region correctly | 23 | * target/openrisc: Remove dead code attempting to check "is timer disabled" |
24 | - not resetting state | 24 | * register: Remove unnecessary NULL check |
25 | - not migrating MPU_RNR | 25 | * util/cutils: Fix Coverity array overrun in freq_to_str() |
26 | * configure: Make "does libgio work" test pull in some actual functions | ||
27 | * tmp105: reset the T_low and T_High registers | ||
28 | * tmp105: Correct handling of temperature limit checks | ||
26 | 29 | ||
27 | ---------------------------------------------------------------- | 30 | ---------------------------------------------------------------- |
28 | Peter Maydell (6): | 31 | Alex Chen (1): |
29 | target/arm: Correct MPU trace handling of write vs execute | 32 | exynos: Fix bad printf format specifiers |
30 | target/arm: Don't do MPU lookups for addresses in M profile PPB region | 33 | |
31 | target/arm: Don't allow guest to make System space executable for M profile | 34 | Alistair Francis (1): |
32 | target/arm: Rename cp15.c6_rgnr to pmsav7.rnr | 35 | register: Remove unnecessary NULL check |
33 | target/arm: Move PMSAv7 reset into arm_cpu_reset() so M profile MPUs get reset | 36 | |
34 | target/arm: Migrate MPU_RNR register state for M profile cores | 37 | Andrew Jones (1): |
38 | hw/arm/virt: ARM_VIRT must select ARM_GIC | ||
39 | |||
40 | Peter Maydell (5): | ||
41 | hw/input/ps2.c: Remove remnants of printf debug | ||
42 | target/openrisc: Remove dead code attempting to check "is timer disabled" | ||
43 | configure: Make "does libgio work" test pull in some actual functions | ||
44 | hw/misc/tmp105: reset the T_low and T_High registers | ||
45 | tmp105: Correct handling of temperature limit checks | ||
35 | 46 | ||
36 | Philippe Mathieu-Daudé (1): | 47 | Philippe Mathieu-Daudé (1): |
37 | hw/mps2_scc: fix incorrect properties | 48 | util/cutils: Fix Coverity array overrun in freq_to_str() |
38 | 49 | ||
39 | target/arm/cpu.h | 3 +-- | 50 | configure | 11 +++++-- |
40 | hw/intc/armv7m_nvic.c | 14 +++++----- | 51 | hw/misc/tmp105.h | 7 +++++ |
41 | hw/misc/mps2-scc.c | 4 +-- | 52 | hw/core/register.c | 4 --- |
42 | target/arm/cpu.c | 14 ++++++++++ | 53 | hw/input/ps2.c | 9 ------ |
43 | target/arm/helper.c | 71 ++++++++++++++++++++++++++++++++++----------------- | 54 | hw/misc/tmp105.c | 73 ++++++++++++++++++++++++++++++++++++++------ |
44 | target/arm/machine.c | 30 +++++++++++++++++++++- | 55 | hw/timer/exynos4210_mct.c | 4 +-- |
45 | 6 files changed, 101 insertions(+), 35 deletions(-) | 56 | hw/timer/exynos4210_pwm.c | 8 ++--- |
57 | target/openrisc/sys_helper.c | 3 -- | ||
58 | util/cutils.c | 3 +- | ||
59 | hw/arm/Kconfig | 1 + | ||
60 | 10 files changed, 89 insertions(+), 34 deletions(-) | ||
46 | 61 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Andrew Jones <drjones@redhat.com> | ||
1 | 2 | ||
3 | The removal of the selection of A15MPCORE from ARM_VIRT also | ||
4 | removed what A15MPCORE selects, ARM_GIC. We still need ARM_GIC. | ||
5 | |||
6 | Fixes: bec3c97e0cf9 ("hw/arm/virt: Remove dependency on Cortex-A15 MPCore peripherals") | ||
7 | Reported-by: Miroslav Rezanina <mrezanin@redhat.com> | ||
8 | Signed-off-by: Andrew Jones <drjones@redhat.com> | ||
9 | Reviewed-by: Miroslav Rezanina <mrezanin@redhat.com> | ||
10 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
11 | Message-id: 20201111143440.112763-1-drjones@redhat.com | ||
12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
13 | --- | ||
14 | hw/arm/Kconfig | 1 + | ||
15 | 1 file changed, 1 insertion(+) | ||
16 | |||
17 | diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/arm/Kconfig | ||
20 | +++ b/hw/arm/Kconfig | ||
21 | @@ -XXX,XX +XXX,XX @@ config ARM_VIRT | ||
22 | imply VFIO_PLATFORM | ||
23 | imply VFIO_XGMAC | ||
24 | imply TPM_TIS_SYSBUS | ||
25 | + select ARM_GIC | ||
26 | select ACPI | ||
27 | select ARM_SMMUV3 | ||
28 | select GPIO_KEY | ||
29 | -- | ||
30 | 2.20.1 | ||
31 | |||
32 | diff view generated by jsdifflib |
1 | Almost all of the PMSAv7 state is in the pmsav7 substruct of | 1 | From: Alex Chen <alex.chen@huawei.com> |
---|---|---|---|
2 | the ARM CPU state structure. The exception is the region | ||
3 | number register, which is in cp15.c6_rgnr. This exception | ||
4 | is a bit odd for M profile, which otherwise generally does | ||
5 | not store state in the cp15 substruct. | ||
6 | 2 | ||
7 | Rename cp15.c6_rgnr to pmsav7.rnr accordingly. | 3 | We should use printf format specifier "%u" instead of "%d" for |
4 | argument of type "unsigned int". | ||
8 | 5 | ||
6 | Reported-by: Euler Robot <euler.robot@huawei.com> | ||
7 | Signed-off-by: Alex Chen <alex.chen@huawei.com> | ||
8 | Message-id: 20201111073651.72804-1-alex.chen@huawei.com | ||
9 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 10 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
10 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
11 | Message-id: 1501153150-19984-4-git-send-email-peter.maydell@linaro.org | ||
12 | --- | 11 | --- |
13 | target/arm/cpu.h | 3 +-- | 12 | hw/timer/exynos4210_mct.c | 4 ++-- |
14 | hw/intc/armv7m_nvic.c | 14 +++++++------- | 13 | hw/timer/exynos4210_pwm.c | 8 ++++---- |
15 | target/arm/helper.c | 6 +++--- | 14 | 2 files changed, 6 insertions(+), 6 deletions(-) |
16 | target/arm/machine.c | 2 +- | ||
17 | 4 files changed, 12 insertions(+), 13 deletions(-) | ||
18 | 15 | ||
19 | diff --git a/target/arm/cpu.h b/target/arm/cpu.h | 16 | diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c |
20 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/target/arm/cpu.h | 18 | --- a/hw/timer/exynos4210_mct.c |
22 | +++ b/target/arm/cpu.h | 19 | +++ b/hw/timer/exynos4210_mct.c |
23 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState { | 20 | @@ -XXX,XX +XXX,XX @@ static void exynos4210_gcomp_raise_irq(void *opaque, uint32_t id) |
24 | uint64_t par_el[4]; | 21 | /* If CSTAT is pending and IRQ is enabled */ |
25 | }; | 22 | if ((s->reg.int_cstat & G_INT_CSTAT_COMP(id)) && |
26 | 23 | (s->reg.int_enb & G_INT_ENABLE(id))) { | |
27 | - uint32_t c6_rgnr; | 24 | - DPRINTF("gcmp timer[%d] IRQ\n", id); |
28 | - | 25 | + DPRINTF("gcmp timer[%u] IRQ\n", id); |
29 | uint32_t c9_insn; /* Cache lockdown registers. */ | 26 | qemu_irq_raise(s->irq[id]); |
30 | uint32_t c9_data; | 27 | } |
31 | uint64_t c9_pmcr; /* performance monitor control register */ | 28 | } |
32 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState { | 29 | @@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_update_freq(Exynos4210MCTState *s) |
33 | uint32_t *drbar; | 30 | MCT_CFG_GET_DIVIDER(s->reg_mct_cfg)); |
34 | uint32_t *drsr; | 31 | |
35 | uint32_t *dracr; | 32 | if (freq != s->freq) { |
36 | + uint32_t rnr; | 33 | - DPRINTF("freq=%dHz\n", s->freq); |
37 | } pmsav7; | 34 | + DPRINTF("freq=%uHz\n", s->freq); |
38 | 35 | ||
39 | void *nvic; | 36 | /* global timer */ |
40 | diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c | 37 | tx_ptimer_set_freq(s->g_timer.ptimer_frc, s->freq); |
38 | diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | 39 | index XXXXXXX..XXXXXXX 100644 |
42 | --- a/hw/intc/armv7m_nvic.c | 40 | --- a/hw/timer/exynos4210_pwm.c |
43 | +++ b/hw/intc/armv7m_nvic.c | 41 | +++ b/hw/timer/exynos4210_pwm.c |
44 | @@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset) | 42 | @@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_update_freq(Exynos4210PWMState *s, uint32_t id) |
45 | case 0xd94: /* MPU_CTRL */ | 43 | |
46 | return cpu->env.v7m.mpu_ctrl; | 44 | if (freq != s->timer[id].freq) { |
47 | case 0xd98: /* MPU_RNR */ | 45 | ptimer_set_freq(s->timer[id].ptimer, s->timer[id].freq); |
48 | - return cpu->env.cp15.c6_rgnr; | 46 | - DPRINTF("freq=%dHz\n", s->timer[id].freq); |
49 | + return cpu->env.pmsav7.rnr; | 47 | + DPRINTF("freq=%uHz\n", s->timer[id].freq); |
50 | case 0xd9c: /* MPU_RBAR */ | ||
51 | case 0xda4: /* MPU_RBAR_A1 */ | ||
52 | case 0xdac: /* MPU_RBAR_A2 */ | ||
53 | case 0xdb4: /* MPU_RBAR_A3 */ | ||
54 | { | ||
55 | - int region = cpu->env.cp15.c6_rgnr; | ||
56 | + int region = cpu->env.pmsav7.rnr; | ||
57 | |||
58 | if (region >= cpu->pmsav7_dregion) { | ||
59 | return 0; | ||
60 | @@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset) | ||
61 | case 0xdb0: /* MPU_RASR_A2 */ | ||
62 | case 0xdb8: /* MPU_RASR_A3 */ | ||
63 | { | ||
64 | - int region = cpu->env.cp15.c6_rgnr; | ||
65 | + int region = cpu->env.pmsav7.rnr; | ||
66 | |||
67 | if (region >= cpu->pmsav7_dregion) { | ||
68 | return 0; | ||
69 | @@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) | ||
70 | PRIu32 "/%" PRIu32 "\n", | ||
71 | value, cpu->pmsav7_dregion); | ||
72 | } else { | ||
73 | - cpu->env.cp15.c6_rgnr = value; | ||
74 | + cpu->env.pmsav7.rnr = value; | ||
75 | } | ||
76 | break; | ||
77 | case 0xd9c: /* MPU_RBAR */ | ||
78 | @@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) | ||
79 | region, cpu->pmsav7_dregion); | ||
80 | return; | ||
81 | } | ||
82 | - cpu->env.cp15.c6_rgnr = region; | ||
83 | + cpu->env.pmsav7.rnr = region; | ||
84 | } else { | ||
85 | - region = cpu->env.cp15.c6_rgnr; | ||
86 | + region = cpu->env.pmsav7.rnr; | ||
87 | } | ||
88 | |||
89 | if (region >= cpu->pmsav7_dregion) { | ||
90 | @@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) | ||
91 | case 0xdb0: /* MPU_RASR_A2 */ | ||
92 | case 0xdb8: /* MPU_RASR_A3 */ | ||
93 | { | ||
94 | - int region = cpu->env.cp15.c6_rgnr; | ||
95 | + int region = cpu->env.pmsav7.rnr; | ||
96 | |||
97 | if (region >= cpu->pmsav7_dregion) { | ||
98 | return; | ||
99 | diff --git a/target/arm/helper.c b/target/arm/helper.c | ||
100 | index XXXXXXX..XXXXXXX 100644 | ||
101 | --- a/target/arm/helper.c | ||
102 | +++ b/target/arm/helper.c | ||
103 | @@ -XXX,XX +XXX,XX @@ static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri) | ||
104 | return 0; | ||
105 | } | 48 | } |
106 | |||
107 | - u32p += env->cp15.c6_rgnr; | ||
108 | + u32p += env->pmsav7.rnr; | ||
109 | return *u32p; | ||
110 | } | 49 | } |
111 | 50 | ||
112 | @@ -XXX,XX +XXX,XX @@ static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri, | 51 | @@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_tick(void *opaque) |
113 | return; | 52 | uint32_t id = s->id; |
53 | bool cmp; | ||
54 | |||
55 | - DPRINTF("timer %d tick\n", id); | ||
56 | + DPRINTF("timer %u tick\n", id); | ||
57 | |||
58 | /* set irq status */ | ||
59 | p->reg_tint_cstat |= TINT_CSTAT_STATUS(id); | ||
60 | |||
61 | /* raise IRQ */ | ||
62 | if (p->reg_tint_cstat & TINT_CSTAT_ENABLE(id)) { | ||
63 | - DPRINTF("timer %d IRQ\n", id); | ||
64 | + DPRINTF("timer %u IRQ\n", id); | ||
65 | qemu_irq_raise(p->timer[id].irq); | ||
114 | } | 66 | } |
115 | 67 | ||
116 | - u32p += env->cp15.c6_rgnr; | 68 | @@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_tick(void *opaque) |
117 | + u32p += env->pmsav7.rnr; | 69 | } |
118 | tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */ | 70 | |
119 | *u32p = value; | 71 | if (cmp) { |
120 | } | 72 | - DPRINTF("auto reload timer %d count to %x\n", id, |
121 | @@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav7_cp_reginfo[] = { | 73 | + DPRINTF("auto reload timer %u count to %x\n", id, |
122 | .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, | 74 | p->timer[id].reg_tcntb); |
123 | { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0, | 75 | ptimer_set_count(p->timer[id].ptimer, p->timer[id].reg_tcntb); |
124 | .access = PL1_RW, | 76 | ptimer_run(p->timer[id].ptimer, 1); |
125 | - .fieldoffset = offsetof(CPUARMState, cp15.c6_rgnr), | ||
126 | + .fieldoffset = offsetof(CPUARMState, pmsav7.rnr), | ||
127 | .writefn = pmsav7_rgnr_write }, | ||
128 | REGINFO_SENTINEL | ||
129 | }; | ||
130 | diff --git a/target/arm/machine.c b/target/arm/machine.c | ||
131 | index XXXXXXX..XXXXXXX 100644 | ||
132 | --- a/target/arm/machine.c | ||
133 | +++ b/target/arm/machine.c | ||
134 | @@ -XXX,XX +XXX,XX @@ static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id) | ||
135 | { | ||
136 | ARMCPU *cpu = opaque; | ||
137 | |||
138 | - return cpu->env.cp15.c6_rgnr < cpu->pmsav7_dregion; | ||
139 | + return cpu->env.pmsav7.rnr < cpu->pmsav7_dregion; | ||
140 | } | ||
141 | |||
142 | static const VMStateDescription vmstate_pmsav7 = { | ||
143 | -- | 77 | -- |
144 | 2.7.4 | 78 | 2.20.1 |
145 | 79 | ||
146 | 80 | diff view generated by jsdifflib |
1 | For an M profile v7PMSA, the system space (0xe0000000 - 0xffffffff) can | 1 | In commit 5edab03d4040 we added tracepoints to the ps2 keyboard |
---|---|---|---|
2 | never be executable, even if the guest tries to set the MPU registers | 2 | and mouse emulation. However we didn't remove all the debug-by-printf |
3 | up that way. Enforce this restriction. | 3 | support. In fact there is only one printf() remaining, and it is |
4 | redundant with the trace_ps2_write_mouse() event next to it. | ||
5 | Remove the printf() and the now-unused DEBUG* macros. | ||
4 | 6 | ||
5 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
6 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 8 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
7 | Message-id: 1501153150-19984-3-git-send-email-peter.maydell@linaro.org | 9 | Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> |
10 | Message-id: 20201101133258.4240-1-peter.maydell@linaro.org | ||
8 | --- | 11 | --- |
9 | target/arm/helper.c | 16 +++++++++++++++- | 12 | hw/input/ps2.c | 9 --------- |
10 | 1 file changed, 15 insertions(+), 1 deletion(-) | 13 | 1 file changed, 9 deletions(-) |
11 | 14 | ||
12 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 15 | diff --git a/hw/input/ps2.c b/hw/input/ps2.c |
13 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/arm/helper.c | 17 | --- a/hw/input/ps2.c |
15 | +++ b/target/arm/helper.c | 18 | +++ b/hw/input/ps2.c |
16 | @@ -XXX,XX +XXX,XX @@ static inline bool m_is_ppb_region(CPUARMState *env, uint32_t address) | 19 | @@ -XXX,XX +XXX,XX @@ |
17 | extract32(address, 20, 12) == 0xe00; | 20 | |
18 | } | 21 | #include "trace.h" |
19 | 22 | ||
20 | +static inline bool m_is_system_region(CPUARMState *env, uint32_t address) | 23 | -/* debug PC keyboard */ |
21 | +{ | 24 | -//#define DEBUG_KBD |
22 | + /* True if address is in the M profile system region | 25 | - |
23 | + * 0xe0000000 - 0xffffffff | 26 | -/* debug PC keyboard : only mouse */ |
24 | + */ | 27 | -//#define DEBUG_MOUSE |
25 | + return arm_feature(env, ARM_FEATURE_M) && extract32(address, 29, 3) == 0x7; | 28 | - |
26 | +} | 29 | /* Keyboard Commands */ |
27 | + | 30 | #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ |
28 | static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, | 31 | #define KBD_CMD_ECHO 0xEE |
29 | int access_type, ARMMMUIdx mmu_idx, | 32 | @@ -XXX,XX +XXX,XX @@ void ps2_write_mouse(void *opaque, int val) |
30 | hwaddr *phys_ptr, int *prot, uint32_t *fsr) | 33 | PS2MouseState *s = (PS2MouseState *)opaque; |
31 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, | 34 | |
32 | get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); | 35 | trace_ps2_write_mouse(opaque, val); |
33 | } else { /* a MPU hit! */ | 36 | -#ifdef DEBUG_MOUSE |
34 | uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3); | 37 | - printf("kbd: write mouse 0x%02x\n", val); |
35 | + uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1); | 38 | -#endif |
36 | + | 39 | switch(s->common.write_cmd) { |
37 | + if (m_is_system_region(env, address)) { | 40 | default: |
38 | + /* System space is always execute never */ | 41 | case -1: |
39 | + xn = 1; | ||
40 | + } | ||
41 | |||
42 | if (is_user) { /* User mode AP bit decoding */ | ||
43 | switch (ap) { | ||
44 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, | ||
45 | } | ||
46 | |||
47 | /* execute never */ | ||
48 | - if (env->pmsav7.dracr[n] & (1 << 12)) { | ||
49 | + if (xn) { | ||
50 | *prot &= ~PAGE_EXEC; | ||
51 | } | ||
52 | } | ||
53 | -- | 42 | -- |
54 | 2.7.4 | 43 | 2.20.1 |
55 | 44 | ||
56 | 45 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | In the mtspr helper we attempt to check for "is the timer disabled" | ||
2 | with "if (env->ttmr & TIMER_NONE)". This is wrong because TIMER_NONE | ||
3 | is zero and the condition is always false (Coverity complains about | ||
4 | the dead code.) | ||
1 | 5 | ||
6 | The correct check would be to test whether the TTMR_M field in the | ||
7 | register is equal to TIMER_NONE instead. However, the | ||
8 | cpu_openrisc_timer_update() function checks whether the timer is | ||
9 | enabled (it looks at cpu->env.is_counting, which is set to 0 via | ||
10 | cpu_openrisc_count_stop() when the TTMR_M field is set to | ||
11 | TIMER_NONE), so there's no need to check for "timer disabled" in the | ||
12 | target/openrisc code. Instead, simply remove the dead code. | ||
13 | |||
14 | Fixes: Coverity CID 1005812 | ||
15 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
16 | Acked-by: Stafford Horne <shorne@gmail.com> | ||
17 | Message-id: 20201103114654.18540-1-peter.maydell@linaro.org | ||
18 | --- | ||
19 | target/openrisc/sys_helper.c | 3 --- | ||
20 | 1 file changed, 3 deletions(-) | ||
21 | |||
22 | diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/target/openrisc/sys_helper.c | ||
25 | +++ b/target/openrisc/sys_helper.c | ||
26 | @@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) | ||
27 | |||
28 | case TO_SPR(10, 1): /* TTCR */ | ||
29 | cpu_openrisc_count_set(cpu, rb); | ||
30 | - if (env->ttmr & TIMER_NONE) { | ||
31 | - return; | ||
32 | - } | ||
33 | cpu_openrisc_timer_update(cpu); | ||
34 | break; | ||
35 | #endif | ||
36 | -- | ||
37 | 2.20.1 | ||
38 | |||
39 | diff view generated by jsdifflib |
1 | When the PMSAv7 implementation was originally added it was for R profile | 1 | From: Alistair Francis <alistair.francis@wdc.com> |
---|---|---|---|
2 | CPUs only, and reset was handled using the cpreg .resetfn hooks. | ||
3 | Unfortunately for M profile cores this doesn't work, because they do | ||
4 | not register any cpregs. Move the reset handling into arm_cpu_reset(), | ||
5 | where it will work for both R profile and M profile cores. | ||
6 | 2 | ||
3 | This patch fixes CID 1432800 by removing an unnecessary check. | ||
4 | |||
5 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
9 | Message-id: 1501153150-19984-5-git-send-email-peter.maydell@linaro.org | ||
10 | --- | 8 | --- |
11 | target/arm/cpu.c | 14 ++++++++++++++ | 9 | hw/core/register.c | 4 ---- |
12 | target/arm/helper.c | 28 ++++++++++++---------------- | 10 | 1 file changed, 4 deletions(-) |
13 | 2 files changed, 26 insertions(+), 16 deletions(-) | ||
14 | 11 | ||
15 | diff --git a/target/arm/cpu.c b/target/arm/cpu.c | 12 | diff --git a/hw/core/register.c b/hw/core/register.c |
16 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/arm/cpu.c | 14 | --- a/hw/core/register.c |
18 | +++ b/target/arm/cpu.c | 15 | +++ b/hw/core/register.c |
19 | @@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s) | 16 | @@ -XXX,XX +XXX,XX @@ static RegisterInfoArray *register_init_block(DeviceState *owner, |
20 | 17 | int index = rae[i].addr / data_size; | |
21 | env->vfp.xregs[ARM_VFP_FPEXC] = 0; | 18 | RegisterInfo *r = &ri[index]; |
22 | #endif | 19 | |
23 | + | 20 | - if (data + data_size * index == 0 || !&rae[i]) { |
24 | + if (arm_feature(env, ARM_FEATURE_PMSA) && | 21 | - continue; |
25 | + arm_feature(env, ARM_FEATURE_V7)) { | 22 | - } |
26 | + if (cpu->pmsav7_dregion > 0) { | ||
27 | + memset(env->pmsav7.drbar, 0, | ||
28 | + sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion); | ||
29 | + memset(env->pmsav7.drsr, 0, | ||
30 | + sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion); | ||
31 | + memset(env->pmsav7.dracr, 0, | ||
32 | + sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion); | ||
33 | + } | ||
34 | + env->pmsav7.rnr = 0; | ||
35 | + } | ||
36 | + | ||
37 | set_flush_to_zero(1, &env->vfp.standard_fp_status); | ||
38 | set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); | ||
39 | set_default_nan_mode(1, &env->vfp.standard_fp_status); | ||
40 | diff --git a/target/arm/helper.c b/target/arm/helper.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/target/arm/helper.c | ||
43 | +++ b/target/arm/helper.c | ||
44 | @@ -XXX,XX +XXX,XX @@ static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||
45 | *u32p = value; | ||
46 | } | ||
47 | |||
48 | -static void pmsav7_reset(CPUARMState *env, const ARMCPRegInfo *ri) | ||
49 | -{ | ||
50 | - ARMCPU *cpu = arm_env_get_cpu(env); | ||
51 | - uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); | ||
52 | - | 23 | - |
53 | - if (!u32p) { | 24 | /* Init the register, this will zero it. */ |
54 | - return; | 25 | object_initialize((void *)r, sizeof(*r), TYPE_REGISTER); |
55 | - } | ||
56 | - | ||
57 | - memset(u32p, 0, sizeof(*u32p) * cpu->pmsav7_dregion); | ||
58 | -} | ||
59 | - | ||
60 | static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||
61 | uint64_t value) | ||
62 | { | ||
63 | @@ -XXX,XX +XXX,XX @@ static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||
64 | } | ||
65 | |||
66 | static const ARMCPRegInfo pmsav7_cp_reginfo[] = { | ||
67 | + /* Reset for all these registers is handled in arm_cpu_reset(), | ||
68 | + * because the PMSAv7 is also used by M-profile CPUs, which do | ||
69 | + * not register cpregs but still need the state to be reset. | ||
70 | + */ | ||
71 | { .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0, | ||
72 | .access = PL1_RW, .type = ARM_CP_NO_RAW, | ||
73 | .fieldoffset = offsetof(CPUARMState, pmsav7.drbar), | ||
74 | - .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, | ||
75 | + .readfn = pmsav7_read, .writefn = pmsav7_write, | ||
76 | + .resetfn = arm_cp_reset_ignore }, | ||
77 | { .name = "DRSR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 2, | ||
78 | .access = PL1_RW, .type = ARM_CP_NO_RAW, | ||
79 | .fieldoffset = offsetof(CPUARMState, pmsav7.drsr), | ||
80 | - .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, | ||
81 | + .readfn = pmsav7_read, .writefn = pmsav7_write, | ||
82 | + .resetfn = arm_cp_reset_ignore }, | ||
83 | { .name = "DRACR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 4, | ||
84 | .access = PL1_RW, .type = ARM_CP_NO_RAW, | ||
85 | .fieldoffset = offsetof(CPUARMState, pmsav7.dracr), | ||
86 | - .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, | ||
87 | + .readfn = pmsav7_read, .writefn = pmsav7_write, | ||
88 | + .resetfn = arm_cp_reset_ignore }, | ||
89 | { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0, | ||
90 | .access = PL1_RW, | ||
91 | .fieldoffset = offsetof(CPUARMState, pmsav7.rnr), | ||
92 | - .writefn = pmsav7_rgnr_write }, | ||
93 | + .writefn = pmsav7_rgnr_write, | ||
94 | + .resetfn = arm_cp_reset_ignore }, | ||
95 | REGINFO_SENTINEL | ||
96 | }; | ||
97 | 26 | ||
98 | -- | 27 | -- |
99 | 2.7.4 | 28 | 2.20.1 |
100 | 29 | ||
101 | 30 | diff view generated by jsdifflib |
1 | From: Philippe Mathieu-Daudé <f4bug@amsat.org> | 1 | From: Philippe Mathieu-Daudé <f4bug@amsat.org> |
---|---|---|---|
2 | 2 | ||
3 | Fix Coverity CID 1435957: Memory - illegal accesses (OVERRUN): | ||
4 | |||
5 | >>> Overrunning array "suffixes" of 7 8-byte elements at element | ||
6 | index 7 (byte offset 63) using index "idx" (which evaluates to 7). | ||
7 | |||
8 | Note, the biggest input value freq_to_str() can accept is UINT64_MAX, | ||
9 | which is ~18.446 EHz, less than 1000 EHz. | ||
10 | |||
11 | Reported-by: Eduardo Habkost <ehabkost@redhat.com> | ||
3 | Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 12 | Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> |
4 | Message-id: 20170729234930.725-1-f4bug@amsat.org | ||
5 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 13 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
14 | Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> | ||
15 | Reviewed-by: Luc Michel <luc@lmichel.fr> | ||
16 | Message-id: 20201101215755.2021421-1-f4bug@amsat.org | ||
17 | Suggested-by: Peter Maydell <peter.maydell@linaro.org> | ||
18 | Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
6 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 19 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
7 | --- | 20 | --- |
8 | hw/misc/mps2-scc.c | 4 ++-- | 21 | util/cutils.c | 3 ++- |
9 | 1 file changed, 2 insertions(+), 2 deletions(-) | 22 | 1 file changed, 2 insertions(+), 1 deletion(-) |
10 | 23 | ||
11 | diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c | 24 | diff --git a/util/cutils.c b/util/cutils.c |
12 | index XXXXXXX..XXXXXXX 100644 | 25 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/hw/misc/mps2-scc.c | 26 | --- a/util/cutils.c |
14 | +++ b/hw/misc/mps2-scc.c | 27 | +++ b/util/cutils.c |
15 | @@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = { | 28 | @@ -XXX,XX +XXX,XX @@ char *freq_to_str(uint64_t freq_hz) |
16 | /* Values for various read-only ID registers (which are specific | 29 | double freq = freq_hz; |
17 | * to the board model or FPGA image) | 30 | size_t idx = 0; |
18 | */ | 31 | |
19 | - DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, aid, 0), | 32 | - while (freq >= 1000.0 && idx < ARRAY_SIZE(suffixes)) { |
20 | + DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0), | 33 | + while (freq >= 1000.0) { |
21 | DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0), | 34 | freq /= 1000.0; |
22 | - DEFINE_PROP_UINT32("scc-id", MPS2SCC, aid, 0), | 35 | idx++; |
23 | + DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0), | 36 | } |
24 | /* These are the initial settings for the source clocks on the board. | 37 | + assert(idx < ARRAY_SIZE(suffixes)); |
25 | * In hardware they can be configured via a config file read by the | 38 | |
26 | * motherboard configuration controller to suit the FPGA image. | 39 | return g_strdup_printf("%0.3g %sHz", freq, suffixes[idx]); |
40 | } | ||
27 | -- | 41 | -- |
28 | 2.7.4 | 42 | 2.20.1 |
29 | 43 | ||
30 | 44 | diff view generated by jsdifflib |
1 | Correct off-by-one bug in the PSMAv7 MPU tracing where it would print | 1 | In commit 76346b6264a9b01979 we tried to add a configure check that |
---|---|---|---|
2 | a write access as "reading", an insn fetch as "writing", and a read | 2 | the libgio pkg-config data was correct, which builds an executable |
3 | access as "execute". | 3 | linked against it. Unfortunately this doesn't catch the problem |
4 | (missing static library dependency info), because a "do nothing" test | ||
5 | source file doesn't have any symbol references that cause the linker | ||
6 | to pull in .o files from libgio.a, and so we don't see the "missing | ||
7 | symbols from libmount" error that a full QEMU link triggers. | ||
4 | 8 | ||
5 | Since we have an MMUAccessType enum now, we can make the code clearer | 9 | (The ineffective test went unnoticed because of a typo that |
6 | in the process by using that rather than the raw 0/1/2 values. | 10 | effectively disabled libgio unconditionally, but after commit |
11 | 3569a5dfc11f2 fixed that, a static link of the system emulator on | ||
12 | Ubuntu stopped working again.) | ||
13 | |||
14 | Improve the gio test by having the test source fragment reference a | ||
15 | g_dbus function (which is what is indirectly causing us to end up | ||
16 | wanting functions from libmount). | ||
7 | 17 | ||
8 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 18 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
9 | Reviewed-by: Richard Henderson <rth@twiddle.net> | 19 | Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> |
10 | Message-id: 1500906792-18010-1-git-send-email-peter.maydell@linaro.org | 20 | Message-id: 20201116104617.18333-1-peter.maydell@linaro.org |
11 | --- | 21 | --- |
12 | target/arm/helper.c | 4 ++-- | 22 | configure | 11 +++++++++-- |
13 | 1 file changed, 2 insertions(+), 2 deletions(-) | 23 | 1 file changed, 9 insertions(+), 2 deletions(-) |
14 | 24 | ||
15 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 25 | diff --git a/configure b/configure |
16 | index XXXXXXX..XXXXXXX 100644 | 26 | index XXXXXXX..XXXXXXX 100755 |
17 | --- a/target/arm/helper.c | 27 | --- a/configure |
18 | +++ b/target/arm/helper.c | 28 | +++ b/configure |
19 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address, | 29 | @@ -XXX,XX +XXX,XX @@ if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then |
20 | phys_ptr, prot, fsr); | 30 | # Check that the libraries actually work -- Ubuntu 18.04 ships |
21 | qemu_log_mask(CPU_LOG_MMU, "PMSAv7 MPU lookup for %s at 0x%08" PRIx32 | 31 | # with pkg-config --static --libs data for gio-2.0 that is missing |
22 | " mmu_idx %u -> %s (prot %c%c%c)\n", | 32 | # -lblkid and will give a link error. |
23 | - access_type == 1 ? "reading" : | 33 | - write_c_skeleton |
24 | - (access_type == 2 ? "writing" : "execute"), | 34 | - if compile_prog "" "$gio_libs" ; then |
25 | + access_type == MMU_DATA_LOAD ? "reading" : | 35 | + cat > $TMPC <<EOF |
26 | + (access_type == MMU_DATA_STORE ? "writing" : "execute"), | 36 | +#include <gio/gio.h> |
27 | (uint32_t)address, mmu_idx, | 37 | +int main(void) |
28 | ret ? "Miss" : "Hit", | 38 | +{ |
29 | *prot & PAGE_READ ? 'r' : '-', | 39 | + g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0); |
40 | + return 0; | ||
41 | +} | ||
42 | +EOF | ||
43 | + if compile_prog "$gio_cflags" "$gio_libs" ; then | ||
44 | gio=yes | ||
45 | else | ||
46 | gio=no | ||
30 | -- | 47 | -- |
31 | 2.7.4 | 48 | 2.20.1 |
32 | 49 | ||
33 | 50 | diff view generated by jsdifflib |
1 | The M profile PMSAv7 specification says that if the address being looked | 1 | The TMP105 datasheet (https://www.ti.com/lit/gpn/tmp105) says that the |
---|---|---|---|
2 | up is in the PPB region (0xe0000000 - 0xe00fffff) then we do not use | 2 | power-up reset values for the T_low and T_high registers are 80 degrees C |
3 | the MPU regions but always use the default memory map. Implement this | 3 | and 75 degrees C, which are 0x500 and 0x4B0 hex according to table 5. These |
4 | (we were previously behaving like an R profile PMSAv7, which does not | 4 | values are then shifted right by four bits to give the register reset |
5 | special case this). | 5 | values, since both registers store the 12 bits of temperature data in bits |
6 | [15..4] of a 16 bit register. | ||
7 | |||
8 | We were resetting these registers to zero, which is problematic for Linux | ||
9 | guests which enable the alert interrupt and then immediately take an | ||
10 | unexpected overtemperature alert because the current temperature is above | ||
11 | freezing... | ||
6 | 12 | ||
7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 13 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 14 | Reviewed-by: Cédric Le Goater <clg@kaod.org> |
9 | Message-id: 1501153150-19984-2-git-send-email-peter.maydell@linaro.org | 15 | Message-id: 20201110150023.25533-2-peter.maydell@linaro.org |
10 | --- | 16 | --- |
11 | target/arm/helper.c | 17 ++++++++++++++++- | 17 | hw/misc/tmp105.c | 3 +++ |
12 | 1 file changed, 16 insertions(+), 1 deletion(-) | 18 | 1 file changed, 3 insertions(+) |
13 | 19 | ||
14 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 20 | diff --git a/hw/misc/tmp105.c b/hw/misc/tmp105.c |
15 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/target/arm/helper.c | 22 | --- a/hw/misc/tmp105.c |
17 | +++ b/target/arm/helper.c | 23 | +++ b/hw/misc/tmp105.c |
18 | @@ -XXX,XX +XXX,XX @@ static bool pmsav7_use_background_region(ARMCPU *cpu, | 24 | @@ -XXX,XX +XXX,XX @@ static void tmp105_reset(I2CSlave *i2c) |
19 | } | 25 | s->faults = tmp105_faultq[(s->config >> 3) & 3]; |
26 | s->alarm = 0; | ||
27 | |||
28 | + s->limit[0] = 0x4b00; /* T_LOW, 75 degrees C */ | ||
29 | + s->limit[1] = 0x5000; /* T_HIGH, 80 degrees C */ | ||
30 | + | ||
31 | tmp105_interrupt_update(s); | ||
20 | } | 32 | } |
21 | 33 | ||
22 | +static inline bool m_is_ppb_region(CPUARMState *env, uint32_t address) | ||
23 | +{ | ||
24 | + /* True if address is in the M profile PPB region 0xe0000000 - 0xe00fffff */ | ||
25 | + return arm_feature(env, ARM_FEATURE_M) && | ||
26 | + extract32(address, 20, 12) == 0xe00; | ||
27 | +} | ||
28 | + | ||
29 | static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, | ||
30 | int access_type, ARMMMUIdx mmu_idx, | ||
31 | hwaddr *phys_ptr, int *prot, uint32_t *fsr) | ||
32 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, | ||
33 | *phys_ptr = address; | ||
34 | *prot = 0; | ||
35 | |||
36 | - if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */ | ||
37 | + if (regime_translation_disabled(env, mmu_idx) || | ||
38 | + m_is_ppb_region(env, address)) { | ||
39 | + /* MPU disabled or M profile PPB access: use default memory map. | ||
40 | + * The other case which uses the default memory map in the | ||
41 | + * v7M ARM ARM pseudocode is exception vector reads from the vector | ||
42 | + * table. In QEMU those accesses are done in arm_v7m_load_vector(), | ||
43 | + * which always does a direct read using address_space_ldl(), rather | ||
44 | + * than going via this function, so we don't need to check that here. | ||
45 | + */ | ||
46 | get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); | ||
47 | } else { /* MPU enabled */ | ||
48 | for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) { | ||
49 | -- | 34 | -- |
50 | 2.7.4 | 35 | 2.20.1 |
51 | 36 | ||
52 | 37 | diff view generated by jsdifflib |
1 | The PMSAv7 region number register is migrated for R profile | 1 | The TMP105 datasheet says that in Interrupt Mode (when TM==1) the device |
---|---|---|---|
2 | cores using the cpreg scheme, but M profile doesn't use | 2 | signals an alert when the temperature equals or exceeds the T_high value and |
3 | cpregs, and so we weren't migrating the MPU_RNR register state | 3 | then remains high until a device register is read or the device responds to |
4 | at all. Fix that by adding a migration subsection for the | 4 | the SMBUS Alert Response address, or the device is put into Shutdown Mode. |
5 | M profile case. | 5 | Thereafter the Alert pin will only be re-signalled when temperature falls |
6 | below T_low; alert can then be cleared in the same set of ways, and the | ||
7 | device returns to its initial "alert when temperature goes above T_high" | ||
8 | mode. (If this textual description is confusing, see figure 3 in the | ||
9 | TI datasheet at https://www.ti.com/lit/gpn/tmp105 .) | ||
10 | |||
11 | We were misimplementing this as a simple "always alert if temperature is | ||
12 | above T_high or below T_low" condition, which gives a spurious alert on | ||
13 | startup if using the "T_high = 80 degrees C, T_low = 75 degrees C" reset | ||
14 | limit values. | ||
15 | |||
16 | Implement the correct (hysteresis) behaviour by tracking whether we | ||
17 | are currently looking for the temperature to rise over T_high or | ||
18 | for it to fall below T_low. Our implementation of the comparator | ||
19 | mode (TM==0) wasn't wrong, but rephrase it to match the way that | ||
20 | interrupt mode is now handled for clarity. | ||
6 | 21 | ||
7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 22 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 23 | Reviewed-by: Cédric Le Goater <clg@kaod.org> |
9 | Message-id: 1501153150-19984-6-git-send-email-peter.maydell@linaro.org | 24 | Message-id: 20201110150023.25533-3-peter.maydell@linaro.org |
10 | --- | 25 | --- |
11 | target/arm/machine.c | 28 ++++++++++++++++++++++++++++ | 26 | hw/misc/tmp105.h | 7 +++++ |
12 | 1 file changed, 28 insertions(+) | 27 | hw/misc/tmp105.c | 70 +++++++++++++++++++++++++++++++++++++++++------- |
28 | 2 files changed, 68 insertions(+), 9 deletions(-) | ||
13 | 29 | ||
14 | diff --git a/target/arm/machine.c b/target/arm/machine.c | 30 | diff --git a/hw/misc/tmp105.h b/hw/misc/tmp105.h |
15 | index XXXXXXX..XXXXXXX 100644 | 31 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/target/arm/machine.c | 32 | --- a/hw/misc/tmp105.h |
17 | +++ b/target/arm/machine.c | 33 | +++ b/hw/misc/tmp105.h |
18 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav7 = { | 34 | @@ -XXX,XX +XXX,XX @@ struct TMP105State { |
35 | int16_t limit[2]; | ||
36 | int faults; | ||
37 | uint8_t alarm; | ||
38 | + /* | ||
39 | + * The TMP105 initially looks for a temperature rising above T_high; | ||
40 | + * once this is detected, the condition it looks for next is the | ||
41 | + * temperature falling below T_low. This flag is false when initially | ||
42 | + * looking for T_high, true when looking for T_low. | ||
43 | + */ | ||
44 | + bool detect_falling; | ||
45 | }; | ||
46 | |||
47 | #endif | ||
48 | diff --git a/hw/misc/tmp105.c b/hw/misc/tmp105.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/hw/misc/tmp105.c | ||
51 | +++ b/hw/misc/tmp105.c | ||
52 | @@ -XXX,XX +XXX,XX @@ static void tmp105_alarm_update(TMP105State *s) | ||
53 | return; | ||
19 | } | 54 | } |
20 | }; | 55 | |
21 | 56 | - if ((s->config >> 1) & 1) { /* TM */ | |
22 | +static bool pmsav7_rnr_needed(void *opaque) | 57 | - if (s->temperature >= s->limit[1]) |
58 | - s->alarm = 1; | ||
59 | - else if (s->temperature < s->limit[0]) | ||
60 | - s->alarm = 1; | ||
61 | + if (s->config >> 1 & 1) { | ||
62 | + /* | ||
63 | + * TM == 1 : Interrupt mode. We signal Alert when the | ||
64 | + * temperature rises above T_high, and expect the guest to clear | ||
65 | + * it (eg by reading a device register). | ||
66 | + */ | ||
67 | + if (s->detect_falling) { | ||
68 | + if (s->temperature < s->limit[0]) { | ||
69 | + s->alarm = 1; | ||
70 | + s->detect_falling = false; | ||
71 | + } | ||
72 | + } else { | ||
73 | + if (s->temperature >= s->limit[1]) { | ||
74 | + s->alarm = 1; | ||
75 | + s->detect_falling = true; | ||
76 | + } | ||
77 | + } | ||
78 | } else { | ||
79 | - if (s->temperature >= s->limit[1]) | ||
80 | - s->alarm = 1; | ||
81 | - else if (s->temperature < s->limit[0]) | ||
82 | - s->alarm = 0; | ||
83 | + /* | ||
84 | + * TM == 0 : Comparator mode. We signal Alert when the temperature | ||
85 | + * rises above T_high, and stop signalling it when the temperature | ||
86 | + * falls below T_low. | ||
87 | + */ | ||
88 | + if (s->detect_falling) { | ||
89 | + if (s->temperature < s->limit[0]) { | ||
90 | + s->alarm = 0; | ||
91 | + s->detect_falling = false; | ||
92 | + } | ||
93 | + } else { | ||
94 | + if (s->temperature >= s->limit[1]) { | ||
95 | + s->alarm = 1; | ||
96 | + s->detect_falling = true; | ||
97 | + } | ||
98 | + } | ||
99 | } | ||
100 | |||
101 | tmp105_interrupt_update(s); | ||
102 | @@ -XXX,XX +XXX,XX @@ static int tmp105_post_load(void *opaque, int version_id) | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | +static bool detect_falling_needed(void *opaque) | ||
23 | +{ | 107 | +{ |
24 | + ARMCPU *cpu = opaque; | 108 | + TMP105State *s = opaque; |
25 | + CPUARMState *env = &cpu->env; | ||
26 | + | 109 | + |
27 | + /* For R profile cores pmsav7.rnr is migrated via the cpreg | 110 | + /* |
28 | + * "RGNR" definition in helper.h. For M profile we have to | 111 | + * We only need to migrate the detect_falling bool if it's set; |
29 | + * migrate it separately. | 112 | + * for migration from older machines we assume that it is false |
113 | + * (ie temperature is not out of range). | ||
30 | + */ | 114 | + */ |
31 | + return arm_feature(env, ARM_FEATURE_M); | 115 | + return s->detect_falling; |
32 | +} | 116 | +} |
33 | + | 117 | + |
34 | +static const VMStateDescription vmstate_pmsav7_rnr = { | 118 | +static const VMStateDescription vmstate_tmp105_detect_falling = { |
35 | + .name = "cpu/pmsav7-rnr", | 119 | + .name = "TMP105/detect-falling", |
36 | + .version_id = 1, | 120 | + .version_id = 1, |
37 | + .minimum_version_id = 1, | 121 | + .minimum_version_id = 1, |
38 | + .needed = pmsav7_rnr_needed, | 122 | + .needed = detect_falling_needed, |
39 | + .fields = (VMStateField[]) { | 123 | + .fields = (VMStateField[]) { |
40 | + VMSTATE_UINT32(env.pmsav7.rnr, ARMCPU), | 124 | + VMSTATE_BOOL(detect_falling, TMP105State), |
41 | + VMSTATE_END_OF_LIST() | 125 | + VMSTATE_END_OF_LIST() |
42 | + } | 126 | + } |
43 | +}; | 127 | +}; |
44 | + | 128 | + |
45 | static int get_cpsr(QEMUFile *f, void *opaque, size_t size, | 129 | static const VMStateDescription vmstate_tmp105 = { |
46 | VMStateField *field) | 130 | .name = "TMP105", |
47 | { | 131 | .version_id = 0, |
48 | @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = { | 132 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_tmp105 = { |
49 | &vmstate_iwmmxt, | 133 | VMSTATE_UINT8(alarm, TMP105State), |
50 | &vmstate_m, | 134 | VMSTATE_I2C_SLAVE(i2c, TMP105State), |
51 | &vmstate_thumb2ee, | 135 | VMSTATE_END_OF_LIST() |
52 | + /* pmsav7_rnr must come before pmsav7 so that we have the | 136 | + }, |
53 | + * region number before we test it in the VMSTATE_VALIDATE | 137 | + .subsections = (const VMStateDescription*[]) { |
54 | + * in vmstate_pmsav7. | 138 | + &vmstate_tmp105_detect_falling, |
55 | + */ | 139 | + NULL |
56 | + &vmstate_pmsav7_rnr, | ||
57 | &vmstate_pmsav7, | ||
58 | NULL | ||
59 | } | 140 | } |
141 | }; | ||
142 | |||
143 | @@ -XXX,XX +XXX,XX @@ static void tmp105_reset(I2CSlave *i2c) | ||
144 | s->config = 0; | ||
145 | s->faults = tmp105_faultq[(s->config >> 3) & 3]; | ||
146 | s->alarm = 0; | ||
147 | + s->detect_falling = false; | ||
148 | |||
149 | s->limit[0] = 0x4b00; /* T_LOW, 75 degrees C */ | ||
150 | s->limit[1] = 0x5000; /* T_HIGH, 80 degrees C */ | ||
60 | -- | 151 | -- |
61 | 2.7.4 | 152 | 2.20.1 |
62 | 153 | ||
63 | 154 | diff view generated by jsdifflib |