1
A random mix of items here, nothing very major.
1
Arm queue; bugfixes only.
2
2
3
thanks
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit 48aa8f0ac536db3550a35c295ff7de94e4c33739:
6
7
7
The following changes since commit d0dff238a87fa81393ed72754d4dc8b09e50b08b:
8
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2020-11-16' into staging (2020-11-17 11:07:00 +0000)
8
9
9
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170206' into staging (2017-02-07 15:29:26 +0000)
10
are available in the Git repository at:
10
11
11
are available in the git repository at:
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201117
12
13
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170207
14
for you to fetch changes up to ab135622cf478585bdfcb68b85e4a817d74a0c42:
14
15
15
for you to fetch changes up to 7727b832886fafbdec7299eb7773dc9071bf4cdd:
16
tmp105: Correct handling of temperature limit checks (2020-11-17 12:56:33 +0000)
16
17
stellaris: Use the 'unimplemented' device for parts we don't implement (2017-02-07 18:30:00 +0000)
18
17
19
----------------------------------------------------------------
18
----------------------------------------------------------------
20
target-arm:
19
target-arm queue:
21
* new "unimplemented" device for stubbing out devices in a
20
* hw/arm/virt: ARM_VIRT must select ARM_GIC
22
system model so accesses can be logged
21
* exynos: Fix bad printf format specifiers
23
* stellaris: document the SoC memory map
22
* hw/input/ps2.c: Remove remnants of printf debug
24
* arm: create instruction syndromes for AArch32 data aborts
23
* target/openrisc: Remove dead code attempting to check "is timer disabled"
25
* arm: Correctly handle watchpoints for BE32 CPUs
24
* register: Remove unnecessary NULL check
26
* Fix Thumb-1 BE32 execution and disassembly
25
* util/cutils: Fix Coverity array overrun in freq_to_str()
27
* arm: Add cfgend parameter for ARM CPU selection
26
* configure: Make "does libgio work" test pull in some actual functions
28
* sd: sdhci: check data length during dma_memory_read
27
* tmp105: reset the T_low and T_High registers
29
* aspeed: add a watchdog controller
28
* tmp105: Correct handling of temperature limit checks
30
* integratorcp: adding vmstate for save/restore
31
29
32
----------------------------------------------------------------
30
----------------------------------------------------------------
33
Cédric Le Goater (2):
31
Alex Chen (1):
34
wdt: Add Aspeed watchdog device model
32
exynos: Fix bad printf format specifiers
35
aspeed: add a watchdog controller
36
33
37
Julian Brown (4):
34
Alistair Francis (1):
38
hw/arm/integratorcp: Support specifying features via -cpu
35
register: Remove unnecessary NULL check
39
target/arm: Add cfgend parameter for ARM CPU selection.
40
Fix Thumb-1 BE32 execution and disassembly.
41
arm: Correctly handle watchpoints for BE32 CPUs
42
36
43
Pavel Dovgalyuk (1):
37
Andrew Jones (1):
44
integratorcp: adding vmstate for save/restore
38
hw/arm/virt: ARM_VIRT must select ARM_GIC
45
39
46
Peter Maydell (5):
40
Peter Maydell (5):
47
target/arm: Abstract out pbit/wbit tests in ARM ldr/str decode
41
hw/input/ps2.c: Remove remnants of printf debug
48
target/arm: A32, T32: Create Instruction Syndromes for Data Aborts
42
target/openrisc: Remove dead code attempting to check "is timer disabled"
49
stellaris: Document memory map and which SoC devices are unimplemented
43
configure: Make "does libgio work" test pull in some actual functions
50
hw/misc: New "unimplemented" sysbus device
44
hw/misc/tmp105: reset the T_low and T_High registers
51
stellaris: Use the 'unimplemented' device for parts we don't implement
45
tmp105: Correct handling of temperature limit checks
52
46
53
Prasad J Pandit (1):
47
Philippe Mathieu-Daudé (1):
54
sd: sdhci: check data length during dma_memory_read
48
util/cutils: Fix Coverity array overrun in freq_to_str()
55
49
56
hw/misc/Makefile.objs | 2 +
50
configure | 11 +++++--
57
hw/watchdog/Makefile.objs | 1 +
51
hw/misc/tmp105.h | 7 +++++
58
include/disas/bfd.h | 7 ++
52
hw/core/register.c | 4 ---
59
include/hw/arm/aspeed_soc.h | 2 +
53
hw/input/ps2.c | 9 ------
60
include/hw/misc/unimp.h | 39 +++++++
54
hw/misc/tmp105.c | 73 ++++++++++++++++++++++++++++++++++++++------
61
include/hw/watchdog/wdt_aspeed.h | 32 ++++++
55
hw/timer/exynos4210_mct.c | 4 +--
62
include/qom/cpu.h | 3 +
56
hw/timer/exynos4210_pwm.c | 8 ++---
63
target/arm/arm_ldst.h | 10 +-
57
target/openrisc/sys_helper.c | 3 --
64
target/arm/cpu.h | 7 ++
58
util/cutils.c | 3 +-
65
target/arm/internals.h | 5 +
59
hw/arm/Kconfig | 1 +
66
target/arm/translate.h | 14 +++
60
10 files changed, 89 insertions(+), 34 deletions(-)
67
disas.c | 1 +
68
exec.c | 1 +
69
hw/arm/aspeed_soc.c | 13 +++
70
hw/arm/integratorcp.c | 78 +++++++++++++-
71
hw/arm/stellaris.c | 48 +++++++++
72
hw/misc/unimp.c | 107 +++++++++++++++++++
73
hw/sd/sdhci.c | 2 +-
74
hw/watchdog/wdt_aspeed.c | 225 +++++++++++++++++++++++++++++++++++++++
75
qom/cpu.c | 6 ++
76
target/arm/cpu.c | 39 +++++++
77
target/arm/op_helper.c | 22 ++++
78
target/arm/translate-a64.c | 14 ---
79
target/arm/translate.c | 193 ++++++++++++++++++++++++---------
80
24 files changed, 801 insertions(+), 70 deletions(-)
81
create mode 100644 include/hw/misc/unimp.h
82
create mode 100644 include/hw/watchdog/wdt_aspeed.h
83
create mode 100644 hw/misc/unimp.c
84
create mode 100644 hw/watchdog/wdt_aspeed.c
85
61
diff view generated by jsdifflib
1
From: Julian Brown <julian@codesourcery.com>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
In BE32 mode, sub-word size watchpoints can fail to trigger because the
3
The removal of the selection of A15MPCORE from ARM_VIRT also
4
address of the access is adjusted in the opcode helpers before being
4
removed what A15MPCORE selects, ARM_GIC. We still need ARM_GIC.
5
compared with the watchpoint registers. This patch reverses the address
6
adjustment before performing the comparison with the help of a new CPUClass
7
hook.
8
5
9
This version of the patch augments and tidies up comments a little.
6
Fixes: bec3c97e0cf9 ("hw/arm/virt: Remove dependency on Cortex-A15 MPCore peripherals")
10
7
Reported-by: Miroslav Rezanina <mrezanin@redhat.com>
11
Signed-off-by: Julian Brown <julian@codesourcery.com>
8
Signed-off-by: Andrew Jones <drjones@redhat.com>
12
Message-id: caaf64ffc72f6ae183015337b7afdbd4b8989cb6.1484929304.git.julian@codesourcery.com
9
Reviewed-by: Miroslav Rezanina <mrezanin@redhat.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20201111143440.112763-1-drjones@redhat.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
include/qom/cpu.h | 3 +++
14
hw/arm/Kconfig | 1 +
17
target/arm/internals.h | 5 +++++
15
1 file changed, 1 insertion(+)
18
exec.c | 1 +
19
qom/cpu.c | 6 ++++++
20
target/arm/cpu.c | 3 +++
21
target/arm/op_helper.c | 22 ++++++++++++++++++++++
22
6 files changed, 40 insertions(+)
23
16
24
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
17
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/include/qom/cpu.h
19
--- a/hw/arm/Kconfig
27
+++ b/include/qom/cpu.h
20
+++ b/hw/arm/Kconfig
28
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock;
21
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
29
* @cpu_exec_exit: Callback for cpu_exec cleanup.
22
imply VFIO_PLATFORM
30
* @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec.
23
imply VFIO_XGMAC
31
* @disas_set_info: Setup architecture specific components of disassembly info
24
imply TPM_TIS_SYSBUS
32
+ * @adjust_watchpoint_address: Perform a target-specific adjustment to an
25
+ select ARM_GIC
33
+ * address before attempting to match it against watchpoints.
26
select ACPI
34
*
27
select ARM_SMMUV3
35
* Represents a CPU family or model.
28
select GPIO_KEY
36
*/
37
@@ -XXX,XX +XXX,XX @@ typedef struct CPUClass {
38
bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
39
40
void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
41
+ vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
42
} CPUClass;
43
44
#ifdef HOST_WORDS_BIGENDIAN
45
diff --git a/target/arm/internals.h b/target/arm/internals.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/internals.h
48
+++ b/target/arm/internals.h
49
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update_all(ARMCPU *cpu);
50
/* Callback function for checking if a watchpoint should trigger. */
51
bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
52
53
+/* Adjust addresses (in BE32 mode) before testing against watchpoint
54
+ * addresses.
55
+ */
56
+vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len);
57
+
58
/* Callback function for when a watchpoint or breakpoint triggers. */
59
void arm_debug_excp_handler(CPUState *cs);
60
61
diff --git a/exec.c b/exec.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/exec.c
64
+++ b/exec.c
65
@@ -XXX,XX +XXX,XX @@ static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags)
66
return;
67
}
68
vaddr = (cpu->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
69
+ vaddr = cc->adjust_watchpoint_address(cpu, vaddr, len);
70
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
71
if (cpu_watchpoint_address_matches(wp, vaddr, len)
72
&& (wp->flags & flags)) {
73
diff --git a/qom/cpu.c b/qom/cpu.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/qom/cpu.c
76
+++ b/qom/cpu.c
77
@@ -XXX,XX +XXX,XX @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
78
return cpu->cpu_index;
79
}
80
81
+static vaddr cpu_adjust_watchpoint_address(CPUState *cpu, vaddr addr, int len)
82
+{
83
+ return addr;
84
+}
85
+
86
static void cpu_class_init(ObjectClass *klass, void *data)
87
{
88
DeviceClass *dc = DEVICE_CLASS(klass);
89
@@ -XXX,XX +XXX,XX @@ static void cpu_class_init(ObjectClass *klass, void *data)
90
k->cpu_exec_enter = cpu_common_noop;
91
k->cpu_exec_exit = cpu_common_noop;
92
k->cpu_exec_interrupt = cpu_common_exec_interrupt;
93
+ k->adjust_watchpoint_address = cpu_adjust_watchpoint_address;
94
set_bit(DEVICE_CATEGORY_CPU, dc->categories);
95
dc->realize = cpu_common_realizefn;
96
dc->unrealize = cpu_common_unrealizefn;
97
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/arm/cpu.c
100
+++ b/target/arm/cpu.c
101
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
102
cc->gdb_stop_before_watchpoint = true;
103
cc->debug_excp_handler = arm_debug_excp_handler;
104
cc->debug_check_watchpoint = arm_debug_check_watchpoint;
105
+#if !defined(CONFIG_USER_ONLY)
106
+ cc->adjust_watchpoint_address = arm_adjust_watchpoint_address;
107
+#endif
108
109
cc->disas_set_info = arm_disas_set_info;
110
}
111
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/op_helper.c
114
+++ b/target/arm/op_helper.c
115
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
116
return check_watchpoints(cpu);
117
}
118
119
+vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)
120
+{
121
+ ARMCPU *cpu = ARM_CPU(cs);
122
+ CPUARMState *env = &cpu->env;
123
+
124
+ /* In BE32 system mode, target memory is stored byteswapped (on a
125
+ * little-endian host system), and by the time we reach here (via an
126
+ * opcode helper) the addresses of subword accesses have been adjusted
127
+ * to account for that, which means that watchpoints will not match.
128
+ * Undo the adjustment here.
129
+ */
130
+ if (arm_sctlr_b(env)) {
131
+ if (len == 1) {
132
+ addr ^= 3;
133
+ } else if (len == 2) {
134
+ addr ^= 2;
135
+ }
136
+ }
137
+
138
+ return addr;
139
+}
140
+
141
void arm_debug_excp_handler(CPUState *cs)
142
{
143
/* Called by core code when a watchpoint or breakpoint fires;
144
--
29
--
145
2.7.4
30
2.20.1
146
31
147
32
diff view generated by jsdifflib
1
From: Julian Brown <julian@codesourcery.com>
1
From: Alex Chen <alex.chen@huawei.com>
2
2
3
Add a new "cfgend" property which selects whether the CPU resets into
3
We should use printf format specifier "%u" instead of "%d" for
4
big-endian mode or not. This setting affects whether we reset with
4
argument of type "unsigned int".
5
SCTLR_B (ARMv6 and earlier) or SCTLR_EE (ARMv7 and later) set.
6
5
7
Signed-off-by: Julian Brown <julian@codesourcery.com>
6
Reported-by: Euler Robot <euler.robot@huawei.com>
8
Message-id: 11420d1c49636c1790e60578ee996e51f0f0b835.1484929304.git.julian@codesourcery.com
7
Signed-off-by: Alex Chen <alex.chen@huawei.com>
9
[PMM: use error_report_err() rather than error_report();
8
Message-id: 20201111073651.72804-1-alex.chen@huawei.com
10
move the integratorcp changes to their own patch;
11
drop an unnecessary extra #include;
12
rephrase commit message accordingly;
13
move setting of reset_sctlr above registration of cpregs
14
so it actually has an effect]
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
11
---
18
target/arm/cpu.h | 7 +++++++
12
hw/timer/exynos4210_mct.c | 4 ++--
19
target/arm/cpu.c | 13 +++++++++++++
13
hw/timer/exynos4210_pwm.c | 8 ++++----
20
2 files changed, 20 insertions(+)
14
2 files changed, 6 insertions(+), 6 deletions(-)
21
15
22
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
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
18
--- a/hw/timer/exynos4210_mct.c
25
+++ b/target/arm/cpu.h
19
+++ b/hw/timer/exynos4210_mct.c
26
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
20
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gcomp_raise_irq(void *opaque, uint32_t id)
27
int gic_vpribits; /* number of virtual priority bits */
21
/* If CSTAT is pending and IRQ is enabled */
28
int gic_vprebits; /* number of virtual preemption bits */
22
if ((s->reg.int_cstat & G_INT_CSTAT_COMP(id)) &&
29
23
(s->reg.int_enb & G_INT_ENABLE(id))) {
30
+ /* Whether the cfgend input is high (i.e. this CPU should reset into
24
- DPRINTF("gcmp timer[%d] IRQ\n", id);
31
+ * big-endian mode). This setting isn't used directly: instead it modifies
25
+ DPRINTF("gcmp timer[%u] IRQ\n", id);
32
+ * the reset_sctlr value to have SCTLR_B or SCTLR_EE set, depending on the
26
qemu_irq_raise(s->irq[id]);
33
+ * architecture version.
27
}
34
+ */
28
}
35
+ bool cfgend;
29
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_update_freq(Exynos4210MCTState *s)
36
+
30
MCT_CFG_GET_DIVIDER(s->reg_mct_cfg));
37
ARMELChangeHook *el_change_hook;
31
38
void *el_change_hook_opaque;
32
if (freq != s->freq) {
39
};
33
- DPRINTF("freq=%dHz\n", s->freq);
40
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
34
+ DPRINTF("freq=%uHz\n", s->freq);
35
36
/* global timer */
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/target/arm/cpu.c
40
--- a/hw/timer/exynos4210_pwm.c
43
+++ b/target/arm/cpu.c
41
+++ b/hw/timer/exynos4210_pwm.c
44
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_has_el2_property =
42
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_update_freq(Exynos4210PWMState *s, uint32_t id)
45
static Property arm_cpu_has_el3_property =
43
46
DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true);
44
if (freq != s->timer[id].freq) {
47
45
ptimer_set_freq(s->timer[id].ptimer, s->timer[id].freq);
48
+static Property arm_cpu_cfgend_property =
46
- DPRINTF("freq=%dHz\n", s->timer[id].freq);
49
+ DEFINE_PROP_BOOL("cfgend", ARMCPU, cfgend, false);
47
+ DPRINTF("freq=%uHz\n", s->timer[id].freq);
50
+
51
/* use property name "pmu" to match other archs and virt tools */
52
static Property arm_cpu_has_pmu_property =
53
DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true);
54
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_post_init(Object *obj)
55
}
56
}
48
}
57
58
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
59
+ &error_abort);
60
}
49
}
61
50
62
static void arm_cpu_finalizefn(Object *obj)
51
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_tick(void *opaque)
63
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
52
uint32_t id = s->id;
64
cpu->reset_sctlr |= (1 << 13);
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);
65
}
66
}
66
67
67
+ if (cpu->cfgend) {
68
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_tick(void *opaque)
68
+ if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
69
}
69
+ cpu->reset_sctlr |= SCTLR_EE;
70
70
+ } else {
71
if (cmp) {
71
+ cpu->reset_sctlr |= SCTLR_B;
72
- DPRINTF("auto reload timer %d count to %x\n", id,
72
+ }
73
+ DPRINTF("auto reload timer %u count to %x\n", id,
73
+ }
74
p->timer[id].reg_tcntb);
74
+
75
ptimer_set_count(p->timer[id].ptimer, p->timer[id].reg_tcntb);
75
if (!cpu->has_el3) {
76
ptimer_run(p->timer[id].ptimer, 1);
76
/* If the has_el3 CPU property is disabled then we need to disable the
77
* feature.
78
--
77
--
79
2.7.4
78
2.20.1
80
79
81
80
diff view generated by jsdifflib
1
Use the 'unimplemented' dummy device to cover regions of the
1
In commit 5edab03d4040 we added tracepoints to the ps2 keyboard
2
SoC device memory map which we don't have proper device
2
and mouse emulation. However we didn't remove all the debug-by-printf
3
implementations for yet.
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: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 1484247815-15279-4-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
hw/arm/stellaris.c | 14 ++++++++++++++
12
hw/input/ps2.c | 9 ---------
10
1 file changed, 14 insertions(+)
13
1 file changed, 9 deletions(-)
11
14
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.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/hw/arm/stellaris.c
17
--- a/hw/input/ps2.c
15
+++ b/hw/arm/stellaris.c
18
+++ b/hw/input/ps2.c
16
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
17
#include "exec/address-spaces.h"
20
18
#include "sysemu/sysemu.h"
21
#include "trace.h"
19
#include "hw/char/pl011.h"
22
20
+#include "hw/misc/unimp.h"
23
-/* debug PC keyboard */
21
24
-//#define DEBUG_KBD
22
#define GPIO_A 0
25
-
23
#define GPIO_B 1
26
-/* debug PC keyboard : only mouse */
24
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
27
-//#define DEBUG_MOUSE
25
}
28
-
26
}
29
/* Keyboard Commands */
27
}
30
#define KBD_CMD_SET_LEDS    0xED    /* Set keyboard leds */
28
+
31
#define KBD_CMD_ECHO     0xEE
29
+ /* Add dummy regions for the devices we don't implement yet,
32
@@ -XXX,XX +XXX,XX @@ void ps2_write_mouse(void *opaque, int val)
30
+ * so guest accesses don't cause unlogged crashes.
33
PS2MouseState *s = (PS2MouseState *)opaque;
31
+ */
34
32
+ create_unimplemented_device("wdtimer", 0x40000000, 0x1000);
35
trace_ps2_write_mouse(opaque, val);
33
+ create_unimplemented_device("i2c-0", 0x40002000, 0x1000);
36
-#ifdef DEBUG_MOUSE
34
+ create_unimplemented_device("i2c-2", 0x40021000, 0x1000);
37
- printf("kbd: write mouse 0x%02x\n", val);
35
+ create_unimplemented_device("PWM", 0x40028000, 0x1000);
38
-#endif
36
+ create_unimplemented_device("QEI-0", 0x4002c000, 0x1000);
39
switch(s->common.write_cmd) {
37
+ create_unimplemented_device("QEI-1", 0x4002d000, 0x1000);
40
default:
38
+ create_unimplemented_device("analogue-comparator", 0x4003c000, 0x1000);
41
case -1:
39
+ create_unimplemented_device("hibernation", 0x400fc000, 0x1000);
40
+ create_unimplemented_device("flash-control", 0x400fd000, 0x1000);
41
}
42
43
/* FIXME: Figure out how to generate these from stellaris_boards. */
44
--
42
--
45
2.7.4
43
2.20.1
46
44
47
45
diff view generated by jsdifflib
1
Add a comment documenting the memory map of the SoC devices and which
1
In the mtspr helper we attempt to check for "is the timer disabled"
2
are not implemented.
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.)
3
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
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 1484247815-15279-2-git-send-email-peter.maydell@linaro.org
16
Acked-by: Stafford Horne <shorne@gmail.com>
17
Message-id: 20201103114654.18540-1-peter.maydell@linaro.org
6
---
18
---
7
hw/arm/stellaris.c | 34 ++++++++++++++++++++++++++++++++++
19
target/openrisc/sys_helper.c | 3 ---
8
1 file changed, 34 insertions(+)
20
1 file changed, 3 deletions(-)
9
21
10
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
22
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
11
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/stellaris.c
24
--- a/target/openrisc/sys_helper.c
13
+++ b/hw/arm/stellaris.c
25
+++ b/target/openrisc/sys_helper.c
14
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
26
@@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
15
0x40024000, 0x40025000, 0x40026000};
27
16
static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
28
case TO_SPR(10, 1): /* TTCR */
17
29
cpu_openrisc_count_set(cpu, rb);
18
+ /* Memory map of SoC devices, from
30
- if (env->ttmr & TIMER_NONE) {
19
+ * Stellaris LM3S6965 Microcontroller Data Sheet (rev I)
31
- return;
20
+ * http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
32
- }
21
+ *
33
cpu_openrisc_timer_update(cpu);
22
+ * 40000000 wdtimer (unimplemented)
34
break;
23
+ * 40002000 i2c (unimplemented)
35
#endif
24
+ * 40004000 GPIO
25
+ * 40005000 GPIO
26
+ * 40006000 GPIO
27
+ * 40007000 GPIO
28
+ * 40008000 SSI
29
+ * 4000c000 UART
30
+ * 4000d000 UART
31
+ * 4000e000 UART
32
+ * 40020000 i2c
33
+ * 40021000 i2c (unimplemented)
34
+ * 40024000 GPIO
35
+ * 40025000 GPIO
36
+ * 40026000 GPIO
37
+ * 40028000 PWM (unimplemented)
38
+ * 4002c000 QEI (unimplemented)
39
+ * 4002d000 QEI (unimplemented)
40
+ * 40030000 gptimer
41
+ * 40031000 gptimer
42
+ * 40032000 gptimer
43
+ * 40033000 gptimer
44
+ * 40038000 ADC
45
+ * 4003c000 analogue comparator (unimplemented)
46
+ * 40048000 ethernet
47
+ * 400fc000 hibernation module (unimplemented)
48
+ * 400fd000 flash memory control (unimplemented)
49
+ * 400fe000 system control
50
+ */
51
+
52
DeviceState *gpio_dev[7], *nvic;
53
qemu_irq gpio_in[7][8];
54
qemu_irq gpio_out[7][8];
55
--
36
--
56
2.7.4
37
2.20.1
57
38
58
39
diff view generated by jsdifflib
1
From: Julian Brown <julian@codesourcery.com>
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
Thumb-1 code has some issues in BE32 mode (as currently implemented). In
3
This patch fixes CID 1432800 by removing an unnecessary check.
4
short, since bytes are swapped within words at load time for BE32
5
executables, this also swaps pairs of adjacent Thumb-1 instructions.
6
4
7
This patch un-swaps those pairs of instructions again, both for execution,
5
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
and for disassembly. (The previous version of the patch always read four
9
bytes in arm_read_memory_func and then extracted the proper two bytes,
10
in a probably misguided attempt to match the behaviour of actual hardware
11
as described by e.g. the ARM9TDMI TRM, section 3.3 "Endian effects for
12
instruction fetches". It's less complicated to just read the correct
13
two bytes though.)
14
15
Signed-off-by: Julian Brown <julian@codesourcery.com>
16
Message-id: ca20462a044848000370318a8bd41dd0a4ed273f.1484929304.git.julian@codesourcery.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
8
---
20
include/disas/bfd.h | 7 +++++++
9
hw/core/register.c | 4 ----
21
target/arm/arm_ldst.h | 10 +++++++++-
10
1 file changed, 4 deletions(-)
22
disas.c | 1 +
23
target/arm/cpu.c | 23 +++++++++++++++++++++++
24
4 files changed, 40 insertions(+), 1 deletion(-)
25
11
26
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
12
diff --git a/hw/core/register.c b/hw/core/register.c
27
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
28
--- a/include/disas/bfd.h
14
--- a/hw/core/register.c
29
+++ b/include/disas/bfd.h
15
+++ b/hw/core/register.c
30
@@ -XXX,XX +XXX,XX @@ typedef struct disassemble_info {
16
@@ -XXX,XX +XXX,XX @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
31
The bottom 16 bits are for the internal use of the disassembler. */
17
int index = rae[i].addr / data_size;
32
unsigned long flags;
18
RegisterInfo *r = &ri[index];
33
#define INSN_HAS_RELOC    0x80000000
19
34
+#define INSN_ARM_BE32    0x00010000
20
- if (data + data_size * index == 0 || !&rae[i]) {
35
PTR private_data;
21
- continue;
36
22
- }
37
/* Function used to get bytes to disassemble. MEMADDR is the
23
-
38
@@ -XXX,XX +XXX,XX @@ typedef struct disassemble_info {
24
/* Init the register, this will zero it. */
39
(bfd_vma memaddr, bfd_byte *myaddr, int length,
25
object_initialize((void *)r, sizeof(*r), TYPE_REGISTER);
40
     struct disassemble_info *info);
26
41
42
+ /* A place to stash the real read_memory_func if read_memory_func wants to
43
+ do some funky address arithmetic or similar (e.g. for ARM BE32 mode). */
44
+ int (*read_memory_inner_func)
45
+ (bfd_vma memaddr, bfd_byte *myaddr, int length,
46
+ struct disassemble_info *info);
47
+
48
/* Function which should be called if we get an error that we can't
49
recover from. STATUS is the errno value from read_memory_func and
50
MEMADDR is the address that we were trying to read. INFO is a
51
diff --git a/target/arm/arm_ldst.h b/target/arm/arm_ldst.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/arm_ldst.h
54
+++ b/target/arm/arm_ldst.h
55
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_ldl_code(CPUARMState *env, target_ulong addr,
56
static inline uint16_t arm_lduw_code(CPUARMState *env, target_ulong addr,
57
bool sctlr_b)
58
{
59
- uint16_t insn = cpu_lduw_code(env, addr);
60
+ uint16_t insn;
61
+#ifndef CONFIG_USER_ONLY
62
+ /* In big-endian (BE32) mode, adjacent Thumb instructions have been swapped
63
+ within each word. Undo that now. */
64
+ if (sctlr_b) {
65
+ addr ^= 2;
66
+ }
67
+#endif
68
+ insn = cpu_lduw_code(env, addr);
69
if (bswap_code(sctlr_b)) {
70
return bswap16(insn);
71
}
72
diff --git a/disas.c b/disas.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/disas.c
75
+++ b/disas.c
76
@@ -XXX,XX +XXX,XX @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
77
78
s.cpu = cpu;
79
s.info.read_memory_func = target_read_memory;
80
+ s.info.read_memory_inner_func = NULL;
81
s.info.buffer_vma = code;
82
s.info.buffer_length = size;
83
s.info.print_address_func = generic_print_address;
84
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/cpu.c
87
+++ b/target/arm/cpu.c
88
@@ -XXX,XX +XXX,XX @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
89
return print_insn_arm(pc | 1, info);
90
}
91
92
+static int arm_read_memory_func(bfd_vma memaddr, bfd_byte *b,
93
+ int length, struct disassemble_info *info)
94
+{
95
+ assert(info->read_memory_inner_func);
96
+ assert((info->flags & INSN_ARM_BE32) == 0 || length == 2 || length == 4);
97
+
98
+ if ((info->flags & INSN_ARM_BE32) != 0 && length == 2) {
99
+ assert(info->endian == BFD_ENDIAN_LITTLE);
100
+ return info->read_memory_inner_func(memaddr ^ 2, (bfd_byte *)b, 2,
101
+ info);
102
+ } else {
103
+ return info->read_memory_inner_func(memaddr, b, length, info);
104
+ }
105
+}
106
+
107
static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
108
{
109
ARMCPU *ac = ARM_CPU(cpu);
110
@@ -XXX,XX +XXX,XX @@ static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
111
info->endian = BFD_ENDIAN_BIG;
112
#endif
113
}
114
+ if (info->read_memory_inner_func == NULL) {
115
+ info->read_memory_inner_func = info->read_memory_func;
116
+ info->read_memory_func = arm_read_memory_func;
117
+ }
118
+ info->flags &= ~INSN_ARM_BE32;
119
+ if (arm_sctlr_b(env)) {
120
+ info->flags |= INSN_ARM_BE32;
121
+ }
122
}
123
124
static void arm_cpu_initfn(Object *obj)
125
--
27
--
126
2.7.4
28
2.20.1
127
29
128
30
diff view generated by jsdifflib
1
From: Julian Brown <julian@codesourcery.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Since the integratorcp board creates the CPU object directly
3
Fix Coverity CID 1435957: Memory - illegal accesses (OVERRUN):
4
rather than via cpu_arm_init(), we have to call the CPU
5
class parse_features() method ourselves if we want to
6
support the user passing features via the -cpu command
7
line argument as well as just the cpu name. Do so.
8
4
9
Signed-off-by: Julian Brown <julian@codesourcery.com>
5
>>> Overrunning array "suffixes" of 7 8-byte elements at element
10
[PMM: split out into its own patch]
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>
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
20
---
14
hw/arm/integratorcp.c | 19 +++++++++++++++++--
21
util/cutils.c | 3 ++-
15
1 file changed, 17 insertions(+), 2 deletions(-)
22
1 file changed, 2 insertions(+), 1 deletion(-)
16
23
17
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
24
diff --git a/util/cutils.c b/util/cutils.c
18
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/integratorcp.c
26
--- a/util/cutils.c
20
+++ b/hw/arm/integratorcp.c
27
+++ b/util/cutils.c
21
@@ -XXX,XX +XXX,XX @@ static void integratorcp_init(MachineState *machine)
28
@@ -XXX,XX +XXX,XX @@ char *freq_to_str(uint64_t freq_hz)
22
const char *kernel_filename = machine->kernel_filename;
29
double freq = freq_hz;
23
const char *kernel_cmdline = machine->kernel_cmdline;
30
size_t idx = 0;
24
const char *initrd_filename = machine->initrd_filename;
31
25
+ char **cpustr;
32
- while (freq >= 1000.0 && idx < ARRAY_SIZE(suffixes)) {
26
ObjectClass *cpu_oc;
33
+ while (freq >= 1000.0) {
27
+ CPUClass *cc;
34
freq /= 1000.0;
28
Object *cpuobj;
35
idx++;
29
ARMCPU *cpu;
30
+ const char *typename;
31
MemoryRegion *address_space_mem = get_system_memory();
32
MemoryRegion *ram = g_new(MemoryRegion, 1);
33
MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
34
qemu_irq pic[32];
35
DeviceState *dev, *sic, *icp;
36
int i;
37
+ Error *err = NULL;
38
39
if (!cpu_model) {
40
cpu_model = "arm926";
41
}
36
}
42
37
+ assert(idx < ARRAY_SIZE(suffixes));
43
- cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
38
44
+ cpustr = g_strsplit(cpu_model, ",", 2);
39
return g_strdup_printf("%0.3g %sHz", freq, suffixes[idx]);
45
+
40
}
46
+ cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
47
if (!cpu_oc) {
48
fprintf(stderr, "Unable to find CPU definition\n");
49
exit(1);
50
}
51
+ typename = object_class_get_name(cpu_oc);
52
+
53
+ cc = CPU_CLASS(cpu_oc);
54
+ cc->parse_features(typename, cpustr[1], &err);
55
+ g_strfreev(cpustr);
56
+ if (err) {
57
+ error_report_err(err);
58
+ exit(1);
59
+ }
60
61
- cpuobj = object_new(object_class_get_name(cpu_oc));
62
+ cpuobj = object_new(typename);
63
64
/* By default ARM1176 CPUs have EL3 enabled. This board does not
65
* currently support EL3 so the CPU EL3 property is disabled before
66
--
41
--
67
2.7.4
42
2.20.1
68
43
69
44
diff view generated by jsdifflib
1
Create a new "unimplemented" sysbus device, which simply accepts
1
In commit 76346b6264a9b01979 we tried to add a configure check that
2
all read and write accesses, and implements them as read-as-zero,
2
the libgio pkg-config data was correct, which builds an executable
3
write-ignored, with logging of the access as LOG_UNIMP.
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
This is useful for stubbing out bits of an SoC or board model
9
(The ineffective test went unnoticed because of a typo that
6
which haven't been written yet.
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: Alex Bennée <alex.bennee@linaro.org>
19
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
10
Message-id: 1484247815-15279-3-git-send-email-peter.maydell@linaro.org
20
Message-id: 20201116104617.18333-1-peter.maydell@linaro.org
11
---
21
---
12
hw/misc/Makefile.objs | 2 +
22
configure | 11 +++++++++--
13
include/hw/misc/unimp.h | 39 ++++++++++++++++++
23
1 file changed, 9 insertions(+), 2 deletions(-)
14
hw/misc/unimp.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
15
3 files changed, 148 insertions(+)
16
create mode 100644 include/hw/misc/unimp.h
17
create mode 100644 hw/misc/unimp.c
18
24
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
25
diff --git a/configure b/configure
20
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100755
21
--- a/hw/misc/Makefile.objs
27
--- a/configure
22
+++ b/hw/misc/Makefile.objs
28
+++ b/configure
23
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_SGA) += sga.o
29
@@ -XXX,XX +XXX,XX @@ if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
24
common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
30
# Check that the libraries actually work -- Ubuntu 18.04 ships
25
common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
31
# with pkg-config --static --libs data for gio-2.0 that is missing
26
32
# -lblkid and will give a link error.
27
+common-obj-y += unimp.o
33
- write_c_skeleton
28
+
34
- if compile_prog "" "$gio_libs" ; then
29
obj-$(CONFIG_VMPORT) += vmport.o
35
+ cat > $TMPC <<EOF
30
36
+#include <gio/gio.h>
31
# ARM devices
37
+int main(void)
32
diff --git a/include/hw/misc/unimp.h b/include/hw/misc/unimp.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/misc/unimp.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * "Unimplemented" device
40
+ *
41
+ * Copyright Linaro Limited, 2017
42
+ * Written by Peter Maydell
43
+ */
44
+
45
+#ifndef HW_MISC_UNIMP_H
46
+#define HW_MISC_UNIMP_H
47
+
48
+#define TYPE_UNIMPLEMENTED_DEVICE "unimplemented-device"
49
+
50
+/**
51
+ * create_unimplemented_device: create and map a dummy device
52
+ * @name: name of the device for debug logging
53
+ * @base: base address of the device's MMIO region
54
+ * @size: size of the device's MMIO region
55
+ *
56
+ * This utility function creates and maps an instance of unimplemented-device,
57
+ * which is a dummy device which simply logs all guest accesses to
58
+ * it via the qemu_log LOG_UNIMP debug log.
59
+ * The device is mapped at priority -1000, which means that you can
60
+ * use it to cover a large region and then map other devices on top of it
61
+ * if necessary.
62
+ */
63
+static inline void create_unimplemented_device(const char *name,
64
+ hwaddr base,
65
+ hwaddr size)
66
+{
38
+{
67
+ DeviceState *dev = qdev_create(NULL, TYPE_UNIMPLEMENTED_DEVICE);
39
+ g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
68
+
69
+ qdev_prop_set_string(dev, "name", name);
70
+ qdev_prop_set_uint64(dev, "size", size);
71
+ qdev_init_nofail(dev);
72
+
73
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(dev), 0, base, -1000);
74
+}
75
+
76
+#endif
77
diff --git a/hw/misc/unimp.c b/hw/misc/unimp.c
78
new file mode 100644
79
index XXXXXXX..XXXXXXX
80
--- /dev/null
81
+++ b/hw/misc/unimp.c
82
@@ -XXX,XX +XXX,XX @@
83
+/* "Unimplemented" device
84
+ *
85
+ * This is a dummy device which accepts and logs all accesses.
86
+ * It's useful for stubbing out regions of an SoC or board
87
+ * map which correspond to devices that have not yet been
88
+ * implemented. This is often sufficient to placate initial
89
+ * guest device driver probing such that the system will
90
+ * come up.
91
+ *
92
+ * Copyright Linaro Limited, 2017
93
+ * Written by Peter Maydell
94
+ */
95
+
96
+#include "qemu/osdep.h"
97
+#include "hw/hw.h"
98
+#include "hw/sysbus.h"
99
+#include "hw/misc/unimp.h"
100
+#include "qemu/log.h"
101
+#include "qapi/error.h"
102
+
103
+#define UNIMPLEMENTED_DEVICE(obj) \
104
+ OBJECT_CHECK(UnimplementedDeviceState, (obj), TYPE_UNIMPLEMENTED_DEVICE)
105
+
106
+typedef struct {
107
+ SysBusDevice parent_obj;
108
+ MemoryRegion iomem;
109
+ char *name;
110
+ uint64_t size;
111
+} UnimplementedDeviceState;
112
+
113
+static uint64_t unimp_read(void *opaque, hwaddr offset, unsigned size)
114
+{
115
+ UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
116
+
117
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
118
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
119
+ s->name, size, offset);
120
+ return 0;
40
+ return 0;
121
+}
41
+}
122
+
42
+EOF
123
+static void unimp_write(void *opaque, hwaddr offset,
43
+ if compile_prog "$gio_cflags" "$gio_libs" ; then
124
+ uint64_t value, unsigned size)
44
gio=yes
125
+{
45
else
126
+ UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
46
gio=no
127
+
128
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
129
+ "(size %d, value 0x%" PRIx64
130
+ ", offset 0x%" HWADDR_PRIx ")\n",
131
+ s->name, size, value, offset);
132
+}
133
+
134
+static const MemoryRegionOps unimp_ops = {
135
+ .read = unimp_read,
136
+ .write = unimp_write,
137
+ .impl.min_access_size = 1,
138
+ .impl.max_access_size = 8,
139
+ .valid.min_access_size = 1,
140
+ .valid.max_access_size = 8,
141
+ .endianness = DEVICE_NATIVE_ENDIAN,
142
+};
143
+
144
+static void unimp_realize(DeviceState *dev, Error **errp)
145
+{
146
+ UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(dev);
147
+
148
+ if (s->size == 0) {
149
+ error_setg(errp, "property 'size' not specified or zero");
150
+ return;
151
+ }
152
+
153
+ if (s->name == NULL) {
154
+ error_setg(errp, "property 'name' not specified");
155
+ return;
156
+ }
157
+
158
+ memory_region_init_io(&s->iomem, OBJECT(s), &unimp_ops, s,
159
+ s->name, s->size);
160
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
161
+}
162
+
163
+static Property unimp_properties[] = {
164
+ DEFINE_PROP_UINT64("size", UnimplementedDeviceState, size, 0),
165
+ DEFINE_PROP_STRING("name", UnimplementedDeviceState, name),
166
+ DEFINE_PROP_END_OF_LIST(),
167
+};
168
+
169
+static void unimp_class_init(ObjectClass *klass, void *data)
170
+{
171
+ DeviceClass *dc = DEVICE_CLASS(klass);
172
+
173
+ dc->realize = unimp_realize;
174
+ dc->props = unimp_properties;
175
+}
176
+
177
+static const TypeInfo unimp_info = {
178
+ .name = TYPE_UNIMPLEMENTED_DEVICE,
179
+ .parent = TYPE_SYS_BUS_DEVICE,
180
+ .instance_size = sizeof(UnimplementedDeviceState),
181
+ .class_init = unimp_class_init,
182
+};
183
+
184
+static void unimp_register_types(void)
185
+{
186
+ type_register_static(&unimp_info);
187
+}
188
+
189
+type_init(unimp_register_types)
190
--
47
--
191
2.7.4
48
2.20.1
192
49
193
50
diff view generated by jsdifflib
1
Add support for generating the ISS (Instruction Specific Syndrome)
1
The TMP105 datasheet (https://www.ti.com/lit/gpn/tmp105) says that the
2
for Data Abort exceptions taken from AArch32. These syndromes are
2
power-up reset values for the T_low and T_high registers are 80 degrees C
3
used by hypervisors for example to trap and emulate memory accesses.
3
and 75 degrees C, which are 0x500 and 0x4B0 hex according to table 5. These
4
values are then shifted right by four bits to give the register reset
5
values, since both registers store the 12 bits of temperature data in bits
6
[15..4] of a 16 bit register.
4
7
5
This is the equivalent for AArch32 guests of the work done for AArch64
8
We were resetting these registers to zero, which is problematic for Linux
6
guests in commit aaa1f954d4cab243.
9
guests which enable the alert interrupt and then immediately take an
10
unexpected overtemperature alert because the current temperature is above
11
freezing...
7
12
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
14
Reviewed-by: Cédric Le Goater <clg@kaod.org>
15
Message-id: 20201110150023.25533-2-peter.maydell@linaro.org
10
---
16
---
11
target/arm/translate.h | 14 ++++
17
hw/misc/tmp105.c | 3 +++
12
target/arm/translate-a64.c | 14 ----
18
1 file changed, 3 insertions(+)
13
target/arm/translate.c | 184 +++++++++++++++++++++++++++++++++------------
14
3 files changed, 149 insertions(+), 63 deletions(-)
15
19
16
diff --git a/target/arm/translate.h b/target/arm/translate.h
20
diff --git a/hw/misc/tmp105.c b/hw/misc/tmp105.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.h
22
--- a/hw/misc/tmp105.c
19
+++ b/target/arm/translate.h
23
+++ b/hw/misc/tmp105.c
20
@@ -XXX,XX +XXX,XX @@ static inline int default_exception_el(DisasContext *s)
24
@@ -XXX,XX +XXX,XX @@ static void tmp105_reset(I2CSlave *i2c)
21
? 3 : MAX(1, s->current_el);
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);
22
}
32
}
23
33
24
+static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
25
+{
26
+ /* We don't need to save all of the syndrome so we mask and shift
27
+ * out unneeded bits to help the sleb128 encoder do a better job.
28
+ */
29
+ syn &= ARM_INSN_START_WORD2_MASK;
30
+ syn >>= ARM_INSN_START_WORD2_SHIFT;
31
+
32
+ /* We check and clear insn_start_idx to catch multiple updates. */
33
+ assert(s->insn_start_idx != 0);
34
+ tcg_set_insn_param(s->insn_start_idx, 2, syn);
35
+ s->insn_start_idx = 0;
36
+}
37
+
38
/* target-specific extra values for is_jmp */
39
/* These instructions trap after executing, so the A32/T32 decoder must
40
* defer them until after the conditional execution state has been updated.
41
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/translate-a64.c
44
+++ b/target/arm/translate-a64.c
45
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
46
}
47
}
48
49
-static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
50
-{
51
- /* We don't need to save all of the syndrome so we mask and shift
52
- * out uneeded bits to help the sleb128 encoder do a better job.
53
- */
54
- syn &= ARM_INSN_START_WORD2_MASK;
55
- syn >>= ARM_INSN_START_WORD2_SHIFT;
56
-
57
- /* We check and clear insn_start_idx to catch multiple updates. */
58
- assert(s->insn_start_idx != 0);
59
- tcg_set_insn_param(s->insn_start_idx, 2, syn);
60
- s->insn_start_idx = 0;
61
-}
62
-
63
static void unallocated_encoding(DisasContext *s)
64
{
65
/* Unallocated and reserved encodings are uncategorized */
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
71
a64_translate_init();
72
}
73
74
+/* Flags for the disas_set_da_iss info argument:
75
+ * lower bits hold the Rt register number, higher bits are flags.
76
+ */
77
+typedef enum ISSInfo {
78
+ ISSNone = 0,
79
+ ISSRegMask = 0x1f,
80
+ ISSInvalid = (1 << 5),
81
+ ISSIsAcqRel = (1 << 6),
82
+ ISSIsWrite = (1 << 7),
83
+ ISSIs16Bit = (1 << 8),
84
+} ISSInfo;
85
+
86
+/* Save the syndrome information for a Data Abort */
87
+static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
88
+{
89
+ uint32_t syn;
90
+ int sas = memop & MO_SIZE;
91
+ bool sse = memop & MO_SIGN;
92
+ bool is_acqrel = issinfo & ISSIsAcqRel;
93
+ bool is_write = issinfo & ISSIsWrite;
94
+ bool is_16bit = issinfo & ISSIs16Bit;
95
+ int srt = issinfo & ISSRegMask;
96
+
97
+ if (issinfo & ISSInvalid) {
98
+ /* Some callsites want to conditionally provide ISS info,
99
+ * eg "only if this was not a writeback"
100
+ */
101
+ return;
102
+ }
103
+
104
+ if (srt == 15) {
105
+ /* For AArch32, insns where the src/dest is R15 never generate
106
+ * ISS information. Catching that here saves checking at all
107
+ * the call sites.
108
+ */
109
+ return;
110
+ }
111
+
112
+ syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
113
+ 0, 0, 0, is_write, 0, is_16bit);
114
+ disas_set_insn_syndrome(s, syn);
115
+}
116
+
117
static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
118
{
119
/* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
120
@@ -XXX,XX +XXX,XX @@ static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
121
TCGv_i32 a32, int index) \
122
{ \
123
gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
124
+} \
125
+static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
126
+ TCGv_i32 val, \
127
+ TCGv_i32 a32, int index, \
128
+ ISSInfo issinfo) \
129
+{ \
130
+ gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
131
+ disas_set_da_iss(s, OPC, issinfo); \
132
}
133
134
#define DO_GEN_ST(SUFF, OPC) \
135
@@ -XXX,XX +XXX,XX @@ static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
136
TCGv_i32 a32, int index) \
137
{ \
138
gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
139
+} \
140
+static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
141
+ TCGv_i32 val, \
142
+ TCGv_i32 a32, int index, \
143
+ ISSInfo issinfo) \
144
+{ \
145
+ gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
146
+ disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
147
}
148
149
static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
150
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
151
tmp = tcg_temp_new_i32();
152
switch (op1) {
153
case 0: /* lda */
154
- gen_aa32_ld32u(s, tmp, addr,
155
- get_mem_index(s));
156
+ gen_aa32_ld32u_iss(s, tmp, addr,
157
+ get_mem_index(s),
158
+ rd | ISSIsAcqRel);
159
break;
160
case 2: /* ldab */
161
- gen_aa32_ld8u(s, tmp, addr,
162
- get_mem_index(s));
163
+ gen_aa32_ld8u_iss(s, tmp, addr,
164
+ get_mem_index(s),
165
+ rd | ISSIsAcqRel);
166
break;
167
case 3: /* ldah */
168
- gen_aa32_ld16u(s, tmp, addr,
169
- get_mem_index(s));
170
+ gen_aa32_ld16u_iss(s, tmp, addr,
171
+ get_mem_index(s),
172
+ rd | ISSIsAcqRel);
173
break;
174
default:
175
abort();
176
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
177
tmp = load_reg(s, rm);
178
switch (op1) {
179
case 0: /* stl */
180
- gen_aa32_st32(s, tmp, addr,
181
- get_mem_index(s));
182
+ gen_aa32_st32_iss(s, tmp, addr,
183
+ get_mem_index(s),
184
+ rm | ISSIsAcqRel);
185
break;
186
case 2: /* stlb */
187
- gen_aa32_st8(s, tmp, addr,
188
- get_mem_index(s));
189
+ gen_aa32_st8_iss(s, tmp, addr,
190
+ get_mem_index(s),
191
+ rm | ISSIsAcqRel);
192
break;
193
case 3: /* stlh */
194
- gen_aa32_st16(s, tmp, addr,
195
- get_mem_index(s));
196
+ gen_aa32_st16_iss(s, tmp, addr,
197
+ get_mem_index(s),
198
+ rm | ISSIsAcqRel);
199
break;
200
default:
201
abort();
202
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
203
bool wbit = insn & (1 << 21);
204
bool pbit = insn & (1 << 24);
205
bool doubleword = false;
206
+ ISSInfo issinfo;
207
+
208
/* Misc load/store */
209
rn = (insn >> 16) & 0xf;
210
rd = (insn >> 12) & 0xf;
211
212
+ /* ISS not valid if writeback */
213
+ issinfo = (pbit & !wbit) ? rd : ISSInvalid;
214
+
215
if (!load && (sh & 2)) {
216
/* doubleword */
217
ARCH(5TE);
218
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
219
tmp = tcg_temp_new_i32();
220
switch (sh) {
221
case 1:
222
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
223
+ gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
224
+ issinfo);
225
break;
226
case 2:
227
- gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
228
+ gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
229
+ issinfo);
230
break;
231
default:
232
case 3:
233
- gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
234
+ gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
235
+ issinfo);
236
break;
237
}
238
} else {
239
/* store */
240
tmp = load_reg(s, rd);
241
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
242
+ gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
243
tcg_temp_free_i32(tmp);
244
}
245
/* Perform base writeback before the loaded value to
246
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
247
/* load */
248
tmp = tcg_temp_new_i32();
249
if (insn & (1 << 22)) {
250
- gen_aa32_ld8u(s, tmp, tmp2, i);
251
+ gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
252
} else {
253
- gen_aa32_ld32u(s, tmp, tmp2, i);
254
+ gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
255
}
256
} else {
257
/* store */
258
tmp = load_reg(s, rd);
259
if (insn & (1 << 22)) {
260
- gen_aa32_st8(s, tmp, tmp2, i);
261
+ gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
262
} else {
263
- gen_aa32_st32(s, tmp, tmp2, i);
264
+ gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
265
}
266
tcg_temp_free_i32(tmp);
267
}
268
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
269
tmp = tcg_temp_new_i32();
270
switch (op) {
271
case 0: /* ldab */
272
- gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
273
+ gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
274
+ rs | ISSIsAcqRel);
275
break;
276
case 1: /* ldah */
277
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
278
+ gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
279
+ rs | ISSIsAcqRel);
280
break;
281
case 2: /* lda */
282
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
283
+ gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
284
+ rs | ISSIsAcqRel);
285
break;
286
default:
287
abort();
288
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
289
tmp = load_reg(s, rs);
290
switch (op) {
291
case 0: /* stlb */
292
- gen_aa32_st8(s, tmp, addr, get_mem_index(s));
293
+ gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
294
+ rs | ISSIsAcqRel);
295
break;
296
case 1: /* stlh */
297
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
298
+ gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
299
+ rs | ISSIsAcqRel);
300
break;
301
case 2: /* stl */
302
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
303
+ gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
304
+ rs | ISSIsAcqRel);
305
break;
306
default:
307
abort();
308
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
309
int postinc = 0;
310
int writeback = 0;
311
int memidx;
312
+ ISSInfo issinfo;
313
+
314
if ((insn & 0x01100000) == 0x01000000) {
315
if (disas_neon_ls_insn(s, insn)) {
316
goto illegal_op;
317
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
318
}
319
}
320
}
321
+
322
+ issinfo = writeback ? ISSInvalid : rs;
323
+
324
if (insn & (1 << 20)) {
325
/* Load. */
326
tmp = tcg_temp_new_i32();
327
switch (op) {
328
case 0:
329
- gen_aa32_ld8u(s, tmp, addr, memidx);
330
+ gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
331
break;
332
case 4:
333
- gen_aa32_ld8s(s, tmp, addr, memidx);
334
+ gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
335
break;
336
case 1:
337
- gen_aa32_ld16u(s, tmp, addr, memidx);
338
+ gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
339
break;
340
case 5:
341
- gen_aa32_ld16s(s, tmp, addr, memidx);
342
+ gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
343
break;
344
case 2:
345
- gen_aa32_ld32u(s, tmp, addr, memidx);
346
+ gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
347
break;
348
default:
349
tcg_temp_free_i32(tmp);
350
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
351
tmp = load_reg(s, rs);
352
switch (op) {
353
case 0:
354
- gen_aa32_st8(s, tmp, addr, memidx);
355
+ gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
356
break;
357
case 1:
358
- gen_aa32_st16(s, tmp, addr, memidx);
359
+ gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
360
break;
361
case 2:
362
- gen_aa32_st32(s, tmp, addr, memidx);
363
+ gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
364
break;
365
default:
366
tcg_temp_free_i32(tmp);
367
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
368
addr = tcg_temp_new_i32();
369
tcg_gen_movi_i32(addr, val);
370
tmp = tcg_temp_new_i32();
371
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
372
+ gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
373
+ rd | ISSIs16Bit);
374
tcg_temp_free_i32(addr);
375
store_reg(s, rd, tmp);
376
break;
377
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
378
379
switch (op) {
380
case 0: /* str */
381
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
382
+ gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
383
break;
384
case 1: /* strh */
385
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
386
+ gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
387
break;
388
case 2: /* strb */
389
- gen_aa32_st8(s, tmp, addr, get_mem_index(s));
390
+ gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
391
break;
392
case 3: /* ldrsb */
393
- gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
394
+ gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
395
break;
396
case 4: /* ldr */
397
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
398
+ gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
399
break;
400
case 5: /* ldrh */
401
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
402
+ gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
403
break;
404
case 6: /* ldrb */
405
- gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
406
+ gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
407
break;
408
case 7: /* ldrsh */
409
- gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
410
+ gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
411
break;
412
}
413
if (op >= 3) { /* load */
414
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
415
if (insn & (1 << 11)) {
416
/* load */
417
tmp = tcg_temp_new_i32();
418
- gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
419
+ gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
420
store_reg(s, rd, tmp);
421
} else {
422
/* store */
423
tmp = load_reg(s, rd);
424
- gen_aa32_st8(s, tmp, addr, get_mem_index(s));
425
+ gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
426
tcg_temp_free_i32(tmp);
427
}
428
tcg_temp_free_i32(addr);
429
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
430
if (insn & (1 << 11)) {
431
/* load */
432
tmp = tcg_temp_new_i32();
433
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
434
+ gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
435
store_reg(s, rd, tmp);
436
} else {
437
/* store */
438
tmp = load_reg(s, rd);
439
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
440
+ gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
441
tcg_temp_free_i32(tmp);
442
}
443
tcg_temp_free_i32(addr);
444
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
445
if (insn & (1 << 11)) {
446
/* load */
447
tmp = tcg_temp_new_i32();
448
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
449
+ gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
450
store_reg(s, rd, tmp);
451
} else {
452
/* store */
453
tmp = load_reg(s, rd);
454
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
455
+ gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
456
tcg_temp_free_i32(tmp);
457
}
458
tcg_temp_free_i32(addr);
459
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
460
store_cpu_field(tmp, condexec_bits);
461
}
462
do {
463
+ dc->insn_start_idx = tcg_op_buf_count();
464
tcg_gen_insn_start(dc->pc,
465
(dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
466
0);
467
--
34
--
468
2.7.4
35
2.20.1
469
36
470
37
diff view generated by jsdifflib
1
From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
1
The TMP105 datasheet says that in Interrupt Mode (when TM==1) the device
2
signals an alert when the temperature equals or exceeds the T_high value and
3
then remains high until a device register is read or the device responds to
4
the SMBUS Alert Response address, or the device is put into Shutdown Mode.
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 .)
2
10
3
VMState added by this patch preserves correct
11
We were misimplementing this as a simple "always alert if temperature is
4
loading of the integratorcp device state.
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.
5
15
6
Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
16
Implement the correct (hysteresis) behaviour by tracking whether we
7
Message-id: 20170131114310.6768.79416.stgit@PASHA-ISP
17
are currently looking for the temperature to rise over T_high or
8
[PMM: removed unnecessary minimum_version_id_old lines]
18
for it to fall below T_low. Our implementation of the comparator
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
mode (TM==0) wasn't wrong, but rephrase it to match the way that
20
interrupt mode is now handled for clarity.
21
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Cédric Le Goater <clg@kaod.org>
24
Message-id: 20201110150023.25533-3-peter.maydell@linaro.org
11
---
25
---
12
hw/arm/integratorcp.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++
26
hw/misc/tmp105.h | 7 +++++
13
1 file changed, 59 insertions(+)
27
hw/misc/tmp105.c | 70 +++++++++++++++++++++++++++++++++++++++++-------
28
2 files changed, 68 insertions(+), 9 deletions(-)
14
29
15
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
30
diff --git a/hw/misc/tmp105.h b/hw/misc/tmp105.h
16
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/integratorcp.c
32
--- a/hw/misc/tmp105.h
18
+++ b/hw/arm/integratorcp.c
33
+++ b/hw/misc/tmp105.h
19
@@ -XXX,XX +XXX,XX @@ static uint8_t integrator_spd[128] = {
34
@@ -XXX,XX +XXX,XX @@ struct TMP105State {
20
0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
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;
21
};
45
};
22
46
23
+static const VMStateDescription vmstate_integratorcm = {
47
#endif
24
+ .name = "integratorcm",
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;
54
}
55
56
- if ((s->config >> 1) & 1) {                    /* TM */
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)
107
+{
108
+ TMP105State *s = opaque;
109
+
110
+ /*
111
+ * We only need to migrate the detect_falling bool if it's set;
112
+ * for migration from older machines we assume that it is false
113
+ * (ie temperature is not out of range).
114
+ */
115
+ return s->detect_falling;
116
+}
117
+
118
+static const VMStateDescription vmstate_tmp105_detect_falling = {
119
+ .name = "TMP105/detect-falling",
25
+ .version_id = 1,
120
+ .version_id = 1,
26
+ .minimum_version_id = 1,
121
+ .minimum_version_id = 1,
27
+ .fields = (VMStateField[]) {
122
+ .needed = detect_falling_needed,
28
+ VMSTATE_UINT32(cm_osc, IntegratorCMState),
123
+ .fields = (VMStateField[]) {
29
+ VMSTATE_UINT32(cm_ctrl, IntegratorCMState),
124
+ VMSTATE_BOOL(detect_falling, TMP105State),
30
+ VMSTATE_UINT32(cm_lock, IntegratorCMState),
31
+ VMSTATE_UINT32(cm_auxosc, IntegratorCMState),
32
+ VMSTATE_UINT32(cm_sdram, IntegratorCMState),
33
+ VMSTATE_UINT32(cm_init, IntegratorCMState),
34
+ VMSTATE_UINT32(cm_flags, IntegratorCMState),
35
+ VMSTATE_UINT32(cm_nvflags, IntegratorCMState),
36
+ VMSTATE_UINT32(int_level, IntegratorCMState),
37
+ VMSTATE_UINT32(irq_enabled, IntegratorCMState),
38
+ VMSTATE_UINT32(fiq_enabled, IntegratorCMState),
39
+ VMSTATE_END_OF_LIST()
125
+ VMSTATE_END_OF_LIST()
40
+ }
126
+ }
41
+};
127
+};
42
+
128
+
43
static uint64_t integratorcm_read(void *opaque, hwaddr offset,
129
static const VMStateDescription vmstate_tmp105 = {
44
unsigned size)
130
.name = "TMP105",
45
{
131
.version_id = 0,
46
@@ -XXX,XX +XXX,XX @@ typedef struct icp_pic_state {
132
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_tmp105 = {
47
qemu_irq parent_fiq;
133
VMSTATE_UINT8(alarm, TMP105State),
48
} icp_pic_state;
134
VMSTATE_I2C_SLAVE(i2c, TMP105State),
49
135
VMSTATE_END_OF_LIST()
50
+static const VMStateDescription vmstate_icp_pic = {
136
+ },
51
+ .name = "icp_pic",
137
+ .subsections = (const VMStateDescription*[]) {
52
+ .version_id = 1,
138
+ &vmstate_tmp105_detect_falling,
53
+ .minimum_version_id = 1,
139
+ NULL
54
+ .fields = (VMStateField[]) {
140
}
55
+ VMSTATE_UINT32(level, icp_pic_state),
56
+ VMSTATE_UINT32(irq_enabled, icp_pic_state),
57
+ VMSTATE_UINT32(fiq_enabled, icp_pic_state),
58
+ VMSTATE_END_OF_LIST()
59
+ }
60
+};
61
+
62
static void icp_pic_update(icp_pic_state *s)
63
{
64
uint32_t flags;
65
@@ -XXX,XX +XXX,XX @@ typedef struct ICPCtrlRegsState {
66
#define ICP_INTREG_WPROT (1 << 0)
67
#define ICP_INTREG_CARDIN (1 << 3)
68
69
+static const VMStateDescription vmstate_icp_control = {
70
+ .name = "icp_control",
71
+ .version_id = 1,
72
+ .minimum_version_id = 1,
73
+ .fields = (VMStateField[]) {
74
+ VMSTATE_UINT32(intreg_state, ICPCtrlRegsState),
75
+ VMSTATE_END_OF_LIST()
76
+ }
77
+};
78
+
79
static uint64_t icp_control_read(void *opaque, hwaddr offset,
80
unsigned size)
81
{
82
@@ -XXX,XX +XXX,XX @@ static void core_class_init(ObjectClass *klass, void *data)
83
84
dc->props = core_properties;
85
dc->realize = integratorcm_realize;
86
+ dc->vmsd = &vmstate_integratorcm;
87
+}
88
+
89
+static void icp_pic_class_init(ObjectClass *klass, void *data)
90
+{
91
+ DeviceClass *dc = DEVICE_CLASS(klass);
92
+
93
+ dc->vmsd = &vmstate_icp_pic;
94
+}
95
+
96
+static void icp_control_class_init(ObjectClass *klass, void *data)
97
+{
98
+ DeviceClass *dc = DEVICE_CLASS(klass);
99
+
100
+ dc->vmsd = &vmstate_icp_control;
101
}
102
103
static const TypeInfo core_info = {
104
@@ -XXX,XX +XXX,XX @@ static const TypeInfo icp_pic_info = {
105
.parent = TYPE_SYS_BUS_DEVICE,
106
.instance_size = sizeof(icp_pic_state),
107
.instance_init = icp_pic_init,
108
+ .class_init = icp_pic_class_init,
109
};
141
};
110
142
111
static const TypeInfo icp_ctrl_regs_info = {
143
@@ -XXX,XX +XXX,XX @@ static void tmp105_reset(I2CSlave *i2c)
112
@@ -XXX,XX +XXX,XX @@ static const TypeInfo icp_ctrl_regs_info = {
144
s->config = 0;
113
.parent = TYPE_SYS_BUS_DEVICE,
145
s->faults = tmp105_faultq[(s->config >> 3) & 3];
114
.instance_size = sizeof(ICPCtrlRegsState),
146
s->alarm = 0;
115
.instance_init = icp_control_init,
147
+ s->detect_falling = false;
116
+ .class_init = icp_control_class_init,
148
117
};
149
s->limit[0] = 0x4b00; /* T_LOW, 75 degrees C */
118
150
s->limit[1] = 0x5000; /* T_HIGH, 80 degrees C */
119
static void integratorcp_register_types(void)
120
--
151
--
121
2.7.4
152
2.20.1
122
153
123
154
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The Aspeed SoC includes a set of watchdog timers using 32-bit
4
decrement counters, which can be based either on the APB clock or
5
a 1 MHz clock.
6
7
The watchdog timer is designed to prevent system deadlock and, in
8
general, it should be restarted before timeout. When a timeout occurs,
9
different types of signals can be generated, ARM reset, SOC reset,
10
System reset, CPU Interrupt, external signal or boot from alternate
11
block. The current model only performs the system reset function as
12
this is used by U-Boot and Linux.
13
14
Signed-off-by: Joel Stanley <joel@jms.id.au>
15
Message-id: 1485452251-1593-2-git-send-email-clg@kaod.org
16
[clg: - fixed compile breakage
17
- fixed io region size
18
- added watchdog_perform_action() on timer expiry
19
- wrote a commit log
20
- merged fixes from Andrew Jeffery to scale the reload value ]
21
Signed-off-by: Cédric Le Goater <clg@kaod.org>
22
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
25
hw/watchdog/Makefile.objs | 1 +
26
include/hw/watchdog/wdt_aspeed.h | 32 ++++++
27
hw/watchdog/wdt_aspeed.c | 225 +++++++++++++++++++++++++++++++++++++++
28
3 files changed, 258 insertions(+)
29
create mode 100644 include/hw/watchdog/wdt_aspeed.h
30
create mode 100644 hw/watchdog/wdt_aspeed.c
31
32
diff --git a/hw/watchdog/Makefile.objs b/hw/watchdog/Makefile.objs
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/watchdog/Makefile.objs
35
+++ b/hw/watchdog/Makefile.objs
36
@@ -XXX,XX +XXX,XX @@ common-obj-y += watchdog.o
37
common-obj-$(CONFIG_WDT_IB6300ESB) += wdt_i6300esb.o
38
common-obj-$(CONFIG_WDT_IB700) += wdt_ib700.o
39
common-obj-$(CONFIG_WDT_DIAG288) += wdt_diag288.o
40
+common-obj-$(CONFIG_ASPEED_SOC) += wdt_aspeed.o
41
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
42
new file mode 100644
43
index XXXXXXX..XXXXXXX
44
--- /dev/null
45
+++ b/include/hw/watchdog/wdt_aspeed.h
46
@@ -XXX,XX +XXX,XX @@
47
+/*
48
+ * ASPEED Watchdog Controller
49
+ *
50
+ * Copyright (C) 2016-2017 IBM Corp.
51
+ *
52
+ * This code is licensed under the GPL version 2 or later. See the
53
+ * COPYING file in the top-level directory.
54
+ */
55
+#ifndef ASPEED_WDT_H
56
+#define ASPEED_WDT_H
57
+
58
+#include "hw/sysbus.h"
59
+
60
+#define TYPE_ASPEED_WDT "aspeed.wdt"
61
+#define ASPEED_WDT(obj) \
62
+ OBJECT_CHECK(AspeedWDTState, (obj), TYPE_ASPEED_WDT)
63
+
64
+#define ASPEED_WDT_REGS_MAX (0x20 / 4)
65
+
66
+typedef struct AspeedWDTState {
67
+ /*< private >*/
68
+ SysBusDevice parent_obj;
69
+ QEMUTimer *timer;
70
+
71
+ /*< public >*/
72
+ MemoryRegion iomem;
73
+ uint32_t regs[ASPEED_WDT_REGS_MAX];
74
+
75
+ uint32_t pclk_freq;
76
+} AspeedWDTState;
77
+
78
+#endif /* ASPEED_WDT_H */
79
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
80
new file mode 100644
81
index XXXXXXX..XXXXXXX
82
--- /dev/null
83
+++ b/hw/watchdog/wdt_aspeed.c
84
@@ -XXX,XX +XXX,XX @@
85
+/*
86
+ * ASPEED Watchdog Controller
87
+ *
88
+ * Copyright (C) 2016-2017 IBM Corp.
89
+ *
90
+ * This code is licensed under the GPL version 2 or later. See the
91
+ * COPYING file in the top-level directory.
92
+ */
93
+
94
+#include "qemu/osdep.h"
95
+#include "qemu/log.h"
96
+#include "sysemu/watchdog.h"
97
+#include "hw/sysbus.h"
98
+#include "qemu/timer.h"
99
+#include "hw/watchdog/wdt_aspeed.h"
100
+
101
+#define WDT_STATUS (0x00 / 4)
102
+#define WDT_RELOAD_VALUE (0x04 / 4)
103
+#define WDT_RESTART (0x08 / 4)
104
+#define WDT_CTRL (0x0C / 4)
105
+#define WDT_CTRL_RESET_MODE_SOC (0x00 << 5)
106
+#define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5)
107
+#define WDT_CTRL_1MHZ_CLK BIT(4)
108
+#define WDT_CTRL_WDT_EXT BIT(3)
109
+#define WDT_CTRL_WDT_INTR BIT(2)
110
+#define WDT_CTRL_RESET_SYSTEM BIT(1)
111
+#define WDT_CTRL_ENABLE BIT(0)
112
+
113
+#define WDT_TIMEOUT_STATUS (0x10 / 4)
114
+#define WDT_TIMEOUT_CLEAR (0x14 / 4)
115
+#define WDT_RESET_WDITH (0x18 / 4)
116
+
117
+#define WDT_RESTART_MAGIC 0x4755
118
+
119
+static bool aspeed_wdt_is_enabled(const AspeedWDTState *s)
120
+{
121
+ return s->regs[WDT_CTRL] & WDT_CTRL_ENABLE;
122
+}
123
+
124
+static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
125
+{
126
+ AspeedWDTState *s = ASPEED_WDT(opaque);
127
+
128
+ offset >>= 2;
129
+
130
+ switch (offset) {
131
+ case WDT_STATUS:
132
+ return s->regs[WDT_STATUS];
133
+ case WDT_RELOAD_VALUE:
134
+ return s->regs[WDT_RELOAD_VALUE];
135
+ case WDT_RESTART:
136
+ qemu_log_mask(LOG_GUEST_ERROR,
137
+ "%s: read from write-only reg at offset 0x%"
138
+ HWADDR_PRIx "\n", __func__, offset);
139
+ return 0;
140
+ case WDT_CTRL:
141
+ return s->regs[WDT_CTRL];
142
+ case WDT_TIMEOUT_STATUS:
143
+ case WDT_TIMEOUT_CLEAR:
144
+ case WDT_RESET_WDITH:
145
+ qemu_log_mask(LOG_UNIMP,
146
+ "%s: uninmplemented read at offset 0x%" HWADDR_PRIx "\n",
147
+ __func__, offset);
148
+ return 0;
149
+ default:
150
+ qemu_log_mask(LOG_GUEST_ERROR,
151
+ "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
152
+ __func__, offset);
153
+ return 0;
154
+ }
155
+
156
+}
157
+
158
+static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
159
+{
160
+ uint32_t reload;
161
+
162
+ if (pclk) {
163
+ reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND,
164
+ s->pclk_freq);
165
+ } else {
166
+ reload = s->regs[WDT_RELOAD_VALUE] * 1000;
167
+ }
168
+
169
+ if (aspeed_wdt_is_enabled(s)) {
170
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
171
+ }
172
+}
173
+
174
+static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
175
+ unsigned size)
176
+{
177
+ AspeedWDTState *s = ASPEED_WDT(opaque);
178
+ bool enable = data & WDT_CTRL_ENABLE;
179
+
180
+ offset >>= 2;
181
+
182
+ switch (offset) {
183
+ case WDT_STATUS:
184
+ qemu_log_mask(LOG_GUEST_ERROR,
185
+ "%s: write to read-only reg at offset 0x%"
186
+ HWADDR_PRIx "\n", __func__, offset);
187
+ break;
188
+ case WDT_RELOAD_VALUE:
189
+ s->regs[WDT_RELOAD_VALUE] = data;
190
+ break;
191
+ case WDT_RESTART:
192
+ if ((data & 0xFFFF) == WDT_RESTART_MAGIC) {
193
+ s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE];
194
+ aspeed_wdt_reload(s, !(data & WDT_CTRL_1MHZ_CLK));
195
+ }
196
+ break;
197
+ case WDT_CTRL:
198
+ if (enable && !aspeed_wdt_is_enabled(s)) {
199
+ s->regs[WDT_CTRL] = data;
200
+ aspeed_wdt_reload(s, !(data & WDT_CTRL_1MHZ_CLK));
201
+ } else if (!enable && aspeed_wdt_is_enabled(s)) {
202
+ s->regs[WDT_CTRL] = data;
203
+ timer_del(s->timer);
204
+ }
205
+ break;
206
+ case WDT_TIMEOUT_STATUS:
207
+ case WDT_TIMEOUT_CLEAR:
208
+ case WDT_RESET_WDITH:
209
+ qemu_log_mask(LOG_UNIMP,
210
+ "%s: uninmplemented write at offset 0x%" HWADDR_PRIx "\n",
211
+ __func__, offset);
212
+ break;
213
+ default:
214
+ qemu_log_mask(LOG_GUEST_ERROR,
215
+ "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
216
+ __func__, offset);
217
+ }
218
+ return;
219
+}
220
+
221
+static WatchdogTimerModel model = {
222
+ .wdt_name = TYPE_ASPEED_WDT,
223
+ .wdt_description = "Aspeed watchdog device",
224
+};
225
+
226
+static const VMStateDescription vmstate_aspeed_wdt = {
227
+ .name = "vmstate_aspeed_wdt",
228
+ .version_id = 0,
229
+ .minimum_version_id = 0,
230
+ .fields = (VMStateField[]) {
231
+ VMSTATE_TIMER_PTR(timer, AspeedWDTState),
232
+ VMSTATE_UINT32_ARRAY(regs, AspeedWDTState, ASPEED_WDT_REGS_MAX),
233
+ VMSTATE_END_OF_LIST()
234
+ }
235
+};
236
+
237
+static const MemoryRegionOps aspeed_wdt_ops = {
238
+ .read = aspeed_wdt_read,
239
+ .write = aspeed_wdt_write,
240
+ .endianness = DEVICE_LITTLE_ENDIAN,
241
+ .valid.min_access_size = 4,
242
+ .valid.max_access_size = 4,
243
+ .valid.unaligned = false,
244
+};
245
+
246
+static void aspeed_wdt_reset(DeviceState *dev)
247
+{
248
+ AspeedWDTState *s = ASPEED_WDT(dev);
249
+
250
+ s->regs[WDT_STATUS] = 0x3EF1480;
251
+ s->regs[WDT_RELOAD_VALUE] = 0x03EF1480;
252
+ s->regs[WDT_RESTART] = 0;
253
+ s->regs[WDT_CTRL] = 0;
254
+
255
+ timer_del(s->timer);
256
+}
257
+
258
+static void aspeed_wdt_timer_expired(void *dev)
259
+{
260
+ AspeedWDTState *s = ASPEED_WDT(dev);
261
+
262
+ qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
263
+ watchdog_perform_action();
264
+ timer_del(s->timer);
265
+}
266
+
267
+#define PCLK_HZ 24000000
268
+
269
+static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
270
+{
271
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
272
+ AspeedWDTState *s = ASPEED_WDT(dev);
273
+
274
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev);
275
+
276
+ /* FIXME: This setting should be derived from the SCU hw strapping
277
+ * register SCU70
278
+ */
279
+ s->pclk_freq = PCLK_HZ;
280
+
281
+ memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_wdt_ops, s,
282
+ TYPE_ASPEED_WDT, ASPEED_WDT_REGS_MAX * 4);
283
+ sysbus_init_mmio(sbd, &s->iomem);
284
+}
285
+
286
+static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
287
+{
288
+ DeviceClass *dc = DEVICE_CLASS(klass);
289
+
290
+ dc->realize = aspeed_wdt_realize;
291
+ dc->reset = aspeed_wdt_reset;
292
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
293
+ dc->vmsd = &vmstate_aspeed_wdt;
294
+}
295
+
296
+static const TypeInfo aspeed_wdt_info = {
297
+ .parent = TYPE_SYS_BUS_DEVICE,
298
+ .name = TYPE_ASPEED_WDT,
299
+ .instance_size = sizeof(AspeedWDTState),
300
+ .class_init = aspeed_wdt_class_init,
301
+};
302
+
303
+static void wdt_aspeed_register_types(void)
304
+{
305
+ watchdog_add_model(&model);
306
+ type_register_static(&aspeed_wdt_info);
307
+}
308
+
309
+type_init(wdt_aspeed_register_types)
310
--
311
2.7.4
312
313
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
This enables reboot of a guest from U-Boot and Linux.
4
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Joel Stanley <joel@jms.id.au>
7
Message-id: 1485452251-1593-3-git-send-email-clg@kaod.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
include/hw/arm/aspeed_soc.h | 2 ++
11
hw/arm/aspeed_soc.c | 13 +++++++++++++
12
2 files changed, 15 insertions(+)
13
14
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/aspeed_soc.h
17
+++ b/include/hw/arm/aspeed_soc.h
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/timer/aspeed_timer.h"
20
#include "hw/i2c/aspeed_i2c.h"
21
#include "hw/ssi/aspeed_smc.h"
22
+#include "hw/watchdog/wdt_aspeed.h"
23
24
#define ASPEED_SPIS_NUM 2
25
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
27
AspeedSMCState fmc;
28
AspeedSMCState spi[ASPEED_SPIS_NUM];
29
AspeedSDMCState sdmc;
30
+ AspeedWDTState wdt;
31
} AspeedSoCState;
32
33
#define TYPE_ASPEED_SOC "aspeed-soc"
34
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/aspeed_soc.c
37
+++ b/hw/arm/aspeed_soc.c
38
@@ -XXX,XX +XXX,XX @@
39
#define ASPEED_SOC_SCU_BASE 0x1E6E2000
40
#define ASPEED_SOC_SRAM_BASE 0x1E720000
41
#define ASPEED_SOC_TIMER_BASE 0x1E782000
42
+#define ASPEED_SOC_WDT_BASE 0x1E785000
43
#define ASPEED_SOC_I2C_BASE 0x1E78A000
44
45
static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
46
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
47
sc->info->silicon_rev);
48
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
49
"ram-size", &error_abort);
50
+
51
+ object_initialize(&s->wdt, sizeof(s->wdt), TYPE_ASPEED_WDT);
52
+ object_property_add_child(obj, "wdt", OBJECT(&s->wdt), NULL);
53
+ qdev_set_parent_bus(DEVICE(&s->wdt), sysbus_get_default());
54
}
55
56
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
57
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
58
return;
59
}
60
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, ASPEED_SOC_SDMC_BASE);
61
+
62
+ /* Watch dog */
63
+ object_property_set_bool(OBJECT(&s->wdt), true, "realized", &err);
64
+ if (err) {
65
+ error_propagate(errp, err);
66
+ return;
67
+ }
68
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt), 0, ASPEED_SOC_WDT_BASE);
69
}
70
71
static void aspeed_soc_class_init(ObjectClass *oc, void *data)
72
--
73
2.7.4
74
75
diff view generated by jsdifflib
Deleted patch
1
From: Prasad J Pandit <pjp@fedoraproject.org>
2
1
3
While doing multi block SDMA transfer in routine
4
'sdhci_sdma_transfer_multi_blocks', the 's->fifo_buffer' starting
5
index 'begin' and data length 's->data_count' could end up to be same.
6
This could lead to an OOB access issue. Correct transfer data length
7
to avoid it.
8
9
Cc: qemu-stable@nongnu.org
10
Reported-by: Jiang Xin <jiangxin1@huawei.com>
11
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20170130064736.9236-1-ppandit@redhat.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/sd/sdhci.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
18
19
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/sd/sdhci.c
22
+++ b/hw/sd/sdhci.c
23
@@ -XXX,XX +XXX,XX @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
24
boundary_count -= block_size - begin;
25
}
26
dma_memory_read(&address_space_memory, s->sdmasysad,
27
- &s->fifo_buffer[begin], s->data_count);
28
+ &s->fifo_buffer[begin], s->data_count - begin);
29
s->sdmasysad += s->data_count - begin;
30
if (s->data_count == block_size) {
31
for (n = 0; n < block_size; n++) {
32
--
33
2.7.4
34
35
diff view generated by jsdifflib
Deleted patch
1
In the ARM ldr/str decode path, rather than directly testing
2
"insn & (1 << 21)" and "insn & (1 << 24)", abstract these
3
bits out into wbit and pbit local flags. (We will want to
4
do more tests against them to determine whether we need to
5
provide syndrome information.)
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
---
10
target/arm/translate.c | 9 ++++++---
11
1 file changed, 6 insertions(+), 3 deletions(-)
12
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
18
} else {
19
int address_offset;
20
bool load = insn & (1 << 20);
21
+ bool wbit = insn & (1 << 21);
22
+ bool pbit = insn & (1 << 24);
23
bool doubleword = false;
24
/* Misc load/store */
25
rn = (insn >> 16) & 0xf;
26
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
27
}
28
29
addr = load_reg(s, rn);
30
- if (insn & (1 << 24))
31
+ if (pbit) {
32
gen_add_datah_offset(s, insn, 0, addr);
33
+ }
34
address_offset = 0;
35
36
if (doubleword) {
37
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
38
ensure correct behavior with overlapping index registers.
39
ldrd with base writeback is undefined if the
40
destination and index registers overlap. */
41
- if (!(insn & (1 << 24))) {
42
+ if (!pbit) {
43
gen_add_datah_offset(s, insn, address_offset, addr);
44
store_reg(s, rn, addr);
45
- } else if (insn & (1 << 21)) {
46
+ } else if (wbit) {
47
if (address_offset)
48
tcg_gen_addi_i32(addr, addr, address_offset);
49
store_reg(s, rn, addr);
50
--
51
2.7.4
52
53
diff view generated by jsdifflib