1
A random mix of items here, nothing very major.
1
Arm patch queue -- these are all bug fix patches but we might
2
as well put them in to rc0...
2
3
3
thanks
4
thanks
4
-- PMM
5
-- PMM
5
6
7
The following changes since commit 2c8cfc0b52b5a4d123c26c0b5fdf941be24805be:
6
8
7
The following changes since commit d0dff238a87fa81393ed72754d4dc8b09e50b08b:
9
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2018-03-19 11:44:26 +0000)
8
10
9
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170206' into staging (2017-02-07 15:29:26 +0000)
11
are available in the Git repository at:
10
12
11
are available in the git repository at:
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180319
12
14
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170207
15
for you to fetch changes up to ff72cb6b46b95bb530787add5277c211af3d31c6:
14
16
15
for you to fetch changes up to 7727b832886fafbdec7299eb7773dc9071bf4cdd:
17
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs (2018-03-19 18:23:24 +0000)
16
17
stellaris: Use the 'unimplemented' device for parts we don't implement (2017-02-07 18:30:00 +0000)
18
18
19
----------------------------------------------------------------
19
----------------------------------------------------------------
20
target-arm:
20
target-arm queue:
21
* new "unimplemented" device for stubbing out devices in a
21
* fsl-imx6: Fix incorrect Ethernet interrupt defines
22
system model so accesses can be logged
22
* dump: Update correct kdump phys_base field for AArch64
23
* stellaris: document the SoC memory map
23
* char: i.MX: Add support for "TX complete" interrupt
24
* arm: create instruction syndromes for AArch32 data aborts
24
* bcm2836/raspi: Fix various bugs resulting in panics trying
25
* arm: Correctly handle watchpoints for BE32 CPUs
25
to boot a Debian Linux kernel on raspi3
26
* Fix Thumb-1 BE32 execution and disassembly
27
* arm: Add cfgend parameter for ARM CPU selection
28
* sd: sdhci: check data length during dma_memory_read
29
* aspeed: add a watchdog controller
30
* integratorcp: adding vmstate for save/restore
31
26
32
----------------------------------------------------------------
27
----------------------------------------------------------------
33
Cédric Le Goater (2):
28
Andrey Smirnov (2):
34
wdt: Add Aspeed watchdog device model
29
char: i.MX: Simplify imx_update()
35
aspeed: add a watchdog controller
30
char: i.MX: Add support for "TX complete" interrupt
36
31
37
Julian Brown (4):
32
Guenter Roeck (1):
38
hw/arm/integratorcp: Support specifying features via -cpu
33
fsl-imx6: Swap Ethernet interrupt defines
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
34
43
Pavel Dovgalyuk (1):
35
Peter Maydell (9):
44
integratorcp: adding vmstate for save/restore
36
hw/arm/raspi: Don't do board-setup or secure-boot for raspi3
37
hw/arm/boot: assert that secure_boot and secure_board_setup are false for AArch64
38
hw/arm/boot: If booting a kernel in EL2, set SCR_EL3.HCE
39
hw/arm/bcm2386: Fix parent type of bcm2386
40
hw/arm/bcm2836: Rename bcm2836 type/struct to bcm283x
41
hw/arm/bcm2836: Create proper bcm2837 device
42
hw/arm/bcm2836: Use correct affinity values for BCM2837
43
hw/arm/bcm2836: Hardcode correct CPU type
44
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs
45
45
46
Peter Maydell (5):
46
Wei Huang (1):
47
target/arm: Abstract out pbit/wbit tests in ARM ldr/str decode
47
dump: Update correct kdump phys_base field for AArch64
48
target/arm: A32, T32: Create Instruction Syndromes for Data Aborts
49
stellaris: Document memory map and which SoC devices are unimplemented
50
hw/misc: New "unimplemented" sysbus device
51
stellaris: Use the 'unimplemented' device for parts we don't implement
52
48
53
Prasad J Pandit (1):
49
include/hw/arm/bcm2836.h | 31 +++++++++++++---
54
sd: sdhci: check data length during dma_memory_read
50
include/hw/arm/fsl-imx6.h | 4 +-
51
include/hw/char/imx_serial.h | 3 ++
52
dump.c | 14 +++++--
53
hw/arm/bcm2836.c | 87 +++++++++++++++++++++++++++++++-------------
54
hw/arm/boot.c | 12 ++++++
55
hw/arm/raspi.c | 77 +++++++++++++++++++++++++++++++--------
56
hw/char/imx_serial.c | 44 ++++++++++++++++------
57
hw/net/imx_fec.c | 28 +++++++++++++-
58
9 files changed, 237 insertions(+), 63 deletions(-)
55
59
56
hw/misc/Makefile.objs | 2 +
57
hw/watchdog/Makefile.objs | 1 +
58
include/disas/bfd.h | 7 ++
59
include/hw/arm/aspeed_soc.h | 2 +
60
include/hw/misc/unimp.h | 39 +++++++
61
include/hw/watchdog/wdt_aspeed.h | 32 ++++++
62
include/qom/cpu.h | 3 +
63
target/arm/arm_ldst.h | 10 +-
64
target/arm/cpu.h | 7 ++
65
target/arm/internals.h | 5 +
66
target/arm/translate.h | 14 +++
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
diff view generated by jsdifflib
1
From: Julian Brown <julian@codesourcery.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
In BE32 mode, sub-word size watchpoints can fail to trigger because the
3
The sabrelite machine model used by qemu-system-arm is based on the
4
address of the access is adjusted in the opcode helpers before being
4
Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
5
compared with the watchpoint registers. This patch reverses the address
5
controller which is supported in QEMU using the imx_fec.c module
6
adjustment before performing the comparison with the help of a new CPUClass
6
(actually called imx.enet for this model.)
7
hook.
8
7
9
This version of the patch augments and tidies up comments a little.
8
The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for the
9
imx.enet device like this:
10
10
11
Signed-off-by: Julian Brown <julian@codesourcery.com>
11
#define FSL_IMX6_ENET_MAC_1588_IRQ 118
12
Message-id: caaf64ffc72f6ae183015337b7afdbd4b8989cb6.1484929304.git.julian@codesourcery.com
12
#define FSL_IMX6_ENET_MAC_IRQ 119
13
14
According to https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf,
15
page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary,
16
interrupts are as follows.
17
18
150 ENET MAC 0 IRQ
19
151 ENET MAC 0 1588 Timer interrupt
20
21
where
22
23
150 - 32 == 118
24
151 - 32 == 119
25
26
In other words, the vector definitions in the fsl-imx6.h file are reversed.
27
28
Fixing the interrupts alone causes problems with older Linux kernels:
29
The Ethernet interface will fail to probe with Linux v4.9 and earlier.
30
Linux v4.1 and earlier will crash due to a bug in Ethernet driver probe
31
error handling. This is a Linux kernel problem, not a qemu problem:
32
the Linux kernel only worked by accident since it requested both interrupts.
33
34
For backward compatibility, generate the Ethernet interrupt on both interrupt
35
lines. This was shown to work from all Linux kernel releases starting with
36
v3.16.
37
38
Link: https://bugs.launchpad.net/qemu/+bug/1753309
39
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
40
Message-id: 1520723090-22130-1-git-send-email-linux@roeck-us.net
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
41
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
43
---
16
include/qom/cpu.h | 3 +++
44
include/hw/arm/fsl-imx6.h | 4 ++--
17
target/arm/internals.h | 5 +++++
45
hw/net/imx_fec.c | 28 +++++++++++++++++++++++++++-
18
exec.c | 1 +
46
2 files changed, 29 insertions(+), 3 deletions(-)
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
47
24
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
48
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
25
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
26
--- a/include/qom/cpu.h
50
--- a/include/hw/arm/fsl-imx6.h
27
+++ b/include/qom/cpu.h
51
+++ b/include/hw/arm/fsl-imx6.h
28
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock;
52
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
29
* @cpu_exec_exit: Callback for cpu_exec cleanup.
53
#define FSL_IMX6_HDMI_MASTER_IRQ 115
30
* @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec.
54
#define FSL_IMX6_HDMI_CEC_IRQ 116
31
* @disas_set_info: Setup architecture specific components of disassembly info
55
#define FSL_IMX6_MLB150_LOW_IRQ 117
32
+ * @adjust_watchpoint_address: Perform a target-specific adjustment to an
56
-#define FSL_IMX6_ENET_MAC_1588_IRQ 118
33
+ * address before attempting to match it against watchpoints.
57
-#define FSL_IMX6_ENET_MAC_IRQ 119
34
*
58
+#define FSL_IMX6_ENET_MAC_IRQ 118
35
* Represents a CPU family or model.
59
+#define FSL_IMX6_ENET_MAC_1588_IRQ 119
36
*/
60
#define FSL_IMX6_PCIE1_IRQ 120
37
@@ -XXX,XX +XXX,XX @@ typedef struct CPUClass {
61
#define FSL_IMX6_PCIE2_IRQ 121
38
bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
62
#define FSL_IMX6_PCIE3_IRQ 122
39
63
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
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
64
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/internals.h
65
--- a/hw/net/imx_fec.c
48
+++ b/target/arm/internals.h
66
+++ b/hw/net/imx_fec.c
49
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update_all(ARMCPU *cpu);
67
@@ -XXX,XX +XXX,XX @@ static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
50
/* Callback function for checking if a watchpoint should trigger. */
68
51
bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
69
static void imx_eth_update(IMXFECState *s)
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
{
70
{
88
DeviceClass *dc = DEVICE_CLASS(klass);
71
- if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
89
@@ -XXX,XX +XXX,XX @@ static void cpu_class_init(ObjectClass *klass, void *data)
72
+ /*
90
k->cpu_exec_enter = cpu_common_noop;
73
+ * Previous versions of qemu had the ENET_INT_MAC and ENET_INT_TS_TIMER
91
k->cpu_exec_exit = cpu_common_noop;
74
+ * interrupts swapped. This worked with older versions of Linux (4.14
92
k->cpu_exec_interrupt = cpu_common_exec_interrupt;
75
+ * and older) since Linux associated both interrupt lines with Ethernet
93
+ k->adjust_watchpoint_address = cpu_adjust_watchpoint_address;
76
+ * MAC interrupts. Specifically,
94
set_bit(DEVICE_CATEGORY_CPU, dc->categories);
77
+ * - Linux 4.15 and later have separate interrupt handlers for the MAC and
95
dc->realize = cpu_common_realizefn;
78
+ * timer interrupts. Those versions of Linux fail with versions of QEMU
96
dc->unrealize = cpu_common_unrealizefn;
79
+ * with swapped interrupt assignments.
97
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
80
+ * - In linux 4.14, both interrupt lines were registered with the Ethernet
98
index XXXXXXX..XXXXXXX 100644
81
+ * MAC interrupt handler. As a result, all versions of qemu happen to
99
--- a/target/arm/cpu.c
82
+ * work, though that is accidental.
100
+++ b/target/arm/cpu.c
83
+ * - In Linux 4.9 and older, the timer interrupt was registered directly
101
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
84
+ * with the Ethernet MAC interrupt handler. The MAC interrupt was
102
cc->gdb_stop_before_watchpoint = true;
85
+ * redirected to a GPIO interrupt to work around erratum ERR006687.
103
cc->debug_excp_handler = arm_debug_excp_handler;
86
+ * This was implemented using the SOC's IOMUX block. In qemu, this GPIO
104
cc->debug_check_watchpoint = arm_debug_check_watchpoint;
87
+ * interrupt never fired since IOMUX is currently not supported in qemu.
105
+#if !defined(CONFIG_USER_ONLY)
88
+ * Linux instead received MAC interrupts on the timer interrupt.
106
+ cc->adjust_watchpoint_address = arm_adjust_watchpoint_address;
89
+ * As a result, qemu versions with the swapped interrupt assignment work,
107
+#endif
90
+ * albeit accidentally, but qemu versions with the correct interrupt
108
91
+ * assignment fail.
109
cc->disas_set_info = arm_disas_set_info;
92
+ *
110
}
93
+ * To ensure that all versions of Linux work, generate ENET_INT_MAC
111
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
94
+ * interrrupts on both interrupt lines. This should be changed if and when
112
index XXXXXXX..XXXXXXX 100644
95
+ * qemu supports IOMUX.
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
+ */
96
+ */
130
+ if (arm_sctlr_b(env)) {
97
+ if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] &
131
+ if (len == 1) {
98
+ (ENET_INT_MAC | ENET_INT_TS_TIMER)) {
132
+ addr ^= 3;
99
qemu_set_irq(s->irq[1], 1);
133
+ } else if (len == 2) {
100
} else {
134
+ addr ^= 2;
101
qemu_set_irq(s->irq[1], 0);
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
--
102
--
145
2.7.4
103
2.16.2
146
104
147
105
diff view generated by jsdifflib
1
From: Julian Brown <julian@codesourcery.com>
1
From: Wei Huang <wei@redhat.com>
2
2
3
Since the integratorcp board creates the CPU object directly
3
For guest kernel that supports KASLR, the load address can change every
4
rather than via cpu_arm_init(), we have to call the CPU
4
time when guest VM runs. To find the physical base address correctly,
5
class parse_features() method ourselves if we want to
5
current QEMU dump searches VMCOREINFO for the string "NUMBER(phys_base)=".
6
support the user passing features via the -cpu command
6
However this string pattern is only available on x86_64. AArch64 uses a
7
line argument as well as just the cpu name. Do so.
7
different field, called "NUMBER(PHYS_OFFSET)=". This patch makes sure
8
QEMU dump uses the correct string on AArch64.
8
9
9
Signed-off-by: Julian Brown <julian@codesourcery.com>
10
Signed-off-by: Wei Huang <wei@redhat.com>
10
[PMM: split out into its own patch]
11
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1520615003-20869-1-git-send-email-wei@redhat.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
---
14
hw/arm/integratorcp.c | 19 +++++++++++++++++--
15
dump.c | 14 +++++++++++---
15
1 file changed, 17 insertions(+), 2 deletions(-)
16
1 file changed, 11 insertions(+), 3 deletions(-)
16
17
17
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
18
diff --git a/dump.c b/dump.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/integratorcp.c
20
--- a/dump.c
20
+++ b/hw/arm/integratorcp.c
21
+++ b/dump.c
21
@@ -XXX,XX +XXX,XX @@ static void integratorcp_init(MachineState *machine)
22
@@ -XXX,XX +XXX,XX @@ static void vmcoreinfo_update_phys_base(DumpState *s)
22
const char *kernel_filename = machine->kernel_filename;
23
23
const char *kernel_cmdline = machine->kernel_cmdline;
24
lines = g_strsplit((char *)vmci, "\n", -1);
24
const char *initrd_filename = machine->initrd_filename;
25
for (i = 0; lines[i]; i++) {
25
+ char **cpustr;
26
- if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
26
ObjectClass *cpu_oc;
27
- if (qemu_strtou64(lines[i] + 18, NULL, 16,
27
+ CPUClass *cc;
28
+ const char *prefix = NULL;
28
Object *cpuobj;
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
}
42
43
- cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
44
+ cpustr = g_strsplit(cpu_model, ",", 2);
45
+
29
+
46
+ cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
30
+ if (s->dump_info.d_machine == EM_X86_64) {
47
if (!cpu_oc) {
31
+ prefix = "NUMBER(phys_base)=";
48
fprintf(stderr, "Unable to find CPU definition\n");
32
+ } else if (s->dump_info.d_machine == EM_AARCH64) {
49
exit(1);
33
+ prefix = "NUMBER(PHYS_OFFSET)=";
50
}
34
+ }
51
+ typename = object_class_get_name(cpu_oc);
52
+
35
+
53
+ cc = CPU_CLASS(cpu_oc);
36
+ if (prefix && g_str_has_prefix(lines[i], prefix)) {
54
+ cc->parse_features(typename, cpustr[1], &err);
37
+ if (qemu_strtou64(lines[i] + strlen(prefix), NULL, 16,
55
+ g_strfreev(cpustr);
38
&phys_base) < 0) {
56
+ if (err) {
39
- warn_report("Failed to read NUMBER(phys_base)=");
57
+ error_report_err(err);
40
+ warn_report("Failed to read %s", prefix);
58
+ exit(1);
41
} else {
59
+ }
42
s->dump_info.phys_base = phys_base;
60
43
}
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
--
44
--
67
2.7.4
45
2.16.2
68
46
69
47
diff view generated by jsdifflib
1
From: Julian Brown <julian@codesourcery.com>
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
2
3
Add a new "cfgend" property which selects whether the CPU resets into
3
Code of imx_update() is slightly confusing since the "flags" variable
4
big-endian mode or not. This setting affects whether we reset with
4
doesn't really corespond to anything in real hardware and server as a
5
SCTLR_B (ARMv6 and earlier) or SCTLR_EE (ARMv7 and later) set.
5
kitchensink accumulating events normally reported via USR1 and USR2
6
registers.
6
7
7
Signed-off-by: Julian Brown <julian@codesourcery.com>
8
Change the code to explicitly evaluate state of interrupts reported
8
Message-id: 11420d1c49636c1790e60578ee996e51f0f0b835.1484929304.git.julian@codesourcery.com
9
via USR1 and USR2 against corresponding masking bits and use the to
9
[PMM: use error_report_err() rather than error_report();
10
detemine if IRQ line should be asserted or not.
10
move the integratorcp changes to their own patch;
11
11
drop an unnecessary extra #include;
12
NOTE: Check for UTS1_TXEMPTY being set has been dropped for two
12
rephrase commit message accordingly;
13
reasons:
13
move setting of reset_sctlr above registration of cpregs
14
14
so it actually has an effect]
15
1. Emulation code implements a single character FIFO, so this flag
16
will always be set since characters are trasmitted as a part of
17
the code emulating "push" into the FIFO
18
19
2. imx_update() is really just a function doing ORing and maksing
20
of reported events, so checking for UTS1_TXEMPTY should happen,
21
if it's ever really needed should probably happen outside of
22
it.
23
24
Cc: qemu-devel@nongnu.org
25
Cc: qemu-arm@nongnu.org
26
Cc: Bill Paul <wpaul@windriver.com>
27
Cc: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
29
Message-id: 20180315191141.6789-1-andrew.smirnov@gmail.com
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
32
---
18
target/arm/cpu.h | 7 +++++++
33
hw/char/imx_serial.c | 24 ++++++++++++++++--------
19
target/arm/cpu.c | 13 +++++++++++++
34
1 file changed, 16 insertions(+), 8 deletions(-)
20
2 files changed, 20 insertions(+)
21
35
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
23
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
38
--- a/hw/char/imx_serial.c
25
+++ b/target/arm/cpu.h
39
+++ b/hw/char/imx_serial.c
26
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
27
int gic_vpribits; /* number of virtual priority bits */
41
28
int gic_vprebits; /* number of virtual preemption bits */
42
static void imx_update(IMXSerialState *s)
29
43
{
30
+ /* Whether the cfgend input is high (i.e. this CPU should reset into
44
- uint32_t flags;
31
+ * big-endian mode). This setting isn't used directly: instead it modifies
45
+ uint32_t usr1;
32
+ * the reset_sctlr value to have SCTLR_B or SCTLR_EE set, depending on the
46
+ uint32_t usr2;
33
+ * architecture version.
47
+ uint32_t mask;
48
49
- flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
50
- if (s->ucr1 & UCR1_TXMPTYEN) {
51
- flags |= (s->uts1 & UTS1_TXEMPTY);
52
- } else {
53
- flags &= ~USR1_TRDY;
54
- }
55
+ /*
56
+ * Lucky for us TRDY and RRDY has the same offset in both USR1 and
57
+ * UCR1, so we can get away with something as simple as the
58
+ * following:
34
+ */
59
+ */
35
+ bool cfgend;
60
+ usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
36
+
61
+ /*
37
ARMELChangeHook *el_change_hook;
62
+ * Bits that we want in USR2 are not as conveniently laid out,
38
void *el_change_hook_opaque;
63
+ * unfortunately.
39
};
64
+ */
40
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
65
+ mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
41
index XXXXXXX..XXXXXXX 100644
66
+ usr2 = s->usr2 & mask;
42
--- a/target/arm/cpu.c
67
43
+++ b/target/arm/cpu.c
68
- qemu_set_irq(s->irq, !!flags);
44
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_has_el2_property =
69
+ qemu_set_irq(s->irq, usr1 || usr2);
45
static Property arm_cpu_has_el3_property =
46
DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true);
47
48
+static Property arm_cpu_cfgend_property =
49
+ DEFINE_PROP_BOOL("cfgend", ARMCPU, cfgend, false);
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
}
57
58
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
59
+ &error_abort);
60
}
70
}
61
71
62
static void arm_cpu_finalizefn(Object *obj)
72
static void imx_serial_reset(IMXSerialState *s)
63
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
64
cpu->reset_sctlr |= (1 << 13);
65
}
66
67
+ if (cpu->cfgend) {
68
+ if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
69
+ cpu->reset_sctlr |= SCTLR_EE;
70
+ } else {
71
+ cpu->reset_sctlr |= SCTLR_B;
72
+ }
73
+ }
74
+
75
if (!cpu->has_el3) {
76
/* If the has_el3 CPU property is disabled then we need to disable the
77
* feature.
78
--
73
--
79
2.7.4
74
2.16.2
80
75
81
76
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
2
3
The Aspeed SoC includes a set of watchdog timers using 32-bit
3
Add support for "TX complete"/TXDC interrupt generate by real HW since
4
decrement counters, which can be based either on the APB clock or
4
it is needed to support guests other than Linux.
5
a 1 MHz clock.
6
5
7
The watchdog timer is designed to prevent system deadlock and, in
6
Based on the patch by Bill Paul as found here:
8
general, it should be restarted before timeout. When a timeout occurs,
7
https://bugs.launchpad.net/qemu/+bug/1753314
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
8
14
Signed-off-by: Joel Stanley <joel@jms.id.au>
9
Cc: qemu-devel@nongnu.org
15
Message-id: 1485452251-1593-2-git-send-email-clg@kaod.org
10
Cc: qemu-arm@nongnu.org
16
[clg: - fixed compile breakage
11
Cc: Bill Paul <wpaul@windriver.com>
17
- fixed io region size
12
Cc: Peter Maydell <peter.maydell@linaro.org>
18
- added watchdog_perform_action() on timer expiry
13
Signed-off-by: Bill Paul <wpaul@windriver.com>
19
- wrote a commit log
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
20
- merged fixes from Andrew Jeffery to scale the reload value ]
15
Message-id: 20180315191141.6789-2-andrew.smirnov@gmail.com
21
Signed-off-by: Cédric Le Goater <clg@kaod.org>
22
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
18
---
25
hw/watchdog/Makefile.objs | 1 +
19
include/hw/char/imx_serial.h | 3 +++
26
include/hw/watchdog/wdt_aspeed.h | 32 ++++++
20
hw/char/imx_serial.c | 20 +++++++++++++++++---
27
hw/watchdog/wdt_aspeed.c | 225 +++++++++++++++++++++++++++++++++++++++
21
2 files changed, 20 insertions(+), 3 deletions(-)
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
22
32
diff --git a/hw/watchdog/Makefile.objs b/hw/watchdog/Makefile.objs
23
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
33
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/watchdog/Makefile.objs
25
--- a/include/hw/char/imx_serial.h
35
+++ b/hw/watchdog/Makefile.objs
26
+++ b/include/hw/char/imx_serial.h
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 @@
27
@@ -XXX,XX +XXX,XX @@
47
+/*
28
#define UCR2_RXEN (1<<1) /* Receiver enable */
48
+ * ASPEED Watchdog Controller
29
#define UCR2_SRST (1<<0) /* Reset complete */
49
+ *
30
50
+ * Copyright (C) 2016-2017 IBM Corp.
31
+#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
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
+
32
+
58
+#include "hw/sysbus.h"
33
#define UTS1_TXEMPTY (1<<6)
34
#define UTS1_RXEMPTY (1<<5)
35
#define UTS1_TXFULL (1<<4)
36
@@ -XXX,XX +XXX,XX @@ typedef struct IMXSerialState {
37
uint32_t ubmr;
38
uint32_t ubrc;
39
uint32_t ucr3;
40
+ uint32_t ucr4;
41
42
qemu_irq irq;
43
CharBackend chr;
44
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/char/imx_serial.c
47
+++ b/hw/char/imx_serial.c
48
@@ -XXX,XX +XXX,XX @@
49
50
static const VMStateDescription vmstate_imx_serial = {
51
.name = TYPE_IMX_SERIAL,
52
- .version_id = 1,
53
- .minimum_version_id = 1,
54
+ .version_id = 2,
55
+ .minimum_version_id = 2,
56
.fields = (VMStateField[]) {
57
VMSTATE_INT32(readbuff, IMXSerialState),
58
VMSTATE_UINT32(usr1, IMXSerialState),
59
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
60
VMSTATE_UINT32(ubmr, IMXSerialState),
61
VMSTATE_UINT32(ubrc, IMXSerialState),
62
VMSTATE_UINT32(ucr3, IMXSerialState),
63
+ VMSTATE_UINT32(ucr4, IMXSerialState),
64
VMSTATE_END_OF_LIST()
65
},
66
};
67
@@ -XXX,XX +XXX,XX @@ static void imx_update(IMXSerialState *s)
68
* unfortunately.
69
*/
70
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
71
+ /*
72
+ * TCEN and TXDC are both bit 3
73
+ */
74
+ mask |= s->ucr4 & UCR4_TCEN;
59
+
75
+
60
+#define TYPE_ASPEED_WDT "aspeed.wdt"
76
usr2 = s->usr2 & mask;
61
+#define ASPEED_WDT(obj) \
77
62
+ OBJECT_CHECK(AspeedWDTState, (obj), TYPE_ASPEED_WDT)
78
qemu_set_irq(s->irq, usr1 || usr2);
79
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
80
return s->ucr3;
81
82
case 0x23: /* UCR4 */
83
+ return s->ucr4;
63
+
84
+
64
+#define ASPEED_WDT_REGS_MAX (0x20 / 4)
85
case 0x29: /* BRM Incremental */
86
return 0x0; /* TODO */
87
88
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
89
* qemu_chr_fe_write and background I/O callbacks */
90
qemu_chr_fe_write_all(&s->chr, &ch, 1);
91
s->usr1 &= ~USR1_TRDY;
92
+ s->usr2 &= ~USR2_TXDC;
93
imx_update(s);
94
s->usr1 |= USR1_TRDY;
95
+ s->usr2 |= USR2_TXDC;
96
imx_update(s);
97
}
98
break;
99
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
100
s->ucr3 = value & 0xffff;
101
break;
102
103
- case 0x2d: /* UTS1 */
104
case 0x23: /* UCR4 */
105
+ s->ucr4 = value & 0xffff;
106
+ imx_update(s);
107
+ break;
65
+
108
+
66
+typedef struct AspeedWDTState {
109
+ case 0x2d: /* UTS1 */
67
+ /*< private >*/
110
qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
68
+ SysBusDevice parent_obj;
111
HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
69
+ QEMUTimer *timer;
112
/* TODO */
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
--
113
--
311
2.7.4
114
2.16.2
312
115
313
116
diff view generated by jsdifflib
1
Use the 'unimplemented' dummy device to cover regions of the
1
For the rpi1 and 2 we want to boot the Linux kernel via some
2
SoC device memory map which we don't have proper device
2
custom setup code that makes sure that the SMC instruction
3
implementations for yet.
3
acts as a no-op, because it's used for cache maintenance.
4
The rpi3 boots AArch64 kernels, which don't need SMC for
5
cache maintenance and always expect to be booted non-secure.
6
Don't fill in the aarch32-specific parts of the binfo struct.
4
7
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
7
Message-id: 1484247815-15279-4-git-send-email-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20180313153458.26822-2-peter.maydell@linaro.org
8
---
12
---
9
hw/arm/stellaris.c | 14 ++++++++++++++
13
hw/arm/raspi.c | 17 +++++++++++++----
10
1 file changed, 14 insertions(+)
14
1 file changed, 13 insertions(+), 4 deletions(-)
11
15
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
16
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/stellaris.c
18
--- a/hw/arm/raspi.c
15
+++ b/hw/arm/stellaris.c
19
+++ b/hw/arm/raspi.c
16
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
17
#include "exec/address-spaces.h"
21
binfo.board_id = raspi_boardid[version];
18
#include "sysemu/sysemu.h"
22
binfo.ram_size = ram_size;
19
#include "hw/char/pl011.h"
23
binfo.nb_cpus = smp_cpus;
20
+#include "hw/misc/unimp.h"
24
- binfo.board_setup_addr = BOARDSETUP_ADDR;
21
25
- binfo.write_board_setup = write_board_setup;
22
#define GPIO_A 0
26
- binfo.secure_board_setup = true;
23
#define GPIO_B 1
27
- binfo.secure_boot = true;
24
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
25
}
26
}
27
}
28
+
28
+
29
+ /* Add dummy regions for the devices we don't implement yet,
29
+ if (version <= 2) {
30
+ * so guest accesses don't cause unlogged crashes.
30
+ /* The rpi1 and 2 require some custom setup code to run in Secure
31
+ */
31
+ * mode before booting a kernel (to set up the SMC vectors so
32
+ create_unimplemented_device("wdtimer", 0x40000000, 0x1000);
32
+ * that we get a no-op SMC; this is used by Linux to call the
33
+ create_unimplemented_device("i2c-0", 0x40002000, 0x1000);
33
+ * firmware for some cache maintenance operations.
34
+ create_unimplemented_device("i2c-2", 0x40021000, 0x1000);
34
+ * The rpi3 doesn't need this.
35
+ create_unimplemented_device("PWM", 0x40028000, 0x1000);
35
+ */
36
+ create_unimplemented_device("QEI-0", 0x4002c000, 0x1000);
36
+ binfo.board_setup_addr = BOARDSETUP_ADDR;
37
+ create_unimplemented_device("QEI-1", 0x4002d000, 0x1000);
37
+ binfo.write_board_setup = write_board_setup;
38
+ create_unimplemented_device("analogue-comparator", 0x4003c000, 0x1000);
38
+ binfo.secure_board_setup = true;
39
+ create_unimplemented_device("hibernation", 0x400fc000, 0x1000);
39
+ binfo.secure_boot = true;
40
+ create_unimplemented_device("flash-control", 0x400fd000, 0x1000);
40
+ }
41
}
41
42
42
/* Pi2 and Pi3 requires SMP setup */
43
/* FIXME: Figure out how to generate these from stellaris_boards. */
43
if (version >= 2) {
44
--
44
--
45
2.7.4
45
2.16.2
46
46
47
47
diff view generated by jsdifflib
1
Create a new "unimplemented" sysbus device, which simply accepts
1
Add some assertions that if we're about to boot an AArch64 kernel,
2
all read and write accesses, and implements them as read-as-zero,
2
the board code has not mistakenly set either secure_boot or
3
write-ignored, with logging of the access as LOG_UNIMP.
3
secure_board_setup. It doesn't make sense to set secure_boot,
4
because all AArch64 kernels must be booted in non-secure mode.
4
5
5
This is useful for stubbing out bits of an SoC or board model
6
It might in theory make sense to set secure_board_setup, but
6
which haven't been written yet.
7
we don't currently support that, because only the AArch32
8
bootloader[] code calls this hook; bootloader_aarch64[] does not.
9
Since we don't have a current need for this functionality, just
10
assert that we don't try to use it. If it's needed we'll add
11
it later.
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: Alex Bennée <alex.bennee@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 1484247815-15279-3-git-send-email-peter.maydell@linaro.org
15
Message-id: 20180313153458.26822-3-peter.maydell@linaro.org
11
---
16
---
12
hw/misc/Makefile.objs | 2 +
17
hw/arm/boot.c | 7 +++++++
13
include/hw/misc/unimp.h | 39 ++++++++++++++++++
18
1 file changed, 7 insertions(+)
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
19
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
20
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/misc/Makefile.objs
22
--- a/hw/arm/boot.c
22
+++ b/hw/misc/Makefile.objs
23
+++ b/hw/arm/boot.c
23
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_SGA) += sga.o
24
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
24
common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
25
} else {
25
common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
26
env->pstate = PSTATE_MODE_EL1h;
26
27
}
27
+common-obj-y += unimp.o
28
+ /* AArch64 kernels never boot in secure mode */
28
+
29
+ assert(!info->secure_boot);
29
obj-$(CONFIG_VMPORT) += vmport.o
30
+ /* This hook is only supported for AArch32 currently:
30
31
+ * bootloader_aarch64[] will not call the hook, and
31
# ARM devices
32
+ * the code above has already dropped us into EL2 or EL1.
32
diff --git a/include/hw/misc/unimp.h b/include/hw/misc/unimp.h
33
+ */
33
new file mode 100644
34
+ assert(!info->secure_board_setup);
34
index XXXXXXX..XXXXXXX
35
}
35
--- /dev/null
36
36
+++ b/include/hw/misc/unimp.h
37
/* Set to non-secure if not a secure boot */
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
+{
67
+ DeviceState *dev = qdev_create(NULL, TYPE_UNIMPLEMENTED_DEVICE);
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;
121
+}
122
+
123
+static void unimp_write(void *opaque, hwaddr offset,
124
+ uint64_t value, unsigned size)
125
+{
126
+ UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
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
--
38
--
191
2.7.4
39
2.16.2
192
40
193
41
diff view generated by jsdifflib
1
In the ARM ldr/str decode path, rather than directly testing
1
If we're directly booting a Linux kernel and the CPU supports both
2
"insn & (1 << 21)" and "insn & (1 << 24)", abstract these
2
EL3 and EL2, we start the kernel in EL2, as it expects. We must also
3
bits out into wbit and pbit local flags. (We will want to
3
set the SCR_EL3.HCE bit in this situation, so that the HVC
4
do more tests against them to determine whether we need to
4
instruction is enabled rather than UNDEFing. Otherwise at least some
5
provide syndrome information.)
5
kernels will panic when trying to initialize KVM in the guest.
6
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Message-id: 20180313153458.26822-4-peter.maydell@linaro.org
9
---
9
---
10
target/arm/translate.c | 9 ++++++---
10
hw/arm/boot.c | 5 +++++
11
1 file changed, 6 insertions(+), 3 deletions(-)
11
1 file changed, 5 insertions(+)
12
12
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
15
--- a/hw/arm/boot.c
16
+++ b/target/arm/translate.c
16
+++ b/hw/arm/boot.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
17
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
18
} else {
18
assert(!info->secure_board_setup);
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
}
19
}
28
20
29
addr = load_reg(s, rn);
21
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
30
- if (insn & (1 << 24))
22
+ /* If we have EL2 then Linux expects the HVC insn to work */
31
+ if (pbit) {
23
+ env->cp15.scr_el3 |= SCR_HCE;
32
gen_add_datah_offset(s, insn, 0, addr);
33
+ }
24
+ }
34
address_offset = 0;
25
+
35
26
/* Set to non-secure if not a secure boot */
36
if (doubleword) {
27
if (!info->secure_boot &&
37
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
28
(cs != first_cpu || !info->secure_board_setup)) {
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
--
29
--
51
2.7.4
30
2.16.2
52
31
53
32
diff view generated by jsdifflib
1
From: Prasad J Pandit <pjp@fedoraproject.org>
1
The TypeInfo and state struct for bcm2386 disagree about what the
2
parent class is -- the TypeInfo says it's TYPE_SYS_BUS_DEVICE,
3
but the BCM2386State struct only defines the parent_obj field
4
as DeviceState. This would have caused problems if anything
5
actually tried to treat the object as a TYPE_SYS_BUS_DEVICE.
6
Fix the TypeInfo to use TYPE_DEVICE as the parent, since we don't
7
need any of the additional functionality TYPE_SYS_BUS_DEVICE
8
provides.
2
9
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>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180313153458.26822-5-peter.maydell@linaro.org
15
---
14
---
16
hw/sd/sdhci.c | 2 +-
15
hw/arm/bcm2836.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
18
17
19
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
18
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/sd/sdhci.c
20
--- a/hw/arm/bcm2836.c
22
+++ b/hw/sd/sdhci.c
21
+++ b/hw/arm/bcm2836.c
23
@@ -XXX,XX +XXX,XX @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
22
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
24
boundary_count -= block_size - begin;
23
25
}
24
static const TypeInfo bcm2836_type_info = {
26
dma_memory_read(&address_space_memory, s->sdmasysad,
25
.name = TYPE_BCM2836,
27
- &s->fifo_buffer[begin], s->data_count);
26
- .parent = TYPE_SYS_BUS_DEVICE,
28
+ &s->fifo_buffer[begin], s->data_count - begin);
27
+ .parent = TYPE_DEVICE,
29
s->sdmasysad += s->data_count - begin;
28
.instance_size = sizeof(BCM2836State),
30
if (s->data_count == block_size) {
29
.instance_init = bcm2836_init,
31
for (n = 0; n < block_size; n++) {
30
.class_init = bcm2836_class_init,
32
--
31
--
33
2.7.4
32
2.16.2
34
33
35
34
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Our BCM2836 type is really a generic one that can be any of
2
the bcm283x family. Rename it accordingly. We change only
3
the names which are visible via the header file to the
4
rest of the QEMU code, leaving private function names
5
in bcm2836.c as they are.
2
6
3
This enables reboot of a guest from U-Boot and Linux.
7
This is a preliminary to making bcm283x be an abstract
8
parent class to specific types for the bcm2836 and bcm2837.
4
9
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>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180313153458.26822-6-peter.maydell@linaro.org
9
---
14
---
10
include/hw/arm/aspeed_soc.h | 2 ++
15
include/hw/arm/bcm2836.h | 12 ++++++------
11
hw/arm/aspeed_soc.c | 13 +++++++++++++
16
hw/arm/bcm2836.c | 17 +++++++++--------
12
2 files changed, 15 insertions(+)
17
hw/arm/raspi.c | 16 ++++++++--------
18
3 files changed, 23 insertions(+), 22 deletions(-)
13
19
14
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
20
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/aspeed_soc.h
22
--- a/include/hw/arm/bcm2836.h
17
+++ b/include/hw/arm/aspeed_soc.h
23
+++ b/include/hw/arm/bcm2836.h
18
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
19
#include "hw/timer/aspeed_timer.h"
25
#include "hw/arm/bcm2835_peripherals.h"
20
#include "hw/i2c/aspeed_i2c.h"
26
#include "hw/intc/bcm2836_control.h"
21
#include "hw/ssi/aspeed_smc.h"
27
22
+#include "hw/watchdog/wdt_aspeed.h"
28
-#define TYPE_BCM2836 "bcm2836"
23
29
-#define BCM2836(obj) OBJECT_CHECK(BCM2836State, (obj), TYPE_BCM2836)
24
#define ASPEED_SPIS_NUM 2
30
+#define TYPE_BCM283X "bcm283x"
25
31
+#define BCM283X(obj) OBJECT_CHECK(BCM283XState, (obj), TYPE_BCM283X)
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
32
27
AspeedSMCState fmc;
33
-#define BCM2836_NCPUS 4
28
AspeedSMCState spi[ASPEED_SPIS_NUM];
34
+#define BCM283X_NCPUS 4
29
AspeedSDMCState sdmc;
35
30
+ AspeedWDTState wdt;
36
-typedef struct BCM2836State {
31
} AspeedSoCState;
37
+typedef struct BCM283XState {
32
38
/*< private >*/
33
#define TYPE_ASPEED_SOC "aspeed-soc"
39
DeviceState parent_obj;
34
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
40
/*< public >*/
41
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
42
char *cpu_type;
43
uint32_t enabled_cpus;
44
45
- ARMCPU cpus[BCM2836_NCPUS];
46
+ ARMCPU cpus[BCM283X_NCPUS];
47
BCM2836ControlState control;
48
BCM2835PeripheralState peripherals;
49
-} BCM2836State;
50
+} BCM283XState;
51
52
#endif /* BCM2836_H */
53
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
35
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/aspeed_soc.c
55
--- a/hw/arm/bcm2836.c
37
+++ b/hw/arm/aspeed_soc.c
56
+++ b/hw/arm/bcm2836.c
38
@@ -XXX,XX +XXX,XX @@
57
@@ -XXX,XX +XXX,XX @@
39
#define ASPEED_SOC_SCU_BASE 0x1E6E2000
58
40
#define ASPEED_SOC_SRAM_BASE 0x1E720000
59
static void bcm2836_init(Object *obj)
41
#define ASPEED_SOC_TIMER_BASE 0x1E782000
60
{
42
+#define ASPEED_SOC_WDT_BASE 0x1E785000
61
- BCM2836State *s = BCM2836(obj);
43
#define ASPEED_SOC_I2C_BASE 0x1E78A000
62
+ BCM283XState *s = BCM283X(obj);
44
63
45
static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
64
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
46
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
65
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
47
sc->info->silicon_rev);
66
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
48
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
67
49
"ram-size", &error_abort);
68
static void bcm2836_realize(DeviceState *dev, Error **errp)
50
+
69
{
51
+ object_initialize(&s->wdt, sizeof(s->wdt), TYPE_ASPEED_WDT);
70
- BCM2836State *s = BCM2836(dev);
52
+ object_property_add_child(obj, "wdt", OBJECT(&s->wdt), NULL);
71
+ BCM283XState *s = BCM283X(dev);
53
+ qdev_set_parent_bus(DEVICE(&s->wdt), sysbus_get_default());
72
Object *obj;
73
Error *err = NULL;
74
int n;
75
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
76
/* common peripherals from bcm2835 */
77
78
obj = OBJECT(dev);
79
- for (n = 0; n < BCM2836_NCPUS; n++) {
80
+ for (n = 0; n < BCM283X_NCPUS; n++) {
81
object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
82
s->cpu_type);
83
object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
84
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
85
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
86
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
87
88
- for (n = 0; n < BCM2836_NCPUS; n++) {
89
+ for (n = 0; n < BCM283X_NCPUS; n++) {
90
/* Mirror bcm2836, which has clusterid set to 0xf
91
* TODO: this should be converted to a property of ARM_CPU
92
*/
93
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
54
}
94
}
55
95
56
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
96
static Property bcm2836_props[] = {
57
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
97
- DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
58
return;
98
- DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
59
}
99
+ DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
60
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, ASPEED_SOC_SDMC_BASE);
100
+ DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
61
+
101
+ BCM283X_NCPUS),
62
+ /* Watch dog */
102
DEFINE_PROP_END_OF_LIST()
63
+ object_property_set_bool(OBJECT(&s->wdt), true, "realized", &err);
103
};
64
+ if (err) {
104
65
+ error_propagate(errp, err);
105
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
66
+ return;
67
+ }
68
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt), 0, ASPEED_SOC_WDT_BASE);
69
}
106
}
70
107
71
static void aspeed_soc_class_init(ObjectClass *oc, void *data)
108
static const TypeInfo bcm2836_type_info = {
109
- .name = TYPE_BCM2836,
110
+ .name = TYPE_BCM283X,
111
.parent = TYPE_DEVICE,
112
- .instance_size = sizeof(BCM2836State),
113
+ .instance_size = sizeof(BCM283XState),
114
.instance_init = bcm2836_init,
115
.class_init = bcm2836_class_init,
116
};
117
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/hw/arm/raspi.c
120
+++ b/hw/arm/raspi.c
121
@@ -XXX,XX +XXX,XX @@
122
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
123
124
typedef struct RasPiState {
125
- BCM2836State soc;
126
+ BCM283XState soc;
127
MemoryRegion ram;
128
} RasPiState;
129
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2836);
135
+ object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
136
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
137
&error_abort);
138
139
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
143
- mc->max_cpus = BCM2836_NCPUS;
144
- mc->min_cpus = BCM2836_NCPUS;
145
- mc->default_cpus = BCM2836_NCPUS;
146
+ mc->max_cpus = BCM283X_NCPUS;
147
+ mc->min_cpus = BCM283X_NCPUS;
148
+ mc->default_cpus = BCM283X_NCPUS;
149
mc->default_ram_size = 1024 * 1024 * 1024;
150
mc->ignore_memory_transaction_failures = true;
151
};
152
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_init(MachineClass *mc)
153
mc->no_floppy = 1;
154
mc->no_cdrom = 1;
155
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
156
- mc->max_cpus = BCM2836_NCPUS;
157
- mc->min_cpus = BCM2836_NCPUS;
158
- mc->default_cpus = BCM2836_NCPUS;
159
+ mc->max_cpus = BCM283X_NCPUS;
160
+ mc->min_cpus = BCM283X_NCPUS;
161
+ mc->default_cpus = BCM283X_NCPUS;
162
mc->default_ram_size = 1024 * 1024 * 1024;
163
}
164
DEFINE_MACHINE("raspi3", raspi3_machine_init)
72
--
165
--
73
2.7.4
166
2.16.2
74
167
75
168
diff view generated by jsdifflib
1
From: Julian Brown <julian@codesourcery.com>
1
The bcm2837 is pretty similar to the bcm2836, but it does have
2
some differences. Notably, the MPIDR affinity aff1 values it
3
sets for the CPUs are 0x0, rather than the 0xf that the bcm2836
4
uses, and if this is wrong Linux will not boot.
2
5
3
Thumb-1 code has some issues in BE32 mode (as currently implemented). In
6
Rather than trying to have one device with properties that
4
short, since bytes are swapped within words at load time for BE32
7
configure it differently for the two cases, create two
5
executables, this also swaps pairs of adjacent Thumb-1 instructions.
8
separate QOM devices for the two SoCs. We use the same approach
9
as hw/arm/aspeed_soc.c and share code and have a data table
10
that might differ per-SoC. For the moment the two types don't
11
actually have different behaviour.
6
12
7
This patch un-swaps those pairs of instructions again, both for execution,
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
and for disassembly. (The previous version of the patch always read four
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
bytes in arm_read_memory_func and then extracted the proper two bytes,
15
Message-id: 20180313153458.26822-7-peter.maydell@linaro.org
10
in a probably misguided attempt to match the behaviour of actual hardware
16
---
11
as described by e.g. the ARM9TDMI TRM, section 3.3 "Endian effects for
17
include/hw/arm/bcm2836.h | 19 +++++++++++++++++++
12
instruction fetches". It's less complicated to just read the correct
18
hw/arm/bcm2836.c | 37 ++++++++++++++++++++++++++++++++-----
13
two bytes though.)
19
hw/arm/raspi.c | 3 ++-
20
3 files changed, 53 insertions(+), 6 deletions(-)
14
21
15
Signed-off-by: Julian Brown <julian@codesourcery.com>
22
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
16
Message-id: ca20462a044848000370318a8bd41dd0a4ed273f.1484929304.git.julian@codesourcery.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
include/disas/bfd.h | 7 +++++++
21
target/arm/arm_ldst.h | 10 +++++++++-
22
disas.c | 1 +
23
target/arm/cpu.c | 23 +++++++++++++++++++++++
24
4 files changed, 40 insertions(+), 1 deletion(-)
25
26
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
27
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
28
--- a/include/disas/bfd.h
24
--- a/include/hw/arm/bcm2836.h
29
+++ b/include/disas/bfd.h
25
+++ b/include/hw/arm/bcm2836.h
30
@@ -XXX,XX +XXX,XX @@ typedef struct disassemble_info {
26
@@ -XXX,XX +XXX,XX @@
31
The bottom 16 bits are for the internal use of the disassembler. */
27
32
unsigned long flags;
28
#define BCM283X_NCPUS 4
33
#define INSN_HAS_RELOC    0x80000000
29
34
+#define INSN_ARM_BE32    0x00010000
30
+/* These type names are for specific SoCs; other than instantiating
35
PTR private_data;
31
+ * them, code using these devices should always handle them via the
36
32
+ * BCM283x base class, so they have no BCM2836(obj) etc macros.
37
/* Function used to get bytes to disassemble. MEMADDR is the
33
+ */
38
@@ -XXX,XX +XXX,XX @@ typedef struct disassemble_info {
34
+#define TYPE_BCM2836 "bcm2836"
39
(bfd_vma memaddr, bfd_byte *myaddr, int length,
35
+#define TYPE_BCM2837 "bcm2837"
40
     struct disassemble_info *info);
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
+
36
+
48
/* Function which should be called if we get an error that we can't
37
typedef struct BCM283XState {
49
recover from. STATUS is the errno value from read_memory_func and
38
/*< private >*/
50
MEMADDR is the address that we were trying to read. INFO is a
39
DeviceState parent_obj;
51
diff --git a/target/arm/arm_ldst.h b/target/arm/arm_ldst.h
40
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XState {
41
BCM2835PeripheralState peripherals;
42
} BCM283XState;
43
44
+typedef struct BCM283XInfo BCM283XInfo;
45
+
46
+typedef struct BCM283XClass {
47
+ DeviceClass parent_class;
48
+ const BCM283XInfo *info;
49
+} BCM283XClass;
50
+
51
+#define BCM283X_CLASS(klass) \
52
+ OBJECT_CLASS_CHECK(BCM283XClass, (klass), TYPE_BCM283X)
53
+#define BCM283X_GET_CLASS(obj) \
54
+ OBJECT_GET_CLASS(BCM283XClass, (obj), TYPE_BCM283X)
55
+
56
#endif /* BCM2836_H */
57
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
52
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/arm_ldst.h
59
--- a/hw/arm/bcm2836.c
54
+++ b/target/arm/arm_ldst.h
60
+++ b/hw/arm/bcm2836.c
55
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_ldl_code(CPUARMState *env, target_ulong addr,
61
@@ -XXX,XX +XXX,XX @@
56
static inline uint16_t arm_lduw_code(CPUARMState *env, target_ulong addr,
62
/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
57
bool sctlr_b)
63
#define BCM2836_CONTROL_BASE 0x40000000
64
65
+struct BCM283XInfo {
66
+ const char *name;
67
+};
68
+
69
+static const BCM283XInfo bcm283x_socs[] = {
70
+ {
71
+ .name = TYPE_BCM2836,
72
+ },
73
+ {
74
+ .name = TYPE_BCM2837,
75
+ },
76
+};
77
+
78
static void bcm2836_init(Object *obj)
58
{
79
{
59
- uint16_t insn = cpu_lduw_code(env, addr);
80
BCM283XState *s = BCM283X(obj);
60
+ uint16_t insn;
81
@@ -XXX,XX +XXX,XX @@ static Property bcm2836_props[] = {
61
+#ifndef CONFIG_USER_ONLY
82
DEFINE_PROP_END_OF_LIST()
62
+ /* In big-endian (BE32) mode, adjacent Thumb instructions have been swapped
83
};
63
+ within each word. Undo that now. */
84
64
+ if (sctlr_b) {
85
-static void bcm2836_class_init(ObjectClass *oc, void *data)
65
+ addr ^= 2;
86
+static void bcm283x_class_init(ObjectClass *oc, void *data)
66
+ }
87
{
67
+#endif
88
DeviceClass *dc = DEVICE_CLASS(oc);
68
+ insn = cpu_lduw_code(env, addr);
89
+ BCM283XClass *bc = BCM283X_CLASS(oc);
69
if (bswap_code(sctlr_b)) {
90
70
return bswap16(insn);
91
- dc->props = bcm2836_props;
71
}
92
+ bc->info = data;
72
diff --git a/disas.c b/disas.c
93
dc->realize = bcm2836_realize;
73
index XXXXXXX..XXXXXXX 100644
94
+ dc->props = bcm2836_props;
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
}
95
}
91
96
92
+static int arm_read_memory_func(bfd_vma memaddr, bfd_byte *b,
97
-static const TypeInfo bcm2836_type_info = {
93
+ int length, struct disassemble_info *info)
98
+static const TypeInfo bcm283x_type_info = {
94
+{
99
.name = TYPE_BCM283X,
95
+ assert(info->read_memory_inner_func);
100
.parent = TYPE_DEVICE,
96
+ assert((info->flags & INSN_ARM_BE32) == 0 || length == 2 || length == 4);
101
.instance_size = sizeof(BCM283XState),
102
.instance_init = bcm2836_init,
103
- .class_init = bcm2836_class_init,
104
+ .class_size = sizeof(BCM283XClass),
105
+ .abstract = true,
106
};
107
108
static void bcm2836_register_types(void)
109
{
110
- type_register_static(&bcm2836_type_info);
111
+ int i;
97
+
112
+
98
+ if ((info->flags & INSN_ARM_BE32) != 0 && length == 2) {
113
+ type_register_static(&bcm283x_type_info);
99
+ assert(info->endian == BFD_ENDIAN_LITTLE);
114
+ for (i = 0; i < ARRAY_SIZE(bcm283x_socs); i++) {
100
+ return info->read_memory_inner_func(memaddr ^ 2, (bfd_byte *)b, 2,
115
+ TypeInfo ti = {
101
+ info);
116
+ .name = bcm283x_socs[i].name,
102
+ } else {
117
+ .parent = TYPE_BCM283X,
103
+ return info->read_memory_inner_func(memaddr, b, length, info);
118
+ .class_init = bcm283x_class_init,
104
+ }
119
+ .class_data = (void *) &bcm283x_socs[i],
105
+}
120
+ };
106
+
121
+ type_register(&ti);
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
+ }
122
}
123
}
123
124
124
static void arm_cpu_initfn(Object *obj)
125
type_init(bcm2836_register_types)
126
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/arm/raspi.c
129
+++ b/hw/arm/raspi.c
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
135
+ object_initialize(&s->soc, sizeof(s->soc),
136
+ version == 3 ? TYPE_BCM2837 : TYPE_BCM2836);
137
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
138
&error_abort);
139
125
--
140
--
126
2.7.4
141
2.16.2
127
142
128
143
diff view generated by jsdifflib
1
Add a comment documenting the memory map of the SoC devices and which
1
The BCM2837 sets the Aff1 field of the MPIDR affinity values for the
2
are not implemented.
2
CPUs to 0, whereas the BCM2836 uses 0xf. Set this correctly, as it
3
is required for Linux to boot.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 1484247815-15279-2-git-send-email-peter.maydell@linaro.org
6
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180313153458.26822-8-peter.maydell@linaro.org
6
---
9
---
7
hw/arm/stellaris.c | 34 ++++++++++++++++++++++++++++++++++
10
hw/arm/bcm2836.c | 11 +++++++----
8
1 file changed, 34 insertions(+)
11
1 file changed, 7 insertions(+), 4 deletions(-)
9
12
10
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
13
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
11
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/stellaris.c
15
--- a/hw/arm/bcm2836.c
13
+++ b/hw/arm/stellaris.c
16
+++ b/hw/arm/bcm2836.c
14
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
17
@@ -XXX,XX +XXX,XX @@
15
0x40024000, 0x40025000, 0x40026000};
18
16
static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
19
struct BCM283XInfo {
17
20
const char *name;
18
+ /* Memory map of SoC devices, from
21
+ int clusterid;
19
+ * Stellaris LM3S6965 Microcontroller Data Sheet (rev I)
22
};
20
+ * http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
23
21
+ *
24
static const BCM283XInfo bcm283x_socs[] = {
22
+ * 40000000 wdtimer (unimplemented)
25
{
23
+ * 40002000 i2c (unimplemented)
26
.name = TYPE_BCM2836,
24
+ * 40004000 GPIO
27
+ .clusterid = 0xf,
25
+ * 40005000 GPIO
28
},
26
+ * 40006000 GPIO
29
{
27
+ * 40007000 GPIO
30
.name = TYPE_BCM2837,
28
+ * 40008000 SSI
31
+ .clusterid = 0x0,
29
+ * 4000c000 UART
32
},
30
+ * 4000d000 UART
33
};
31
+ * 4000e000 UART
34
32
+ * 40020000 i2c
35
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
33
+ * 40021000 i2c (unimplemented)
36
static void bcm2836_realize(DeviceState *dev, Error **errp)
34
+ * 40024000 GPIO
37
{
35
+ * 40025000 GPIO
38
BCM283XState *s = BCM283X(dev);
36
+ * 40026000 GPIO
39
+ BCM283XClass *bc = BCM283X_GET_CLASS(dev);
37
+ * 40028000 PWM (unimplemented)
40
+ const BCM283XInfo *info = bc->info;
38
+ * 4002c000 QEI (unimplemented)
41
Object *obj;
39
+ * 4002d000 QEI (unimplemented)
42
Error *err = NULL;
40
+ * 40030000 gptimer
43
int n;
41
+ * 40031000 gptimer
44
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
42
+ * 40032000 gptimer
45
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
43
+ * 40033000 gptimer
46
44
+ * 40038000 ADC
47
for (n = 0; n < BCM283X_NCPUS; n++) {
45
+ * 4003c000 analogue comparator (unimplemented)
48
- /* Mirror bcm2836, which has clusterid set to 0xf
46
+ * 40048000 ethernet
49
- * TODO: this should be converted to a property of ARM_CPU
47
+ * 400fc000 hibernation module (unimplemented)
50
- */
48
+ * 400fd000 flash memory control (unimplemented)
51
- s->cpus[n].mp_affinity = 0xF00 | n;
49
+ * 400fe000 system control
52
+ /* TODO: this should be converted to a property of ARM_CPU */
50
+ */
53
+ s->cpus[n].mp_affinity = (info->clusterid << 8) | n;
51
+
54
52
DeviceState *gpio_dev[7], *nvic;
55
/* set periphbase/CBAR value for CPU-local registers */
53
qemu_irq gpio_in[7][8];
56
object_property_set_int(OBJECT(&s->cpus[n]),
54
qemu_irq gpio_out[7][8];
55
--
57
--
56
2.7.4
58
2.16.2
57
59
58
60
diff view generated by jsdifflib
1
From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
1
Now we have separate types for BCM2386 and BCM2387, we might as well
2
just hard-code the CPU type they use rather than having it passed
3
through as an object property. This then lets us put the initialization
4
of the CPU object in init rather than realize.
2
5
3
VMState added by this patch preserves correct
6
Note that this change means that it's no longer possible on
4
loading of the integratorcp device state.
7
the command line to use -cpu to ask for a different kind of
8
CPU than the SoC supports. This was never a supported thing to
9
do anyway; we were just not sanity-checking the command line.
5
10
6
Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
11
This does require us to only build the bcm2837 object on
7
Message-id: 20170131114310.6768.79416.stgit@PASHA-ISP
12
TARGET_AARCH64 configs, since otherwise it won't instantiate
8
[PMM: removed unnecessary minimum_version_id_old lines]
13
due to the missing cortex-a53 device and "make check" will fail.
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Message-id: 20180313153458.26822-9-peter.maydell@linaro.org
11
---
19
---
12
hw/arm/integratorcp.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++
20
hw/arm/bcm2836.c | 24 +++++++++++++++---------
13
1 file changed, 59 insertions(+)
21
hw/arm/raspi.c | 2 --
22
2 files changed, 15 insertions(+), 11 deletions(-)
14
23
15
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
24
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
16
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/integratorcp.c
26
--- a/hw/arm/bcm2836.c
18
+++ b/hw/arm/integratorcp.c
27
+++ b/hw/arm/bcm2836.c
19
@@ -XXX,XX +XXX,XX @@ static uint8_t integrator_spd[128] = {
28
@@ -XXX,XX +XXX,XX @@
20
0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
29
30
struct BCM283XInfo {
31
const char *name;
32
+ const char *cpu_type;
33
int clusterid;
21
};
34
};
22
35
23
+static const VMStateDescription vmstate_integratorcm = {
36
static const BCM283XInfo bcm283x_socs[] = {
24
+ .name = "integratorcm",
37
{
25
+ .version_id = 1,
38
.name = TYPE_BCM2836,
26
+ .minimum_version_id = 1,
39
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"),
27
+ .fields = (VMStateField[]) {
40
.clusterid = 0xf,
28
+ VMSTATE_UINT32(cm_osc, IntegratorCMState),
41
},
29
+ VMSTATE_UINT32(cm_ctrl, IntegratorCMState),
42
+#ifdef TARGET_AARCH64
30
+ VMSTATE_UINT32(cm_lock, IntegratorCMState),
43
{
31
+ VMSTATE_UINT32(cm_auxosc, IntegratorCMState),
44
.name = TYPE_BCM2837,
32
+ VMSTATE_UINT32(cm_sdram, IntegratorCMState),
45
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
33
+ VMSTATE_UINT32(cm_init, IntegratorCMState),
46
.clusterid = 0x0,
34
+ VMSTATE_UINT32(cm_flags, IntegratorCMState),
47
},
35
+ VMSTATE_UINT32(cm_nvflags, IntegratorCMState),
48
+#endif
36
+ VMSTATE_UINT32(int_level, IntegratorCMState),
49
};
37
+ VMSTATE_UINT32(irq_enabled, IntegratorCMState),
50
38
+ VMSTATE_UINT32(fiq_enabled, IntegratorCMState),
51
static void bcm2836_init(Object *obj)
39
+ VMSTATE_END_OF_LIST()
52
{
53
BCM283XState *s = BCM283X(obj);
54
+ BCM283XClass *bc = BCM283X_GET_CLASS(obj);
55
+ const BCM283XInfo *info = bc->info;
56
+ int n;
57
+
58
+ for (n = 0; n < BCM283X_NCPUS; n++) {
59
+ object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
60
+ info->cpu_type);
61
+ object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
62
+ &error_abort);
40
+ }
63
+ }
41
+};
64
42
+
65
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
43
static uint64_t integratorcm_read(void *opaque, hwaddr offset,
66
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
44
unsigned size)
67
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
45
{
68
46
@@ -XXX,XX +XXX,XX @@ typedef struct icp_pic_state {
69
/* common peripherals from bcm2835 */
47
qemu_irq parent_fiq;
70
48
} icp_pic_state;
71
- obj = OBJECT(dev);
49
72
- for (n = 0; n < BCM283X_NCPUS; n++) {
50
+static const VMStateDescription vmstate_icp_pic = {
73
- object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
51
+ .name = "icp_pic",
74
- s->cpu_type);
52
+ .version_id = 1,
75
- object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
53
+ .minimum_version_id = 1,
76
- &error_abort);
54
+ .fields = (VMStateField[]) {
77
- }
55
+ VMSTATE_UINT32(level, icp_pic_state),
78
-
56
+ VMSTATE_UINT32(irq_enabled, icp_pic_state),
79
obj = object_property_get_link(OBJECT(dev), "ram", &err);
57
+ VMSTATE_UINT32(fiq_enabled, icp_pic_state),
80
if (obj == NULL) {
58
+ VMSTATE_END_OF_LIST()
81
error_setg(errp, "%s: required ram link not found: %s",
59
+ }
82
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
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
}
83
}
102
84
103
static const TypeInfo core_info = {
85
static Property bcm2836_props[] = {
104
@@ -XXX,XX +XXX,XX @@ static const TypeInfo icp_pic_info = {
86
- DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
105
.parent = TYPE_SYS_BUS_DEVICE,
87
DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
106
.instance_size = sizeof(icp_pic_state),
88
BCM283X_NCPUS),
107
.instance_init = icp_pic_init,
89
DEFINE_PROP_END_OF_LIST()
108
+ .class_init = icp_pic_class_init,
90
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
109
};
91
index XXXXXXX..XXXXXXX 100644
110
92
--- a/hw/arm/raspi.c
111
static const TypeInfo icp_ctrl_regs_info = {
93
+++ b/hw/arm/raspi.c
112
@@ -XXX,XX +XXX,XX @@ static const TypeInfo icp_ctrl_regs_info = {
94
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
113
.parent = TYPE_SYS_BUS_DEVICE,
95
/* Setup the SOC */
114
.instance_size = sizeof(ICPCtrlRegsState),
96
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
115
.instance_init = icp_control_init,
97
&error_abort);
116
+ .class_init = icp_control_class_init,
98
- object_property_set_str(OBJECT(&s->soc), machine->cpu_type, "cpu-type",
117
};
99
- &error_abort);
118
100
object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
119
static void integratorcp_register_types(void)
101
&error_abort);
102
int board_rev = version == 3 ? 0xa02082 : 0xa21041;
120
--
103
--
121
2.7.4
104
2.16.2
122
105
123
106
diff view generated by jsdifflib
1
Add support for generating the ISS (Instruction Specific Syndrome)
1
The raspi3 has AArch64 CPUs, which means that our smpboot
2
for Data Abort exceptions taken from AArch32. These syndromes are
2
code for keeping the secondary CPUs in a pen needs to have
3
used by hypervisors for example to trap and emulate memory accesses.
3
a version for A64 as well as A32. Without this, the
4
4
secondary CPUs go into an infinite loop of taking undefined
5
This is the equivalent for AArch32 guests of the work done for AArch64
5
instruction exceptions.
6
guests in commit aaa1f954d4cab243.
7
6
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20180313153458.26822-10-peter.maydell@linaro.org
10
---
10
---
11
target/arm/translate.h | 14 ++++
11
hw/arm/raspi.c | 41 ++++++++++++++++++++++++++++++++++++++++-
12
target/arm/translate-a64.c | 14 ----
12
1 file changed, 40 insertions(+), 1 deletion(-)
13
target/arm/translate.c | 184 +++++++++++++++++++++++++++++++++------------
14
3 files changed, 149 insertions(+), 63 deletions(-)
15
13
16
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.h
16
--- a/hw/arm/raspi.c
19
+++ b/target/arm/translate.h
17
+++ b/hw/arm/raspi.c
20
@@ -XXX,XX +XXX,XX @@ static inline int default_exception_el(DisasContext *s)
18
@@ -XXX,XX +XXX,XX @@
21
? 3 : MAX(1, s->current_el);
19
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
20
#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
21
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
22
+#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
23
24
/* Table of Linux board IDs for different Pi versions */
25
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
26
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
27
info->smp_loader_start);
22
}
28
}
23
29
24
+static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
30
+static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
25
+{
31
+{
26
+ /* We don't need to save all of the syndrome so we mask and shift
32
+ /* Unlike the AArch32 version we don't need to call the board setup hook.
27
+ * out unneeded bits to help the sleb128 encoder do a better job.
33
+ * The mechanism for doing the spin-table is also entirely different.
34
+ * We must have four 64-bit fields at absolute addresses
35
+ * 0xd8, 0xe0, 0xe8, 0xf0 in RAM, which are the flag variables for
36
+ * our CPUs, and which we must ensure are zero initialized before
37
+ * the primary CPU goes into the kernel. We put these variables inside
38
+ * a rom blob, so that the reset for ROM contents zeroes them for us.
28
+ */
39
+ */
29
+ syn &= ARM_INSN_START_WORD2_MASK;
40
+ static const uint32_t smpboot[] = {
30
+ syn >>= ARM_INSN_START_WORD2_SHIFT;
41
+ 0xd2801b05, /* mov x5, 0xd8 */
42
+ 0xd53800a6, /* mrs x6, mpidr_el1 */
43
+ 0x924004c6, /* and x6, x6, #0x3 */
44
+ 0xd503205f, /* spin: wfe */
45
+ 0xf86678a4, /* ldr x4, [x5,x6,lsl #3] */
46
+ 0xb4ffffc4, /* cbz x4, spin */
47
+ 0xd2800000, /* mov x0, #0x0 */
48
+ 0xd2800001, /* mov x1, #0x0 */
49
+ 0xd2800002, /* mov x2, #0x0 */
50
+ 0xd2800003, /* mov x3, #0x0 */
51
+ 0xd61f0080, /* br x4 */
52
+ };
31
+
53
+
32
+ /* We check and clear insn_start_idx to catch multiple updates. */
54
+ static const uint64_t spintables[] = {
33
+ assert(s->insn_start_idx != 0);
55
+ 0, 0, 0, 0
34
+ tcg_set_insn_param(s->insn_start_idx, 2, syn);
56
+ };
35
+ s->insn_start_idx = 0;
57
+
58
+ rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
59
+ info->smp_loader_start);
60
+ rom_add_blob_fixed("raspi_spintables", spintables, sizeof(spintables),
61
+ SPINTABLE_ADDR);
36
+}
62
+}
37
+
63
+
38
/* target-specific extra values for is_jmp */
64
static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
39
/* These instructions trap after executing, so the A32/T32 decoder must
65
{
40
* defer them until after the conditional execution state has been updated.
66
arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
41
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
67
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
42
index XXXXXXX..XXXXXXX 100644
68
/* Pi2 and Pi3 requires SMP setup */
43
--- a/target/arm/translate-a64.c
69
if (version >= 2) {
44
+++ b/target/arm/translate-a64.c
70
binfo.smp_loader_start = SMPBOOT_ADDR;
45
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
71
- binfo.write_secondary_boot = write_smpboot;
72
+ if (version == 2) {
73
+ binfo.write_secondary_boot = write_smpboot;
74
+ } else {
75
+ binfo.write_secondary_boot = write_smpboot64;
76
+ }
77
binfo.secondary_cpu_reset_hook = reset_secondary;
46
}
78
}
47
}
79
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
--
80
--
468
2.7.4
81
2.16.2
469
82
470
83
diff view generated by jsdifflib