1
target-arm queue: I have a lot more still in my to-review
1
Another go at the v8.5-MemTag linux-user support, plus a
2
queue, but my rule of thumb is when I get to 50 patches or
2
couple more npcm7xx devices.
3
so to send out what I have.
4
3
5
thanks
6
-- PMM
4
-- PMM
7
5
8
The following changes since commit 9a7beaad3dbba982f7a461d676b55a5c3851d312:
6
The following changes since commit 8ba4bca570ace1e60614a0808631a517cf5df67a:
9
7
10
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20210304' into staging (2021-03-05 10:47:46 +0000)
8
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2021-02-15 17:13:57 +0000)
11
9
12
are available in the Git repository at:
10
are available in the Git repository at:
13
11
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210305
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210216
15
13
16
for you to fetch changes up to 2c669ff88ec6733420a000103a2b8b9e93df4945:
14
for you to fetch changes up to 64fd5bddf3b71d1b92b55382ab39768bd87ecfbd:
17
15
18
hw/arm/mps2: Update old infocenter.arm.com URLs (2021-03-05 15:17:38 +0000)
16
tests/qtests: Add npcm7xx emc model test (2021-02-16 14:27:05 +0000)
19
17
20
----------------------------------------------------------------
18
----------------------------------------------------------------
21
* sbsa-ref: remove cortex-a53 from list of supported cpus
19
target-arm queue:
22
* sbsa-ref: add 'max' to list of allowed cpus
20
* Support ARMv8.5-MemTag for linux-user
23
* target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
21
* ncpm7xx: Support SMBus, EMC ethernet devices
24
* npcm7xx: add EMC model
22
* MAINTAINERS: add section for Clock framework
25
* xlnx-zynqmp: Remove obsolete 'has_rpu' property
26
* target/arm: Speed up aarch64 TBL/TBX
27
* virtio-mmio: improve virtio-mmio get_dev_path alog
28
* target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
29
* target/arm: Restrict v8M IDAU to TCG
30
* target/arm/cpu: Update coding style to make checkpatch.pl happy
31
* musicpal, tc6393xb, omap_lcdc, tcx: drop dead code for non-32-bit-RGB surfaces
32
* Add new board: mps3-an524
33
23
34
----------------------------------------------------------------
24
----------------------------------------------------------------
35
Doug Evans (3):
25
Doug Evans (3):
36
hw/net: Add npcm7xx emc model
26
hw/net: Add npcm7xx emc model
37
hw/arm: Add npcm7xx emc model
27
hw/arm: Add npcm7xx emc model
38
tests/qtests: Add npcm7xx emc model test
28
tests/qtests: Add npcm7xx emc model test
39
29
40
Marcin Juszkiewicz (2):
30
Hao Wu (5):
41
sbsa-ref: remove cortex-a53 from list of supported cpus
31
hw/i2c: Implement NPCM7XX SMBus Module Single Mode
42
sbsa-ref: add 'max' to list of allowed cpus
32
hw/arm: Add I2C sensors for NPCM750 eval board
33
hw/arm: Add I2C sensors and EEPROM for GSJ machine
34
hw/i2c: Add a QTest for NPCM7XX SMBus Device
35
hw/i2c: Implement NPCM7XX SMBus Module FIFO Mode
43
36
44
Peter Collingbourne (1):
37
Luc Michel (1):
45
target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
38
MAINTAINERS: add myself maintainer for the clock framework
46
39
47
Peter Maydell (34):
40
Richard Henderson (31):
48
hw/arm/musicpal: Remove dead code for non-32-bit-RGB surfaces
41
tcg: Introduce target-specific page data for user-only
49
hw/display/tc6393xb: Remove dead code for handling non-32bpp surfaces
42
linux-user: Introduce PAGE_ANON
50
hw/display/tc6393xb: Expand out macros in template header
43
exec: Use uintptr_t for guest_base
51
hw/display/tc6393xb: Inline tc6393xb_draw_graphic32() at its callsite
44
exec: Use uintptr_t in cpu_ldst.h
52
hw/display/omap_lcdc: Expand out macros in template header
45
exec: Improve types for guest_addr_valid
53
hw/display/omap_lcdc: Drop broken bigendian ifdef
46
linux-user: Check for overflow in access_ok
54
hw/display/omap_lcdc: Fix coding style issues in template header
47
linux-user: Tidy VERIFY_READ/VERIFY_WRITE
55
hw/display/omap_lcdc: Inline template header into C file
48
bsd-user: Tidy VERIFY_READ/VERIFY_WRITE
56
hw/display/omap_lcdc: Delete unnecessary macro
49
linux-user: Do not use guest_addr_valid for h2g_valid
57
hw/display/tcx: Drop unnecessary code for handling BGR format outputs
50
linux-user: Fix guest_addr_valid vs reserved_va
58
hw/arm/mps2-tz: Make SYSCLK frequency board-specific
51
exec: Introduce cpu_untagged_addr
59
hw/misc/mps2-scc: Support configurable number of OSCCLK values
52
exec: Use cpu_untagged_addr in g2h; split out g2h_untagged
60
hw/arm/mps2-tz: Correct the OSCCLK settings for mps2-an505 and mps2-an511
53
linux-user: Explicitly untag memory management syscalls
61
hw/arm/mps2-tz: Make the OSCCLK settings be configurable per-board
54
linux-user: Use guest_range_valid in access_ok
62
hw/misc/mps2-fpgaio: Make number of LEDs configurable by board
55
exec: Rename guest_{addr,range}_valid to *_untagged
63
hw/misc/mps2-fpgaio: Support SWITCH register
56
linux-user: Use cpu_untagged_addr in access_ok; split out *_untagged
64
hw/arm/mps2-tz: Make FPGAIO switch and LED config per-board
57
linux-user: Move lock_user et al out of line
65
hw/arm/mps2-tz: Condition IRQ splitting on number of CPUs, not board type
58
linux-user: Fix types in uaccess.c
66
hw/arm/mps2-tz: Make number of IRQs board-specific
59
linux-user: Handle tags in lock_user/unlock_user
67
hw/misc/mps2-scc: Implement CFG_REG5 and CFG_REG6 for MPS3 AN524
60
linux-user/aarch64: Implement PR_TAGGED_ADDR_ENABLE
68
hw/arm/mps2-tz: Correct wrong interrupt numbers for DMA and SPI
61
target/arm: Improve gen_top_byte_ignore
69
hw/arm/mps2-tz: Allow PPCPortInfo structures to specify device interrupts
62
target/arm: Use the proper TBI settings for linux-user
70
hw/arm/mps2-tz: Move device IRQ info to data structures
63
linux-user/aarch64: Implement PR_MTE_TCF and PR_MTE_TAG
71
hw/arm/mps2-tz: Size the uart-irq-orgate based on the number of UARTs
64
linux-user/aarch64: Implement PROT_MTE
72
hw/arm/mps2-tz: Allow boards to have different PPCInfo data
65
target/arm: Split out syndrome.h from internals.h
73
hw/arm/mps2-tz: Make RAM arrangement board-specific
66
linux-user/aarch64: Pass syndrome to EXC_*_ABORT
74
hw/arm/mps2-tz: Set MachineClass default_ram info from RAMInfo data
67
linux-user/aarch64: Signal SEGV_MTESERR for sync tag check fault
75
hw/arm/mps2-tz: Support ROMs as well as RAMs
68
linux-user/aarch64: Signal SEGV_MTEAERR for async tag check error
76
hw/arm/mps2-tz: Get armv7m_load_kernel() size argument from RAMInfo
69
target/arm: Add allocation tag storage for user mode
77
hw/arm/mps2-tz: Add new mps3-an524 board
70
target/arm: Enable MTE for user-only
78
hw/arm/mps2-tz: Stub out USB controller for mps3-an524
71
tests/tcg/aarch64: Add mte smoke tests
79
hw/arm/mps2-tz: Provide PL031 RTC on mps3-an524
80
docs/system/arm/mps2.rst: Document the new mps3-an524 board
81
hw/arm/mps2: Update old infocenter.arm.com URLs
82
72
83
Philippe Mathieu-Daudé (4):
73
docs/system/arm/nuvoton.rst | 5 +-
84
hw/arm/xlnx-zynqmp: Remove obsolete 'has_rpu' property
74
bsd-user/qemu.h | 17 +-
85
hw/i2c/npcm7xx_smbus: Simplify npcm7xx_smbus_init()
75
include/exec/cpu-all.h | 47 +-
86
target/arm: Restrict v8M IDAU to TCG
76
include/exec/cpu_ldst.h | 39 +-
87
target/arm/cpu: Update coding style to make checkpatch.pl happy
77
include/exec/exec-all.h | 2 +-
88
78
include/hw/arm/npcm7xx.h | 4 +
89
Rebecca Cran (3):
79
include/hw/i2c/npcm7xx_smbus.h | 113 ++++
90
target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
80
include/hw/net/npcm7xx_emc.h | 286 +++++++++
91
target/arm: Enable FEAT_SSBS for "max" AARCH64 CPU
81
linux-user/aarch64/target_signal.h | 3 +
92
target/arm: Set ID_PFR2.SSBS to 1 for "max" 32-bit CPU
82
linux-user/aarch64/target_syscall.h | 13 +
93
83
linux-user/qemu.h | 76 +--
94
Richard Henderson (1):
84
linux-user/syscall_defs.h | 1 +
95
target/arm: Speed up aarch64 TBL/TBX
85
target/arm/cpu-param.h | 3 +
96
86
target/arm/cpu.h | 32 +
97
schspa (1):
87
target/arm/internals.h | 249 +-------
98
virtio-mmio: improve virtio-mmio get_dev_path alog
88
target/arm/syndrome.h | 273 +++++++++
99
89
tests/tcg/aarch64/mte.h | 60 ++
100
docs/system/arm/mps2.rst | 24 +-
90
accel/tcg/translate-all.c | 32 +-
101
docs/system/arm/nuvoton.rst | 3 +-
91
accel/tcg/user-exec.c | 51 +-
102
hw/display/omap_lcd_template.h | 169 --------
92
bsd-user/elfload.c | 2 +-
103
hw/display/tc6393xb_template.h | 72 ----
93
bsd-user/main.c | 8 +-
104
include/hw/arm/armsse.h | 4 +-
94
bsd-user/mmap.c | 23 +-
105
include/hw/arm/npcm7xx.h | 2 +
95
hw/arm/npcm7xx.c | 118 +++-
106
include/hw/arm/xlnx-zynqmp.h | 2 -
96
hw/arm/npcm7xx_boards.c | 46 ++
107
include/hw/misc/armsse-cpuid.h | 2 +-
97
hw/i2c/npcm7xx_smbus.c | 1099 +++++++++++++++++++++++++++++++++++
108
include/hw/misc/armsse-mhu.h | 2 +-
98
hw/net/npcm7xx_emc.c | 857 +++++++++++++++++++++++++++
109
include/hw/misc/iotkit-secctl.h | 2 +-
99
linux-user/aarch64/cpu_loop.c | 38 +-
110
include/hw/misc/iotkit-sysctl.h | 2 +-
100
linux-user/elfload.c | 18 +-
111
include/hw/misc/iotkit-sysinfo.h | 2 +-
101
linux-user/flatload.c | 2 +-
112
include/hw/misc/mps2-fpgaio.h | 8 +-
102
linux-user/hppa/cpu_loop.c | 39 +-
113
include/hw/misc/mps2-scc.h | 10 +-
103
linux-user/i386/cpu_loop.c | 6 +-
114
include/hw/net/npcm7xx_emc.h | 286 +++++++++++++
104
linux-user/i386/signal.c | 5 +-
115
include/ui/console.h | 10 -
105
linux-user/main.c | 4 +-
116
target/arm/cpu.h | 15 +-
106
linux-user/mmap.c | 88 +--
117
target/arm/helper-a64.h | 2 +-
107
linux-user/ppc/signal.c | 4 +-
118
target/arm/internals.h | 6 +
108
linux-user/syscall.c | 165 ++++--
119
hw/arm/mps2-tz.c | 632 +++++++++++++++++++++++-----
109
linux-user/uaccess.c | 82 ++-
120
hw/arm/mps2.c | 5 +
110
target/arm/cpu.c | 25 +-
121
hw/arm/musicpal.c | 64 ++-
111
target/arm/helper-a64.c | 4 +-
122
hw/arm/npcm7xx.c | 50 ++-
112
target/arm/mte_helper.c | 39 +-
123
hw/arm/sbsa-ref.c | 2 +-
113
target/arm/tlb_helper.c | 15 +-
124
hw/arm/xlnx-zynqmp.c | 6 -
114
target/arm/translate-a64.c | 25 +-
125
hw/display/omap_lcdc.c | 129 +++++-
115
target/hppa/op_helper.c | 2 +-
126
hw/display/tc6393xb.c | 48 +--
116
target/i386/tcg/mem_helper.c | 2 +-
127
hw/display/tcx.c | 31 +-
117
target/s390x/mem_helper.c | 4 +-
128
hw/i2c/npcm7xx_smbus.c | 1 -
118
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++
129
hw/misc/armsse-cpuid.c | 2 +-
119
tests/qtest/npcm7xx_smbus-test.c | 495 ++++++++++++++++
130
hw/misc/armsse-mhu.c | 2 +-
120
tests/tcg/aarch64/mte-1.c | 28 +
131
hw/misc/iotkit-sysctl.c | 2 +-
121
tests/tcg/aarch64/mte-2.c | 45 ++
132
hw/misc/iotkit-sysinfo.c | 2 +-
122
tests/tcg/aarch64/mte-3.c | 51 ++
133
hw/misc/mps2-fpgaio.c | 43 +-
123
tests/tcg/aarch64/mte-4.c | 45 ++
134
hw/misc/mps2-scc.c | 93 ++++-
124
tests/tcg/aarch64/pauth-2.c | 1 -
135
hw/net/npcm7xx_emc.c | 857 ++++++++++++++++++++++++++++++++++++++
125
MAINTAINERS | 11 +
136
hw/virtio/virtio-mmio.c | 13 +-
126
hw/arm/Kconfig | 1 +
137
target/arm/cpu.c | 23 +-
127
hw/i2c/meson.build | 1 +
138
target/arm/cpu64.c | 5 +
128
hw/i2c/trace-events | 12 +
139
target/arm/cpu_tcg.c | 8 +
129
hw/net/meson.build | 1 +
140
target/arm/helper-a64.c | 32 --
130
hw/net/trace-events | 17 +
141
target/arm/helper.c | 39 +-
131
tests/qtest/meson.build | 2 +
142
target/arm/mte_helper.c | 13 +-
132
tests/tcg/aarch64/Makefile.target | 6 +
143
target/arm/translate-a64.c | 70 +---
133
tests/tcg/configure.sh | 4 +
144
target/arm/vec_helper.c | 48 +++
134
61 files changed, 5052 insertions(+), 556 deletions(-)
145
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++++++++
135
create mode 100644 include/hw/i2c/npcm7xx_smbus.h
146
hw/net/meson.build | 1 +
147
hw/net/trace-events | 17 +
148
tests/qtest/meson.build | 3 +-
149
49 files changed, 3098 insertions(+), 628 deletions(-)
150
delete mode 100644 hw/display/omap_lcd_template.h
151
delete mode 100644 hw/display/tc6393xb_template.h
152
create mode 100644 include/hw/net/npcm7xx_emc.h
136
create mode 100644 include/hw/net/npcm7xx_emc.h
137
create mode 100644 target/arm/syndrome.h
138
create mode 100644 tests/tcg/aarch64/mte.h
139
create mode 100644 hw/i2c/npcm7xx_smbus.c
153
create mode 100644 hw/net/npcm7xx_emc.c
140
create mode 100644 hw/net/npcm7xx_emc.c
154
create mode 100644 tests/qtest/npcm7xx_emc-test.c
141
create mode 100644 tests/qtest/npcm7xx_emc-test.c
142
create mode 100644 tests/qtest/npcm7xx_smbus-test.c
143
create mode 100644 tests/tcg/aarch64/mte-1.c
144
create mode 100644 tests/tcg/aarch64/mte-2.c
145
create mode 100644 tests/tcg/aarch64/mte-3.c
146
create mode 100644 tests/tcg/aarch64/mte-4.c
155
147
diff view generated by jsdifflib
1
The armv7m_load_kernel() function takes a mem_size argument which it
1
From: Richard Henderson <richard.henderson@linaro.org>
2
expects to be the size of the memory region at guest address 0. (It
3
uses this argument only as a limit on how large a raw image file it
4
can load at address zero).
5
2
6
Instead of hardcoding this value, find the RAMInfo corresponding to
3
This data can be allocated by page_alloc_target_data() and
7
the 0 address and extract its size.
4
released by page_set_flags(start, end, prot | PAGE_RESET).
8
5
6
This data will be used to hold tag memory for AArch64 MTE.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210212184902.1251044-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-20-peter.maydell@linaro.org
13
---
12
---
14
hw/arm/mps2-tz.c | 17 ++++++++++++++++-
13
include/exec/cpu-all.h | 42 +++++++++++++++++++++++++++++++++------
15
1 file changed, 16 insertions(+), 1 deletion(-)
14
accel/tcg/translate-all.c | 28 ++++++++++++++++++++++++++
15
linux-user/mmap.c | 4 +++-
16
linux-user/syscall.c | 4 ++--
17
4 files changed, 69 insertions(+), 9 deletions(-)
16
18
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
21
--- a/include/exec/cpu-all.h
20
+++ b/hw/arm/mps2-tz.c
22
+++ b/include/exec/cpu-all.h
21
@@ -XXX,XX +XXX,XX @@ static void create_non_mpc_ram(MPS2TZMachineState *mms)
23
@@ -XXX,XX +XXX,XX @@ extern intptr_t qemu_host_page_mask;
24
#define PAGE_EXEC 0x0004
25
#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
26
#define PAGE_VALID 0x0008
27
-/* original state of the write flag (used when tracking self-modifying
28
- code */
29
+/*
30
+ * Original state of the write flag (used when tracking self-modifying code)
31
+ */
32
#define PAGE_WRITE_ORG 0x0010
33
-/* Invalidate the TLB entry immediately, helpful for s390x
34
- * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs() */
35
-#define PAGE_WRITE_INV 0x0040
36
+/*
37
+ * Invalidate the TLB entry immediately, helpful for s390x
38
+ * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs()
39
+ */
40
+#define PAGE_WRITE_INV 0x0020
41
+/* For use with page_set_flags: page is being replaced; target_data cleared. */
42
+#define PAGE_RESET 0x0040
43
+
44
#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
45
/* FIXME: Code that sets/uses this is broken and needs to go away. */
46
-#define PAGE_RESERVED 0x0020
47
+#define PAGE_RESERVED 0x0100
48
#endif
49
/* Target-specific bits that will be used via page_get_flags(). */
50
#define PAGE_TARGET_1 0x0080
51
@@ -XXX,XX +XXX,XX @@ int walk_memory_regions(void *, walk_memory_regions_fn);
52
int page_get_flags(target_ulong address);
53
void page_set_flags(target_ulong start, target_ulong end, int flags);
54
int page_check_range(target_ulong start, target_ulong len, int flags);
55
+
56
+/**
57
+ * page_alloc_target_data(address, size)
58
+ * @address: guest virtual address
59
+ * @size: size of data to allocate
60
+ *
61
+ * Allocate @size bytes of out-of-band data to associate with the
62
+ * guest page at @address. If the page is not mapped, NULL will
63
+ * be returned. If there is existing data associated with @address,
64
+ * no new memory will be allocated.
65
+ *
66
+ * The memory will be freed when the guest page is deallocated,
67
+ * e.g. with the munmap system call.
68
+ */
69
+void *page_alloc_target_data(target_ulong address, size_t size);
70
+
71
+/**
72
+ * page_get_target_data(address)
73
+ * @address: guest virtual address
74
+ *
75
+ * Return any out-of-bound memory assocated with the guest page
76
+ * at @address, as per page_alloc_target_data.
77
+ */
78
+void *page_get_target_data(target_ulong address);
79
#endif
80
81
CPUArchState *cpu_copy(CPUArchState *env);
82
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/accel/tcg/translate-all.c
85
+++ b/accel/tcg/translate-all.c
86
@@ -XXX,XX +XXX,XX @@ typedef struct PageDesc {
87
unsigned int code_write_count;
88
#else
89
unsigned long flags;
90
+ void *target_data;
91
#endif
92
#ifndef CONFIG_USER_ONLY
93
QemuSpin lock;
94
@@ -XXX,XX +XXX,XX @@ int page_get_flags(target_ulong address)
95
void page_set_flags(target_ulong start, target_ulong end, int flags)
96
{
97
target_ulong addr, len;
98
+ bool reset_target_data;
99
100
/* This function should never be called with addresses outside the
101
guest address space. If this assert fires, it probably indicates
102
@@ -XXX,XX +XXX,XX @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
103
if (flags & PAGE_WRITE) {
104
flags |= PAGE_WRITE_ORG;
105
}
106
+ reset_target_data = !(flags & PAGE_VALID) || (flags & PAGE_RESET);
107
+ flags &= ~PAGE_RESET;
108
109
for (addr = start, len = end - start;
110
len != 0;
111
@@ -XXX,XX +XXX,XX @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
112
p->first_tb) {
113
tb_invalidate_phys_page(addr, 0);
114
}
115
+ if (reset_target_data && p->target_data) {
116
+ g_free(p->target_data);
117
+ p->target_data = NULL;
118
+ }
119
p->flags = flags;
22
}
120
}
23
}
121
}
24
122
25
+static uint32_t boot_ram_size(MPS2TZMachineState *mms)
123
+void *page_get_target_data(target_ulong address)
26
+{
124
+{
27
+ /* Return the size of the RAM block at guest address zero */
125
+ PageDesc *p = page_find(address >> TARGET_PAGE_BITS);
28
+ const RAMInfo *p;
126
+ return p ? p->target_data : NULL;
29
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
127
+}
30
+
128
+
31
+ for (p = mmc->raminfo; p->name; p++) {
129
+void *page_alloc_target_data(target_ulong address, size_t size)
32
+ if (p->base == 0) {
130
+{
33
+ return p->size;
131
+ PageDesc *p = page_find(address >> TARGET_PAGE_BITS);
132
+ void *ret = NULL;
133
+
134
+ if (p->flags & PAGE_VALID) {
135
+ ret = p->target_data;
136
+ if (!ret) {
137
+ p->target_data = ret = g_malloc0(size);
34
+ }
138
+ }
35
+ }
139
+ }
36
+ g_assert_not_reached();
140
+ return ret;
37
+}
141
+}
38
+
142
+
39
static void mps2tz_common_init(MachineState *machine)
143
int page_check_range(target_ulong start, target_ulong len, int flags)
40
{
144
{
41
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
145
PageDesc *p;
42
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
146
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
43
147
index XXXXXXX..XXXXXXX 100644
44
create_non_mpc_ram(mms);
148
--- a/linux-user/mmap.c
45
149
+++ b/linux-user/mmap.c
46
- armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
150
@@ -XXX,XX +XXX,XX @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
47
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
151
}
48
+ boot_ram_size(mms));
152
}
49
}
153
the_end1:
50
154
+ page_flags |= PAGE_RESET;
51
static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
155
page_set_flags(start, start + len, page_flags);
156
the_end:
157
trace_target_mmap_complete(start);
158
@@ -XXX,XX +XXX,XX @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
159
new_addr = h2g(host_addr);
160
prot = page_get_flags(old_addr);
161
page_set_flags(old_addr, old_addr + old_size, 0);
162
- page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID);
163
+ page_set_flags(new_addr, new_addr + new_size,
164
+ prot | PAGE_VALID | PAGE_RESET);
165
}
166
tb_invalidate_phys_range(new_addr, new_addr + new_size);
167
mmap_unlock();
168
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/linux-user/syscall.c
171
+++ b/linux-user/syscall.c
172
@@ -XXX,XX +XXX,XX @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
173
raddr=h2g((unsigned long)host_raddr);
174
175
page_set_flags(raddr, raddr + shm_info.shm_segsz,
176
- PAGE_VALID | PAGE_READ |
177
- ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
178
+ PAGE_VALID | PAGE_RESET | PAGE_READ |
179
+ (shmflg & SHM_RDONLY ? 0 : PAGE_WRITE));
180
181
for (i = 0; i < N_SHM_REGIONS; i++) {
182
if (!shm_regions[i].in_use) {
52
--
183
--
53
2.20.1
184
2.20.1
54
185
55
186
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We hint the 'has_rpu' property is no longer required since commit
3
Record whether the backing page is anonymous, or if it has file
4
6908ec448b4 ("xlnx-zynqmp: Properly support the smp command line
4
backing. This will allow us to get close to the Linux AArch64
5
option") which was released in QEMU v2.11.0.
5
ABI for MTE, which allows tag memory only on ram-backed VMAs.
6
6
7
Beside, this device is marked 'user_creatable = false', so the
7
The real ABI allows tag memory on files, when those files are
8
only thing that could be setting the property is the board code
8
on ram-backed filesystems, such as tmpfs. We will not be able
9
that creates the device.
9
to implement that in QEMU linux-user.
10
10
11
Since the property is not user-facing, we can remove it without
11
Thankfully, anonymous memory for malloc arenas is the primary
12
going through the deprecation process.
12
consumer of this feature, so this restricted version should
13
still be of use.
13
14
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210219144350.1979905-1-f4bug@amsat.org
17
Message-id: 20210212184902.1251044-3-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
---
19
include/hw/arm/xlnx-zynqmp.h | 2 --
20
include/exec/cpu-all.h | 2 ++
20
hw/arm/xlnx-zynqmp.c | 6 ------
21
linux-user/mmap.c | 3 +++
21
2 files changed, 8 deletions(-)
22
2 files changed, 5 insertions(+)
22
23
23
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
24
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
24
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/xlnx-zynqmp.h
26
--- a/include/exec/cpu-all.h
26
+++ b/include/hw/arm/xlnx-zynqmp.h
27
+++ b/include/exec/cpu-all.h
27
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
28
@@ -XXX,XX +XXX,XX @@ extern intptr_t qemu_host_page_mask;
28
bool secure;
29
#define PAGE_WRITE_INV 0x0020
29
/* Has the ARM Virtualization extensions? */
30
/* For use with page_set_flags: page is being replaced; target_data cleared. */
30
bool virt;
31
#define PAGE_RESET 0x0040
31
- /* Has the RPU subsystem? */
32
+/* For linux-user, indicates that the page is MAP_ANON. */
32
- bool has_rpu;
33
+#define PAGE_ANON 0x0080
33
34
34
/* CAN bus. */
35
#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
35
CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
36
/* FIXME: Code that sets/uses this is broken and needs to go away. */
36
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
37
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
37
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/xlnx-zynqmp.c
39
--- a/linux-user/mmap.c
39
+++ b/hw/arm/xlnx-zynqmp.c
40
+++ b/linux-user/mmap.c
40
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
41
@@ -XXX,XX +XXX,XX @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
41
}
42
}
42
}
43
}
43
44
the_end1:
44
- if (s->has_rpu) {
45
+ if (flags & MAP_ANONYMOUS) {
45
- info_report("The 'has_rpu' property is no longer required, to use the "
46
+ page_flags |= PAGE_ANON;
46
- "RPUs just use -smp 6.");
47
+ }
47
- }
48
page_flags |= PAGE_RESET;
48
-
49
page_set_flags(start, start + len, page_flags);
49
xlnx_zynqmp_create_rpu(ms, s, boot_cpu, &err);
50
the_end:
50
if (err) {
51
error_propagate(errp, err);
52
@@ -XXX,XX +XXX,XX @@ static Property xlnx_zynqmp_props[] = {
53
DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
54
DEFINE_PROP_BOOL("secure", XlnxZynqMPState, secure, false),
55
DEFINE_PROP_BOOL("virtualization", XlnxZynqMPState, virt, false),
56
- DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
57
DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
58
MemoryRegion *),
59
DEFINE_PROP_LINK("canbus0", XlnxZynqMPState, canbus[0], TYPE_CAN_BUS,
60
--
51
--
61
2.20.1
52
2.20.1
62
53
63
54
diff view generated by jsdifflib
1
From: schspa <schspa@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
At the moment the following QEMU command line triggers an assertion
3
This is more descriptive than 'unsigned long'.
4
failure On xlnx-versal SOC:
4
No functional change, since these match on all linux+bsd hosts.
5
qemu-system-aarch64 \
6
-machine xlnx-versal-virt -nographic -smp 2 -m 128 \
7
-fsdev local,id=shareid,path=${HOME}/work,security_model=none \
8
-device virtio-9p-device,fsdev=shareid,mount_tag=share \
9
-fsdev local,id=shareid1,path=${HOME}/Music,security_model=none \
10
-device virtio-9p-device,fsdev=shareid1,mount_tag=share1
11
5
12
qemu-system-aarch64: ../migration/savevm.c:860:
13
vmstate_register_with_alias_id:
14
Assertion `!se->compat || se->instance_id == 0' failed.
15
16
This problem was fixed on arm virt platform in commit f58b39d2d5b
17
("virtio-mmio: format transport base address in BusClass.get_dev_path")
18
19
It works perfectly on arm virt platform. but there is still there on
20
xlnx-versal SOC.
21
22
The main difference between arm virt and xlnx-versal is they use
23
different way to create virtio-mmio qdev. on arm virt, it calls
24
sysbus_create_simple("virtio-mmio", base, pic[irq]); which will call
25
sysbus_mmio_map internally and assign base address to subsys device
26
mmio correctly. but xlnx-versal's implements won't do this.
27
28
However, xlnx-versal can't switch to sysbus_create_simple() to create
29
virtio-mmio device. It's because xlnx-versal's cpu use
30
VersalVirt.soc.fpd.apu.mr as it's memory. which is subregion of
31
system_memory. sysbus_create_simple will add virtio to system_memory,
32
which can't be accessed by cpu.
33
34
Besides, xlnx-versal can't add sysbus_mmio_map api call too, because
35
this will add memory region to system_memory, and it can't be added
36
to VersalVirt.soc.fpd.apu.mr again.
37
38
We can solve this by assign correct base address offset on dev_path.
39
40
This path was test on aarch64 virt & xlnx-versal platform.
41
42
Signed-off-by: schspa <schspa@gmail.com>
43
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210212184902.1251044-4-richard.henderson@linaro.org
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
---
11
---
46
hw/virtio/virtio-mmio.c | 13 +++++++------
12
include/exec/cpu-all.h | 2 +-
47
1 file changed, 7 insertions(+), 6 deletions(-)
13
bsd-user/main.c | 4 ++--
14
linux-user/elfload.c | 4 ++--
15
linux-user/main.c | 4 ++--
16
4 files changed, 7 insertions(+), 7 deletions(-)
48
17
49
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
18
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
50
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/virtio/virtio-mmio.c
20
--- a/include/exec/cpu-all.h
52
+++ b/hw/virtio/virtio-mmio.c
21
+++ b/include/exec/cpu-all.h
53
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
22
@@ -XXX,XX +XXX,XX @@ static inline void tswap64s(uint64_t *s)
54
BusState *virtio_mmio_bus;
23
/* On some host systems the guest address space is reserved on the host.
55
VirtIOMMIOProxy *virtio_mmio_proxy;
24
* This allows the guest address space to be offset to a convenient location.
56
char *proxy_path;
25
*/
57
- SysBusDevice *proxy_sbd;
26
-extern unsigned long guest_base;
58
char *path;
27
+extern uintptr_t guest_base;
59
+ MemoryRegionSection section;
28
extern bool have_guest_base;
60
29
extern unsigned long reserved_va;
61
virtio_mmio_bus = qdev_get_parent_bus(dev);
30
62
virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
31
diff --git a/bsd-user/main.c b/bsd-user/main.c
63
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
32
index XXXXXXX..XXXXXXX 100644
33
--- a/bsd-user/main.c
34
+++ b/bsd-user/main.c
35
@@ -XXX,XX +XXX,XX @@
36
37
int singlestep;
38
unsigned long mmap_min_addr;
39
-unsigned long guest_base;
40
+uintptr_t guest_base;
41
bool have_guest_base;
42
unsigned long reserved_va;
43
44
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
45
g_free(target_environ);
46
47
if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
48
- qemu_log("guest_base 0x%lx\n", guest_base);
49
+ qemu_log("guest_base %p\n", (void *)guest_base);
50
log_page_dump("binary load");
51
52
qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
53
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/linux-user/elfload.c
56
+++ b/linux-user/elfload.c
57
@@ -XXX,XX +XXX,XX @@ static void pgb_have_guest_base(const char *image_name, abi_ulong guest_loaddr,
58
void *addr, *test;
59
60
if (!QEMU_IS_ALIGNED(guest_base, align)) {
61
- fprintf(stderr, "Requested guest base 0x%lx does not satisfy "
62
+ fprintf(stderr, "Requested guest base %p does not satisfy "
63
"host minimum alignment (0x%lx)\n",
64
- guest_base, align);
65
+ (void *)guest_base, align);
66
exit(EXIT_FAILURE);
64
}
67
}
65
68
66
/* Otherwise, we append the base address of the transport. */
69
diff --git a/linux-user/main.c b/linux-user/main.c
67
- proxy_sbd = SYS_BUS_DEVICE(virtio_mmio_proxy);
70
index XXXXXXX..XXXXXXX 100644
68
- assert(proxy_sbd->num_mmio == 1);
71
--- a/linux-user/main.c
69
- assert(proxy_sbd->mmio[0].memory == &virtio_mmio_proxy->iomem);
72
+++ b/linux-user/main.c
70
+ section = memory_region_find(&virtio_mmio_proxy->iomem, 0, 0x200);
73
@@ -XXX,XX +XXX,XX @@ static const char *cpu_model;
71
+ assert(section.mr);
74
static const char *cpu_type;
72
75
static const char *seed_optarg;
73
if (proxy_path) {
76
unsigned long mmap_min_addr;
74
path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
77
-unsigned long guest_base;
75
- proxy_sbd->mmio[0].addr);
78
+uintptr_t guest_base;
76
+ section.offset_within_address_space);
79
bool have_guest_base;
77
} else {
80
78
path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
81
/*
79
- proxy_sbd->mmio[0].addr);
82
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
80
+ section.offset_within_address_space);
83
g_free(target_environ);
81
}
84
82
+ memory_region_unref(section.mr);
85
if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
83
+
86
- qemu_log("guest_base 0x%lx\n", guest_base);
84
g_free(proxy_path);
87
+ qemu_log("guest_base %p\n", (void *)guest_base);
85
return path;
88
log_page_dump("binary load");
86
}
89
90
qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
87
--
91
--
88
2.20.1
92
2.20.1
89
93
90
94
diff view generated by jsdifflib
1
For a long time now the UI layer has guaranteed that the console
1
From: Richard Henderson <richard.henderson@linaro.org>
2
surface is always 32 bits per pixel RGB. Remove the legacy dead
3
code from the tc6393xb display device which was handling the
4
possibility that the console surface was some other format.
5
2
3
This is more descriptive than 'unsigned long'.
4
No functional change, since these match on all linux+bsd hosts.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210212184902.1251044-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215103215.4944-3-peter.maydell@linaro.org
9
---
11
---
10
include/ui/console.h | 10 ----------
12
include/exec/cpu_ldst.h | 6 +++---
11
hw/display/tc6393xb.c | 33 +--------------------------------
13
1 file changed, 3 insertions(+), 3 deletions(-)
12
2 files changed, 1 insertion(+), 42 deletions(-)
13
14
14
diff --git a/include/ui/console.h b/include/ui/console.h
15
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/include/ui/console.h
17
--- a/include/exec/cpu_ldst.h
17
+++ b/include/ui/console.h
18
+++ b/include/exec/cpu_ldst.h
18
@@ -XXX,XX +XXX,XX @@ PixelFormat qemu_default_pixelformat(int bpp);
19
@@ -XXX,XX +XXX,XX @@ typedef uint64_t abi_ptr;
19
DisplaySurface *qemu_create_displaysurface(int width, int height);
20
#endif
20
void qemu_free_displaysurface(DisplaySurface *surface);
21
21
22
/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
22
-static inline int is_surface_bgr(DisplaySurface *surface)
23
-#define g2h(x) ((void *)((unsigned long)(abi_ptr)(x) + guest_base))
23
-{
24
+#define g2h(x) ((void *)((uintptr_t)(abi_ptr)(x) + guest_base))
24
- if (PIXMAN_FORMAT_BPP(surface->format) == 32 &&
25
25
- PIXMAN_FORMAT_TYPE(surface->format) == PIXMAN_TYPE_ABGR) {
26
#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
26
- return 1;
27
#define guest_addr_valid(x) (1)
27
- } else {
28
#else
28
- return 0;
29
#define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
29
- }
30
#endif
30
-}
31
-#define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base)
31
-
32
+#define h2g_valid(x) guest_addr_valid((uintptr_t)(x) - guest_base)
32
static inline int is_buffer_shared(DisplaySurface *surface)
33
34
static inline int guest_range_valid(unsigned long start, unsigned long len)
33
{
35
{
34
return !(surface->flags & QEMU_ALLOCATED_FLAG);
36
@@ -XXX,XX +XXX,XX @@ static inline int guest_range_valid(unsigned long start, unsigned long len)
35
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/display/tc6393xb.c
38
+++ b/hw/display/tc6393xb.c
39
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
40
(uint32_t) addr, value & 0xff);
41
}
37
}
42
38
43
-#define BITS 8
39
#define h2g_nocheck(x) ({ \
44
-#include "tc6393xb_template.h"
40
- unsigned long __ret = (unsigned long)(x) - guest_base; \
45
-#define BITS 15
41
+ uintptr_t __ret = (uintptr_t)(x) - guest_base; \
46
-#include "tc6393xb_template.h"
42
(abi_ptr)__ret; \
47
-#define BITS 16
43
})
48
-#include "tc6393xb_template.h"
49
-#define BITS 24
50
-#include "tc6393xb_template.h"
51
#define BITS 32
52
#include "tc6393xb_template.h"
53
54
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
55
{
56
- DisplaySurface *surface = qemu_console_surface(s->con);
57
-
58
- switch (surface_bits_per_pixel(surface)) {
59
- case 8:
60
- tc6393xb_draw_graphic8(s);
61
- break;
62
- case 15:
63
- tc6393xb_draw_graphic15(s);
64
- break;
65
- case 16:
66
- tc6393xb_draw_graphic16(s);
67
- break;
68
- case 24:
69
- tc6393xb_draw_graphic24(s);
70
- break;
71
- case 32:
72
- tc6393xb_draw_graphic32(s);
73
- break;
74
- default:
75
- printf("tc6393xb: unknown depth %d\n",
76
- surface_bits_per_pixel(surface));
77
- return;
78
- }
79
-
80
+ tc6393xb_draw_graphic32(s);
81
dpy_gfx_update_full(s->con);
82
}
83
44
84
--
45
--
85
2.20.1
46
2.20.1
86
47
87
48
diff view generated by jsdifflib
1
Fix some minor coding style issues in the template header,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
so checkpatch doesn't complain when we move the code.
3
2
3
Return bool not int; pass abi_ulong not 'unsigned long'.
4
All callers use abi_ulong already, so the change in type
5
has no effect.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210212184902.1251044-6-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-8-peter.maydell@linaro.org
8
---
12
---
9
hw/display/omap_lcd_template.h | 6 +++---
13
include/exec/cpu_ldst.h | 2 +-
10
1 file changed, 3 insertions(+), 3 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
11
15
12
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
16
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/display/omap_lcd_template.h
18
--- a/include/exec/cpu_ldst.h
15
+++ b/hw/display/omap_lcd_template.h
19
+++ b/include/exec/cpu_ldst.h
16
@@ -XXX,XX +XXX,XX @@ static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
20
@@ -XXX,XX +XXX,XX @@ typedef uint64_t abi_ptr;
17
b = (pal[v & 3] << 4) & 0xf0;
21
#endif
18
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
22
#define h2g_valid(x) guest_addr_valid((uintptr_t)(x) - guest_base)
19
d += 4;
23
20
- s ++;
24
-static inline int guest_range_valid(unsigned long start, unsigned long len)
21
+ s++;
25
+static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
22
width -= 4;
26
{
23
} while (width > 0);
27
return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
24
}
25
@@ -XXX,XX +XXX,XX @@ static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
26
b = (pal[v & 0xf] << 4) & 0xf0;
27
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
28
d += 4;
29
- s ++;
30
+ s++;
31
width -= 2;
32
} while (width > 0);
33
}
34
@@ -XXX,XX +XXX,XX @@ static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
35
g = pal[v] & 0xf0;
36
b = (pal[v] << 4) & 0xf0;
37
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
38
- s ++;
39
+ s++;
40
d += 4;
41
} while (-- width != 0);
42
}
28
}
43
--
29
--
44
2.20.1
30
2.20.1
45
31
46
32
diff view generated by jsdifflib
1
The AN524 has a PL031 RTC, which we have a model of; provide it
1
From: Richard Henderson <richard.henderson@linaro.org>
2
rather than an unimplemented-device stub.
3
2
3
Verify that addr + size - 1 does not wrap around.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210212184902.1251044-7-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210215115138.20465-23-peter.maydell@linaro.org
8
---
9
---
9
hw/arm/mps2-tz.c | 22 ++++++++++++++++++++--
10
linux-user/qemu.h | 17 ++++++++++++-----
10
1 file changed, 20 insertions(+), 2 deletions(-)
11
1 file changed, 12 insertions(+), 5 deletions(-)
11
12
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
13
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2-tz.c
15
--- a/linux-user/qemu.h
15
+++ b/hw/arm/mps2-tz.c
16
+++ b/linux-user/qemu.h
16
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ extern unsigned long guest_stack_size;
17
#include "hw/misc/tz-msc.h"
18
#define VERIFY_READ 0
18
#include "hw/arm/armsse.h"
19
#define VERIFY_WRITE 1 /* implies read access */
19
#include "hw/dma/pl080.h"
20
20
+#include "hw/rtc/pl031.h"
21
-static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
21
#include "hw/ssi/pl022.h"
22
+static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
22
#include "hw/i2c/arm_sbcon_i2c.h"
23
{
23
#include "hw/net/lan9118.h"
24
- return guest_addr_valid(addr) &&
24
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
25
- (size == 0 || guest_addr_valid(addr + size - 1)) &&
25
UnimplementedDeviceState gpio[4];
26
- page_check_range((target_ulong)addr, size,
26
UnimplementedDeviceState gfx;
27
- (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
27
UnimplementedDeviceState cldc;
28
+ if (!guest_addr_valid(addr)) {
28
- UnimplementedDeviceState rtc;
29
+ return false;
29
UnimplementedDeviceState usb;
30
+ }
30
+ PL031State rtc;
31
+ if (size != 0 &&
31
PL080State dma[4];
32
+ (addr + size - 1 < addr ||
32
TZMSC msc[4];
33
+ !guest_addr_valid(addr + size - 1))) {
33
CMSDKAPBUART uart[6];
34
+ return false;
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
35
+ }
35
return sysbus_mmio_get_region(s, 0);
36
+ return page_check_range((target_ulong)addr, size,
37
+ (type == VERIFY_READ) ? PAGE_READ :
38
+ (PAGE_READ | PAGE_WRITE)) == 0;
36
}
39
}
37
40
38
+static MemoryRegion *make_rtc(MPS2TZMachineState *mms, void *opaque,
41
/* NOTE __get_user and __put_user use host pointers and don't check access.
39
+ const char *name, hwaddr size,
40
+ const int *irqs)
41
+{
42
+ PL031State *pl031 = opaque;
43
+ SysBusDevice *s;
44
+
45
+ object_initialize_child(OBJECT(mms), name, pl031, TYPE_PL031);
46
+ s = SYS_BUS_DEVICE(pl031);
47
+ sysbus_realize(s, &error_fatal);
48
+ /*
49
+ * The board docs don't give an IRQ number for the PL031, so
50
+ * presumably it is not connected.
51
+ */
52
+ return sysbus_mmio_get_region(s, 0);
53
+}
54
+
55
static void create_non_mpc_ram(MPS2TZMachineState *mms)
56
{
57
/*
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
59
60
{ /* port 9 reserved */ },
61
{ "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
62
- { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
63
+ { "rtc", make_rtc, &mms->rtc, 0x4130b000, 0x1000 },
64
},
65
}, {
66
.name = "ahb_ppcexp0",
67
--
42
--
68
2.20.1
43
2.20.1
69
44
70
45
diff view generated by jsdifflib
1
The AN524 has a USB controller (an ISP1763); we don't have a model of
1
From: Richard Henderson <richard.henderson@linaro.org>
2
it but we should provide a stub "unimplemented-device" for it. This
3
is slightly complicated because the USB controller shares a PPC port
4
with the ethernet controller.
5
2
6
Implement a make_* function which provides creates a container
3
These constants are only ever used with access_ok, and friends.
7
MemoryRegion with both the ethernet controller and an
4
Rather than translating them to PAGE_* bits, let them equal
8
unimplemented-device stub for the USB controller.
5
the PAGE_* bits to begin.
9
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210212184902.1251044-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210215115138.20465-22-peter.maydell@linaro.org
14
---
11
---
15
hw/arm/mps2-tz.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
12
linux-user/qemu.h | 8 +++-----
16
1 file changed, 47 insertions(+), 1 deletion(-)
13
1 file changed, 3 insertions(+), 5 deletions(-)
17
14
18
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/mps2-tz.c
17
--- a/linux-user/qemu.h
21
+++ b/hw/arm/mps2-tz.c
18
+++ b/linux-user/qemu.h
22
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
19
@@ -XXX,XX +XXX,XX @@ extern unsigned long guest_stack_size;
23
20
24
ARMSSE iotkit;
21
/* user access */
25
MemoryRegion ram[MPS2TZ_RAM_MAX];
22
26
+ MemoryRegion eth_usb_container;
23
-#define VERIFY_READ 0
27
+
24
-#define VERIFY_WRITE 1 /* implies read access */
28
MPS2SCC scc;
25
+#define VERIFY_READ PAGE_READ
29
MPS2FPGAIO fpgaio;
26
+#define VERIFY_WRITE (PAGE_READ | PAGE_WRITE)
30
TZPPC ppc[5];
27
31
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
28
static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
32
UnimplementedDeviceState gfx;
29
{
33
UnimplementedDeviceState cldc;
30
@@ -XXX,XX +XXX,XX @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
34
UnimplementedDeviceState rtc;
31
!guest_addr_valid(addr + size - 1))) {
35
+ UnimplementedDeviceState usb;
32
return false;
36
PL080State dma[4];
33
}
37
TZMSC msc[4];
34
- return page_check_range((target_ulong)addr, size,
38
CMSDKAPBUART uart[6];
35
- (type == VERIFY_READ) ? PAGE_READ :
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
36
- (PAGE_READ | PAGE_WRITE)) == 0;
40
return sysbus_mmio_get_region(s, 0);
37
+ return page_check_range((target_ulong)addr, size, type) == 0;
41
}
38
}
42
39
43
+static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
40
/* NOTE __get_user and __put_user use host pointers and don't check access.
44
+ const char *name, hwaddr size,
45
+ const int *irqs)
46
+{
47
+ /*
48
+ * The AN524 makes the ethernet and USB share a PPC port.
49
+ * irqs[] is the ethernet IRQ.
50
+ */
51
+ SysBusDevice *s;
52
+ NICInfo *nd = &nd_table[0];
53
+
54
+ memory_region_init(&mms->eth_usb_container, OBJECT(mms),
55
+ "mps2-tz-eth-usb-container", 0x200000);
56
+
57
+ /*
58
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
59
+ * except that it doesn't support the checksum-offload feature.
60
+ */
61
+ qemu_check_nic_model(nd, "lan9118");
62
+ mms->lan9118 = qdev_new(TYPE_LAN9118);
63
+ qdev_set_nic_properties(mms->lan9118, nd);
64
+
65
+ s = SYS_BUS_DEVICE(mms->lan9118);
66
+ sysbus_realize_and_unref(s, &error_fatal);
67
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
68
+
69
+ memory_region_add_subregion(&mms->eth_usb_container,
70
+ 0, sysbus_mmio_get_region(s, 0));
71
+
72
+ /* The USB OTG controller is an ISP1763; we don't have a model of it. */
73
+ object_initialize_child(OBJECT(mms), "usb-otg",
74
+ &mms->usb, TYPE_UNIMPLEMENTED_DEVICE);
75
+ qdev_prop_set_string(DEVICE(&mms->usb), "name", "usb-otg");
76
+ qdev_prop_set_uint64(DEVICE(&mms->usb), "size", 0x100000);
77
+ s = SYS_BUS_DEVICE(&mms->usb);
78
+ sysbus_realize(s, &error_fatal);
79
+
80
+ memory_region_add_subregion(&mms->eth_usb_container,
81
+ 0x100000, sysbus_mmio_get_region(s, 0));
82
+
83
+ return &mms->eth_usb_container;
84
+}
85
+
86
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
87
const char *name, hwaddr size,
88
const int *irqs)
89
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
90
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
91
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
92
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
93
- { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
94
+ { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 48 } },
95
},
96
},
97
};
98
--
41
--
99
2.20.1
42
2.20.1
100
43
101
44
diff view generated by jsdifflib
1
The AN505 and AN521 don't have any read-only memory, but the AN524
1
From: Richard Henderson <richard.henderson@linaro.org>
2
does; add a flag to ROMInfo to mark a region as ROM.
3
2
3
These constants are only ever used with access_ok, and friends.
4
Rather than translating them to PAGE_* bits, let them equal
5
the PAGE_* bits to begin.
6
7
Reviewed-by: Warner Losh <imp@bsdimp.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210212184902.1251044-9-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215115138.20465-19-peter.maydell@linaro.org
7
---
12
---
8
hw/arm/mps2-tz.c | 6 ++++++
13
bsd-user/qemu.h | 9 ++++-----
9
1 file changed, 6 insertions(+)
14
1 file changed, 4 insertions(+), 5 deletions(-)
10
15
11
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2-tz.c
18
--- a/bsd-user/qemu.h
14
+++ b/hw/arm/mps2-tz.c
19
+++ b/bsd-user/qemu.h
15
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
20
@@ -XXX,XX +XXX,XX @@ extern unsigned long x86_stack_size;
16
* Flag values:
21
17
* IS_ALIAS: this RAM area is an alias to the upstream end of the
22
/* user access */
18
* MPC specified by its .mpc value
23
19
+ * IS_ROM: this RAM area is read-only
24
-#define VERIFY_READ 0
20
*/
25
-#define VERIFY_WRITE 1 /* implies read access */
21
#define IS_ALIAS 1
26
+#define VERIFY_READ PAGE_READ
22
+#define IS_ROM 2
27
+#define VERIFY_WRITE (PAGE_READ | PAGE_WRITE)
23
28
24
struct MPS2TZMachineClass {
29
-static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
25
MachineClass parent;
30
+static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
26
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
31
{
27
if (raminfo->mrindex < 0) {
32
- return page_check_range((target_ulong)addr, size,
28
/* Means this RAMInfo is for QEMU's "system memory" */
33
- (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
29
MachineState *machine = MACHINE(mms);
34
+ return page_check_range((target_ulong)addr, size, type) == 0;
30
+ assert(!(raminfo->flags & IS_ROM));
31
return machine->ram;
32
}
33
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
35
36
memory_region_init_ram(ram, NULL, raminfo->name,
37
raminfo->size, &error_fatal);
38
+ if (raminfo->flags & IS_ROM) {
39
+ memory_region_set_readonly(ram, true);
40
+ }
41
return ram;
42
}
35
}
43
36
37
/* NOTE __get_user and __put_user use host pointers and don't check access. */
44
--
38
--
45
2.20.1
39
2.20.1
46
40
47
41
diff view generated by jsdifflib
1
Move the specification of the IRQ information for the uart, ethernet,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
dma and spi devices to the data structures. (The other devices
3
handled by the PPCPortInfo structures don't have any interrupt lines
4
we need to wire up.)
5
2
3
This is the only use of guest_addr_valid that does not begin
4
with a guest address, but a host address being transformed to
5
a guest address.
6
7
We will shortly adjust guest_addr_valid to handle guest memory
8
tags, and the host address should not be subjected to that.
9
10
Move h2g_valid adjacent to the other h2g macros.
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210212184902.1251044-10-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-14-peter.maydell@linaro.org
9
---
16
---
10
hw/arm/mps2-tz.c | 52 +++++++++++++++++++++++-------------------------
17
include/exec/cpu_ldst.h | 5 ++++-
11
1 file changed, 25 insertions(+), 27 deletions(-)
18
1 file changed, 4 insertions(+), 1 deletion(-)
12
19
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
20
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
22
--- a/include/exec/cpu_ldst.h
16
+++ b/hw/arm/mps2-tz.c
23
+++ b/include/exec/cpu_ldst.h
17
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
24
@@ -XXX,XX +XXX,XX @@ typedef uint64_t abi_ptr;
18
const char *name, hwaddr size,
25
#else
19
const int *irqs)
26
#define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
27
#endif
28
-#define h2g_valid(x) guest_addr_valid((uintptr_t)(x) - guest_base)
29
30
static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
20
{
31
{
21
+ /* The irq[] array is tx, rx, combined, in that order */
32
return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
22
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
23
CMSDKAPBUART *uart = opaque;
24
int i = uart - &mms->uart[0];
25
- int rxirqno = i * 2 + 32;
26
- int txirqno = i * 2 + 33;
27
- int combirqno = i + 42;
28
SysBusDevice *s;
29
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
30
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
32
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
33
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
34
s = SYS_BUS_DEVICE(uart);
35
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
36
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, rxirqno));
37
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
38
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
39
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
40
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
41
- sysbus_connect_irq(s, 4, get_sse_irq_in(mms, combirqno));
42
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, irqs[2]));
43
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
44
}
33
}
45
34
46
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
35
+#define h2g_valid(x) \
47
36
+ (HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS || \
48
s = SYS_BUS_DEVICE(mms->lan9118);
37
+ (uintptr_t)(x) - guest_base <= GUEST_ADDR_MAX)
49
sysbus_realize_and_unref(s, &error_fatal);
38
+
50
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
39
#define h2g_nocheck(x) ({ \
51
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
40
uintptr_t __ret = (uintptr_t)(x) - guest_base; \
52
return sysbus_mmio_get_region(s, 0);
41
(abi_ptr)__ret; \
53
}
54
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
56
const char *name, hwaddr size,
57
const int *irqs)
58
{
59
+ /* The irq[] array is DMACINTR, DMACINTERR, DMACINTTC, in that order */
60
PL080State *dma = opaque;
61
int i = dma - &mms->dma[0];
62
SysBusDevice *s;
63
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
64
65
s = SYS_BUS_DEVICE(dma);
66
/* Wire up DMACINTR, DMACINTERR, DMACINTTC */
67
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 58 + i * 3));
68
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, 56 + i * 3));
69
- sysbus_connect_irq(s, 2, get_sse_irq_in(mms, 57 + i * 3));
70
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
71
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
72
+ sysbus_connect_irq(s, 2, get_sse_irq_in(mms, irqs[2]));
73
74
g_free(mscname);
75
return sysbus_mmio_get_region(s, 0);
76
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
77
* lines are set via the "MISC" register in the MPS2 FPGAIO device.
78
*/
79
PL022State *spi = opaque;
80
- int i = spi - &mms->spi[0];
81
SysBusDevice *s;
82
83
object_initialize_child(OBJECT(mms), name, spi, TYPE_PL022);
84
sysbus_realize(SYS_BUS_DEVICE(spi), &error_fatal);
85
s = SYS_BUS_DEVICE(spi);
86
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 51 + i));
87
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
88
return sysbus_mmio_get_region(s, 0);
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
92
}, {
93
.name = "apb_ppcexp1",
94
.ports = {
95
- { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000 },
96
- { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000 },
97
- { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000 },
98
- { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000 },
99
- { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000 },
100
- { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 },
101
- { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 },
102
- { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
103
- { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
104
- { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
105
+ { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000, { 51 } },
106
+ { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000, { 52 } },
107
+ { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000, { 53 } },
108
+ { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000, { 54 } },
109
+ { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000, { 55 } },
110
+ { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000, { 32, 33, 42 } },
111
+ { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000, { 34, 35, 43 } },
112
+ { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000, { 36, 37, 44 } },
113
+ { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000, { 38, 39, 45 } },
114
+ { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000, { 40, 41, 46 } },
115
{ "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
116
{ "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
117
{ "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
118
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
119
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x40101000, 0x1000 },
120
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x40102000, 0x1000 },
121
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x40103000, 0x1000 },
122
- { "eth", make_eth_dev, NULL, 0x42000000, 0x100000 },
123
+ { "eth", make_eth_dev, NULL, 0x42000000, 0x100000, { 48 } },
124
},
125
}, {
126
.name = "ahb_ppcexp1",
127
.ports = {
128
- { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000 },
129
- { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000 },
130
- { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000 },
131
- { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000 },
132
+ { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000, { 58, 56, 57 } },
133
+ { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000, { 61, 59, 60 } },
134
+ { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000, { 64, 62, 63 } },
135
+ { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000, { 67, 65, 66 } },
136
},
137
},
138
};
139
--
42
--
140
2.20.1
43
2.20.1
141
44
142
45
diff view generated by jsdifflib
1
We only include the template header once, so just inline it into the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
source file for the device.
3
2
3
We must always use GUEST_ADDR_MAX, because even 32-bit hosts can
4
use -R <reserved_va> to restrict the memory address of the guest.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210212184902.1251044-11-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-9-peter.maydell@linaro.org
8
---
10
---
9
hw/display/omap_lcd_template.h | 154 ---------------------------------
11
include/exec/cpu_ldst.h | 9 ++++-----
10
hw/display/omap_lcdc.c | 127 ++++++++++++++++++++++++++-
12
1 file changed, 4 insertions(+), 5 deletions(-)
11
2 files changed, 125 insertions(+), 156 deletions(-)
12
delete mode 100644 hw/display/omap_lcd_template.h
13
13
14
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
14
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
15
deleted file mode 100644
16
index XXXXXXX..XXXXXXX
17
--- a/hw/display/omap_lcd_template.h
18
+++ /dev/null
19
@@ -XXX,XX +XXX,XX @@
20
-/*
21
- * QEMU OMAP LCD Emulator templates
22
- *
23
- * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
24
- *
25
- * Redistribution and use in source and binary forms, with or without
26
- * modification, are permitted provided that the following conditions
27
- * are met:
28
- *
29
- * 1. Redistributions of source code must retain the above copyright
30
- * notice, this list of conditions and the following disclaimer.
31
- * 2. Redistributions in binary form must reproduce the above copyright
32
- * notice, this list of conditions and the following disclaimer in
33
- * the documentation and/or other materials provided with the
34
- * distribution.
35
- *
36
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
37
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
38
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
40
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
41
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
42
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
43
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
- */
48
-
49
-/*
50
- * 2-bit colour
51
- */
52
-static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
53
- int width, int deststep)
54
-{
55
- uint16_t *pal = opaque;
56
- uint8_t v, r, g, b;
57
-
58
- do {
59
- v = ldub_p((void *) s);
60
- r = (pal[v & 3] >> 4) & 0xf0;
61
- g = pal[v & 3] & 0xf0;
62
- b = (pal[v & 3] << 4) & 0xf0;
63
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
64
- d += 4;
65
- v >>= 2;
66
- r = (pal[v & 3] >> 4) & 0xf0;
67
- g = pal[v & 3] & 0xf0;
68
- b = (pal[v & 3] << 4) & 0xf0;
69
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
70
- d += 4;
71
- v >>= 2;
72
- r = (pal[v & 3] >> 4) & 0xf0;
73
- g = pal[v & 3] & 0xf0;
74
- b = (pal[v & 3] << 4) & 0xf0;
75
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
76
- d += 4;
77
- v >>= 2;
78
- r = (pal[v & 3] >> 4) & 0xf0;
79
- g = pal[v & 3] & 0xf0;
80
- b = (pal[v & 3] << 4) & 0xf0;
81
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
82
- d += 4;
83
- s++;
84
- width -= 4;
85
- } while (width > 0);
86
-}
87
-
88
-/*
89
- * 4-bit colour
90
- */
91
-static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
92
- int width, int deststep)
93
-{
94
- uint16_t *pal = opaque;
95
- uint8_t v, r, g, b;
96
-
97
- do {
98
- v = ldub_p((void *) s);
99
- r = (pal[v & 0xf] >> 4) & 0xf0;
100
- g = pal[v & 0xf] & 0xf0;
101
- b = (pal[v & 0xf] << 4) & 0xf0;
102
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
103
- d += 4;
104
- v >>= 4;
105
- r = (pal[v & 0xf] >> 4) & 0xf0;
106
- g = pal[v & 0xf] & 0xf0;
107
- b = (pal[v & 0xf] << 4) & 0xf0;
108
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
109
- d += 4;
110
- s++;
111
- width -= 2;
112
- } while (width > 0);
113
-}
114
-
115
-/*
116
- * 8-bit colour
117
- */
118
-static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
119
- int width, int deststep)
120
-{
121
- uint16_t *pal = opaque;
122
- uint8_t v, r, g, b;
123
-
124
- do {
125
- v = ldub_p((void *) s);
126
- r = (pal[v] >> 4) & 0xf0;
127
- g = pal[v] & 0xf0;
128
- b = (pal[v] << 4) & 0xf0;
129
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
130
- s++;
131
- d += 4;
132
- } while (-- width != 0);
133
-}
134
-
135
-/*
136
- * 12-bit colour
137
- */
138
-static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
139
- int width, int deststep)
140
-{
141
- uint16_t v;
142
- uint8_t r, g, b;
143
-
144
- do {
145
- v = lduw_le_p((void *) s);
146
- r = (v >> 4) & 0xf0;
147
- g = v & 0xf0;
148
- b = (v << 4) & 0xf0;
149
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
150
- s += 2;
151
- d += 4;
152
- } while (-- width != 0);
153
-}
154
-
155
-/*
156
- * 16-bit colour
157
- */
158
-static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
159
- int width, int deststep)
160
-{
161
- uint16_t v;
162
- uint8_t r, g, b;
163
-
164
- do {
165
- v = lduw_le_p((void *) s);
166
- r = (v >> 8) & 0xf8;
167
- g = (v >> 3) & 0xfc;
168
- b = (v << 3) & 0xf8;
169
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
170
- s += 2;
171
- d += 4;
172
- } while (-- width != 0);
173
-}
174
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
175
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
176
--- a/hw/display/omap_lcdc.c
16
--- a/include/exec/cpu_ldst.h
177
+++ b/hw/display/omap_lcdc.c
17
+++ b/include/exec/cpu_ldst.h
178
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
18
@@ -XXX,XX +XXX,XX @@ typedef uint64_t abi_ptr;
179
19
/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
180
#define draw_line_func drawfn
20
#define g2h(x) ((void *)((uintptr_t)(abi_ptr)(x) + guest_base))
181
21
182
-#define DEPTH 32
22
-#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
183
-#include "omap_lcd_template.h"
23
-#define guest_addr_valid(x) (1)
184
+/*
24
-#else
185
+ * 2-bit colour
25
-#define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
186
+ */
26
-#endif
187
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
27
+static inline bool guest_addr_valid(abi_ulong x)
188
+ int width, int deststep)
189
+{
28
+{
190
+ uint16_t *pal = opaque;
29
+ return x <= GUEST_ADDR_MAX;
191
+ uint8_t v, r, g, b;
192
+
193
+ do {
194
+ v = ldub_p((void *) s);
195
+ r = (pal[v & 3] >> 4) & 0xf0;
196
+ g = pal[v & 3] & 0xf0;
197
+ b = (pal[v & 3] << 4) & 0xf0;
198
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
199
+ d += 4;
200
+ v >>= 2;
201
+ r = (pal[v & 3] >> 4) & 0xf0;
202
+ g = pal[v & 3] & 0xf0;
203
+ b = (pal[v & 3] << 4) & 0xf0;
204
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
205
+ d += 4;
206
+ v >>= 2;
207
+ r = (pal[v & 3] >> 4) & 0xf0;
208
+ g = pal[v & 3] & 0xf0;
209
+ b = (pal[v & 3] << 4) & 0xf0;
210
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
211
+ d += 4;
212
+ v >>= 2;
213
+ r = (pal[v & 3] >> 4) & 0xf0;
214
+ g = pal[v & 3] & 0xf0;
215
+ b = (pal[v & 3] << 4) & 0xf0;
216
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
217
+ d += 4;
218
+ s++;
219
+ width -= 4;
220
+ } while (width > 0);
221
+}
30
+}
222
+
31
223
+/*
32
static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
224
+ * 4-bit colour
225
+ */
226
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
227
+ int width, int deststep)
228
+{
229
+ uint16_t *pal = opaque;
230
+ uint8_t v, r, g, b;
231
+
232
+ do {
233
+ v = ldub_p((void *) s);
234
+ r = (pal[v & 0xf] >> 4) & 0xf0;
235
+ g = pal[v & 0xf] & 0xf0;
236
+ b = (pal[v & 0xf] << 4) & 0xf0;
237
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
238
+ d += 4;
239
+ v >>= 4;
240
+ r = (pal[v & 0xf] >> 4) & 0xf0;
241
+ g = pal[v & 0xf] & 0xf0;
242
+ b = (pal[v & 0xf] << 4) & 0xf0;
243
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
244
+ d += 4;
245
+ s++;
246
+ width -= 2;
247
+ } while (width > 0);
248
+}
249
+
250
+/*
251
+ * 8-bit colour
252
+ */
253
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
254
+ int width, int deststep)
255
+{
256
+ uint16_t *pal = opaque;
257
+ uint8_t v, r, g, b;
258
+
259
+ do {
260
+ v = ldub_p((void *) s);
261
+ r = (pal[v] >> 4) & 0xf0;
262
+ g = pal[v] & 0xf0;
263
+ b = (pal[v] << 4) & 0xf0;
264
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
265
+ s++;
266
+ d += 4;
267
+ } while (-- width != 0);
268
+}
269
+
270
+/*
271
+ * 12-bit colour
272
+ */
273
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
274
+ int width, int deststep)
275
+{
276
+ uint16_t v;
277
+ uint8_t r, g, b;
278
+
279
+ do {
280
+ v = lduw_le_p((void *) s);
281
+ r = (v >> 4) & 0xf0;
282
+ g = v & 0xf0;
283
+ b = (v << 4) & 0xf0;
284
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
285
+ s += 2;
286
+ d += 4;
287
+ } while (-- width != 0);
288
+}
289
+
290
+/*
291
+ * 16-bit colour
292
+ */
293
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
294
+ int width, int deststep)
295
+{
296
+ uint16_t v;
297
+ uint8_t r, g, b;
298
+
299
+ do {
300
+ v = lduw_le_p((void *) s);
301
+ r = (v >> 8) & 0xf8;
302
+ g = (v >> 3) & 0xfc;
303
+ b = (v << 3) & 0xf8;
304
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
305
+ s += 2;
306
+ d += 4;
307
+ } while (-- width != 0);
308
+}
309
310
static void omap_update_display(void *opaque)
311
{
33
{
312
--
34
--
313
2.20.1
35
2.20.1
314
36
315
37
diff view generated by jsdifflib
1
Update old infocenter.arm.com URLs to the equivalent developer.arm.com
1
From: Richard Henderson <richard.henderson@linaro.org>
2
ones (the old URLs should redirect, but we might as well avoid the
3
redirection notice, and the new URLs are pleasantly shorter).
4
2
5
This commit covers the links to the MPS2 board TRM, the various
3
Provide an identity fallback for target that do not
6
Application Notes, the IoTKit and SSE-200 documents.
4
use tagged addresses.
7
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210212184902.1251044-12-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210215115138.20465-25-peter.maydell@linaro.org
11
---
10
---
12
include/hw/arm/armsse.h | 4 ++--
11
include/exec/cpu_ldst.h | 7 +++++++
13
include/hw/misc/armsse-cpuid.h | 2 +-
12
1 file changed, 7 insertions(+)
14
include/hw/misc/armsse-mhu.h | 2 +-
15
include/hw/misc/iotkit-secctl.h | 2 +-
16
include/hw/misc/iotkit-sysctl.h | 2 +-
17
include/hw/misc/iotkit-sysinfo.h | 2 +-
18
include/hw/misc/mps2-fpgaio.h | 2 +-
19
hw/arm/mps2-tz.c | 11 +++++------
20
hw/misc/armsse-cpuid.c | 2 +-
21
hw/misc/armsse-mhu.c | 2 +-
22
hw/misc/iotkit-sysctl.c | 2 +-
23
hw/misc/iotkit-sysinfo.c | 2 +-
24
hw/misc/mps2-fpgaio.c | 2 +-
25
hw/misc/mps2-scc.c | 2 +-
26
14 files changed, 19 insertions(+), 20 deletions(-)
27
13
28
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
29
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/armsse.h
16
--- a/include/exec/cpu_ldst.h
31
+++ b/include/hw/arm/armsse.h
17
+++ b/include/exec/cpu_ldst.h
32
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ typedef uint64_t abi_ptr;
33
* hardware, which include the IoT Kit and the SSE-050, SSE-100 and
19
#define TARGET_ABI_FMT_ptr "%"PRIx64
34
* SSE-200. Currently we model:
20
#endif
35
* - the Arm IoT Kit which is documented in
21
36
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
22
+#ifndef TARGET_TAGGED_ADDRESSES
37
+ * https://developer.arm.com/documentation/ecm0601256/latest
23
+static inline abi_ptr cpu_untagged_addr(CPUState *cs, abi_ptr x)
38
* - the SSE-200 which is documented in
24
+{
39
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
25
+ return x;
40
+ * https://developer.arm.com/documentation/101104/latest/
26
+}
41
*
27
+#endif
42
* The IoTKit contains:
28
+
43
* a Cortex-M33
29
/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
44
diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h
30
#define g2h(x) ((void *)((uintptr_t)(abi_ptr)(x) + guest_base))
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/misc/armsse-cpuid.h
47
+++ b/include/hw/misc/armsse-cpuid.h
48
@@ -XXX,XX +XXX,XX @@
49
/*
50
* This is a model of the "CPU_IDENTITY" register block which is part of the
51
* Arm SSE-200 and documented in
52
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
53
+ * https://developer.arm.com/documentation/101104/latest/
54
*
55
* QEMU interface:
56
* + QOM property "CPUID": the value to use for the CPUID register
57
diff --git a/include/hw/misc/armsse-mhu.h b/include/hw/misc/armsse-mhu.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/include/hw/misc/armsse-mhu.h
60
+++ b/include/hw/misc/armsse-mhu.h
61
@@ -XXX,XX +XXX,XX @@
62
/*
63
* This is a model of the Message Handling Unit (MHU) which is part of the
64
* Arm SSE-200 and documented in
65
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
66
+ * https://developer.arm.com/documentation/101104/latest/
67
*
68
* QEMU interface:
69
* + sysbus MMIO region 0: the system information register bank
70
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/include/hw/misc/iotkit-secctl.h
73
+++ b/include/hw/misc/iotkit-secctl.h
74
@@ -XXX,XX +XXX,XX @@
75
76
/* This is a model of the security controller which is part of the
77
* Arm IoT Kit and documented in
78
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
79
+ * https://developer.arm.com/documentation/ecm0601256/latest
80
*
81
* QEMU interface:
82
* + sysbus MMIO region 0 is the "secure privilege control block" registers
83
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
84
index XXXXXXX..XXXXXXX 100644
85
--- a/include/hw/misc/iotkit-sysctl.h
86
+++ b/include/hw/misc/iotkit-sysctl.h
87
@@ -XXX,XX +XXX,XX @@
88
/*
89
* This is a model of the "system control element" which is part of the
90
* Arm IoTKit and documented in
91
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
92
+ * https://developer.arm.com/documentation/ecm0601256/latest
93
* Specifically, it implements the "system information block" and
94
* "system control register" blocks.
95
*
96
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
97
index XXXXXXX..XXXXXXX 100644
98
--- a/include/hw/misc/iotkit-sysinfo.h
99
+++ b/include/hw/misc/iotkit-sysinfo.h
100
@@ -XXX,XX +XXX,XX @@
101
/*
102
* This is a model of the "system information block" which is part of the
103
* Arm IoTKit and documented in
104
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
105
+ * https://developer.arm.com/documentation/ecm0601256/latest
106
* QEMU interface:
107
* + QOM property "SYS_VERSION": value to use for SYS_VERSION register
108
* + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register
109
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
110
index XXXXXXX..XXXXXXX 100644
111
--- a/include/hw/misc/mps2-fpgaio.h
112
+++ b/include/hw/misc/mps2-fpgaio.h
113
@@ -XXX,XX +XXX,XX @@
114
/* This is a model of the FPGAIO register block in the AN505
115
* FPGA image for the MPS2 dev board; it is documented in the
116
* application note:
117
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
118
+ * https://developer.arm.com/documentation/dai0505/latest/
119
*
120
* QEMU interface:
121
* + sysbus MMIO region 0: the register bank
122
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/arm/mps2-tz.c
125
+++ b/hw/arm/mps2-tz.c
126
@@ -XXX,XX +XXX,XX @@
127
* https://developer.arm.com/products/system-design/development-boards/fpga-prototyping-boards/mps2
128
*
129
* Board TRM:
130
- * http://infocenter.arm.com/help/topic/com.arm.doc.100112_0200_06_en/versatile_express_cortex_m_prototyping_systems_v2m_mps2_and_v2m_mps2plus_technical_reference_100112_0200_06_en.pdf
131
+ * https://developer.arm.com/documentation/100112/latest/
132
* Application Note AN505:
133
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
134
+ * https://developer.arm.com/documentation/dai0505/latest/
135
* Application Note AN521:
136
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
137
+ * https://developer.arm.com/documentation/dai0521/latest/
138
* Application Note AN524:
139
* https://developer.arm.com/documentation/dai0524/latest/
140
*
141
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
142
* (ARM ECM0601256) for the details of some of the device layout:
143
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
144
+ * https://developer.arm.com/documentation/ecm0601256/latest
145
* Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
146
* most of the device layout:
147
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
148
- *
149
+ * https://developer.arm.com/documentation/101104/latest/
150
*/
151
152
#include "qemu/osdep.h"
153
diff --git a/hw/misc/armsse-cpuid.c b/hw/misc/armsse-cpuid.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/misc/armsse-cpuid.c
156
+++ b/hw/misc/armsse-cpuid.c
157
@@ -XXX,XX +XXX,XX @@
158
/*
159
* This is a model of the "CPU_IDENTITY" register block which is part of the
160
* Arm SSE-200 and documented in
161
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
162
+ * https://developer.arm.com/documentation/101104/latest/
163
*
164
* It consists of one read-only CPUID register (set by QOM property), plus the
165
* usual ID registers.
166
diff --git a/hw/misc/armsse-mhu.c b/hw/misc/armsse-mhu.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/hw/misc/armsse-mhu.c
169
+++ b/hw/misc/armsse-mhu.c
170
@@ -XXX,XX +XXX,XX @@
171
/*
172
* This is a model of the Message Handling Unit (MHU) which is part of the
173
* Arm SSE-200 and documented in
174
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
175
+ * https://developer.arm.com/documentation/101104/latest/
176
*/
177
178
#include "qemu/osdep.h"
179
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
180
index XXXXXXX..XXXXXXX 100644
181
--- a/hw/misc/iotkit-sysctl.c
182
+++ b/hw/misc/iotkit-sysctl.c
183
@@ -XXX,XX +XXX,XX @@
184
/*
185
* This is a model of the "system control element" which is part of the
186
* Arm IoTKit and documented in
187
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
188
+ * https://developer.arm.com/documentation/ecm0601256/latest
189
* Specifically, it implements the "system control register" blocks.
190
*/
191
192
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/hw/misc/iotkit-sysinfo.c
195
+++ b/hw/misc/iotkit-sysinfo.c
196
@@ -XXX,XX +XXX,XX @@
197
/*
198
* This is a model of the "system information block" which is part of the
199
* Arm IoTKit and documented in
200
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
201
+ * https://developer.arm.com/documentation/ecm0601256/latest
202
* It consists of 2 read-only version/config registers, plus the
203
* usual ID registers.
204
*/
205
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/hw/misc/mps2-fpgaio.c
208
+++ b/hw/misc/mps2-fpgaio.c
209
@@ -XXX,XX +XXX,XX @@
210
/* This is a model of the "FPGA system control and I/O" block found
211
* in the AN505 FPGA image for the MPS2 devboard.
212
* It is documented in AN505:
213
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
214
+ * https://developer.arm.com/documentation/dai0505/latest/
215
*/
216
217
#include "qemu/osdep.h"
218
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/misc/mps2-scc.c
221
+++ b/hw/misc/mps2-scc.c
222
@@ -XXX,XX +XXX,XX @@
223
* found in the FPGA images of MPS2 development boards.
224
*
225
* Documentation of it can be found in the MPS2 TRM:
226
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100112_0100_03_en/index.html
227
+ * https://developer.arm.com/documentation/100112/latest/
228
* and also in the Application Notes documenting individual FPGA images.
229
*/
230
31
231
--
32
--
232
2.20.1
33
2.20.1
233
34
234
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Always perform one call instead of two for 16-byte operands.
3
Use g2h_untagged in contexts that have no cpu, e.g. the binary
4
Use byte loads/stores directly into the vector register file
4
loaders that operate before the primary cpu is created. As a
5
instead of extractions and deposits to a 64-bit local variable.
5
colollary, target_mmap and friends must use untagged addresses,
6
since they are used by the loaders.
6
7
7
In order to easily receive pointers into the vector register file,
8
Use g2h_untagged on values returned from target_mmap, as the
8
convert the helper to the gvec out-of-line signature. Move the
9
kernel never applies a tag itself.
9
helper into vec_helper.c, where it can make use of H1 and clear_tail.
10
10
11
Use g2h_untagged on all pc values. The only current user of
12
tags, aarch64, removes tags from code addresses upon branch,
13
so "pc" is always untagged.
14
15
Use g2h with the cpu context on hand wherever possible.
16
17
Use g2h_untagged in lock_user, which will be updated soon.
18
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
21
Message-id: 20210212184902.1251044-13-richard.henderson@linaro.org
13
Tested-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 20210224230532.276878-1-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
23
---
17
target/arm/helper-a64.h | 2 +-
24
bsd-user/qemu.h | 8 ++--
18
target/arm/helper-a64.c | 32 ---------------------
25
include/exec/cpu_ldst.h | 12 +++++-
19
target/arm/translate-a64.c | 58 +++++---------------------------------
26
include/exec/exec-all.h | 2 +-
20
target/arm/vec_helper.c | 48 +++++++++++++++++++++++++++++++
27
linux-user/qemu.h | 6 +--
21
4 files changed, 56 insertions(+), 84 deletions(-)
28
accel/tcg/translate-all.c | 4 +-
29
accel/tcg/user-exec.c | 48 ++++++++++++------------
30
bsd-user/elfload.c | 2 +-
31
bsd-user/main.c | 4 +-
32
bsd-user/mmap.c | 23 ++++++------
33
linux-user/elfload.c | 12 +++---
34
linux-user/flatload.c | 2 +-
35
linux-user/hppa/cpu_loop.c | 31 ++++++++--------
36
linux-user/i386/cpu_loop.c | 4 +-
37
linux-user/mmap.c | 45 +++++++++++-----------
38
linux-user/ppc/signal.c | 4 +-
39
linux-user/syscall.c | 72 +++++++++++++++++++-----------------
40
target/arm/helper-a64.c | 4 +-
41
target/hppa/op_helper.c | 2 +-
42
target/i386/tcg/mem_helper.c | 2 +-
43
target/s390x/mem_helper.c | 4 +-
44
20 files changed, 154 insertions(+), 137 deletions(-)
22
45
23
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
46
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
24
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-a64.h
48
--- a/bsd-user/qemu.h
26
+++ b/target/arm/helper-a64.h
49
+++ b/bsd-user/qemu.h
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
50
@@ -XXX,XX +XXX,XX @@ static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy
28
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
51
void *addr;
29
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
52
addr = g_malloc(len);
30
DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr)
53
if (copy)
31
-DEF_HELPER_FLAGS_5(simd_tbl, TCG_CALL_NO_RWG_SE, i64, env, i64, i64, i32, i32)
54
- memcpy(addr, g2h(guest_addr), len);
32
+DEF_HELPER_FLAGS_4(simd_tblx, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
55
+ memcpy(addr, g2h_untagged(guest_addr), len);
33
DEF_HELPER_FLAGS_3(vfp_mulxs, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
56
else
34
DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
57
memset(addr, 0, len);
35
DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
58
return addr;
59
}
60
#else
61
- return g2h(guest_addr);
62
+ return g2h_untagged(guest_addr);
63
#endif
64
}
65
66
@@ -XXX,XX +XXX,XX @@ static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
67
#ifdef DEBUG_REMAP
68
if (!host_ptr)
69
return;
70
- if (host_ptr == g2h(guest_addr))
71
+ if (host_ptr == g2h_untagged(guest_addr))
72
return;
73
if (len > 0)
74
- memcpy(g2h(guest_addr), host_ptr, len);
75
+ memcpy(g2h_untagged(guest_addr), host_ptr, len);
76
g_free(host_ptr);
77
#endif
78
}
79
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
80
index XXXXXXX..XXXXXXX 100644
81
--- a/include/exec/cpu_ldst.h
82
+++ b/include/exec/cpu_ldst.h
83
@@ -XXX,XX +XXX,XX @@ static inline abi_ptr cpu_untagged_addr(CPUState *cs, abi_ptr x)
84
#endif
85
86
/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
87
-#define g2h(x) ((void *)((uintptr_t)(abi_ptr)(x) + guest_base))
88
+static inline void *g2h_untagged(abi_ptr x)
89
+{
90
+ return (void *)((uintptr_t)(x) + guest_base);
91
+}
92
+
93
+static inline void *g2h(CPUState *cs, abi_ptr x)
94
+{
95
+ return g2h_untagged(cpu_untagged_addr(cs, x));
96
+}
97
98
static inline bool guest_addr_valid(abi_ulong x)
99
{
100
@@ -XXX,XX +XXX,XX @@ static inline int cpu_ldsw_code(CPUArchState *env, abi_ptr addr)
101
static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
102
MMUAccessType access_type, int mmu_idx)
103
{
104
- return g2h(addr);
105
+ return g2h(env_cpu(env), addr);
106
}
107
#else
108
void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
109
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
110
index XXXXXXX..XXXXXXX 100644
111
--- a/include/exec/exec-all.h
112
+++ b/include/exec/exec-all.h
113
@@ -XXX,XX +XXX,XX @@ static inline tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env,
114
void **hostp)
115
{
116
if (hostp) {
117
- *hostp = g2h(addr);
118
+ *hostp = g2h_untagged(addr);
119
}
120
return addr;
121
}
122
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
123
index XXXXXXX..XXXXXXX 100644
124
--- a/linux-user/qemu.h
125
+++ b/linux-user/qemu.h
126
@@ -XXX,XX +XXX,XX @@ static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy
127
return addr;
128
}
129
#else
130
- return g2h(guest_addr);
131
+ return g2h_untagged(guest_addr);
132
#endif
133
}
134
135
@@ -XXX,XX +XXX,XX @@ static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
136
#ifdef DEBUG_REMAP
137
if (!host_ptr)
138
return;
139
- if (host_ptr == g2h(guest_addr))
140
+ if (host_ptr == g2h_untagged(guest_addr))
141
return;
142
if (len > 0)
143
- memcpy(g2h(guest_addr), host_ptr, len);
144
+ memcpy(g2h_untagged(guest_addr), host_ptr, len);
145
g_free(host_ptr);
146
#endif
147
}
148
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/accel/tcg/translate-all.c
151
+++ b/accel/tcg/translate-all.c
152
@@ -XXX,XX +XXX,XX @@ static inline void tb_page_add(PageDesc *p, TranslationBlock *tb,
153
prot |= p2->flags;
154
p2->flags &= ~PAGE_WRITE;
155
}
156
- mprotect(g2h(page_addr), qemu_host_page_size,
157
+ mprotect(g2h_untagged(page_addr), qemu_host_page_size,
158
(prot & PAGE_BITS) & ~PAGE_WRITE);
159
if (DEBUG_TB_INVALIDATE_GATE) {
160
printf("protecting code page: 0x" TB_PAGE_ADDR_FMT "\n", page_addr);
161
@@ -XXX,XX +XXX,XX @@ int page_unprotect(target_ulong address, uintptr_t pc)
162
}
163
#endif
164
}
165
- mprotect((void *)g2h(host_start), qemu_host_page_size,
166
+ mprotect((void *)g2h_untagged(host_start), qemu_host_page_size,
167
prot & PAGE_BITS);
168
}
169
mmap_unlock();
170
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/accel/tcg/user-exec.c
173
+++ b/accel/tcg/user-exec.c
174
@@ -XXX,XX +XXX,XX @@ int probe_access_flags(CPUArchState *env, target_ulong addr,
175
int flags;
176
177
flags = probe_access_internal(env, addr, 0, access_type, nonfault, ra);
178
- *phost = flags ? NULL : g2h(addr);
179
+ *phost = flags ? NULL : g2h(env_cpu(env), addr);
180
return flags;
181
}
182
183
@@ -XXX,XX +XXX,XX @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
184
flags = probe_access_internal(env, addr, size, access_type, false, ra);
185
g_assert(flags == 0);
186
187
- return size ? g2h(addr) : NULL;
188
+ return size ? g2h(env_cpu(env), addr) : NULL;
189
}
190
191
#if defined(__i386__)
192
@@ -XXX,XX +XXX,XX @@ uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr)
193
uint16_t meminfo = trace_mem_get_info(MO_UB, MMU_USER_IDX, false);
194
195
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
196
- ret = ldub_p(g2h(ptr));
197
+ ret = ldub_p(g2h(env_cpu(env), ptr));
198
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
199
return ret;
200
}
201
@@ -XXX,XX +XXX,XX @@ int cpu_ldsb_data(CPUArchState *env, abi_ptr ptr)
202
uint16_t meminfo = trace_mem_get_info(MO_SB, MMU_USER_IDX, false);
203
204
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
205
- ret = ldsb_p(g2h(ptr));
206
+ ret = ldsb_p(g2h(env_cpu(env), ptr));
207
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
208
return ret;
209
}
210
@@ -XXX,XX +XXX,XX @@ uint32_t cpu_lduw_be_data(CPUArchState *env, abi_ptr ptr)
211
uint16_t meminfo = trace_mem_get_info(MO_BEUW, MMU_USER_IDX, false);
212
213
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
214
- ret = lduw_be_p(g2h(ptr));
215
+ ret = lduw_be_p(g2h(env_cpu(env), ptr));
216
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
217
return ret;
218
}
219
@@ -XXX,XX +XXX,XX @@ int cpu_ldsw_be_data(CPUArchState *env, abi_ptr ptr)
220
uint16_t meminfo = trace_mem_get_info(MO_BESW, MMU_USER_IDX, false);
221
222
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
223
- ret = ldsw_be_p(g2h(ptr));
224
+ ret = ldsw_be_p(g2h(env_cpu(env), ptr));
225
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
226
return ret;
227
}
228
@@ -XXX,XX +XXX,XX @@ uint32_t cpu_ldl_be_data(CPUArchState *env, abi_ptr ptr)
229
uint16_t meminfo = trace_mem_get_info(MO_BEUL, MMU_USER_IDX, false);
230
231
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
232
- ret = ldl_be_p(g2h(ptr));
233
+ ret = ldl_be_p(g2h(env_cpu(env), ptr));
234
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
235
return ret;
236
}
237
@@ -XXX,XX +XXX,XX @@ uint64_t cpu_ldq_be_data(CPUArchState *env, abi_ptr ptr)
238
uint16_t meminfo = trace_mem_get_info(MO_BEQ, MMU_USER_IDX, false);
239
240
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
241
- ret = ldq_be_p(g2h(ptr));
242
+ ret = ldq_be_p(g2h(env_cpu(env), ptr));
243
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
244
return ret;
245
}
246
@@ -XXX,XX +XXX,XX @@ uint32_t cpu_lduw_le_data(CPUArchState *env, abi_ptr ptr)
247
uint16_t meminfo = trace_mem_get_info(MO_LEUW, MMU_USER_IDX, false);
248
249
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
250
- ret = lduw_le_p(g2h(ptr));
251
+ ret = lduw_le_p(g2h(env_cpu(env), ptr));
252
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
253
return ret;
254
}
255
@@ -XXX,XX +XXX,XX @@ int cpu_ldsw_le_data(CPUArchState *env, abi_ptr ptr)
256
uint16_t meminfo = trace_mem_get_info(MO_LESW, MMU_USER_IDX, false);
257
258
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
259
- ret = ldsw_le_p(g2h(ptr));
260
+ ret = ldsw_le_p(g2h(env_cpu(env), ptr));
261
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
262
return ret;
263
}
264
@@ -XXX,XX +XXX,XX @@ uint32_t cpu_ldl_le_data(CPUArchState *env, abi_ptr ptr)
265
uint16_t meminfo = trace_mem_get_info(MO_LEUL, MMU_USER_IDX, false);
266
267
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
268
- ret = ldl_le_p(g2h(ptr));
269
+ ret = ldl_le_p(g2h(env_cpu(env), ptr));
270
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
271
return ret;
272
}
273
@@ -XXX,XX +XXX,XX @@ uint64_t cpu_ldq_le_data(CPUArchState *env, abi_ptr ptr)
274
uint16_t meminfo = trace_mem_get_info(MO_LEQ, MMU_USER_IDX, false);
275
276
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
277
- ret = ldq_le_p(g2h(ptr));
278
+ ret = ldq_le_p(g2h(env_cpu(env), ptr));
279
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
280
return ret;
281
}
282
@@ -XXX,XX +XXX,XX @@ void cpu_stb_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
283
uint16_t meminfo = trace_mem_get_info(MO_UB, MMU_USER_IDX, true);
284
285
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
286
- stb_p(g2h(ptr), val);
287
+ stb_p(g2h(env_cpu(env), ptr), val);
288
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
289
}
290
291
@@ -XXX,XX +XXX,XX @@ void cpu_stw_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
292
uint16_t meminfo = trace_mem_get_info(MO_BEUW, MMU_USER_IDX, true);
293
294
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
295
- stw_be_p(g2h(ptr), val);
296
+ stw_be_p(g2h(env_cpu(env), ptr), val);
297
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
298
}
299
300
@@ -XXX,XX +XXX,XX @@ void cpu_stl_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
301
uint16_t meminfo = trace_mem_get_info(MO_BEUL, MMU_USER_IDX, true);
302
303
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
304
- stl_be_p(g2h(ptr), val);
305
+ stl_be_p(g2h(env_cpu(env), ptr), val);
306
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
307
}
308
309
@@ -XXX,XX +XXX,XX @@ void cpu_stq_be_data(CPUArchState *env, abi_ptr ptr, uint64_t val)
310
uint16_t meminfo = trace_mem_get_info(MO_BEQ, MMU_USER_IDX, true);
311
312
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
313
- stq_be_p(g2h(ptr), val);
314
+ stq_be_p(g2h(env_cpu(env), ptr), val);
315
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
316
}
317
318
@@ -XXX,XX +XXX,XX @@ void cpu_stw_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
319
uint16_t meminfo = trace_mem_get_info(MO_LEUW, MMU_USER_IDX, true);
320
321
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
322
- stw_le_p(g2h(ptr), val);
323
+ stw_le_p(g2h(env_cpu(env), ptr), val);
324
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
325
}
326
327
@@ -XXX,XX +XXX,XX @@ void cpu_stl_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
328
uint16_t meminfo = trace_mem_get_info(MO_LEUL, MMU_USER_IDX, true);
329
330
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
331
- stl_le_p(g2h(ptr), val);
332
+ stl_le_p(g2h(env_cpu(env), ptr), val);
333
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
334
}
335
336
@@ -XXX,XX +XXX,XX @@ void cpu_stq_le_data(CPUArchState *env, abi_ptr ptr, uint64_t val)
337
uint16_t meminfo = trace_mem_get_info(MO_LEQ, MMU_USER_IDX, true);
338
339
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
340
- stq_le_p(g2h(ptr), val);
341
+ stq_le_p(g2h(env_cpu(env), ptr), val);
342
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
343
}
344
345
@@ -XXX,XX +XXX,XX @@ uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr ptr)
346
uint32_t ret;
347
348
set_helper_retaddr(1);
349
- ret = ldub_p(g2h(ptr));
350
+ ret = ldub_p(g2h_untagged(ptr));
351
clear_helper_retaddr();
352
return ret;
353
}
354
@@ -XXX,XX +XXX,XX @@ uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr ptr)
355
uint32_t ret;
356
357
set_helper_retaddr(1);
358
- ret = lduw_p(g2h(ptr));
359
+ ret = lduw_p(g2h_untagged(ptr));
360
clear_helper_retaddr();
361
return ret;
362
}
363
@@ -XXX,XX +XXX,XX @@ uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr ptr)
364
uint32_t ret;
365
366
set_helper_retaddr(1);
367
- ret = ldl_p(g2h(ptr));
368
+ ret = ldl_p(g2h_untagged(ptr));
369
clear_helper_retaddr();
370
return ret;
371
}
372
@@ -XXX,XX +XXX,XX @@ uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr ptr)
373
uint64_t ret;
374
375
set_helper_retaddr(1);
376
- ret = ldq_p(g2h(ptr));
377
+ ret = ldq_p(g2h_untagged(ptr));
378
clear_helper_retaddr();
379
return ret;
380
}
381
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
382
if (unlikely(addr & (size - 1))) {
383
cpu_loop_exit_atomic(env_cpu(env), retaddr);
384
}
385
- void *ret = g2h(addr);
386
+ void *ret = g2h(env_cpu(env), addr);
387
set_helper_retaddr(retaddr);
388
return ret;
389
}
390
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
391
index XXXXXXX..XXXXXXX 100644
392
--- a/bsd-user/elfload.c
393
+++ b/bsd-user/elfload.c
394
@@ -XXX,XX +XXX,XX @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
395
end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
396
end_addr = HOST_PAGE_ALIGN(elf_bss);
397
if (end_addr1 < end_addr) {
398
- mmap((void *)g2h(end_addr1), end_addr - end_addr1,
399
+ mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
400
PROT_READ|PROT_WRITE|PROT_EXEC,
401
MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0);
402
}
403
diff --git a/bsd-user/main.c b/bsd-user/main.c
404
index XXXXXXX..XXXXXXX 100644
405
--- a/bsd-user/main.c
406
+++ b/bsd-user/main.c
407
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
408
env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
409
PROT_READ|PROT_WRITE,
410
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
411
- idt_table = g2h(env->idt.base);
412
+ idt_table = g2h_untagged(env->idt.base);
413
set_idt(0, 0);
414
set_idt(1, 0);
415
set_idt(2, 0);
416
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
417
PROT_READ|PROT_WRITE,
418
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
419
env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
420
- gdt_table = g2h(env->gdt.base);
421
+ gdt_table = g2h_untagged(env->gdt.base);
422
#ifdef TARGET_ABI32
423
write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
424
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
425
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
426
index XXXXXXX..XXXXXXX 100644
427
--- a/bsd-user/mmap.c
428
+++ b/bsd-user/mmap.c
429
@@ -XXX,XX +XXX,XX @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
430
}
431
end = host_end;
432
}
433
- ret = mprotect(g2h(host_start), qemu_host_page_size, prot1 & PAGE_BITS);
434
+ ret = mprotect(g2h_untagged(host_start),
435
+ qemu_host_page_size, prot1 & PAGE_BITS);
436
if (ret != 0)
437
goto error;
438
host_start += qemu_host_page_size;
439
@@ -XXX,XX +XXX,XX @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
440
for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
441
prot1 |= page_get_flags(addr);
442
}
443
- ret = mprotect(g2h(host_end - qemu_host_page_size), qemu_host_page_size,
444
- prot1 & PAGE_BITS);
445
+ ret = mprotect(g2h_untagged(host_end - qemu_host_page_size),
446
+ qemu_host_page_size, prot1 & PAGE_BITS);
447
if (ret != 0)
448
goto error;
449
host_end -= qemu_host_page_size;
450
@@ -XXX,XX +XXX,XX @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
451
452
/* handle the pages in the middle */
453
if (host_start < host_end) {
454
- ret = mprotect(g2h(host_start), host_end - host_start, prot);
455
+ ret = mprotect(g2h_untagged(host_start), host_end - host_start, prot);
456
if (ret != 0)
457
goto error;
458
}
459
@@ -XXX,XX +XXX,XX @@ static int mmap_frag(abi_ulong real_start,
460
int prot1, prot_new;
461
462
real_end = real_start + qemu_host_page_size;
463
- host_start = g2h(real_start);
464
+ host_start = g2h_untagged(real_start);
465
466
/* get the protection of the target pages outside the mapping */
467
prot1 = 0;
468
@@ -XXX,XX +XXX,XX @@ static int mmap_frag(abi_ulong real_start,
469
mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
470
471
/* read the corresponding file data */
472
- pread(fd, g2h(start), end - start, offset);
473
+ pread(fd, g2h_untagged(start), end - start, offset);
474
475
/* put final protection */
476
if (prot_new != (prot1 | PROT_WRITE))
477
@@ -XXX,XX +XXX,XX @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
478
/* Note: we prefer to control the mapping address. It is
479
especially important if qemu_host_page_size >
480
qemu_real_host_page_size */
481
- p = mmap(g2h(mmap_start),
482
+ p = mmap(g2h_untagged(mmap_start),
483
host_len, prot, flags | MAP_FIXED, fd, host_offset);
484
if (p == MAP_FAILED)
485
goto fail;
486
@@ -XXX,XX +XXX,XX @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
487
-1, 0);
488
if (retaddr == -1)
489
goto fail;
490
- pread(fd, g2h(start), len, offset);
491
+ pread(fd, g2h_untagged(start), len, offset);
492
if (!(prot & PROT_WRITE)) {
493
ret = target_mprotect(start, len, prot);
494
if (ret != 0) {
495
@@ -XXX,XX +XXX,XX @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
496
offset1 = 0;
497
else
498
offset1 = offset + real_start - start;
499
- p = mmap(g2h(real_start), real_end - real_start,
500
+ p = mmap(g2h_untagged(real_start), real_end - real_start,
501
prot, flags, fd, offset1);
502
if (p == MAP_FAILED)
503
goto fail;
504
@@ -XXX,XX +XXX,XX @@ int target_munmap(abi_ulong start, abi_ulong len)
505
ret = 0;
506
/* unmap what we can */
507
if (real_start < real_end) {
508
- ret = munmap(g2h(real_start), real_end - real_start);
509
+ ret = munmap(g2h_untagged(real_start), real_end - real_start);
510
}
511
512
if (ret == 0)
513
@@ -XXX,XX +XXX,XX @@ int target_msync(abi_ulong start, abi_ulong len, int flags)
514
return 0;
515
516
start &= qemu_host_page_mask;
517
- return msync(g2h(start), end - start, flags);
518
+ return msync(g2h_untagged(start), end - start, flags);
519
}
520
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
521
index XXXXXXX..XXXXXXX 100644
522
--- a/linux-user/elfload.c
523
+++ b/linux-user/elfload.c
524
@@ -XXX,XX +XXX,XX @@ enum {
525
526
static bool init_guest_commpage(void)
527
{
528
- void *want = g2h(ARM_COMMPAGE & -qemu_host_page_size);
529
+ void *want = g2h_untagged(ARM_COMMPAGE & -qemu_host_page_size);
530
void *addr = mmap(want, qemu_host_page_size, PROT_READ | PROT_WRITE,
531
MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
532
533
@@ -XXX,XX +XXX,XX @@ static bool init_guest_commpage(void)
534
}
535
536
/* Set kernel helper versions; rest of page is 0. */
537
- __put_user(5, (uint32_t *)g2h(0xffff0ffcu));
538
+ __put_user(5, (uint32_t *)g2h_untagged(0xffff0ffcu));
539
540
if (mprotect(addr, qemu_host_page_size, PROT_READ)) {
541
perror("Protecting guest commpage");
542
@@ -XXX,XX +XXX,XX @@ static void zero_bss(abi_ulong elf_bss, abi_ulong last_bss, int prot)
543
here is still actually needed. For now, continue with it,
544
but merge it with the "normal" mmap that would allocate the bss. */
545
546
- host_start = (uintptr_t) g2h(elf_bss);
547
- host_end = (uintptr_t) g2h(last_bss);
548
+ host_start = (uintptr_t) g2h_untagged(elf_bss);
549
+ host_end = (uintptr_t) g2h_untagged(last_bss);
550
host_map_start = REAL_HOST_PAGE_ALIGN(host_start);
551
552
if (host_map_start < host_end) {
553
@@ -XXX,XX +XXX,XX @@ static void pgb_have_guest_base(const char *image_name, abi_ulong guest_loaddr,
554
}
555
556
/* Reserve the address space for the binary, or reserved_va. */
557
- test = g2h(guest_loaddr);
558
+ test = g2h_untagged(guest_loaddr);
559
addr = mmap(test, guest_hiaddr - guest_loaddr, PROT_NONE, flags, -1, 0);
560
if (test != addr) {
561
pgb_fail_in_use(image_name);
562
@@ -XXX,XX +XXX,XX @@ static void pgb_reserved_va(const char *image_name, abi_ulong guest_loaddr,
563
564
/* Reserve the memory on the host. */
565
assert(guest_base != 0);
566
- test = g2h(0);
567
+ test = g2h_untagged(0);
568
addr = mmap(test, reserved_va, PROT_NONE, flags, -1, 0);
569
if (addr == MAP_FAILED || addr != test) {
570
error_report("Unable to reserve 0x%lx bytes of virtual address "
571
diff --git a/linux-user/flatload.c b/linux-user/flatload.c
572
index XXXXXXX..XXXXXXX 100644
573
--- a/linux-user/flatload.c
574
+++ b/linux-user/flatload.c
575
@@ -XXX,XX +XXX,XX @@ static int load_flat_file(struct linux_binprm * bprm,
576
}
577
578
/* zero the BSS. */
579
- memset(g2h(datapos + data_len), 0, bss_len);
580
+ memset(g2h_untagged(datapos + data_len), 0, bss_len);
581
582
return 0;
583
}
584
diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
585
index XXXXXXX..XXXXXXX 100644
586
--- a/linux-user/hppa/cpu_loop.c
587
+++ b/linux-user/hppa/cpu_loop.c
588
@@ -XXX,XX +XXX,XX @@
589
590
static abi_ulong hppa_lws(CPUHPPAState *env)
591
{
592
+ CPUState *cs = env_cpu(env);
593
uint32_t which = env->gr[20];
594
abi_ulong addr = env->gr[26];
595
abi_ulong old = env->gr[25];
596
@@ -XXX,XX +XXX,XX @@ static abi_ulong hppa_lws(CPUHPPAState *env)
597
}
598
old = tswap32(old);
599
new = tswap32(new);
600
- ret = qatomic_cmpxchg((uint32_t *)g2h(addr), old, new);
601
+ ret = qatomic_cmpxchg((uint32_t *)g2h(cs, addr), old, new);
602
ret = tswap32(ret);
603
break;
604
605
@@ -XXX,XX +XXX,XX @@ static abi_ulong hppa_lws(CPUHPPAState *env)
606
can be host-endian as well. */
607
switch (size) {
608
case 0:
609
- old = *(uint8_t *)g2h(old);
610
- new = *(uint8_t *)g2h(new);
611
- ret = qatomic_cmpxchg((uint8_t *)g2h(addr), old, new);
612
+ old = *(uint8_t *)g2h(cs, old);
613
+ new = *(uint8_t *)g2h(cs, new);
614
+ ret = qatomic_cmpxchg((uint8_t *)g2h(cs, addr), old, new);
615
ret = ret != old;
616
break;
617
case 1:
618
- old = *(uint16_t *)g2h(old);
619
- new = *(uint16_t *)g2h(new);
620
- ret = qatomic_cmpxchg((uint16_t *)g2h(addr), old, new);
621
+ old = *(uint16_t *)g2h(cs, old);
622
+ new = *(uint16_t *)g2h(cs, new);
623
+ ret = qatomic_cmpxchg((uint16_t *)g2h(cs, addr), old, new);
624
ret = ret != old;
625
break;
626
case 2:
627
- old = *(uint32_t *)g2h(old);
628
- new = *(uint32_t *)g2h(new);
629
- ret = qatomic_cmpxchg((uint32_t *)g2h(addr), old, new);
630
+ old = *(uint32_t *)g2h(cs, old);
631
+ new = *(uint32_t *)g2h(cs, new);
632
+ ret = qatomic_cmpxchg((uint32_t *)g2h(cs, addr), old, new);
633
ret = ret != old;
634
break;
635
case 3:
636
{
637
uint64_t o64, n64, r64;
638
- o64 = *(uint64_t *)g2h(old);
639
- n64 = *(uint64_t *)g2h(new);
640
+ o64 = *(uint64_t *)g2h(cs, old);
641
+ n64 = *(uint64_t *)g2h(cs, new);
642
#ifdef CONFIG_ATOMIC64
643
- r64 = qatomic_cmpxchg__nocheck((uint64_t *)g2h(addr),
644
+ r64 = qatomic_cmpxchg__nocheck((uint64_t *)g2h(cs, addr),
645
o64, n64);
646
ret = r64 != o64;
647
#else
648
start_exclusive();
649
- r64 = *(uint64_t *)g2h(addr);
650
+ r64 = *(uint64_t *)g2h(cs, addr);
651
ret = 1;
652
if (r64 == o64) {
653
- *(uint64_t *)g2h(addr) = n64;
654
+ *(uint64_t *)g2h(cs, addr) = n64;
655
ret = 0;
656
}
657
end_exclusive();
658
diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
659
index XXXXXXX..XXXXXXX 100644
660
--- a/linux-user/i386/cpu_loop.c
661
+++ b/linux-user/i386/cpu_loop.c
662
@@ -XXX,XX +XXX,XX @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
663
env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
664
PROT_READ|PROT_WRITE,
665
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
666
- idt_table = g2h(env->idt.base);
667
+ idt_table = g2h_untagged(env->idt.base);
668
set_idt(0, 0);
669
set_idt(1, 0);
670
set_idt(2, 0);
671
@@ -XXX,XX +XXX,XX @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
672
PROT_READ|PROT_WRITE,
673
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
674
env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
675
- gdt_table = g2h(env->gdt.base);
676
+ gdt_table = g2h_untagged(env->gdt.base);
677
#ifdef TARGET_ABI32
678
write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
679
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
680
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
681
index XXXXXXX..XXXXXXX 100644
682
--- a/linux-user/mmap.c
683
+++ b/linux-user/mmap.c
684
@@ -XXX,XX +XXX,XX @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
685
}
686
end = host_end;
687
}
688
- ret = mprotect(g2h(host_start), qemu_host_page_size,
689
+ ret = mprotect(g2h_untagged(host_start), qemu_host_page_size,
690
prot1 & PAGE_BITS);
691
if (ret != 0) {
692
goto error;
693
@@ -XXX,XX +XXX,XX @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
694
for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
695
prot1 |= page_get_flags(addr);
696
}
697
- ret = mprotect(g2h(host_end - qemu_host_page_size),
698
+ ret = mprotect(g2h_untagged(host_end - qemu_host_page_size),
699
qemu_host_page_size, prot1 & PAGE_BITS);
700
if (ret != 0) {
701
goto error;
702
@@ -XXX,XX +XXX,XX @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
703
704
/* handle the pages in the middle */
705
if (host_start < host_end) {
706
- ret = mprotect(g2h(host_start), host_end - host_start, host_prot);
707
+ ret = mprotect(g2h_untagged(host_start),
708
+ host_end - host_start, host_prot);
709
if (ret != 0) {
710
goto error;
711
}
712
@@ -XXX,XX +XXX,XX @@ static int mmap_frag(abi_ulong real_start,
713
int prot1, prot_new;
714
715
real_end = real_start + qemu_host_page_size;
716
- host_start = g2h(real_start);
717
+ host_start = g2h_untagged(real_start);
718
719
/* get the protection of the target pages outside the mapping */
720
prot1 = 0;
721
@@ -XXX,XX +XXX,XX @@ static int mmap_frag(abi_ulong real_start,
722
mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
723
724
/* read the corresponding file data */
725
- if (pread(fd, g2h(start), end - start, offset) == -1)
726
+ if (pread(fd, g2h_untagged(start), end - start, offset) == -1)
727
return -1;
728
729
/* put final protection */
730
@@ -XXX,XX +XXX,XX @@ static int mmap_frag(abi_ulong real_start,
731
mprotect(host_start, qemu_host_page_size, prot_new);
732
}
733
if (prot_new & PROT_WRITE) {
734
- memset(g2h(start), 0, end - start);
735
+ memset(g2h_untagged(start), 0, end - start);
736
}
737
}
738
return 0;
739
@@ -XXX,XX +XXX,XX @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
740
* - mremap() with MREMAP_FIXED flag
741
* - shmat() with SHM_REMAP flag
742
*/
743
- ptr = mmap(g2h(addr), size, PROT_NONE,
744
+ ptr = mmap(g2h_untagged(addr), size, PROT_NONE,
745
MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
746
747
/* ENOMEM, if host address space has no memory */
748
@@ -XXX,XX +XXX,XX @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
749
/* Note: we prefer to control the mapping address. It is
750
especially important if qemu_host_page_size >
751
qemu_real_host_page_size */
752
- p = mmap(g2h(start), host_len, host_prot,
753
+ p = mmap(g2h_untagged(start), host_len, host_prot,
754
flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
755
if (p == MAP_FAILED) {
756
goto fail;
757
@@ -XXX,XX +XXX,XX @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
758
/* update start so that it points to the file position at 'offset' */
759
host_start = (unsigned long)p;
760
if (!(flags & MAP_ANONYMOUS)) {
761
- p = mmap(g2h(start), len, host_prot,
762
+ p = mmap(g2h_untagged(start), len, host_prot,
763
flags | MAP_FIXED, fd, host_offset);
764
if (p == MAP_FAILED) {
765
- munmap(g2h(start), host_len);
766
+ munmap(g2h_untagged(start), host_len);
767
goto fail;
768
}
769
host_start += offset - host_offset;
770
@@ -XXX,XX +XXX,XX @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
771
-1, 0);
772
if (retaddr == -1)
773
goto fail;
774
- if (pread(fd, g2h(start), len, offset) == -1)
775
+ if (pread(fd, g2h_untagged(start), len, offset) == -1)
776
goto fail;
777
if (!(host_prot & PROT_WRITE)) {
778
ret = target_mprotect(start, len, target_prot);
779
@@ -XXX,XX +XXX,XX @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
780
offset1 = 0;
781
else
782
offset1 = offset + real_start - start;
783
- p = mmap(g2h(real_start), real_end - real_start,
784
+ p = mmap(g2h_untagged(real_start), real_end - real_start,
785
host_prot, flags, fd, offset1);
786
if (p == MAP_FAILED)
787
goto fail;
788
@@ -XXX,XX +XXX,XX @@ static void mmap_reserve(abi_ulong start, abi_ulong size)
789
real_end -= qemu_host_page_size;
790
}
791
if (real_start != real_end) {
792
- mmap(g2h(real_start), real_end - real_start, PROT_NONE,
793
+ mmap(g2h_untagged(real_start), real_end - real_start, PROT_NONE,
794
MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE,
795
-1, 0);
796
}
797
@@ -XXX,XX +XXX,XX @@ int target_munmap(abi_ulong start, abi_ulong len)
798
if (reserved_va) {
799
mmap_reserve(real_start, real_end - real_start);
800
} else {
801
- ret = munmap(g2h(real_start), real_end - real_start);
802
+ ret = munmap(g2h_untagged(real_start), real_end - real_start);
803
}
804
}
805
806
@@ -XXX,XX +XXX,XX @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
807
mmap_lock();
808
809
if (flags & MREMAP_FIXED) {
810
- host_addr = mremap(g2h(old_addr), old_size, new_size,
811
- flags, g2h(new_addr));
812
+ host_addr = mremap(g2h_untagged(old_addr), old_size, new_size,
813
+ flags, g2h_untagged(new_addr));
814
815
if (reserved_va && host_addr != MAP_FAILED) {
816
/* If new and old addresses overlap then the above mremap will
817
@@ -XXX,XX +XXX,XX @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
818
errno = ENOMEM;
819
host_addr = MAP_FAILED;
820
} else {
821
- host_addr = mremap(g2h(old_addr), old_size, new_size,
822
- flags | MREMAP_FIXED, g2h(mmap_start));
823
+ host_addr = mremap(g2h_untagged(old_addr), old_size, new_size,
824
+ flags | MREMAP_FIXED,
825
+ g2h_untagged(mmap_start));
826
if (reserved_va) {
827
mmap_reserve(old_addr, old_size);
828
}
829
@@ -XXX,XX +XXX,XX @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
830
}
831
}
832
if (prot == 0) {
833
- host_addr = mremap(g2h(old_addr), old_size, new_size, flags);
834
+ host_addr = mremap(g2h_untagged(old_addr),
835
+ old_size, new_size, flags);
836
837
if (host_addr != MAP_FAILED) {
838
/* Check if address fits target address space */
839
if (!guest_range_valid(h2g(host_addr), new_size)) {
840
/* Revert mremap() changes */
841
- host_addr = mremap(g2h(old_addr), new_size, old_size,
842
- flags);
843
+ host_addr = mremap(g2h_untagged(old_addr),
844
+ new_size, old_size, flags);
845
errno = ENOMEM;
846
host_addr = MAP_FAILED;
847
} else if (reserved_va && old_size > new_size) {
848
diff --git a/linux-user/ppc/signal.c b/linux-user/ppc/signal.c
849
index XXXXXXX..XXXXXXX 100644
850
--- a/linux-user/ppc/signal.c
851
+++ b/linux-user/ppc/signal.c
852
@@ -XXX,XX +XXX,XX @@ static void restore_user_regs(CPUPPCState *env,
853
uint64_t v_addr;
854
/* 64-bit needs to recover the pointer to the vectors from the frame */
855
__get_user(v_addr, &frame->v_regs);
856
- v_regs = g2h(v_addr);
857
+ v_regs = g2h(env_cpu(env), v_addr);
858
#else
859
v_regs = (ppc_avr_t *)frame->mc_vregs.altivec;
860
#endif
861
@@ -XXX,XX +XXX,XX @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
862
if (get_ppc64_abi(image) < 2) {
863
/* ELFv1 PPC64 function pointers are pointers to OPD entries. */
864
struct target_func_ptr *handler =
865
- (struct target_func_ptr *)g2h(ka->_sa_handler);
866
+ (struct target_func_ptr *)g2h(env_cpu(env), ka->_sa_handler);
867
env->nip = tswapl(handler->entry);
868
env->gpr[2] = tswapl(handler->toc);
869
} else {
870
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
871
index XXXXXXX..XXXXXXX 100644
872
--- a/linux-user/syscall.c
873
+++ b/linux-user/syscall.c
874
@@ -XXX,XX +XXX,XX @@ abi_long do_brk(abi_ulong new_brk)
875
/* Heap contents are initialized to zero, as for anonymous
876
* mapped pages. */
877
if (new_brk > target_brk) {
878
- memset(g2h(target_brk), 0, new_brk - target_brk);
879
+ memset(g2h_untagged(target_brk), 0, new_brk - target_brk);
880
}
881
    target_brk = new_brk;
882
DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
883
@@ -XXX,XX +XXX,XX @@ abi_long do_brk(abi_ulong new_brk)
884
* come from the remaining part of the previous page: it may
885
* contains garbage data due to a previous heap usage (grown
886
* then shrunken). */
887
- memset(g2h(target_brk), 0, brk_page - target_brk);
888
+ memset(g2h_untagged(target_brk), 0, brk_page - target_brk);
889
890
target_brk = new_brk;
891
brk_page = HOST_PAGE_ALIGN(target_brk);
892
@@ -XXX,XX +XXX,XX @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
893
mmap_lock();
894
895
if (shmaddr)
896
- host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
897
+ host_raddr = shmat(shmid, (void *)g2h_untagged(shmaddr), shmflg);
898
else {
899
abi_ulong mmap_start;
900
901
@@ -XXX,XX +XXX,XX @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
902
errno = ENOMEM;
903
host_raddr = (void *)-1;
904
} else
905
- host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
906
+ host_raddr = shmat(shmid, g2h_untagged(mmap_start),
907
+ shmflg | SHM_REMAP);
908
}
909
910
if (host_raddr == (void *)-1) {
911
@@ -XXX,XX +XXX,XX @@ static inline abi_long do_shmdt(abi_ulong shmaddr)
912
break;
913
}
914
}
915
- rv = get_errno(shmdt(g2h(shmaddr)));
916
+ rv = get_errno(shmdt(g2h_untagged(shmaddr)));
917
918
mmap_unlock();
919
920
@@ -XXX,XX +XXX,XX @@ static abi_long write_ldt(CPUX86State *env,
921
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
922
if (env->ldt.base == -1)
923
return -TARGET_ENOMEM;
924
- memset(g2h(env->ldt.base), 0,
925
+ memset(g2h_untagged(env->ldt.base), 0,
926
TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
927
env->ldt.limit = 0xffff;
928
- ldt_table = g2h(env->ldt.base);
929
+ ldt_table = g2h_untagged(env->ldt.base);
930
}
931
932
/* NOTE: same code as Linux kernel */
933
@@ -XXX,XX +XXX,XX @@ static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
934
#if defined(TARGET_ABI32)
935
abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
936
{
937
- uint64_t *gdt_table = g2h(env->gdt.base);
938
+ uint64_t *gdt_table = g2h_untagged(env->gdt.base);
939
struct target_modify_ldt_ldt_s ldt_info;
940
struct target_modify_ldt_ldt_s *target_ldt_info;
941
int seg_32bit, contents, read_exec_only, limit_in_pages;
942
@@ -XXX,XX +XXX,XX @@ install:
943
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
944
{
945
struct target_modify_ldt_ldt_s *target_ldt_info;
946
- uint64_t *gdt_table = g2h(env->gdt.base);
947
+ uint64_t *gdt_table = g2h_untagged(env->gdt.base);
948
uint32_t base_addr, limit, flags;
949
int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
950
int seg_not_present, useable, lm;
951
@@ -XXX,XX +XXX,XX @@ static int do_safe_futex(int *uaddr, int op, int val,
952
tricky. However they're probably useless because guest atomic
953
operations won't work either. */
954
#if defined(TARGET_NR_futex)
955
-static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
956
- target_ulong uaddr2, int val3)
957
+static int do_futex(CPUState *cpu, target_ulong uaddr, int op, int val,
958
+ target_ulong timeout, target_ulong uaddr2, int val3)
959
{
960
struct timespec ts, *pts;
961
int base_op;
962
@@ -XXX,XX +XXX,XX @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
963
} else {
964
pts = NULL;
965
}
966
- return do_safe_futex(g2h(uaddr), op, tswap32(val), pts, NULL, val3);
967
+ return do_safe_futex(g2h(cpu, uaddr),
968
+ op, tswap32(val), pts, NULL, val3);
969
case FUTEX_WAKE:
970
- return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
971
+ return do_safe_futex(g2h(cpu, uaddr),
972
+ op, val, NULL, NULL, 0);
973
case FUTEX_FD:
974
- return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
975
+ return do_safe_futex(g2h(cpu, uaddr),
976
+ op, val, NULL, NULL, 0);
977
case FUTEX_REQUEUE:
978
case FUTEX_CMP_REQUEUE:
979
case FUTEX_WAKE_OP:
980
@@ -XXX,XX +XXX,XX @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
981
to satisfy the compiler. We do not need to tswap TIMEOUT
982
since it's not compared to guest memory. */
983
pts = (struct timespec *)(uintptr_t) timeout;
984
- return do_safe_futex(g2h(uaddr), op, val, pts, g2h(uaddr2),
985
+ return do_safe_futex(g2h(cpu, uaddr), op, val, pts, g2h(cpu, uaddr2),
986
(base_op == FUTEX_CMP_REQUEUE
987
- ? tswap32(val3)
988
- : val3));
989
+ ? tswap32(val3) : val3));
990
default:
991
return -TARGET_ENOSYS;
992
}
993
@@ -XXX,XX +XXX,XX @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
994
#endif
995
996
#if defined(TARGET_NR_futex_time64)
997
-static int do_futex_time64(target_ulong uaddr, int op, int val, target_ulong timeout,
998
+static int do_futex_time64(CPUState *cpu, target_ulong uaddr, int op,
999
+ int val, target_ulong timeout,
1000
target_ulong uaddr2, int val3)
1001
{
1002
struct timespec ts, *pts;
1003
@@ -XXX,XX +XXX,XX @@ static int do_futex_time64(target_ulong uaddr, int op, int val, target_ulong tim
1004
} else {
1005
pts = NULL;
1006
}
1007
- return do_safe_futex(g2h(uaddr), op, tswap32(val), pts, NULL, val3);
1008
+ return do_safe_futex(g2h(cpu, uaddr), op,
1009
+ tswap32(val), pts, NULL, val3);
1010
case FUTEX_WAKE:
1011
- return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
1012
+ return do_safe_futex(g2h(cpu, uaddr), op, val, NULL, NULL, 0);
1013
case FUTEX_FD:
1014
- return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
1015
+ return do_safe_futex(g2h(cpu, uaddr), op, val, NULL, NULL, 0);
1016
case FUTEX_REQUEUE:
1017
case FUTEX_CMP_REQUEUE:
1018
case FUTEX_WAKE_OP:
1019
@@ -XXX,XX +XXX,XX @@ static int do_futex_time64(target_ulong uaddr, int op, int val, target_ulong tim
1020
to satisfy the compiler. We do not need to tswap TIMEOUT
1021
since it's not compared to guest memory. */
1022
pts = (struct timespec *)(uintptr_t) timeout;
1023
- return do_safe_futex(g2h(uaddr), op, val, pts, g2h(uaddr2),
1024
+ return do_safe_futex(g2h(cpu, uaddr), op, val, pts, g2h(cpu, uaddr2),
1025
(base_op == FUTEX_CMP_REQUEUE
1026
- ? tswap32(val3)
1027
- : val3));
1028
+ ? tswap32(val3) : val3));
1029
default:
1030
return -TARGET_ENOSYS;
1031
}
1032
@@ -XXX,XX +XXX,XX @@ static int open_self_maps(void *cpu_env, int fd)
1033
const char *path;
1034
1035
max = h2g_valid(max - 1) ?
1036
- max : (uintptr_t) g2h(GUEST_ADDR_MAX) + 1;
1037
+ max : (uintptr_t) g2h_untagged(GUEST_ADDR_MAX) + 1;
1038
1039
if (page_check_range(h2g(min), max - min, flags) == -1) {
1040
continue;
1041
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
1042
1043
if (ts->child_tidptr) {
1044
put_user_u32(0, ts->child_tidptr);
1045
- do_sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
1046
- NULL, NULL, 0);
1047
+ do_sys_futex(g2h(cpu, ts->child_tidptr),
1048
+ FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
1049
}
1050
thread_cpu = NULL;
1051
g_free(ts);
1052
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
1053
if (!arg5) {
1054
ret = mount(p, p2, p3, (unsigned long)arg4, NULL);
1055
} else {
1056
- ret = mount(p, p2, p3, (unsigned long)arg4, g2h(arg5));
1057
+ ret = mount(p, p2, p3, (unsigned long)arg4, g2h(cpu, arg5));
1058
}
1059
ret = get_errno(ret);
1060
1061
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
1062
/* ??? msync/mlock/munlock are broken for softmmu. */
1063
#ifdef TARGET_NR_msync
1064
case TARGET_NR_msync:
1065
- return get_errno(msync(g2h(arg1), arg2, arg3));
1066
+ return get_errno(msync(g2h(cpu, arg1), arg2, arg3));
1067
#endif
1068
#ifdef TARGET_NR_mlock
1069
case TARGET_NR_mlock:
1070
- return get_errno(mlock(g2h(arg1), arg2));
1071
+ return get_errno(mlock(g2h(cpu, arg1), arg2));
1072
#endif
1073
#ifdef TARGET_NR_munlock
1074
case TARGET_NR_munlock:
1075
- return get_errno(munlock(g2h(arg1), arg2));
1076
+ return get_errno(munlock(g2h(cpu, arg1), arg2));
1077
#endif
1078
#ifdef TARGET_NR_mlockall
1079
case TARGET_NR_mlockall:
1080
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
1081
1082
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
1083
case TARGET_NR_set_tid_address:
1084
- return get_errno(set_tid_address((int *)g2h(arg1)));
1085
+ return get_errno(set_tid_address((int *)g2h(cpu, arg1)));
1086
#endif
1087
1088
case TARGET_NR_tkill:
1089
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
1090
#endif
1091
#ifdef TARGET_NR_futex
1092
case TARGET_NR_futex:
1093
- return do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
1094
+ return do_futex(cpu, arg1, arg2, arg3, arg4, arg5, arg6);
1095
#endif
1096
#ifdef TARGET_NR_futex_time64
1097
case TARGET_NR_futex_time64:
1098
- return do_futex_time64(arg1, arg2, arg3, arg4, arg5, arg6);
1099
+ return do_futex_time64(cpu, arg1, arg2, arg3, arg4, arg5, arg6);
1100
#endif
1101
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
1102
case TARGET_NR_inotify_init:
36
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
1103
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
37
index XXXXXXX..XXXXXXX 100644
1104
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/helper-a64.c
1105
--- a/target/arm/helper-a64.c
39
+++ b/target/arm/helper-a64.c
1106
+++ b/target/arm/helper-a64.c
40
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_mulxd)(float64 a, float64 b, void *fpstp)
1107
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_le)(CPUARMState *env, uint64_t addr,
41
return float64_mul(a, b, fpst);
1108
42
}
1109
#ifdef CONFIG_USER_ONLY
43
1110
/* ??? Enforce alignment. */
44
-uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
1111
- uint64_t *haddr = g2h(addr);
45
- uint32_t rn, uint32_t numregs)
1112
+ uint64_t *haddr = g2h(env_cpu(env), addr);
46
-{
1113
47
- /* Helper function for SIMD TBL and TBX. We have to do the table
1114
set_helper_retaddr(ra);
48
- * lookup part for the 64 bits worth of indices we're passed in.
1115
o0 = ldq_le_p(haddr + 0);
49
- * result is the initial results vector (either zeroes for TBL
1116
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be)(CPUARMState *env, uint64_t addr,
50
- * or some guest values for TBX), rn the register number where
1117
51
- * the table starts, and numregs the number of registers in the table.
1118
#ifdef CONFIG_USER_ONLY
52
- * We return the results of the lookups.
1119
/* ??? Enforce alignment. */
53
- */
1120
- uint64_t *haddr = g2h(addr);
54
- int shift;
1121
+ uint64_t *haddr = g2h(env_cpu(env), addr);
55
-
1122
56
- for (shift = 0; shift < 64; shift += 8) {
1123
set_helper_retaddr(ra);
57
- int index = extract64(indices, shift, 8);
1124
o1 = ldq_be_p(haddr + 0);
58
- if (index < 16 * numregs) {
1125
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
59
- /* Convert index (a byte offset into the virtual table
1126
index XXXXXXX..XXXXXXX 100644
60
- * which is a series of 128-bit vectors concatenated)
1127
--- a/target/hppa/op_helper.c
61
- * into the correct register element plus a bit offset
1128
+++ b/target/hppa/op_helper.c
62
- * into that element, bearing in mind that the table
1129
@@ -XXX,XX +XXX,XX @@ static void atomic_store_3(CPUHPPAState *env, target_ulong addr, uint32_t val,
63
- * can wrap around from V31 to V0.
1130
#ifdef CONFIG_USER_ONLY
64
- */
1131
uint32_t old, new, cmp;
65
- int elt = (rn * 2 + (index >> 3)) % 64;
1132
66
- int bitidx = (index & 7) * 8;
1133
- uint32_t *haddr = g2h(addr - 1);
67
- uint64_t *q = aa64_vfp_qreg(env, elt >> 1);
1134
+ uint32_t *haddr = g2h(env_cpu(env), addr - 1);
68
- uint64_t val = extract64(q[elt & 1], bitidx, 8);
1135
old = *haddr;
69
-
1136
while (1) {
70
- result = deposit64(result, shift, 8, val);
1137
new = (old & ~mask) | (val & mask);
71
- }
1138
diff --git a/target/i386/tcg/mem_helper.c b/target/i386/tcg/mem_helper.c
72
- }
1139
index XXXXXXX..XXXXXXX 100644
73
- return result;
1140
--- a/target/i386/tcg/mem_helper.c
74
-}
1141
+++ b/target/i386/tcg/mem_helper.c
75
-
1142
@@ -XXX,XX +XXX,XX @@ void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
76
/* 64bit/double versions of the neon float compare functions */
1143
77
uint64_t HELPER(neon_ceq_f64)(float64 a, float64 b, void *fpstp)
1144
#ifdef CONFIG_USER_ONLY
78
{
1145
{
79
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
1146
- uint64_t *haddr = g2h(a0);
80
index XXXXXXX..XXXXXXX 100644
1147
+ uint64_t *haddr = g2h(env_cpu(env), a0);
81
--- a/target/arm/translate-a64.c
1148
cmpv = cpu_to_le64(cmpv);
82
+++ b/target/arm/translate-a64.c
1149
newv = cpu_to_le64(newv);
83
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
1150
oldv = qatomic_cmpxchg__nocheck(haddr, cmpv, newv);
84
int rm = extract32(insn, 16, 5);
1151
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
85
int rn = extract32(insn, 5, 5);
1152
index XXXXXXX..XXXXXXX 100644
86
int rd = extract32(insn, 0, 5);
1153
--- a/target/s390x/mem_helper.c
87
- int is_tblx = extract32(insn, 12, 1);
1154
+++ b/target/s390x/mem_helper.c
88
- int len = extract32(insn, 13, 2);
1155
@@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
89
- TCGv_i64 tcg_resl, tcg_resh, tcg_idx;
1156
90
- TCGv_i32 tcg_regno, tcg_numregs;
1157
if (parallel) {
91
+ int is_tbx = extract32(insn, 12, 1);
1158
#ifdef CONFIG_USER_ONLY
92
+ int len = (extract32(insn, 13, 2) + 1) * 16;
1159
- uint32_t *haddr = g2h(a1);
93
1160
+ uint32_t *haddr = g2h(env_cpu(env), a1);
94
if (op2 != 0) {
1161
ov = qatomic_cmpxchg__nocheck(haddr, cv, nv);
95
unallocated_encoding(s);
1162
#else
96
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
1163
TCGMemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mem_idx);
97
return;
1164
@@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
98
}
1165
if (parallel) {
99
1166
#ifdef CONFIG_ATOMIC64
100
- /* This does a table lookup: for every byte element in the input
1167
# ifdef CONFIG_USER_ONLY
101
- * we index into a table formed from up to four vector registers,
1168
- uint64_t *haddr = g2h(a1);
102
- * and then the output is the result of the lookups. Our helper
1169
+ uint64_t *haddr = g2h(env_cpu(env), a1);
103
- * function does the lookup operation for a single 64 bit part of
1170
ov = qatomic_cmpxchg__nocheck(haddr, cv, nv);
104
- * the input.
1171
# else
105
- */
1172
TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN, mem_idx);
106
- tcg_resl = tcg_temp_new_i64();
107
- tcg_resh = NULL;
108
-
109
- if (is_tblx) {
110
- read_vec_element(s, tcg_resl, rd, 0, MO_64);
111
- } else {
112
- tcg_gen_movi_i64(tcg_resl, 0);
113
- }
114
-
115
- if (is_q) {
116
- tcg_resh = tcg_temp_new_i64();
117
- if (is_tblx) {
118
- read_vec_element(s, tcg_resh, rd, 1, MO_64);
119
- } else {
120
- tcg_gen_movi_i64(tcg_resh, 0);
121
- }
122
- }
123
-
124
- tcg_idx = tcg_temp_new_i64();
125
- tcg_regno = tcg_const_i32(rn);
126
- tcg_numregs = tcg_const_i32(len + 1);
127
- read_vec_element(s, tcg_idx, rm, 0, MO_64);
128
- gen_helper_simd_tbl(tcg_resl, cpu_env, tcg_resl, tcg_idx,
129
- tcg_regno, tcg_numregs);
130
- if (is_q) {
131
- read_vec_element(s, tcg_idx, rm, 1, MO_64);
132
- gen_helper_simd_tbl(tcg_resh, cpu_env, tcg_resh, tcg_idx,
133
- tcg_regno, tcg_numregs);
134
- }
135
- tcg_temp_free_i64(tcg_idx);
136
- tcg_temp_free_i32(tcg_regno);
137
- tcg_temp_free_i32(tcg_numregs);
138
-
139
- write_vec_element(s, tcg_resl, rd, 0, MO_64);
140
- tcg_temp_free_i64(tcg_resl);
141
-
142
- if (is_q) {
143
- write_vec_element(s, tcg_resh, rd, 1, MO_64);
144
- tcg_temp_free_i64(tcg_resh);
145
- }
146
- clear_vec_high(s, is_q, rd);
147
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd),
148
+ vec_full_reg_offset(s, rm), cpu_env,
149
+ is_q ? 16 : 8, vec_full_reg_size(s),
150
+ (len << 6) | (is_tbx << 5) | rn,
151
+ gen_helper_simd_tblx);
152
}
153
154
/* ZIP/UZP/TRN
155
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/vec_helper.c
158
+++ b/target/arm/vec_helper.c
159
@@ -XXX,XX +XXX,XX @@ DO_VRINT_RMODE(gvec_vrint_rm_h, helper_rinth, uint16_t)
160
DO_VRINT_RMODE(gvec_vrint_rm_s, helper_rints, uint32_t)
161
162
#undef DO_VRINT_RMODE
163
+
164
+#ifdef TARGET_AARCH64
165
+void HELPER(simd_tblx)(void *vd, void *vm, void *venv, uint32_t desc)
166
+{
167
+ const uint8_t *indices = vm;
168
+ CPUARMState *env = venv;
169
+ size_t oprsz = simd_oprsz(desc);
170
+ uint32_t rn = extract32(desc, SIMD_DATA_SHIFT, 5);
171
+ bool is_tbx = extract32(desc, SIMD_DATA_SHIFT + 5, 1);
172
+ uint32_t table_len = desc >> (SIMD_DATA_SHIFT + 6);
173
+ union {
174
+ uint8_t b[16];
175
+ uint64_t d[2];
176
+ } result;
177
+
178
+ /*
179
+ * We must construct the final result in a temp, lest the output
180
+ * overlaps the input table. For TBL, begin with zero; for TBX,
181
+ * begin with the original register contents. Note that we always
182
+ * copy 16 bytes here to avoid an extra branch; clearing the high
183
+ * bits of the register for oprsz == 8 is handled below.
184
+ */
185
+ if (is_tbx) {
186
+ memcpy(&result, vd, 16);
187
+ } else {
188
+ memset(&result, 0, 16);
189
+ }
190
+
191
+ for (size_t i = 0; i < oprsz; ++i) {
192
+ uint32_t index = indices[H1(i)];
193
+
194
+ if (index < table_len) {
195
+ /*
196
+ * Convert index (a byte offset into the virtual table
197
+ * which is a series of 128-bit vectors concatenated)
198
+ * into the correct register element, bearing in mind
199
+ * that the table can wrap around from V31 to V0.
200
+ */
201
+ const uint8_t *table = (const uint8_t *)
202
+ aa64_vfp_qreg(env, (rn + (index >> 4)) % 32);
203
+ result.b[H1(i)] = table[H1(index % 16)];
204
+ }
205
+ }
206
+
207
+ memcpy(vd, &result, 16);
208
+ clear_tail(vd, oprsz, simd_maxsz(desc));
209
+}
210
+#endif
211
--
1173
--
212
2.20.1
1174
2.20.1
213
1175
214
1176
diff view generated by jsdifflib
1
Add brief documentation of the new mps3-an524 board.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We define target_mmap et al as untagged, so that they can be
4
used from the binary loaders. Explicitly call cpu_untagged_addr
5
for munmap, mprotect, mremap syscall entry points.
6
7
Add a few comments for the syscalls that are exempted by the
8
kernel's tagged-address-abi.rst.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210212184902.1251044-14-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215115138.20465-24-peter.maydell@linaro.org
7
---
14
---
8
docs/system/arm/mps2.rst | 24 ++++++++++++++++++------
15
linux-user/syscall.c | 11 +++++++++++
9
1 file changed, 18 insertions(+), 6 deletions(-)
16
1 file changed, 11 insertions(+)
10
17
11
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
18
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/docs/system/arm/mps2.rst
20
--- a/linux-user/syscall.c
14
+++ b/docs/system/arm/mps2.rst
21
+++ b/linux-user/syscall.c
15
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ abi_long do_brk(abi_ulong new_brk)
16
-Arm MPS2 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``)
23
abi_long mapped_addr;
17
-================================================================================================================
24
abi_ulong new_alloc_size;
18
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
25
19
+=========================================================================================================================================
26
+ /* brk pointers are always untagged */
20
21
These board models all use Arm M-profile CPUs.
22
23
-The Arm MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
24
-FPGA but is otherwise the same as the 2). Since the CPU itself
25
-and most of the devices are in the FPGA, the details of the board
26
-as seen by the guest depend significantly on the FPGA image.
27
+The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
28
+bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
29
+FPGA again, can handle 4GB of RAM and has a USB controller and QSPI flash).
30
+
27
+
31
+Since the CPU itself and most of the devices are in the FPGA, the
28
DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
32
+details of the board as seen by the guest depend significantly on the
29
33
+FPGA image.
30
if (!new_brk) {
34
31
@@ -XXX,XX +XXX,XX @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
35
QEMU models the following FPGA images:
32
int i,ret;
36
33
abi_ulong shmlba;
37
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
34
38
Cortex-M3 'DesignStart' as documented in Arm Application Note AN511
35
+ /* shmat pointers are always untagged */
39
``mps2-an521``
36
+
40
Dual Cortex-M33 as documented in Arm Application Note AN521
37
/* find out the length of the shared memory segment */
41
+``mps3-an524``
38
ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
42
+ Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
39
if (is_error(ret)) {
43
40
@@ -XXX,XX +XXX,XX @@ static inline abi_long do_shmdt(abi_ulong shmaddr)
44
Differences between QEMU and real hardware:
41
int i;
45
42
abi_long rv;
46
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
43
47
block RAM is unimplemented (QEMU always maps this to ZBT SSRAM1, as
44
+ /* shmdt pointers are always untagged */
48
if zbt_boot_ctrl is always zero)
45
+
49
+- AN524 remapping of low memory to either BRAM or to QSPI flash is
46
mmap_lock();
50
+ unimplemented (QEMU always maps this to BRAM, ignoring the
47
51
+ SCC CFG_REG0 memory-remap bit)
48
for (i = 0; i < N_SHM_REGIONS; ++i) {
52
- QEMU provides a LAN9118 ethernet rather than LAN9220; the only guest
49
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
53
visible difference is that the LAN9118 doesn't support checksum
50
v5, v6));
54
offloading
51
}
55
+- QEMU does not model the QSPI flash in MPS3 boards as real QSPI
52
#else
56
+ flash, but only as simple ROM, so attempting to rewrite the flash
53
+ /* mmap pointers are always untagged */
57
+ from the guest will fail
54
ret = get_errno(target_mmap(arg1, arg2, arg3,
58
+- QEMU does not model the USB controller in MPS3 boards
55
target_to_host_bitmask(arg4, mmap_flags_tbl),
56
arg5,
57
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
58
return get_errno(ret);
59
#endif
60
case TARGET_NR_munmap:
61
+ arg1 = cpu_untagged_addr(cpu, arg1);
62
return get_errno(target_munmap(arg1, arg2));
63
case TARGET_NR_mprotect:
64
+ arg1 = cpu_untagged_addr(cpu, arg1);
65
{
66
TaskState *ts = cpu->opaque;
67
/* Special hack to detect libc making the stack executable. */
68
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
69
return get_errno(target_mprotect(arg1, arg2, arg3));
70
#ifdef TARGET_NR_mremap
71
case TARGET_NR_mremap:
72
+ arg1 = cpu_untagged_addr(cpu, arg1);
73
+ /* mremap new_addr (arg5) is always untagged */
74
return get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
75
#endif
76
/* ??? msync/mlock/munlock are broken for softmmu. */
59
--
77
--
60
2.20.1
78
2.20.1
61
79
62
80
diff view generated by jsdifflib
1
Instead of hardcoding the MachineClass default_ram_size and
1
From: Richard Henderson <richard.henderson@linaro.org>
2
default_ram_id fields, set them on class creation by finding the
3
entry in the RAMInfo array which is marked as being the QEMU system
4
RAM.
5
2
3
We're currently open-coding the range check in access_ok;
4
use guest_range_valid when size != 0.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210212184902.1251044-15-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-18-peter.maydell@linaro.org
9
---
10
---
10
hw/arm/mps2-tz.c | 24 ++++++++++++++++++++++--
11
linux-user/qemu.h | 9 +++------
11
1 file changed, 22 insertions(+), 2 deletions(-)
12
1 file changed, 3 insertions(+), 6 deletions(-)
12
13
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
16
--- a/linux-user/qemu.h
16
+++ b/hw/arm/mps2-tz.c
17
+++ b/linux-user/qemu.h
17
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
18
@@ -XXX,XX +XXX,XX @@ extern unsigned long guest_stack_size;
18
19
19
mc->init = mps2tz_common_init;
20
static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
20
iic->check = mps2_tz_idau_check;
21
{
21
- mc->default_ram_size = 16 * MiB;
22
- if (!guest_addr_valid(addr)) {
22
- mc->default_ram_id = "mps.ram";
23
- return false;
23
+}
24
- }
24
+
25
- if (size != 0 &&
25
+static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc)
26
- (addr + size - 1 < addr ||
26
+{
27
- !guest_addr_valid(addr + size - 1))) {
27
+ /*
28
+ if (size == 0
28
+ * Set mc->default_ram_size and default_ram_id from the
29
+ ? !guest_addr_valid(addr)
29
+ * information in mmc->raminfo.
30
+ : !guest_range_valid(addr, size)) {
30
+ */
31
return false;
31
+ MachineClass *mc = MACHINE_CLASS(mmc);
32
}
32
+ const RAMInfo *p;
33
return page_check_range((target_ulong)addr, size, type) == 0;
33
+
34
+ for (p = mmc->raminfo; p->name; p++) {
35
+ if (p->mrindex < 0) {
36
+ /* Found the entry for "system memory" */
37
+ mc->default_ram_size = p->size;
38
+ mc->default_ram_id = p->name;
39
+ return;
40
+ }
41
+ }
42
+ g_assert_not_reached();
43
}
44
45
static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
46
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
47
mmc->numirq = 92;
48
mmc->raminfo = an505_raminfo;
49
mmc->armsse_type = TYPE_IOTKIT;
50
+ mps2tz_set_default_ram_info(mmc);
51
}
52
53
static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
54
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
55
mmc->numirq = 92;
56
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
57
mmc->armsse_type = TYPE_SSE200;
58
+ mps2tz_set_default_ram_info(mmc);
59
}
60
61
static const TypeInfo mps2tz_info = {
62
--
34
--
63
2.20.1
35
2.20.1
64
36
65
37
diff view generated by jsdifflib
1
The AN505 and AN511 happen to share the same OSCCLK values, but the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
AN524 will have a different set (and more of them), so split the
3
settings out to be per-board.
4
2
3
The places that use these are better off using untagged
4
addresses, so do not provide a tagged versions. Rename
5
to make it clear about the address type.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210212184902.1251044-16-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-5-peter.maydell@linaro.org
9
---
11
---
10
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
12
include/exec/cpu_ldst.h | 4 ++--
11
1 file changed, 18 insertions(+), 5 deletions(-)
13
linux-user/qemu.h | 4 ++--
14
accel/tcg/user-exec.c | 3 ++-
15
linux-user/mmap.c | 14 +++++++-------
16
linux-user/syscall.c | 2 +-
17
5 files changed, 14 insertions(+), 13 deletions(-)
12
18
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
21
--- a/include/exec/cpu_ldst.h
16
+++ b/hw/arm/mps2-tz.c
22
+++ b/include/exec/cpu_ldst.h
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
23
@@ -XXX,XX +XXX,XX @@ static inline void *g2h(CPUState *cs, abi_ptr x)
18
MPS2TZFPGAType fpga_type;
24
return g2h_untagged(cpu_untagged_addr(cs, x));
19
uint32_t scc_id;
20
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
21
+ uint32_t len_oscclk;
22
+ const uint32_t *oscclk;
23
const char *armsse_type;
24
};
25
26
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
27
/* Slow 32Khz S32KCLK frequency in Hz */
28
#define S32KCLK_FRQ (32 * 1000)
29
30
+static const uint32_t an505_oscclk[] = {
31
+ 40000000,
32
+ 24580000,
33
+ 25000000,
34
+};
35
+
36
/* Create an alias of an entire original MemoryRegion @orig
37
* located at @base in the memory map.
38
*/
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
40
MPS2SCC *scc = opaque;
41
DeviceState *sccdev;
42
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
43
+ uint32_t i;
44
45
object_initialize_child(OBJECT(mms), "scc", scc, TYPE_MPS2_SCC);
46
sccdev = DEVICE(scc);
47
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
48
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
49
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
50
- /* This will need to be per-FPGA image eventually */
51
- qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
52
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
53
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
54
- qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
55
+ qdev_prop_set_uint32(sccdev, "len-oscclk", mmc->len_oscclk);
56
+ for (i = 0; i < mmc->len_oscclk; i++) {
57
+ g_autofree char *propname = g_strdup_printf("oscclk[%u]", i);
58
+ qdev_prop_set_uint32(sccdev, propname, mmc->oscclk[i]);
59
+ }
60
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
61
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
62
}
25
}
63
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
26
64
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
27
-static inline bool guest_addr_valid(abi_ulong x)
65
mmc->scc_id = 0x41045050;
28
+static inline bool guest_addr_valid_untagged(abi_ulong x)
66
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
29
{
67
+ mmc->oscclk = an505_oscclk;
30
return x <= GUEST_ADDR_MAX;
68
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
69
mmc->armsse_type = TYPE_IOTKIT;
70
}
31
}
71
32
72
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
33
-static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
73
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
34
+static inline bool guest_range_valid_untagged(abi_ulong start, abi_ulong len)
74
mmc->scc_id = 0x41045210;
35
{
75
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
36
return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
76
+ mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
77
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
78
mmc->armsse_type = TYPE_SSE200;
79
}
37
}
38
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/linux-user/qemu.h
41
+++ b/linux-user/qemu.h
42
@@ -XXX,XX +XXX,XX @@ extern unsigned long guest_stack_size;
43
static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
44
{
45
if (size == 0
46
- ? !guest_addr_valid(addr)
47
- : !guest_range_valid(addr, size)) {
48
+ ? !guest_addr_valid_untagged(addr)
49
+ : !guest_range_valid_untagged(addr, size)) {
50
return false;
51
}
52
return page_check_range((target_ulong)addr, size, type) == 0;
53
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/accel/tcg/user-exec.c
56
+++ b/accel/tcg/user-exec.c
57
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
58
g_assert_not_reached();
59
}
60
61
- if (!guest_addr_valid(addr) || page_check_range(addr, 1, flags) < 0) {
62
+ if (!guest_addr_valid_untagged(addr) ||
63
+ page_check_range(addr, 1, flags) < 0) {
64
if (nonfault) {
65
return TLB_INVALID_MASK;
66
} else {
67
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/linux-user/mmap.c
70
+++ b/linux-user/mmap.c
71
@@ -XXX,XX +XXX,XX @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
72
}
73
len = TARGET_PAGE_ALIGN(len);
74
end = start + len;
75
- if (!guest_range_valid(start, len)) {
76
+ if (!guest_range_valid_untagged(start, len)) {
77
return -TARGET_ENOMEM;
78
}
79
if (len == 0) {
80
@@ -XXX,XX +XXX,XX @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
81
* It can fail only on 64-bit host with 32-bit target.
82
* On any other target/host host mmap() handles this error correctly.
83
*/
84
- if (end < start || !guest_range_valid(start, len)) {
85
+ if (end < start || !guest_range_valid_untagged(start, len)) {
86
errno = ENOMEM;
87
goto fail;
88
}
89
@@ -XXX,XX +XXX,XX @@ int target_munmap(abi_ulong start, abi_ulong len)
90
if (start & ~TARGET_PAGE_MASK)
91
return -TARGET_EINVAL;
92
len = TARGET_PAGE_ALIGN(len);
93
- if (len == 0 || !guest_range_valid(start, len)) {
94
+ if (len == 0 || !guest_range_valid_untagged(start, len)) {
95
return -TARGET_EINVAL;
96
}
97
98
@@ -XXX,XX +XXX,XX @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
99
int prot;
100
void *host_addr;
101
102
- if (!guest_range_valid(old_addr, old_size) ||
103
+ if (!guest_range_valid_untagged(old_addr, old_size) ||
104
((flags & MREMAP_FIXED) &&
105
- !guest_range_valid(new_addr, new_size)) ||
106
+ !guest_range_valid_untagged(new_addr, new_size)) ||
107
((flags & MREMAP_MAYMOVE) == 0 &&
108
- !guest_range_valid(old_addr, new_size))) {
109
+ !guest_range_valid_untagged(old_addr, new_size))) {
110
errno = ENOMEM;
111
return -1;
112
}
113
@@ -XXX,XX +XXX,XX @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
114
115
if (host_addr != MAP_FAILED) {
116
/* Check if address fits target address space */
117
- if (!guest_range_valid(h2g(host_addr), new_size)) {
118
+ if (!guest_range_valid_untagged(h2g(host_addr), new_size)) {
119
/* Revert mremap() changes */
120
host_addr = mremap(g2h_untagged(old_addr),
121
new_size, old_size, flags);
122
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/linux-user/syscall.c
125
+++ b/linux-user/syscall.c
126
@@ -XXX,XX +XXX,XX @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
127
return -TARGET_EINVAL;
128
}
129
}
130
- if (!guest_range_valid(shmaddr, shm_info.shm_segsz)) {
131
+ if (!guest_range_valid_untagged(shmaddr, shm_info.shm_segsz)) {
132
return -TARGET_EINVAL;
133
}
80
134
81
--
135
--
82
2.20.1
136
2.20.1
83
137
84
138
diff view generated by jsdifflib
1
The AN524 has a different SYSCLK frequency from the AN505 and AN521;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
make the SYSCLK frequency a field in the MPS2TZMachineClass rather
3
than a compile-time constant so we can support the AN524.
4
2
3
Provide both tagged and untagged versions of access_ok.
4
In a few places use thread_cpu, as the user is several
5
callees removed from do_syscall1.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210212184902.1251044-17-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-2-peter.maydell@linaro.org
9
---
11
---
10
hw/arm/mps2-tz.c | 10 ++++++----
12
linux-user/qemu.h | 11 +++++++++--
11
1 file changed, 6 insertions(+), 4 deletions(-)
13
linux-user/elfload.c | 2 +-
14
linux-user/hppa/cpu_loop.c | 8 ++++----
15
linux-user/i386/cpu_loop.c | 2 +-
16
linux-user/i386/signal.c | 5 +++--
17
linux-user/syscall.c | 9 ++++++---
18
6 files changed, 24 insertions(+), 13 deletions(-)
12
19
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
20
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
22
--- a/linux-user/qemu.h
16
+++ b/hw/arm/mps2-tz.c
23
+++ b/linux-user/qemu.h
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
24
@@ -XXX,XX +XXX,XX @@ extern unsigned long guest_stack_size;
18
MachineClass parent;
25
#define VERIFY_READ PAGE_READ
19
MPS2TZFPGAType fpga_type;
26
#define VERIFY_WRITE (PAGE_READ | PAGE_WRITE)
20
uint32_t scc_id;
27
21
+ uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
28
-static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
22
const char *armsse_type;
29
+static inline bool access_ok_untagged(int type, abi_ulong addr, abi_ulong size)
23
};
24
25
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
26
27
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
28
29
-/* Main SYSCLK frequency in Hz */
30
-#define SYSCLK_FRQ 20000000
31
/* Slow 32Khz S32KCLK frequency in Hz */
32
#define S32KCLK_FRQ (32 * 1000)
33
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
35
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
36
const char *name, hwaddr size)
37
{
30
{
38
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
31
if (size == 0
39
CMSDKAPBUART *uart = opaque;
32
? !guest_addr_valid_untagged(addr)
40
int i = uart - &mms->uart[0];
33
@@ -XXX,XX +XXX,XX @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
41
int rxirqno = i * 2;
34
return page_check_range((target_ulong)addr, size, type) == 0;
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
43
44
object_initialize_child(OBJECT(mms), name, uart, TYPE_CMSDK_APB_UART);
45
qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
46
- qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
47
+ qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
48
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
49
s = SYS_BUS_DEVICE(uart);
50
sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
51
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
52
53
/* These clocks don't need migration because they are fixed-frequency */
54
mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
55
- clock_set_hz(mms->sysclk, SYSCLK_FRQ);
56
+ clock_set_hz(mms->sysclk, mmc->sysclk_frq);
57
mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
58
clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
59
60
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
61
mmc->fpga_type = FPGA_AN505;
62
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
63
mmc->scc_id = 0x41045050;
64
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
65
mmc->armsse_type = TYPE_IOTKIT;
66
}
35
}
67
36
68
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
37
+static inline bool access_ok(CPUState *cpu, int type,
69
mmc->fpga_type = FPGA_AN521;
38
+ abi_ulong addr, abi_ulong size)
70
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
39
+{
71
mmc->scc_id = 0x41045210;
40
+ return access_ok_untagged(type, cpu_untagged_addr(cpu, addr), size);
72
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
41
+}
73
mmc->armsse_type = TYPE_SSE200;
42
+
74
}
43
/* NOTE __get_user and __put_user use host pointers and don't check access.
44
These are usually used to access struct data members once the struct has
45
been locked - usually with lock_user_struct. */
46
@@ -XXX,XX +XXX,XX @@ abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
47
host area will have the same contents as the guest. */
48
static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
49
{
50
- if (!access_ok(type, guest_addr, len))
51
+ if (!access_ok_untagged(type, guest_addr, len)) {
52
return NULL;
53
+ }
54
#ifdef DEBUG_REMAP
55
{
56
void *addr;
57
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/linux-user/elfload.c
60
+++ b/linux-user/elfload.c
61
@@ -XXX,XX +XXX,XX @@ static int vma_get_mapping_count(const struct mm_struct *mm)
62
static abi_ulong vma_dump_size(const struct vm_area_struct *vma)
63
{
64
/* if we cannot even read the first page, skip it */
65
- if (!access_ok(VERIFY_READ, vma->vma_start, TARGET_PAGE_SIZE))
66
+ if (!access_ok_untagged(VERIFY_READ, vma->vma_start, TARGET_PAGE_SIZE))
67
return (0);
68
69
/*
70
diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/linux-user/hppa/cpu_loop.c
73
+++ b/linux-user/hppa/cpu_loop.c
74
@@ -XXX,XX +XXX,XX @@ static abi_ulong hppa_lws(CPUHPPAState *env)
75
return -TARGET_ENOSYS;
76
77
case 0: /* elf32 atomic 32bit cmpxchg */
78
- if ((addr & 3) || !access_ok(VERIFY_WRITE, addr, 4)) {
79
+ if ((addr & 3) || !access_ok(cs, VERIFY_WRITE, addr, 4)) {
80
return -TARGET_EFAULT;
81
}
82
old = tswap32(old);
83
@@ -XXX,XX +XXX,XX @@ static abi_ulong hppa_lws(CPUHPPAState *env)
84
return -TARGET_ENOSYS;
85
}
86
if (((addr | old | new) & ((1 << size) - 1))
87
- || !access_ok(VERIFY_WRITE, addr, 1 << size)
88
- || !access_ok(VERIFY_READ, old, 1 << size)
89
- || !access_ok(VERIFY_READ, new, 1 << size)) {
90
+ || !access_ok(cs, VERIFY_WRITE, addr, 1 << size)
91
+ || !access_ok(cs, VERIFY_READ, old, 1 << size)
92
+ || !access_ok(cs, VERIFY_READ, new, 1 << size)) {
93
return -TARGET_EFAULT;
94
}
95
/* Note that below we use host-endian loads so that the cmpxchg
96
diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/linux-user/i386/cpu_loop.c
99
+++ b/linux-user/i386/cpu_loop.c
100
@@ -XXX,XX +XXX,XX @@ static bool write_ok_or_segv(CPUX86State *env, abi_ptr addr, size_t len)
101
* For all the vsyscalls, NULL means "don't write anything" not
102
* "write it at address 0".
103
*/
104
- if (addr == 0 || access_ok(VERIFY_WRITE, addr, len)) {
105
+ if (addr == 0 || access_ok(env_cpu(env), VERIFY_WRITE, addr, len)) {
106
return true;
107
}
108
109
diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/linux-user/i386/signal.c
112
+++ b/linux-user/i386/signal.c
113
@@ -XXX,XX +XXX,XX @@ restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc)
114
115
fpstate_addr = tswapl(sc->fpstate);
116
if (fpstate_addr != 0) {
117
- if (!access_ok(VERIFY_READ, fpstate_addr,
118
- sizeof(struct target_fpstate)))
119
+ if (!access_ok(env_cpu(env), VERIFY_READ, fpstate_addr,
120
+ sizeof(struct target_fpstate))) {
121
goto badframe;
122
+ }
123
#ifndef TARGET_X86_64
124
cpu_x86_frstor(env, fpstate_addr, 1);
125
#else
126
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/linux-user/syscall.c
129
+++ b/linux-user/syscall.c
130
@@ -XXX,XX +XXX,XX @@ static abi_long do_accept4(int fd, abi_ulong target_addr,
131
return -TARGET_EINVAL;
132
}
133
134
- if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
135
+ if (!access_ok(thread_cpu, VERIFY_WRITE, target_addr, addrlen)) {
136
return -TARGET_EFAULT;
137
+ }
138
139
addr = alloca(addrlen);
140
141
@@ -XXX,XX +XXX,XX @@ static abi_long do_getpeername(int fd, abi_ulong target_addr,
142
return -TARGET_EINVAL;
143
}
144
145
- if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
146
+ if (!access_ok(thread_cpu, VERIFY_WRITE, target_addr, addrlen)) {
147
return -TARGET_EFAULT;
148
+ }
149
150
addr = alloca(addrlen);
151
152
@@ -XXX,XX +XXX,XX @@ static abi_long do_getsockname(int fd, abi_ulong target_addr,
153
return -TARGET_EINVAL;
154
}
155
156
- if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
157
+ if (!access_ok(thread_cpu, VERIFY_WRITE, target_addr, addrlen)) {
158
return -TARGET_EFAULT;
159
+ }
160
161
addr = alloca(addrlen);
75
162
76
--
163
--
77
2.20.1
164
2.20.1
78
165
79
166
diff view generated by jsdifflib
1
The AN524 version of the SCC interface has different behaviour for
1
From: Richard Henderson <richard.henderson@linaro.org>
2
some of the CFG registers; implement it.
3
2
4
Each board in this family can have minor differences in the meaning
3
These functions are not small, except for unlock_user
5
of the CFG registers, so rather than trying to specify all the
4
without debugging enabled. Move them out of line, and
6
possible semantics via individual device properties, we make the
5
add missing braces on the way.
7
behaviour conditional on the part-number field of the SCC_ID register
8
which the board code already passes us.
9
6
10
For the AN524, the differences are:
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
* CFG3 is reserved rather than being board switches
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
* CFG5 is a new register ("ACLK Frequency in Hz")
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
* CFG6 is a new register ("Clock divider for BRAM")
10
Message-id: 20210212184902.1251044-18-richard.henderson@linaro.org
11
[PMM: fixed the sense of an ifdef test in qemu.h]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
linux-user/qemu.h | 47 +++++++-------------------------------------
15
linux-user/uaccess.c | 46 +++++++++++++++++++++++++++++++++++++++++++
16
2 files changed, 53 insertions(+), 40 deletions(-)
14
17
15
We implement both of the new registers as reads-as-written.
18
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210215115138.20465-11-peter.maydell@linaro.org
20
---
21
include/hw/misc/mps2-scc.h | 3 ++
22
hw/misc/mps2-scc.c | 71 ++++++++++++++++++++++++++++++++++++--
23
2 files changed, 72 insertions(+), 2 deletions(-)
24
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
26
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/misc/mps2-scc.h
20
--- a/linux-user/qemu.h
28
+++ b/include/hw/misc/mps2-scc.h
21
+++ b/linux-user/qemu.h
29
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
22
@@ -XXX,XX +XXX,XX @@ abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
30
23
31
uint32_t cfg0;
24
/* Lock an area of guest memory into the host. If copy is true then the
32
uint32_t cfg1;
25
host area will have the same contents as the guest. */
33
+ uint32_t cfg2;
26
-static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
34
uint32_t cfg4;
27
-{
35
+ uint32_t cfg5;
28
- if (!access_ok_untagged(type, guest_addr, len)) {
36
+ uint32_t cfg6;
29
- return NULL;
37
uint32_t cfgdata_rtn;
30
- }
38
uint32_t cfgdata_out;
31
-#ifdef DEBUG_REMAP
39
uint32_t cfgctrl;
32
- {
40
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
33
- void *addr;
34
- addr = g_malloc(len);
35
- if (copy)
36
- memcpy(addr, g2h(guest_addr), len);
37
- else
38
- memset(addr, 0, len);
39
- return addr;
40
- }
41
-#else
42
- return g2h_untagged(guest_addr);
43
-#endif
44
-}
45
+void *lock_user(int type, abi_ulong guest_addr, long len, int copy);
46
47
/* Unlock an area of guest memory. The first LEN bytes must be
48
flushed back to guest memory. host_ptr = NULL is explicitly
49
allowed and does nothing. */
50
-static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
51
- long len)
52
-{
53
-
54
-#ifdef DEBUG_REMAP
55
- if (!host_ptr)
56
- return;
57
- if (host_ptr == g2h_untagged(guest_addr))
58
- return;
59
- if (len > 0)
60
- memcpy(g2h_untagged(guest_addr), host_ptr, len);
61
- g_free(host_ptr);
62
+#ifndef DEBUG_REMAP
63
+static inline void unlock_user(void *host_ptr, abi_ulong guest_addr, long len)
64
+{ }
65
+#else
66
+void unlock_user(void *host_ptr, abi_ulong guest_addr, long len);
67
#endif
68
-}
69
70
/* Return the length of a string in target memory or -TARGET_EFAULT if
71
access error. */
72
abi_long target_strlen(abi_ulong gaddr);
73
74
/* Like lock_user but for null terminated strings. */
75
-static inline void *lock_user_string(abi_ulong guest_addr)
76
-{
77
- abi_long len;
78
- len = target_strlen(guest_addr);
79
- if (len < 0)
80
- return NULL;
81
- return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
82
-}
83
+void *lock_user_string(abi_ulong guest_addr);
84
85
/* Helper macros for locking/unlocking a target struct. */
86
#define lock_user_struct(type, host_ptr, guest_addr, copy)    \
87
diff --git a/linux-user/uaccess.c b/linux-user/uaccess.c
41
index XXXXXXX..XXXXXXX 100644
88
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/misc/mps2-scc.c
89
--- a/linux-user/uaccess.c
43
+++ b/hw/misc/mps2-scc.c
90
+++ b/linux-user/uaccess.c
44
@@ -XXX,XX +XXX,XX @@
91
@@ -XXX,XX +XXX,XX @@
45
92
46
REG32(CFG0, 0)
93
#include "qemu.h"
47
REG32(CFG1, 4)
94
48
+REG32(CFG2, 8)
95
+void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
49
REG32(CFG3, 0xc)
50
REG32(CFG4, 0x10)
51
+REG32(CFG5, 0x14)
52
+REG32(CFG6, 0x18)
53
REG32(CFGDATA_RTN, 0xa0)
54
REG32(CFGDATA_OUT, 0xa4)
55
REG32(CFGCTRL, 0xa8)
56
@@ -XXX,XX +XXX,XX @@ REG32(DLL, 0x100)
57
REG32(AID, 0xFF8)
58
REG32(ID, 0xFFC)
59
60
+static int scc_partno(MPS2SCC *s)
61
+{
96
+{
62
+ /* Return the partno field of the SCC_ID (0x524, 0x511, etc) */
97
+ if (!access_ok_untagged(type, guest_addr, len)) {
63
+ return extract32(s->id, 4, 8);
98
+ return NULL;
99
+ }
100
+#ifdef DEBUG_REMAP
101
+ {
102
+ void *addr;
103
+ addr = g_malloc(len);
104
+ if (copy) {
105
+ memcpy(addr, g2h(guest_addr), len);
106
+ } else {
107
+ memset(addr, 0, len);
108
+ }
109
+ return addr;
110
+ }
111
+#else
112
+ return g2h_untagged(guest_addr);
113
+#endif
64
+}
114
+}
65
+
115
+
66
/* Handle a write via the SYS_CFG channel to the specified function/device.
116
+#ifdef DEBUG_REMAP
67
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
117
+void unlock_user(void *host_ptr, abi_ulong guest_addr, long len);
68
*/
118
+{
69
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
119
+ if (!host_ptr) {
70
case A_CFG1:
120
+ return;
71
r = s->cfg1;
121
+ }
72
break;
122
+ if (host_ptr == g2h_untagged(guest_addr)) {
73
+ case A_CFG2:
123
+ return;
74
+ if (scc_partno(s) != 0x524) {
124
+ }
75
+ /* CFG2 reserved on other boards */
125
+ if (len > 0) {
76
+ goto bad_offset;
126
+ memcpy(g2h_untagged(guest_addr), host_ptr, len);
77
+ }
127
+ }
78
+ r = s->cfg2;
128
+ g_free(host_ptr);
79
+ break;
129
+}
80
case A_CFG3:
130
+#endif
81
+ if (scc_partno(s) == 0x524) {
131
+
82
+ /* CFG3 reserved on AN524 */
132
+void *lock_user_string(abi_ulong guest_addr)
83
+ goto bad_offset;
133
+{
84
+ }
134
+ abi_long len = target_strlen(guest_addr);
85
/* These are user-settable DIP switches on the board. We don't
135
+ if (len < 0) {
86
* model that, so just return zeroes.
136
+ return NULL;
87
*/
137
+ }
88
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
138
+ return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
89
case A_CFG4:
139
+}
90
r = s->cfg4;
140
+
91
break;
141
/* copy_from_user() and copy_to_user() are usually used to copy data
92
+ case A_CFG5:
142
* buffers between the target and host. These internally perform
93
+ if (scc_partno(s) != 0x524) {
143
* locking/unlocking of the memory.
94
+ /* CFG5 reserved on other boards */
95
+ goto bad_offset;
96
+ }
97
+ r = s->cfg5;
98
+ break;
99
+ case A_CFG6:
100
+ if (scc_partno(s) != 0x524) {
101
+ /* CFG6 reserved on other boards */
102
+ goto bad_offset;
103
+ }
104
+ r = s->cfg6;
105
+ break;
106
case A_CFGDATA_RTN:
107
r = s->cfgdata_rtn;
108
break;
109
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
110
r = s->id;
111
break;
112
default:
113
+ bad_offset:
114
qemu_log_mask(LOG_GUEST_ERROR,
115
"MPS2 SCC read: bad offset %x\n", (int) offset);
116
r = 0;
117
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
118
led_set_state(s->led[i], extract32(value, i, 1));
119
}
120
break;
121
+ case A_CFG2:
122
+ if (scc_partno(s) != 0x524) {
123
+ /* CFG2 reserved on other boards */
124
+ goto bad_offset;
125
+ }
126
+ /* AN524: QSPI Select signal */
127
+ s->cfg2 = value;
128
+ break;
129
+ case A_CFG5:
130
+ if (scc_partno(s) != 0x524) {
131
+ /* CFG5 reserved on other boards */
132
+ goto bad_offset;
133
+ }
134
+ /* AN524: ACLK frequency in Hz */
135
+ s->cfg5 = value;
136
+ break;
137
+ case A_CFG6:
138
+ if (scc_partno(s) != 0x524) {
139
+ /* CFG6 reserved on other boards */
140
+ goto bad_offset;
141
+ }
142
+ /* AN524: Clock divider for BRAM */
143
+ s->cfg6 = value;
144
+ break;
145
case A_CFGDATA_OUT:
146
s->cfgdata_out = value;
147
break;
148
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
149
s->dll = deposit32(s->dll, 24, 8, extract32(value, 24, 8));
150
break;
151
default:
152
+ bad_offset:
153
qemu_log_mask(LOG_GUEST_ERROR,
154
"MPS2 SCC write: bad offset 0x%x\n", (int) offset);
155
break;
156
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
157
trace_mps2_scc_reset();
158
s->cfg0 = 0;
159
s->cfg1 = 0;
160
+ s->cfg2 = 0;
161
+ s->cfg5 = 0;
162
+ s->cfg6 = 0;
163
s->cfgdata_rtn = 0;
164
s->cfgdata_out = 0;
165
s->cfgctrl = 0x100000;
166
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
167
168
static const VMStateDescription mps2_scc_vmstate = {
169
.name = "mps2-scc",
170
- .version_id = 2,
171
- .minimum_version_id = 2,
172
+ .version_id = 3,
173
+ .minimum_version_id = 3,
174
.fields = (VMStateField[]) {
175
VMSTATE_UINT32(cfg0, MPS2SCC),
176
VMSTATE_UINT32(cfg1, MPS2SCC),
177
+ VMSTATE_UINT32(cfg2, MPS2SCC),
178
+ /* cfg3, cfg4 are read-only so need not be migrated */
179
+ VMSTATE_UINT32(cfg5, MPS2SCC),
180
+ VMSTATE_UINT32(cfg6, MPS2SCC),
181
VMSTATE_UINT32(cfgdata_rtn, MPS2SCC),
182
VMSTATE_UINT32(cfgdata_out, MPS2SCC),
183
VMSTATE_UINT32(cfgctrl, MPS2SCC),
184
--
144
--
185
2.20.1
145
2.20.1
186
146
187
147
diff view generated by jsdifflib
1
The mps2-tz code uses PPCPortInfo data structures to define what
1
From: Richard Henderson <richard.henderson@linaro.org>
2
devices are present and how they are wired up. Currently we use
3
these to specify device types and addresses, but hard-code the
4
interrupt line wiring in each make_* helper function. This works for
5
the two boards we have at the moment, but the AN524 has some devices
6
with different interrupt assignments.
7
2
8
This commit adds the framework to allow PPCPortInfo structures to
3
For copy_*_user, only 0 and -TARGET_EFAULT are returned; no need
9
specify interrupt numbers. We add an array of interrupt numbers to
4
to involve abi_long. Use size_t for lengths. Use bool for the
10
the PPCPortInfo struct, and pass it through to the make_* helpers.
5
lock_user copy argument. Use ssize_t for target_strlen, because
11
The following commit will change the make_* helpers over to using the
6
we can't overflow the host memory space.
12
framework.
13
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210212184902.1251044-19-richard.henderson@linaro.org
12
[PMM: moved fix for ifdef error to previous commit]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210215115138.20465-13-peter.maydell@linaro.org
17
---
14
---
18
hw/arm/mps2-tz.c | 36 ++++++++++++++++++++++++------------
15
linux-user/qemu.h | 12 +++++-------
19
1 file changed, 24 insertions(+), 12 deletions(-)
16
linux-user/uaccess.c | 45 ++++++++++++++++++++++----------------------
17
2 files changed, 28 insertions(+), 29 deletions(-)
20
18
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/mps2-tz.c
21
--- a/linux-user/qemu.h
24
+++ b/hw/arm/mps2-tz.c
22
+++ b/linux-user/qemu.h
25
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
23
@@ -XXX,XX +XXX,XX @@
26
* needs to be plugged into the downstream end of the PPC port.
24
#include "exec/cpu_ldst.h"
25
26
#undef DEBUG_REMAP
27
-#ifdef DEBUG_REMAP
28
-#endif /* DEBUG_REMAP */
29
30
#include "exec/user/abitypes.h"
31
32
@@ -XXX,XX +XXX,XX @@ static inline bool access_ok(CPUState *cpu, int type,
33
* buffers between the target and host. These internally perform
34
* locking/unlocking of the memory.
27
*/
35
*/
28
typedef MemoryRegion *MakeDevFn(MPS2TZMachineState *mms, void *opaque,
36
-abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
29
- const char *name, hwaddr size);
37
-abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
30
+ const char *name, hwaddr size,
38
+int copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
31
+ const int *irqs);
39
+int copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
32
40
33
typedef struct PPCPortInfo {
41
/* Functions for accessing guest memory. The tget and tput functions
34
const char *name;
42
read/write single values, byteswapping as necessary. The lock_user function
35
@@ -XXX,XX +XXX,XX @@ typedef struct PPCPortInfo {
43
@@ -XXX,XX +XXX,XX @@ abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
36
void *opaque;
44
37
hwaddr addr;
45
/* Lock an area of guest memory into the host. If copy is true then the
38
hwaddr size;
46
host area will have the same contents as the guest. */
39
+ int irqs[3]; /* currently no device needs more IRQ lines than this */
47
-void *lock_user(int type, abi_ulong guest_addr, long len, int copy);
40
} PPCPortInfo;
48
+void *lock_user(int type, abi_ulong guest_addr, size_t len, bool copy);
41
49
42
typedef struct PPCInfo {
50
/* Unlock an area of guest memory. The first LEN bytes must be
43
@@ -XXX,XX +XXX,XX @@ typedef struct PPCInfo {
51
flushed back to guest memory. host_ptr = NULL is explicitly
44
} PPCInfo;
52
allowed and does nothing. */
45
53
#ifndef DEBUG_REMAP
46
static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
54
-static inline void unlock_user(void *host_ptr, abi_ulong guest_addr, long len)
47
- void *opaque,
55
+static inline void unlock_user(void *host_ptr, abi_ulong guest_addr, size_t len)
48
- const char *name, hwaddr size)
56
{ }
49
+ void *opaque,
57
#else
50
+ const char *name, hwaddr size,
58
void unlock_user(void *host_ptr, abi_ulong guest_addr, long len);
51
+ const int *irqs)
59
@@ -XXX,XX +XXX,XX @@ void unlock_user(void *host_ptr, abi_ulong guest_addr, long len);
60
61
/* Return the length of a string in target memory or -TARGET_EFAULT if
62
access error. */
63
-abi_long target_strlen(abi_ulong gaddr);
64
+ssize_t target_strlen(abi_ulong gaddr);
65
66
/* Like lock_user but for null terminated strings. */
67
void *lock_user_string(abi_ulong guest_addr);
68
diff --git a/linux-user/uaccess.c b/linux-user/uaccess.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/linux-user/uaccess.c
71
+++ b/linux-user/uaccess.c
72
@@ -XXX,XX +XXX,XX @@
73
74
#include "qemu.h"
75
76
-void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
77
+void *lock_user(int type, abi_ulong guest_addr, size_t len, bool copy)
52
{
78
{
53
/* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
79
if (!access_ok_untagged(type, guest_addr, len)) {
54
* and return a pointer to its MemoryRegion.
80
return NULL;
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
81
@@ -XXX,XX +XXX,XX @@ void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
56
}
82
}
57
83
58
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
84
#ifdef DEBUG_REMAP
59
- const char *name, hwaddr size)
85
-void unlock_user(void *host_ptr, abi_ulong guest_addr, long len);
60
+ const char *name, hwaddr size,
86
+void unlock_user(void *host_ptr, abi_ulong guest_addr, size_t len);
61
+ const int *irqs)
62
{
87
{
63
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
88
if (!host_ptr) {
64
CMSDKAPBUART *uart = opaque;
89
return;
65
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
90
@@ -XXX,XX +XXX,XX @@ void unlock_user(void *host_ptr, abi_ulong guest_addr, long len);
91
if (host_ptr == g2h_untagged(guest_addr)) {
92
return;
93
}
94
- if (len > 0) {
95
+ if (len != 0) {
96
memcpy(g2h_untagged(guest_addr), host_ptr, len);
97
}
98
g_free(host_ptr);
99
@@ -XXX,XX +XXX,XX @@ void unlock_user(void *host_ptr, abi_ulong guest_addr, long len);
100
101
void *lock_user_string(abi_ulong guest_addr)
102
{
103
- abi_long len = target_strlen(guest_addr);
104
+ ssize_t len = target_strlen(guest_addr);
105
if (len < 0) {
106
return NULL;
107
}
108
- return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
109
+ return lock_user(VERIFY_READ, guest_addr, (size_t)len + 1, 1);
66
}
110
}
67
111
68
static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
112
/* copy_from_user() and copy_to_user() are usually used to copy data
69
- const char *name, hwaddr size)
113
* buffers between the target and host. These internally perform
70
+ const char *name, hwaddr size,
114
* locking/unlocking of the memory.
71
+ const int *irqs)
115
*/
116
-abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len)
117
+int copy_from_user(void *hptr, abi_ulong gaddr, size_t len)
72
{
118
{
73
MPS2SCC *scc = opaque;
119
- abi_long ret = 0;
74
DeviceState *sccdev;
120
- void *ghptr;
75
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
121
+ int ret = 0;
122
+ void *ghptr = lock_user(VERIFY_READ, gaddr, len, 1);
123
124
- if ((ghptr = lock_user(VERIFY_READ, gaddr, len, 1))) {
125
+ if (ghptr) {
126
memcpy(hptr, ghptr, len);
127
unlock_user(ghptr, gaddr, 0);
128
- } else
129
+ } else {
130
ret = -TARGET_EFAULT;
131
-
132
+ }
133
return ret;
76
}
134
}
77
135
78
static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
136
-
79
- const char *name, hwaddr size)
137
-abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len)
80
+ const char *name, hwaddr size,
138
+int copy_to_user(abi_ulong gaddr, void *hptr, size_t len)
81
+ const int *irqs)
82
{
139
{
83
MPS2FPGAIO *fpgaio = opaque;
140
- abi_long ret = 0;
84
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
141
- void *ghptr;
85
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
142
+ int ret = 0;
143
+ void *ghptr = lock_user(VERIFY_WRITE, gaddr, len, 0);
144
145
- if ((ghptr = lock_user(VERIFY_WRITE, gaddr, len, 0))) {
146
+ if (ghptr) {
147
memcpy(ghptr, hptr, len);
148
unlock_user(ghptr, gaddr, len);
149
- } else
150
+ } else {
151
ret = -TARGET_EFAULT;
152
+ }
153
154
return ret;
86
}
155
}
87
156
88
static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
157
/* Return the length of a string in target memory or -TARGET_EFAULT if
89
- const char *name, hwaddr size)
158
access error */
90
+ const char *name, hwaddr size,
159
-abi_long target_strlen(abi_ulong guest_addr1)
91
+ const int *irqs)
160
+ssize_t target_strlen(abi_ulong guest_addr1)
92
{
161
{
93
SysBusDevice *s;
162
uint8_t *ptr;
94
NICInfo *nd = &nd_table[0];
163
abi_ulong guest_addr;
95
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
164
- int max_len, len;
165
+ size_t max_len, len;
166
167
guest_addr = guest_addr1;
168
for(;;) {
169
@@ -XXX,XX +XXX,XX @@ abi_long target_strlen(abi_ulong guest_addr1)
170
unlock_user(ptr, guest_addr, 0);
171
guest_addr += len;
172
/* we don't allow wrapping or integer overflow */
173
- if (guest_addr == 0 ||
174
- (guest_addr - guest_addr1) > 0x7fffffff)
175
+ if (guest_addr == 0 || (guest_addr - guest_addr1) > 0x7fffffff) {
176
return -TARGET_EFAULT;
177
- if (len != max_len)
178
+ }
179
+ if (len != max_len) {
180
break;
181
+ }
182
}
183
return guest_addr - guest_addr1;
96
}
184
}
97
98
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
99
- const char *name, hwaddr size)
100
+ const char *name, hwaddr size,
101
+ const int *irqs)
102
{
103
TZMPC *mpc = opaque;
104
int i = mpc - &mms->ssram_mpc[0];
105
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
106
}
107
108
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
109
- const char *name, hwaddr size)
110
+ const char *name, hwaddr size,
111
+ const int *irqs)
112
{
113
PL080State *dma = opaque;
114
int i = dma - &mms->dma[0];
115
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
116
}
117
118
static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
119
- const char *name, hwaddr size)
120
+ const char *name, hwaddr size,
121
+ const int *irqs)
122
{
123
/*
124
* The AN505 has five PL022 SPI controllers.
125
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
126
}
127
128
static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
129
- const char *name, hwaddr size)
130
+ const char *name, hwaddr size,
131
+ const int *irqs)
132
{
133
ArmSbconI2CState *i2c = opaque;
134
SysBusDevice *s;
135
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
136
continue;
137
}
138
139
- mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size);
140
+ mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size,
141
+ pinfo->irqs);
142
portname = g_strdup_printf("port[%d]", port);
143
object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
144
&error_fatal);
145
--
185
--
146
2.20.1
186
2.20.1
147
187
148
188
diff view generated by jsdifflib
1
On the MPS2 boards, the first 32 interrupt lines are entirely
1
From: Richard Henderson <richard.henderson@linaro.org>
2
internal to the SSE; interrupt lines for devices outside the SSE
3
start at 32. In the application notes that document each FPGA image,
4
the interrupt wiring is documented from the point of view of the CPU,
5
so '0' is the first of the SSE's interrupts and the devices in the
6
FPGA image itself are '32' and up: so the UART 0 Receive interrupt is
7
32, the SPI #0 interrupt is 51, and so on.
8
2
9
Within our implementation, because the external interrupts must be
3
Resolve the untagged address once, using thread_cpu.
10
connected to the EXP_IRQ[0...n] lines of the SSE object, we made the
4
Tidy the DEBUG_REMAP code using glib routines.
11
get_sse_irq_in() function take an irqno whose values start at 0 for
12
the first FPGA device interrupt. In this numbering scheme the UART 0
13
Receive interrupt is 0, the SPI #0 interrupt is 19, and so on.
14
5
15
The result of these two different numbering schemes has been that
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
half of the devices were wired up to the wrong IRQs: the UART IRQs
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
are wired up correctly, but the DMA and SPI devices were passing
8
Message-id: 20210212184902.1251044-20-richard.henderson@linaro.org
18
start-at-32 values to get_sse_irq_in() and so being mis-connected.
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
linux-user/uaccess.c | 27 ++++++++++++++-------------
12
1 file changed, 14 insertions(+), 13 deletions(-)
19
13
20
Fix the bug by making get_sse_irq_in() take values specified with the
14
diff --git a/linux-user/uaccess.c b/linux-user/uaccess.c
21
same scheme that the hardware manuals use, to avoid confusion.
22
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20210215115138.20465-12-peter.maydell@linaro.org
26
---
27
hw/arm/mps2-tz.c | 24 +++++++++++++++++-------
28
1 file changed, 17 insertions(+), 7 deletions(-)
29
30
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
31
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/mps2-tz.c
16
--- a/linux-user/uaccess.c
33
+++ b/hw/arm/mps2-tz.c
17
+++ b/linux-user/uaccess.c
34
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
18
@@ -XXX,XX +XXX,XX @@
35
19
36
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
20
void *lock_user(int type, abi_ulong guest_addr, size_t len, bool copy)
37
{
21
{
38
- /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
22
+ void *host_addr;
39
+ /*
40
+ * Return a qemu_irq which will signal IRQ n to all CPUs in the
41
+ * SSE. The irqno should be as the CPU sees it, so the first
42
+ * external-to-the-SSE interrupt is 32.
43
+ */
44
MachineClass *mc = MACHINE_GET_CLASS(mms);
45
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
46
47
- assert(irqno < mmc->numirq);
48
+ assert(irqno >= 32 && irqno < (mmc->numirq + 32));
49
+
23
+
50
+ /*
24
+ guest_addr = cpu_untagged_addr(thread_cpu, guest_addr);
51
+ * Convert from "CPU irq number" (as listed in the FPGA image
25
if (!access_ok_untagged(type, guest_addr, len)) {
52
+ * documentation) to the SSE external-interrupt number.
26
return NULL;
53
+ */
27
}
54
+ irqno -= 32;
28
+ host_addr = g2h_untagged(guest_addr);
55
29
#ifdef DEBUG_REMAP
56
if (mc->max_cpus > 1) {
30
- {
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
31
- void *addr;
58
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
32
- addr = g_malloc(len);
59
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
33
- if (copy) {
60
CMSDKAPBUART *uart = opaque;
34
- memcpy(addr, g2h(guest_addr), len);
61
int i = uart - &mms->uart[0];
35
- } else {
62
- int rxirqno = i * 2;
36
- memset(addr, 0, len);
63
- int txirqno = i * 2 + 1;
37
- }
64
- int combirqno = i + 10;
38
- return addr;
65
+ int rxirqno = i * 2 + 32;
39
+ if (copy) {
66
+ int txirqno = i * 2 + 33;
40
+ host_addr = g_memdup(host_addr, len);
67
+ int combirqno = i + 42;
41
+ } else {
68
SysBusDevice *s;
42
+ host_addr = g_malloc0(len);
69
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
43
}
70
44
-#else
71
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
45
- return g2h_untagged(guest_addr);
72
46
#endif
73
s = SYS_BUS_DEVICE(mms->lan9118);
47
+ return host_addr;
74
sysbus_realize_and_unref(s, &error_fatal);
75
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 16));
76
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
77
return sysbus_mmio_get_region(s, 0);
78
}
48
}
79
49
80
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
50
#ifdef DEBUG_REMAP
81
&error_fatal);
51
void unlock_user(void *host_ptr, abi_ulong guest_addr, size_t len);
82
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
52
{
83
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
53
+ void *host_ptr_conv;
84
- get_sse_irq_in(mms, 15));
54
+
85
+ get_sse_irq_in(mms, 47));
55
if (!host_ptr) {
86
56
return;
87
/* Most of the devices in the FPGA are behind Peripheral Protection
57
}
88
* Controllers. The required order for initializing things is:
58
- if (host_ptr == g2h_untagged(guest_addr)) {
59
+ host_ptr_conv = g2h(thread_cpu, guest_addr);
60
+ if (host_ptr == host_ptr_conv) {
61
return;
62
}
63
if (len != 0) {
64
- memcpy(g2h_untagged(guest_addr), host_ptr, len);
65
+ memcpy(host_ptr_conv, host_ptr, len);
66
}
67
g_free(host_ptr);
68
}
89
--
69
--
90
2.20.1
70
2.20.1
91
71
92
72
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for FEAT_SSBS. SSBS (Speculative Store Bypass Safe) is an
3
This is the prctl bit that controls whether syscalls accept tagged
4
optional feature in ARMv8.0, and mandatory in ARMv8.5.
4
addresses. See Documentation/arm64/tagged-address-abi.rst in the
5
linux kernel.
5
6
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210216224543.16142-2-rebecca@nuviainc.com
9
Message-id: 20210212184902.1251044-21-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/cpu.h | 15 ++++++++++++++-
12
linux-user/aarch64/target_syscall.h | 4 ++++
12
target/arm/internals.h | 6 ++++++
13
target/arm/cpu-param.h | 3 +++
13
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++++++++
14
target/arm/cpu.h | 31 +++++++++++++++++++++++++++++
14
target/arm/translate-a64.c | 12 ++++++++++++
15
linux-user/syscall.c | 24 ++++++++++++++++++++++
15
4 files changed, 69 insertions(+), 1 deletion(-)
16
4 files changed, 62 insertions(+)
16
17
18
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/aarch64/target_syscall.h
21
+++ b/linux-user/aarch64/target_syscall.h
22
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
23
# define TARGET_PR_PAC_APDBKEY (1 << 3)
24
# define TARGET_PR_PAC_APGAKEY (1 << 4)
25
26
+#define TARGET_PR_SET_TAGGED_ADDR_CTRL 55
27
+#define TARGET_PR_GET_TAGGED_ADDR_CTRL 56
28
+# define TARGET_PR_TAGGED_ADDR_ENABLE (1UL << 0)
29
+
30
#endif /* AARCH64_TARGET_SYSCALL_H */
31
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu-param.h
34
+++ b/target/arm/cpu-param.h
35
@@ -XXX,XX +XXX,XX @@
36
37
#ifdef CONFIG_USER_ONLY
38
#define TARGET_PAGE_BITS 12
39
+# ifdef TARGET_AARCH64
40
+# define TARGET_TAGGED_ADDRESSES
41
+# endif
42
#else
43
/*
44
* ARMv7 and later CPUs have 4K pages minimum, but ARMv5 and v6
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
45
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
47
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
48
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
49
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
22
#define SCTLR_TE (1U << 30) /* AArch32 only */
50
const struct arm_boot_info *boot_info;
23
#define SCTLR_EnIB (1U << 30) /* v8.3, AArch64 only */
51
/* Store GICv3CPUState to access from this struct */
24
#define SCTLR_EnIA (1U << 31) /* v8.3, AArch64 only */
52
void *gicv3state;
25
+#define SCTLR_DSSBS_32 (1U << 31) /* v8.5, AArch32 only */
53
+
26
#define SCTLR_BT0 (1ULL << 35) /* v8.5-BTI */
54
+#ifdef TARGET_TAGGED_ADDRESSES
27
#define SCTLR_BT1 (1ULL << 36) /* v8.5-BTI */
55
+ /* Linux syscall tagged address support */
28
#define SCTLR_ITFSB (1ULL << 37) /* v8.5-MemTag */
56
+ bool tagged_addr_enable;
29
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
57
+#endif
30
#define SCTLR_TCF (3ULL << 40) /* v8.5-MemTag */
58
} CPUARMState;
31
#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
59
32
#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
60
static inline void set_feature(CPUARMState *env, int feature)
33
-#define SCTLR_DSSBS (1ULL << 44) /* v8.5 */
61
@@ -XXX,XX +XXX,XX @@ static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs *x)
34
+#define SCTLR_DSSBS_64 (1ULL << 44) /* v8.5, AArch64 only */
62
*/
35
63
#define PAGE_BTI PAGE_TARGET_1
36
#define CPTR_TCPAC (1U << 31)
64
37
#define CPTR_TTA (1U << 20)
65
+#ifdef TARGET_TAGGED_ADDRESSES
38
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
66
+/**
39
#define CPSR_IL (1U << 20)
67
+ * cpu_untagged_addr:
40
#define CPSR_DIT (1U << 21)
68
+ * @cs: CPU context
41
#define CPSR_PAN (1U << 22)
69
+ * @x: tagged address
42
+#define CPSR_SSBS (1U << 23)
70
+ *
43
#define CPSR_J (1U << 24)
71
+ * Remove any address tag from @x. This is explicitly related to the
44
#define CPSR_IT_0_1 (3U << 25)
72
+ * linux syscall TIF_TAGGED_ADDR setting, not TBI in general.
45
#define CPSR_Q (1U << 27)
73
+ *
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
74
+ * There should be a better place to put this, but we need this in
47
#define PSTATE_A (1U << 8)
75
+ * include/exec/cpu_ldst.h, and not some place linux-user specific.
48
#define PSTATE_D (1U << 9)
76
+ */
49
#define PSTATE_BTYPE (3U << 10)
77
+static inline target_ulong cpu_untagged_addr(CPUState *cs, target_ulong x)
50
+#define PSTATE_SSBS (1U << 12)
51
#define PSTATE_IL (1U << 20)
52
#define PSTATE_SS (1U << 21)
53
#define PSTATE_PAN (1U << 22)
54
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
55
return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
56
}
57
58
+static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
59
+{
78
+{
60
+ return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
79
+ ARMCPU *cpu = ARM_CPU(cs);
80
+ if (cpu->env.tagged_addr_enable) {
81
+ /*
82
+ * TBI is enabled for userspace but not kernelspace addresses.
83
+ * Only clear the tag if bit 55 is clear.
84
+ */
85
+ x &= sextract64(x, 0, 56);
86
+ }
87
+ return x;
61
+}
88
+}
89
+#endif
62
+
90
+
63
/*
91
/*
64
* 64-bit feature tests via id registers.
92
* Naming convention for isar_feature functions:
65
*/
93
* Functions which test 32-bit ID registers should have _aa32_ in
66
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
94
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
67
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
95
index XXXXXXX..XXXXXXX 100644
68
}
96
--- a/linux-user/syscall.c
69
97
+++ b/linux-user/syscall.c
70
+static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
98
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
71
+{
99
}
72
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
100
}
73
+}
101
return -TARGET_EINVAL;
102
+ case TARGET_PR_SET_TAGGED_ADDR_CTRL:
103
+ {
104
+ abi_ulong valid_mask = TARGET_PR_TAGGED_ADDR_ENABLE;
105
+ CPUARMState *env = cpu_env;
74
+
106
+
75
/*
107
+ if ((arg2 & ~valid_mask) || arg3 || arg4 || arg5) {
76
* Feature tests for "does this exist in either 32-bit or 64-bit?"
108
+ return -TARGET_EINVAL;
77
*/
109
+ }
78
diff --git a/target/arm/internals.h b/target/arm/internals.h
110
+ env->tagged_addr_enable = arg2 & TARGET_PR_TAGGED_ADDR_ENABLE;
79
index XXXXXXX..XXXXXXX 100644
111
+ return 0;
80
--- a/target/arm/internals.h
112
+ }
81
+++ b/target/arm/internals.h
113
+ case TARGET_PR_GET_TAGGED_ADDR_CTRL:
82
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
114
+ {
83
if (isar_feature_aa32_dit(id)) {
115
+ abi_long ret = 0;
84
valid |= CPSR_DIT;
116
+ CPUARMState *env = cpu_env;
85
}
86
+ if (isar_feature_aa32_ssbs(id)) {
87
+ valid |= CPSR_SSBS;
88
+ }
89
90
return valid;
91
}
92
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
93
if (isar_feature_aa64_dit(id)) {
94
valid |= PSTATE_DIT;
95
}
96
+ if (isar_feature_aa64_ssbs(id)) {
97
+ valid |= PSTATE_SSBS;
98
+ }
99
if (isar_feature_aa64_mte(id)) {
100
valid |= PSTATE_TCO;
101
}
102
diff --git a/target/arm/helper.c b/target/arm/helper.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/helper.c
105
+++ b/target/arm/helper.c
106
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dit_reginfo = {
107
.readfn = aa64_dit_read, .writefn = aa64_dit_write
108
};
109
110
+static uint64_t aa64_ssbs_read(CPUARMState *env, const ARMCPRegInfo *ri)
111
+{
112
+ return env->pstate & PSTATE_SSBS;
113
+}
114
+
117
+
115
+static void aa64_ssbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
118
+ if (arg2 || arg3 || arg4 || arg5) {
116
+ uint64_t value)
119
+ return -TARGET_EINVAL;
117
+{
120
+ }
118
+ env->pstate = (env->pstate & ~PSTATE_SSBS) | (value & PSTATE_SSBS);
121
+ if (env->tagged_addr_enable) {
119
+}
122
+ ret |= TARGET_PR_TAGGED_ADDR_ENABLE;
120
+
123
+ }
121
+static const ARMCPRegInfo ssbs_reginfo = {
124
+ return ret;
122
+ .name = "SSBS", .state = ARM_CP_STATE_AA64,
125
+ }
123
+ .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 6,
126
#endif /* AARCH64 */
124
+ .type = ARM_CP_NO_RAW, .access = PL0_RW,
127
case PR_GET_SECCOMP:
125
+ .readfn = aa64_ssbs_read, .writefn = aa64_ssbs_write
128
case PR_SET_SECCOMP:
126
+};
127
+
128
static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
129
const ARMCPRegInfo *ri,
130
bool isread)
131
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
132
if (cpu_isar_feature(aa64_dit, cpu)) {
133
define_one_arm_cp_reg(cpu, &dit_reginfo);
134
}
135
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
136
+ define_one_arm_cp_reg(cpu, &ssbs_reginfo);
137
+ }
138
139
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
140
define_arm_cp_regs(cpu, vhe_reginfo);
141
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
142
env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
143
env->daif |= mask;
144
145
+ if (cpu_isar_feature(aa32_ssbs, env_archcpu(env))) {
146
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_32) {
147
+ env->uncached_cpsr |= CPSR_SSBS;
148
+ } else {
149
+ env->uncached_cpsr &= ~CPSR_SSBS;
150
+ }
151
+ }
152
+
153
if (new_mode == ARM_CPU_MODE_HYP) {
154
env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
155
env->elr_el[2] = env->regs[15];
156
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
157
new_mode |= PSTATE_TCO;
158
}
159
160
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
161
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_64) {
162
+ new_mode |= PSTATE_SSBS;
163
+ } else {
164
+ new_mode &= ~PSTATE_SSBS;
165
+ }
166
+ }
167
+
168
pstate_write(env, PSTATE_DAIF | new_mode);
169
env->aarch64 = 1;
170
aarch64_restore_sp(env, new_el);
171
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
172
index XXXXXXX..XXXXXXX 100644
173
--- a/target/arm/translate-a64.c
174
+++ b/target/arm/translate-a64.c
175
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
176
tcg_temp_free_i32(t1);
177
break;
178
179
+ case 0x19: /* SSBS */
180
+ if (!dc_isar_feature(aa64_ssbs, s)) {
181
+ goto do_unallocated;
182
+ }
183
+ if (crm & 1) {
184
+ set_pstate_bits(PSTATE_SSBS);
185
+ } else {
186
+ clear_pstate_bits(PSTATE_SSBS);
187
+ }
188
+ /* Don't need to rebuild hflags since SSBS is a nop */
189
+ break;
190
+
191
case 0x1a: /* DIT */
192
if (!dc_isar_feature(aa64_dit, s)) {
193
goto do_unallocated;
194
--
129
--
195
2.20.1
130
2.20.1
196
131
197
132
diff view generated by jsdifflib
1
The MPS2 board has 2 LEDs, but the MPS3 board has 10 LEDs. The
1
From: Richard Henderson <richard.henderson@linaro.org>
2
FPGAIO device is similar on both sets of boards, but the LED0
3
register has correspondingly more bits that have an effect. Add a
4
device property for number of LEDs.
5
2
3
Use simple arithmetic instead of a conditional
4
move when tbi0 != tbi1.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210212184902.1251044-22-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210215115138.20465-6-peter.maydell@linaro.org
10
---
10
---
11
include/hw/misc/mps2-fpgaio.h | 5 ++++-
11
target/arm/translate-a64.c | 25 ++++++++++++++-----------
12
hw/misc/mps2-fpgaio.c | 31 +++++++++++++++++++++++--------
12
1 file changed, 14 insertions(+), 11 deletions(-)
13
2 files changed, 27 insertions(+), 9 deletions(-)
14
13
15
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/mps2-fpgaio.h
16
--- a/target/arm/translate-a64.c
18
+++ b/include/hw/misc/mps2-fpgaio.h
17
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void gen_top_byte_ignore(DisasContext *s, TCGv_i64 dst,
20
#define TYPE_MPS2_FPGAIO "mps2-fpgaio"
19
/* Sign-extend from bit 55. */
21
OBJECT_DECLARE_SIMPLE_TYPE(MPS2FPGAIO, MPS2_FPGAIO)
20
tcg_gen_sextract_i64(dst, src, 0, 56);
22
21
23
+#define MPS2FPGAIO_MAX_LEDS 32
22
- if (tbi != 3) {
24
+
23
- TCGv_i64 tcg_zero = tcg_const_i64(0);
25
struct MPS2FPGAIO {
24
-
26
/*< private >*/
25
- /*
27
SysBusDevice parent_obj;
26
- * The two TBI bits differ.
28
27
- * If tbi0, then !tbi1: only use the extension if positive.
29
/*< public >*/
28
- * if !tbi0, then tbi1: only use the extension if negative.
30
MemoryRegion iomem;
29
- */
31
- LEDState *led[2];
30
- tcg_gen_movcond_i64(tbi == 1 ? TCG_COND_GE : TCG_COND_LT,
32
+ LEDState *led[MPS2FPGAIO_MAX_LEDS];
31
- dst, dst, tcg_zero, dst, src);
33
+ uint32_t num_leds;
32
- tcg_temp_free_i64(tcg_zero);
34
33
+ switch (tbi) {
35
uint32_t led0;
34
+ case 1:
36
uint32_t prescale;
35
+ /* tbi0 but !tbi1: only use the extension if positive */
37
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
36
+ tcg_gen_and_i64(dst, dst, src);
38
index XXXXXXX..XXXXXXX 100644
37
+ break;
39
--- a/hw/misc/mps2-fpgaio.c
38
+ case 2:
40
+++ b/hw/misc/mps2-fpgaio.c
39
+ /* !tbi0 but tbi1: only use the extension if negative */
41
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
40
+ tcg_gen_or_i64(dst, dst, src);
42
41
+ break;
43
switch (offset) {
42
+ case 3:
44
case A_LED0:
43
+ /* tbi0 and tbi1: always use the extension */
45
- s->led0 = value & 0x3;
44
+ break;
46
- led_set_state(s->led[0], value & 0x01);
45
+ default:
47
- led_set_state(s->led[1], value & 0x02);
46
+ g_assert_not_reached();
48
+ if (s->num_leds != 0) {
47
}
49
+ uint32_t i;
50
+
51
+ s->led0 = value & MAKE_64BIT_MASK(0, s->num_leds);
52
+ for (i = 0; i < s->num_leds; i++) {
53
+ led_set_state(s->led[i], value & (1 << i));
54
+ }
55
+ }
56
break;
57
case A_PRESCALE:
58
resync_counter(s);
59
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_reset(DeviceState *dev)
60
s->pscntr = 0;
61
s->pscntr_sync_ticks = now;
62
63
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
64
+ for (size_t i = 0; i < s->num_leds; i++) {
65
device_cold_reset(DEVICE(s->led[i]));
66
}
48
}
67
}
49
}
68
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_init(Object *obj)
69
static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
70
{
71
MPS2FPGAIO *s = MPS2_FPGAIO(dev);
72
+ uint32_t i;
73
74
- s->led[0] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
75
- LED_COLOR_GREEN, "USERLED0");
76
- s->led[1] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
77
- LED_COLOR_GREEN, "USERLED1");
78
+ if (s->num_leds > MPS2FPGAIO_MAX_LEDS) {
79
+ error_setg(errp, "num-leds cannot be greater than %d",
80
+ MPS2FPGAIO_MAX_LEDS);
81
+ return;
82
+ }
83
+
84
+ for (i = 0; i < s->num_leds; i++) {
85
+ g_autofree char *ledname = g_strdup_printf("USERLED%d", i);
86
+ s->led[i] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
87
+ LED_COLOR_GREEN, ledname);
88
+ }
89
}
90
91
static bool mps2_fpgaio_counters_needed(void *opaque)
92
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_fpgaio_vmstate = {
93
static Property mps2_fpgaio_properties[] = {
94
/* Frequency of the prescale counter */
95
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
96
+ /* Number of LEDs controlled by LED0 register */
97
+ DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
98
DEFINE_PROP_END_OF_LIST(),
99
};
100
101
--
50
--
102
2.20.1
51
2.20.1
103
52
104
53
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Enable FEAT_SSBS for the "max" 32-bit CPU.
3
We were fudging TBI1 enabled to speed up the generated code.
4
Now that we've improved the code generation, remove this.
5
Also, tidy the comment to reflect the current code.
4
6
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
7
The pauth test was testing a kernel address (-1) and making
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
incorrect assumptions about TBI1; stick to userland addresses.
7
Message-id: 20210216224543.16142-4-rebecca@nuviainc.com
9
8
[PMM: fix typo causing compilation failure]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210212184902.1251044-23-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/cpu.c | 4 ++++
15
target/arm/internals.h | 4 ++--
12
1 file changed, 4 insertions(+)
16
target/arm/cpu.c | 10 +++-------
17
tests/tcg/aarch64/pauth-2.c | 1 -
18
3 files changed, 5 insertions(+), 10 deletions(-)
13
19
20
diff --git a/target/arm/internals.h b/target/arm/internals.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/internals.h
23
+++ b/target/arm/internals.h
24
@@ -XXX,XX +XXX,XX @@ static inline bool tcma_check(uint32_t desc, int bit55, int ptr_tag)
25
*/
26
static inline uint64_t useronly_clean_ptr(uint64_t ptr)
27
{
28
- /* TBI is known to be enabled. */
29
#ifdef CONFIG_USER_ONLY
30
- ptr = sextract64(ptr, 0, 56);
31
+ /* TBI0 is known to be enabled, while TBI1 is disabled. */
32
+ ptr &= sextract64(ptr, 0, 56);
33
#endif
34
return ptr;
35
}
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
36
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
38
--- a/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
39
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
40
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
19
t = cpu->isar.id_pfr0;
41
env->vfp.zcr_el[1] = MIN(cpu->sve_max_vq - 1, 3);
20
t = FIELD_DP32(t, ID_PFR0, DIT, 1);
42
}
21
cpu->isar.id_pfr0 = t;
43
/*
22
+
44
- * Enable TBI0 and TBI1. While the real kernel only enables TBI0,
23
+ t = cpu->isar.id_pfr2;
45
- * turning on both here will produce smaller code and otherwise
24
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
46
- * make no difference to the user-level emulation.
25
+ cpu->isar.id_pfr2 = t;
47
- *
26
}
48
- * In sve_probe_page, we assume that this is set.
27
#endif
49
- * Do not modify this without other changes.
50
+ * Enable TBI0 but not TBI1.
51
+ * Note that this must match useronly_clean_ptr.
52
*/
53
- env->cp15.tcr_el[1].raw_tcr = (3ULL << 37);
54
+ env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
55
#else
56
/* Reset into the highest available EL */
57
if (arm_feature(env, ARM_FEATURE_EL3)) {
58
diff --git a/tests/tcg/aarch64/pauth-2.c b/tests/tcg/aarch64/pauth-2.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/tests/tcg/aarch64/pauth-2.c
61
+++ b/tests/tcg/aarch64/pauth-2.c
62
@@ -XXX,XX +XXX,XX @@ void do_test(uint64_t value)
63
int main()
64
{
65
do_test(0);
66
- do_test(-1);
67
do_test(0xda004acedeadbeefull);
68
return 0;
28
}
69
}
29
--
70
--
30
2.20.1
71
2.20.1
31
72
32
73
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Cortex-A53 supports 40bits of address space. sbsa-ref's memory starts
3
These prctl fields are required for the function of MTE.
4
above this limit.
5
4
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Acked-by: Leif Lindholm <leif@nuviainc.com>
7
Message-id: 20210212184902.1251044-24-richard.henderson@linaro.org
9
Message-id: 20210216150122.3830863-2-marcin.juszkiewicz@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
hw/arm/sbsa-ref.c | 1 -
10
linux-user/aarch64/target_syscall.h | 9 ++++++
13
1 file changed, 1 deletion(-)
11
linux-user/syscall.c | 43 +++++++++++++++++++++++++++++
12
2 files changed, 52 insertions(+)
14
13
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
14
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
16
--- a/linux-user/aarch64/target_syscall.h
18
+++ b/hw/arm/sbsa-ref.c
17
+++ b/linux-user/aarch64/target_syscall.h
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
18
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
20
};
19
#define TARGET_PR_SET_TAGGED_ADDR_CTRL 55
21
20
#define TARGET_PR_GET_TAGGED_ADDR_CTRL 56
22
static const char * const valid_cpus[] = {
21
# define TARGET_PR_TAGGED_ADDR_ENABLE (1UL << 0)
23
- ARM_CPU_TYPE_NAME("cortex-a53"),
22
+/* MTE tag check fault modes */
24
ARM_CPU_TYPE_NAME("cortex-a57"),
23
+# define TARGET_PR_MTE_TCF_SHIFT 1
25
ARM_CPU_TYPE_NAME("cortex-a72"),
24
+# define TARGET_PR_MTE_TCF_NONE (0UL << TARGET_PR_MTE_TCF_SHIFT)
26
};
25
+# define TARGET_PR_MTE_TCF_SYNC (1UL << TARGET_PR_MTE_TCF_SHIFT)
26
+# define TARGET_PR_MTE_TCF_ASYNC (2UL << TARGET_PR_MTE_TCF_SHIFT)
27
+# define TARGET_PR_MTE_TCF_MASK (3UL << TARGET_PR_MTE_TCF_SHIFT)
28
+/* MTE tag inclusion mask */
29
+# define TARGET_PR_MTE_TAG_SHIFT 3
30
+# define TARGET_PR_MTE_TAG_MASK (0xffffUL << TARGET_PR_MTE_TAG_SHIFT)
31
32
#endif /* AARCH64_TARGET_SYSCALL_H */
33
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/linux-user/syscall.c
36
+++ b/linux-user/syscall.c
37
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
38
{
39
abi_ulong valid_mask = TARGET_PR_TAGGED_ADDR_ENABLE;
40
CPUARMState *env = cpu_env;
41
+ ARMCPU *cpu = env_archcpu(env);
42
+
43
+ if (cpu_isar_feature(aa64_mte, cpu)) {
44
+ valid_mask |= TARGET_PR_MTE_TCF_MASK;
45
+ valid_mask |= TARGET_PR_MTE_TAG_MASK;
46
+ }
47
48
if ((arg2 & ~valid_mask) || arg3 || arg4 || arg5) {
49
return -TARGET_EINVAL;
50
}
51
env->tagged_addr_enable = arg2 & TARGET_PR_TAGGED_ADDR_ENABLE;
52
+
53
+ if (cpu_isar_feature(aa64_mte, cpu)) {
54
+ switch (arg2 & TARGET_PR_MTE_TCF_MASK) {
55
+ case TARGET_PR_MTE_TCF_NONE:
56
+ case TARGET_PR_MTE_TCF_SYNC:
57
+ case TARGET_PR_MTE_TCF_ASYNC:
58
+ break;
59
+ default:
60
+ return -EINVAL;
61
+ }
62
+
63
+ /*
64
+ * Write PR_MTE_TCF to SCTLR_EL1[TCF0].
65
+ * Note that the syscall values are consistent with hw.
66
+ */
67
+ env->cp15.sctlr_el[1] =
68
+ deposit64(env->cp15.sctlr_el[1], 38, 2,
69
+ arg2 >> TARGET_PR_MTE_TCF_SHIFT);
70
+
71
+ /*
72
+ * Write PR_MTE_TAG to GCR_EL1[Exclude].
73
+ * Note that the syscall uses an include mask,
74
+ * and hardware uses an exclude mask -- invert.
75
+ */
76
+ env->cp15.gcr_el1 =
77
+ deposit64(env->cp15.gcr_el1, 0, 16,
78
+ ~arg2 >> TARGET_PR_MTE_TAG_SHIFT);
79
+ arm_rebuild_hflags(env);
80
+ }
81
return 0;
82
}
83
case TARGET_PR_GET_TAGGED_ADDR_CTRL:
84
{
85
abi_long ret = 0;
86
CPUARMState *env = cpu_env;
87
+ ARMCPU *cpu = env_archcpu(env);
88
89
if (arg2 || arg3 || arg4 || arg5) {
90
return -TARGET_EINVAL;
91
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
92
if (env->tagged_addr_enable) {
93
ret |= TARGET_PR_TAGGED_ADDR_ENABLE;
94
}
95
+ if (cpu_isar_feature(aa64_mte, cpu)) {
96
+ /* See above. */
97
+ ret |= (extract64(env->cp15.sctlr_el[1], 38, 2)
98
+ << TARGET_PR_MTE_TCF_SHIFT);
99
+ ret = deposit64(ret, TARGET_PR_MTE_TAG_SHIFT, 16,
100
+ ~env->cp15.gcr_el1);
101
+ }
102
return ret;
103
}
104
#endif /* AARCH64 */
27
--
105
--
28
2.20.1
106
2.20.1
29
107
30
108
diff view generated by jsdifflib
1
Set the FPGAIO num-leds and have-switches properties explicitly
1
From: Richard Henderson <richard.henderson@linaro.org>
2
per-board, rather than relying on the defaults. The AN505 and AN521
3
both have the same settings as the default values, but the AN524 will
4
be different.
5
2
3
Remember the PROT_MTE bit as PAGE_MTE/PAGE_TARGET_2.
4
Otherwise this does not yet have effect.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210212184902.1251044-25-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210215115138.20465-8-peter.maydell@linaro.org
10
---
10
---
11
hw/arm/mps2-tz.c | 9 +++++++++
11
include/exec/cpu-all.h | 1 +
12
1 file changed, 9 insertions(+)
12
linux-user/syscall_defs.h | 1 +
13
target/arm/cpu.h | 1 +
14
linux-user/mmap.c | 22 ++++++++++++++--------
15
4 files changed, 17 insertions(+), 8 deletions(-)
13
16
14
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/mps2-tz.c
19
--- a/include/exec/cpu-all.h
17
+++ b/hw/arm/mps2-tz.c
20
+++ b/include/exec/cpu-all.h
18
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
21
@@ -XXX,XX +XXX,XX @@ extern intptr_t qemu_host_page_mask;
19
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
22
#endif
20
uint32_t len_oscclk;
23
/* Target-specific bits that will be used via page_get_flags(). */
21
const uint32_t *oscclk;
24
#define PAGE_TARGET_1 0x0080
22
+ uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
25
+#define PAGE_TARGET_2 0x0200
23
+ bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
26
24
const char *armsse_type;
27
#if defined(CONFIG_USER_ONLY)
25
};
28
void page_dump(FILE *f);
26
29
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
27
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
30
index XXXXXXX..XXXXXXX 100644
28
const char *name, hwaddr size)
31
--- a/linux-user/syscall_defs.h
29
{
32
+++ b/linux-user/syscall_defs.h
30
MPS2FPGAIO *fpgaio = opaque;
33
@@ -XXX,XX +XXX,XX @@ struct target_winsize {
31
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
34
32
35
#ifdef TARGET_AARCH64
33
object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
36
#define TARGET_PROT_BTI 0x10
34
+ qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
37
+#define TARGET_PROT_MTE 0x20
35
+ qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
38
#endif
36
sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
39
37
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
40
/* Common */
38
}
41
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
39
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
42
index XXXXXXX..XXXXXXX 100644
40
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
43
--- a/target/arm/cpu.h
41
mmc->oscclk = an505_oscclk;
44
+++ b/target/arm/cpu.h
42
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
45
@@ -XXX,XX +XXX,XX @@ static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs *x)
43
+ mmc->fpgaio_num_leds = 2;
46
* AArch64 usage of the PAGE_TARGET_* bits for linux-user.
44
+ mmc->fpgaio_has_switches = false;
47
*/
45
mmc->armsse_type = TYPE_IOTKIT;
48
#define PAGE_BTI PAGE_TARGET_1
46
}
49
+#define PAGE_MTE PAGE_TARGET_2
47
50
48
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
51
#ifdef TARGET_TAGGED_ADDRESSES
49
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
52
/**
50
mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
53
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
51
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
54
index XXXXXXX..XXXXXXX 100644
52
+ mmc->fpgaio_num_leds = 2;
55
--- a/linux-user/mmap.c
53
+ mmc->fpgaio_has_switches = false;
56
+++ b/linux-user/mmap.c
54
mmc->armsse_type = TYPE_SSE200;
57
@@ -XXX,XX +XXX,XX @@ static int validate_prot_to_pageflags(int *host_prot, int prot)
55
}
58
| (prot & PROT_EXEC ? PROT_READ : 0);
59
60
#ifdef TARGET_AARCH64
61
- /*
62
- * The PROT_BTI bit is only accepted if the cpu supports the feature.
63
- * Since this is the unusual case, don't bother checking unless
64
- * the bit has been requested. If set and valid, record the bit
65
- * within QEMU's page_flags.
66
- */
67
- if (prot & TARGET_PROT_BTI) {
68
+ {
69
ARMCPU *cpu = ARM_CPU(thread_cpu);
70
- if (cpu_isar_feature(aa64_bti, cpu)) {
71
+
72
+ /*
73
+ * The PROT_BTI bit is only accepted if the cpu supports the feature.
74
+ * Since this is the unusual case, don't bother checking unless
75
+ * the bit has been requested. If set and valid, record the bit
76
+ * within QEMU's page_flags.
77
+ */
78
+ if ((prot & TARGET_PROT_BTI) && cpu_isar_feature(aa64_bti, cpu)) {
79
valid |= TARGET_PROT_BTI;
80
page_flags |= PAGE_BTI;
81
}
82
+ /* Similarly for the PROT_MTE bit. */
83
+ if ((prot & TARGET_PROT_MTE) && cpu_isar_feature(aa64_mte, cpu)) {
84
+ valid |= TARGET_PROT_MTE;
85
+ page_flags |= PAGE_MTE;
86
+ }
87
}
88
#endif
56
89
57
--
90
--
58
2.20.1
91
2.20.1
59
92
60
93
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
IDAU is specific to M-profile. KVM only supports A-profile.
3
Move everything related to syndromes to a new file,
4
Restrict this interface to TCG, as it is pointless (and
4
which can be shared with linux-user.
5
confusing) on a KVM-only build.
6
5
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210221222617.2579610-2-f4bug@amsat.org
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210212184902.1251044-26-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
target/arm/cpu.c | 7 -------
12
target/arm/internals.h | 245 +-----------------------------------
14
target/arm/cpu_tcg.c | 8 ++++++++
13
target/arm/syndrome.h | 273 +++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 8 insertions(+), 7 deletions(-)
14
2 files changed, 274 insertions(+), 244 deletions(-)
15
create mode 100644 target/arm/syndrome.h
16
16
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.c
19
--- a/target/arm/internals.h
20
+++ b/target/arm/cpu.c
20
+++ b/target/arm/internals.h
21
@@ -XXX,XX +XXX,XX @@ static const TypeInfo arm_cpu_type_info = {
21
@@ -XXX,XX +XXX,XX @@
22
.class_init = arm_cpu_class_init,
22
#define TARGET_ARM_INTERNALS_H
23
};
23
24
24
#include "hw/registerfields.h"
25
-static const TypeInfo idau_interface_type_info = {
25
+#include "syndrome.h"
26
- .name = TYPE_IDAU_INTERFACE,
26
27
- .parent = TYPE_INTERFACE,
27
/* register banks for CPU modes */
28
- .class_size = sizeof(IDAUInterfaceClass),
28
#define BANK_USRSYS 0
29
@@ -XXX,XX +XXX,XX @@ static inline bool extended_addresses_enabled(CPUARMState *env)
30
(arm_feature(env, ARM_FEATURE_LPAE) && (tcr->raw_tcr & TTBCR_EAE));
31
}
32
33
-/* Valid Syndrome Register EC field values */
34
-enum arm_exception_class {
35
- EC_UNCATEGORIZED = 0x00,
36
- EC_WFX_TRAP = 0x01,
37
- EC_CP15RTTRAP = 0x03,
38
- EC_CP15RRTTRAP = 0x04,
39
- EC_CP14RTTRAP = 0x05,
40
- EC_CP14DTTRAP = 0x06,
41
- EC_ADVSIMDFPACCESSTRAP = 0x07,
42
- EC_FPIDTRAP = 0x08,
43
- EC_PACTRAP = 0x09,
44
- EC_CP14RRTTRAP = 0x0c,
45
- EC_BTITRAP = 0x0d,
46
- EC_ILLEGALSTATE = 0x0e,
47
- EC_AA32_SVC = 0x11,
48
- EC_AA32_HVC = 0x12,
49
- EC_AA32_SMC = 0x13,
50
- EC_AA64_SVC = 0x15,
51
- EC_AA64_HVC = 0x16,
52
- EC_AA64_SMC = 0x17,
53
- EC_SYSTEMREGISTERTRAP = 0x18,
54
- EC_SVEACCESSTRAP = 0x19,
55
- EC_INSNABORT = 0x20,
56
- EC_INSNABORT_SAME_EL = 0x21,
57
- EC_PCALIGNMENT = 0x22,
58
- EC_DATAABORT = 0x24,
59
- EC_DATAABORT_SAME_EL = 0x25,
60
- EC_SPALIGNMENT = 0x26,
61
- EC_AA32_FPTRAP = 0x28,
62
- EC_AA64_FPTRAP = 0x2c,
63
- EC_SERROR = 0x2f,
64
- EC_BREAKPOINT = 0x30,
65
- EC_BREAKPOINT_SAME_EL = 0x31,
66
- EC_SOFTWARESTEP = 0x32,
67
- EC_SOFTWARESTEP_SAME_EL = 0x33,
68
- EC_WATCHPOINT = 0x34,
69
- EC_WATCHPOINT_SAME_EL = 0x35,
70
- EC_AA32_BKPT = 0x38,
71
- EC_VECTORCATCH = 0x3a,
72
- EC_AA64_BKPT = 0x3c,
29
-};
73
-};
30
-
74
-
31
static void arm_cpu_register_types(void)
75
-#define ARM_EL_EC_SHIFT 26
32
{
76
-#define ARM_EL_IL_SHIFT 25
33
const size_t cpu_count = ARRAY_SIZE(arm_cpus);
77
-#define ARM_EL_ISV_SHIFT 24
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
78
-#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
35
if (cpu_count) {
79
-#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
36
size_t i;
80
-
37
81
-static inline uint32_t syn_get_ec(uint32_t syn)
38
- type_register_static(&idau_interface_type_info);
82
-{
39
for (i = 0; i < cpu_count; ++i) {
83
- return syn >> ARM_EL_EC_SHIFT;
40
arm_cpu_register(&arm_cpus[i]);
84
-}
41
}
85
-
42
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
86
-/* Utility functions for constructing various kinds of syndrome value.
43
index XXXXXXX..XXXXXXX 100644
87
- * Note that in general we follow the AArch64 syndrome values; in a
44
--- a/target/arm/cpu_tcg.c
88
- * few cases the value in HSR for exceptions taken to AArch32 Hyp
45
+++ b/target/arm/cpu_tcg.c
89
- * mode differs slightly, and we fix this up when populating HSR in
90
- * arm_cpu_do_interrupt_aarch32_hyp().
91
- * The exception is FP/SIMD access traps -- these report extra information
92
- * when taking an exception to AArch32. For those we include the extra coproc
93
- * and TA fields, and mask them out when taking the exception to AArch64.
94
- */
95
-static inline uint32_t syn_uncategorized(void)
96
-{
97
- return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL;
98
-}
99
-
100
-static inline uint32_t syn_aa64_svc(uint32_t imm16)
101
-{
102
- return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
103
-}
104
-
105
-static inline uint32_t syn_aa64_hvc(uint32_t imm16)
106
-{
107
- return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
108
-}
109
-
110
-static inline uint32_t syn_aa64_smc(uint32_t imm16)
111
-{
112
- return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
113
-}
114
-
115
-static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_16bit)
116
-{
117
- return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
118
- | (is_16bit ? 0 : ARM_EL_IL);
119
-}
120
-
121
-static inline uint32_t syn_aa32_hvc(uint32_t imm16)
122
-{
123
- return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
124
-}
125
-
126
-static inline uint32_t syn_aa32_smc(void)
127
-{
128
- return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
129
-}
130
-
131
-static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
132
-{
133
- return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
134
-}
135
-
136
-static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_16bit)
137
-{
138
- return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
139
- | (is_16bit ? 0 : ARM_EL_IL);
140
-}
141
-
142
-static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
143
- int crn, int crm, int rt,
144
- int isread)
145
-{
146
- return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL
147
- | (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5)
148
- | (crm << 1) | isread;
149
-}
150
-
151
-static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
152
- int crn, int crm, int rt, int isread,
153
- bool is_16bit)
154
-{
155
- return (EC_CP14RTTRAP << ARM_EL_EC_SHIFT)
156
- | (is_16bit ? 0 : ARM_EL_IL)
157
- | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
158
- | (crn << 10) | (rt << 5) | (crm << 1) | isread;
159
-}
160
-
161
-static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2,
162
- int crn, int crm, int rt, int isread,
163
- bool is_16bit)
164
-{
165
- return (EC_CP15RTTRAP << ARM_EL_EC_SHIFT)
166
- | (is_16bit ? 0 : ARM_EL_IL)
167
- | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
168
- | (crn << 10) | (rt << 5) | (crm << 1) | isread;
169
-}
170
-
171
-static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm,
172
- int rt, int rt2, int isread,
173
- bool is_16bit)
174
-{
175
- return (EC_CP14RRTTRAP << ARM_EL_EC_SHIFT)
176
- | (is_16bit ? 0 : ARM_EL_IL)
177
- | (cv << 24) | (cond << 20) | (opc1 << 16)
178
- | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
179
-}
180
-
181
-static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
182
- int rt, int rt2, int isread,
183
- bool is_16bit)
184
-{
185
- return (EC_CP15RRTTRAP << ARM_EL_EC_SHIFT)
186
- | (is_16bit ? 0 : ARM_EL_IL)
187
- | (cv << 24) | (cond << 20) | (opc1 << 16)
188
- | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
189
-}
190
-
191
-static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
192
-{
193
- /* AArch32 FP trap or any AArch64 FP/SIMD trap: TA == 0 coproc == 0xa */
194
- return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
195
- | (is_16bit ? 0 : ARM_EL_IL)
196
- | (cv << 24) | (cond << 20) | 0xa;
197
-}
198
-
199
-static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
200
-{
201
- /* AArch32 SIMD trap: TA == 1 coproc == 0 */
202
- return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
203
- | (is_16bit ? 0 : ARM_EL_IL)
204
- | (cv << 24) | (cond << 20) | (1 << 5);
205
-}
206
-
207
-static inline uint32_t syn_sve_access_trap(void)
208
-{
209
- return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
210
-}
211
-
212
-static inline uint32_t syn_pactrap(void)
213
-{
214
- return EC_PACTRAP << ARM_EL_EC_SHIFT;
215
-}
216
-
217
-static inline uint32_t syn_btitrap(int btype)
218
-{
219
- return (EC_BTITRAP << ARM_EL_EC_SHIFT) | btype;
220
-}
221
-
222
-static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
223
-{
224
- return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
225
- | ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
226
-}
227
-
228
-static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
229
- int ea, int cm, int s1ptw,
230
- int wnr, int fsc)
231
-{
232
- return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
233
- | ARM_EL_IL
234
- | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7)
235
- | (wnr << 6) | fsc;
236
-}
237
-
238
-static inline uint32_t syn_data_abort_with_iss(int same_el,
239
- int sas, int sse, int srt,
240
- int sf, int ar,
241
- int ea, int cm, int s1ptw,
242
- int wnr, int fsc,
243
- bool is_16bit)
244
-{
245
- return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
246
- | (is_16bit ? 0 : ARM_EL_IL)
247
- | ARM_EL_ISV | (sas << 22) | (sse << 21) | (srt << 16)
248
- | (sf << 15) | (ar << 14)
249
- | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
250
-}
251
-
252
-static inline uint32_t syn_swstep(int same_el, int isv, int ex)
253
-{
254
- return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
255
- | ARM_EL_IL | (isv << 24) | (ex << 6) | 0x22;
256
-}
257
-
258
-static inline uint32_t syn_watchpoint(int same_el, int cm, int wnr)
259
-{
260
- return (EC_WATCHPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
261
- | ARM_EL_IL | (cm << 8) | (wnr << 6) | 0x22;
262
-}
263
-
264
-static inline uint32_t syn_breakpoint(int same_el)
265
-{
266
- return (EC_BREAKPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
267
- | ARM_EL_IL | 0x22;
268
-}
269
-
270
-static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
271
-{
272
- return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) |
273
- (is_16bit ? 0 : (1 << ARM_EL_IL_SHIFT)) |
274
- (cv << 24) | (cond << 20) | ti;
275
-}
276
-
277
/* Update a QEMU watchpoint based on the information the guest has set in the
278
* DBGWCR<n>_EL1 and DBGWVR<n>_EL1 registers.
279
*/
280
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
281
new file mode 100644
282
index XXXXXXX..XXXXXXX
283
--- /dev/null
284
+++ b/target/arm/syndrome.h
46
@@ -XXX,XX +XXX,XX @@
285
@@ -XXX,XX +XXX,XX @@
47
#include "hw/core/tcg-cpu-ops.h"
286
+/*
48
#endif /* CONFIG_TCG */
287
+ * QEMU ARM CPU -- syndrome functions and types
49
#include "internals.h"
288
+ *
50
+#include "target/arm/idau.h"
289
+ * Copyright (c) 2014 Linaro Ltd
51
290
+ *
52
/* CPU models. These are not needed for the AArch64 linux-user build. */
291
+ * This program is free software; you can redistribute it and/or
53
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
292
+ * modify it under the terms of the GNU General Public License
54
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
293
+ * as published by the Free Software Foundation; either version 2
55
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
294
+ * of the License, or (at your option) any later version.
56
};
295
+ *
57
296
+ * This program is distributed in the hope that it will be useful,
58
+static const TypeInfo idau_interface_type_info = {
297
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
59
+ .name = TYPE_IDAU_INTERFACE,
298
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60
+ .parent = TYPE_INTERFACE,
299
+ * GNU General Public License for more details.
61
+ .class_size = sizeof(IDAUInterfaceClass),
300
+ *
301
+ * You should have received a copy of the GNU General Public License
302
+ * along with this program; if not, see
303
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
304
+ *
305
+ * This header defines functions, types, etc which need to be shared
306
+ * between different source files within target/arm/ but which are
307
+ * private to it and not required by the rest of QEMU.
308
+ */
309
+
310
+#ifndef TARGET_ARM_SYNDROME_H
311
+#define TARGET_ARM_SYNDROME_H
312
+
313
+/* Valid Syndrome Register EC field values */
314
+enum arm_exception_class {
315
+ EC_UNCATEGORIZED = 0x00,
316
+ EC_WFX_TRAP = 0x01,
317
+ EC_CP15RTTRAP = 0x03,
318
+ EC_CP15RRTTRAP = 0x04,
319
+ EC_CP14RTTRAP = 0x05,
320
+ EC_CP14DTTRAP = 0x06,
321
+ EC_ADVSIMDFPACCESSTRAP = 0x07,
322
+ EC_FPIDTRAP = 0x08,
323
+ EC_PACTRAP = 0x09,
324
+ EC_CP14RRTTRAP = 0x0c,
325
+ EC_BTITRAP = 0x0d,
326
+ EC_ILLEGALSTATE = 0x0e,
327
+ EC_AA32_SVC = 0x11,
328
+ EC_AA32_HVC = 0x12,
329
+ EC_AA32_SMC = 0x13,
330
+ EC_AA64_SVC = 0x15,
331
+ EC_AA64_HVC = 0x16,
332
+ EC_AA64_SMC = 0x17,
333
+ EC_SYSTEMREGISTERTRAP = 0x18,
334
+ EC_SVEACCESSTRAP = 0x19,
335
+ EC_INSNABORT = 0x20,
336
+ EC_INSNABORT_SAME_EL = 0x21,
337
+ EC_PCALIGNMENT = 0x22,
338
+ EC_DATAABORT = 0x24,
339
+ EC_DATAABORT_SAME_EL = 0x25,
340
+ EC_SPALIGNMENT = 0x26,
341
+ EC_AA32_FPTRAP = 0x28,
342
+ EC_AA64_FPTRAP = 0x2c,
343
+ EC_SERROR = 0x2f,
344
+ EC_BREAKPOINT = 0x30,
345
+ EC_BREAKPOINT_SAME_EL = 0x31,
346
+ EC_SOFTWARESTEP = 0x32,
347
+ EC_SOFTWARESTEP_SAME_EL = 0x33,
348
+ EC_WATCHPOINT = 0x34,
349
+ EC_WATCHPOINT_SAME_EL = 0x35,
350
+ EC_AA32_BKPT = 0x38,
351
+ EC_VECTORCATCH = 0x3a,
352
+ EC_AA64_BKPT = 0x3c,
62
+};
353
+};
63
+
354
+
64
static void arm_tcg_cpu_register_types(void)
355
+#define ARM_EL_EC_SHIFT 26
65
{
356
+#define ARM_EL_IL_SHIFT 25
66
size_t i;
357
+#define ARM_EL_ISV_SHIFT 24
67
358
+#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
68
+ type_register_static(&idau_interface_type_info);
359
+#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
69
for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) {
360
+
70
arm_cpu_register(&arm_tcg_cpus[i]);
361
+static inline uint32_t syn_get_ec(uint32_t syn)
71
}
362
+{
363
+ return syn >> ARM_EL_EC_SHIFT;
364
+}
365
+
366
+/*
367
+ * Utility functions for constructing various kinds of syndrome value.
368
+ * Note that in general we follow the AArch64 syndrome values; in a
369
+ * few cases the value in HSR for exceptions taken to AArch32 Hyp
370
+ * mode differs slightly, and we fix this up when populating HSR in
371
+ * arm_cpu_do_interrupt_aarch32_hyp().
372
+ * The exception is FP/SIMD access traps -- these report extra information
373
+ * when taking an exception to AArch32. For those we include the extra coproc
374
+ * and TA fields, and mask them out when taking the exception to AArch64.
375
+ */
376
+static inline uint32_t syn_uncategorized(void)
377
+{
378
+ return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL;
379
+}
380
+
381
+static inline uint32_t syn_aa64_svc(uint32_t imm16)
382
+{
383
+ return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
384
+}
385
+
386
+static inline uint32_t syn_aa64_hvc(uint32_t imm16)
387
+{
388
+ return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
389
+}
390
+
391
+static inline uint32_t syn_aa64_smc(uint32_t imm16)
392
+{
393
+ return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
394
+}
395
+
396
+static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_16bit)
397
+{
398
+ return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
399
+ | (is_16bit ? 0 : ARM_EL_IL);
400
+}
401
+
402
+static inline uint32_t syn_aa32_hvc(uint32_t imm16)
403
+{
404
+ return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
405
+}
406
+
407
+static inline uint32_t syn_aa32_smc(void)
408
+{
409
+ return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
410
+}
411
+
412
+static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
413
+{
414
+ return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
415
+}
416
+
417
+static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_16bit)
418
+{
419
+ return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
420
+ | (is_16bit ? 0 : ARM_EL_IL);
421
+}
422
+
423
+static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
424
+ int crn, int crm, int rt,
425
+ int isread)
426
+{
427
+ return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL
428
+ | (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5)
429
+ | (crm << 1) | isread;
430
+}
431
+
432
+static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
433
+ int crn, int crm, int rt, int isread,
434
+ bool is_16bit)
435
+{
436
+ return (EC_CP14RTTRAP << ARM_EL_EC_SHIFT)
437
+ | (is_16bit ? 0 : ARM_EL_IL)
438
+ | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
439
+ | (crn << 10) | (rt << 5) | (crm << 1) | isread;
440
+}
441
+
442
+static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2,
443
+ int crn, int crm, int rt, int isread,
444
+ bool is_16bit)
445
+{
446
+ return (EC_CP15RTTRAP << ARM_EL_EC_SHIFT)
447
+ | (is_16bit ? 0 : ARM_EL_IL)
448
+ | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
449
+ | (crn << 10) | (rt << 5) | (crm << 1) | isread;
450
+}
451
+
452
+static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm,
453
+ int rt, int rt2, int isread,
454
+ bool is_16bit)
455
+{
456
+ return (EC_CP14RRTTRAP << ARM_EL_EC_SHIFT)
457
+ | (is_16bit ? 0 : ARM_EL_IL)
458
+ | (cv << 24) | (cond << 20) | (opc1 << 16)
459
+ | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
460
+}
461
+
462
+static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
463
+ int rt, int rt2, int isread,
464
+ bool is_16bit)
465
+{
466
+ return (EC_CP15RRTTRAP << ARM_EL_EC_SHIFT)
467
+ | (is_16bit ? 0 : ARM_EL_IL)
468
+ | (cv << 24) | (cond << 20) | (opc1 << 16)
469
+ | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
470
+}
471
+
472
+static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
473
+{
474
+ /* AArch32 FP trap or any AArch64 FP/SIMD trap: TA == 0 coproc == 0xa */
475
+ return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
476
+ | (is_16bit ? 0 : ARM_EL_IL)
477
+ | (cv << 24) | (cond << 20) | 0xa;
478
+}
479
+
480
+static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
481
+{
482
+ /* AArch32 SIMD trap: TA == 1 coproc == 0 */
483
+ return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
484
+ | (is_16bit ? 0 : ARM_EL_IL)
485
+ | (cv << 24) | (cond << 20) | (1 << 5);
486
+}
487
+
488
+static inline uint32_t syn_sve_access_trap(void)
489
+{
490
+ return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
491
+}
492
+
493
+static inline uint32_t syn_pactrap(void)
494
+{
495
+ return EC_PACTRAP << ARM_EL_EC_SHIFT;
496
+}
497
+
498
+static inline uint32_t syn_btitrap(int btype)
499
+{
500
+ return (EC_BTITRAP << ARM_EL_EC_SHIFT) | btype;
501
+}
502
+
503
+static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
504
+{
505
+ return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
506
+ | ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
507
+}
508
+
509
+static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
510
+ int ea, int cm, int s1ptw,
511
+ int wnr, int fsc)
512
+{
513
+ return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
514
+ | ARM_EL_IL
515
+ | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7)
516
+ | (wnr << 6) | fsc;
517
+}
518
+
519
+static inline uint32_t syn_data_abort_with_iss(int same_el,
520
+ int sas, int sse, int srt,
521
+ int sf, int ar,
522
+ int ea, int cm, int s1ptw,
523
+ int wnr, int fsc,
524
+ bool is_16bit)
525
+{
526
+ return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
527
+ | (is_16bit ? 0 : ARM_EL_IL)
528
+ | ARM_EL_ISV | (sas << 22) | (sse << 21) | (srt << 16)
529
+ | (sf << 15) | (ar << 14)
530
+ | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
531
+}
532
+
533
+static inline uint32_t syn_swstep(int same_el, int isv, int ex)
534
+{
535
+ return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
536
+ | ARM_EL_IL | (isv << 24) | (ex << 6) | 0x22;
537
+}
538
+
539
+static inline uint32_t syn_watchpoint(int same_el, int cm, int wnr)
540
+{
541
+ return (EC_WATCHPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
542
+ | ARM_EL_IL | (cm << 8) | (wnr << 6) | 0x22;
543
+}
544
+
545
+static inline uint32_t syn_breakpoint(int same_el)
546
+{
547
+ return (EC_BREAKPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
548
+ | ARM_EL_IL | 0x22;
549
+}
550
+
551
+static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
552
+{
553
+ return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) |
554
+ (is_16bit ? 0 : (1 << ARM_EL_IL_SHIFT)) |
555
+ (cv << 24) | (cond << 20) | ti;
556
+}
557
+
558
+#endif /* TARGET_ARM_SYNDROME_H */
72
--
559
--
73
2.20.1
560
2.20.1
74
561
75
562
diff view generated by jsdifflib
1
In the mps2-tz board code, we handle devices whose interrupt lines
1
From: Richard Henderson <richard.henderson@linaro.org>
2
must be wired to all CPUs by creating IRQ splitter devices for the
3
AN521, because it has 2 CPUs, but wiring the device IRQ directly to
4
the SSE/IoTKit input for the AN505, which has only 1 CPU.
5
2
6
We can avoid making an explicit check on the board type constant by
3
A proper syndrome is required to fill in the proper si_code.
7
instead creating and using the IRQ splitters for any board with more
4
Use page_get_flags to determine permission vs translation for user-only.
8
than 1 CPU. This avoids having to add extra cases to the
9
conditionals every time we add new boards.
10
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210212184902.1251044-27-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210215115138.20465-9-peter.maydell@linaro.org
15
---
10
---
16
hw/arm/mps2-tz.c | 19 +++++++++----------
11
linux-user/aarch64/cpu_loop.c | 24 +++++++++++++++++++++---
17
1 file changed, 9 insertions(+), 10 deletions(-)
12
target/arm/tlb_helper.c | 15 +++++++++------
13
2 files changed, 30 insertions(+), 9 deletions(-)
18
14
19
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/mps2-tz.c
17
--- a/linux-user/aarch64/cpu_loop.c
22
+++ b/hw/arm/mps2-tz.c
18
+++ b/linux-user/aarch64/cpu_loop.c
23
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
19
@@ -XXX,XX +XXX,XX @@
24
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
20
#include "cpu_loop-common.h"
21
#include "qemu/guest-random.h"
22
#include "hw/semihosting/common-semi.h"
23
+#include "target/arm/syndrome.h"
24
25
#define get_user_code_u32(x, gaddr, env) \
26
({ abi_long __r = get_user_u32((x), (gaddr)); \
27
@@ -XXX,XX +XXX,XX @@
28
void cpu_loop(CPUARMState *env)
25
{
29
{
26
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
30
CPUState *cs = env_cpu(env);
27
- MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
31
- int trapnr;
28
+ MachineClass *mc = MACHINE_GET_CLASS(mms);
32
+ int trapnr, ec, fsc;
29
33
abi_long ret;
30
assert(irqno < MPS2TZ_NUMIRQ);
34
target_siginfo_t info;
31
35
32
- switch (mmc->fpga_type) {
36
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
33
- case FPGA_AN505:
37
case EXCP_DATA_ABORT:
34
- return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
38
info.si_signo = TARGET_SIGSEGV;
35
- case FPGA_AN521:
39
info.si_errno = 0;
36
+ if (mc->max_cpus > 1) {
40
- /* XXX: check env->error_code */
37
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
41
- info.si_code = TARGET_SEGV_MAPERR;
38
- default:
42
info._sifields._sigfault._addr = env->exception.vaddress;
39
- g_assert_not_reached();
43
+
40
+ } else {
44
+ /* We should only arrive here with EC in {DATAABORT, INSNABORT}. */
41
+ return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
45
+ ec = syn_get_ec(env->exception.syndrome);
46
+ assert(ec == EC_DATAABORT || ec == EC_INSNABORT);
47
+
48
+ /* Both EC have the same format for FSC, or close enough. */
49
+ fsc = extract32(env->exception.syndrome, 0, 6);
50
+ switch (fsc) {
51
+ case 0x04 ... 0x07: /* Translation fault, level {0-3} */
52
+ info.si_code = TARGET_SEGV_MAPERR;
53
+ break;
54
+ case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
55
+ case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
56
+ info.si_code = TARGET_SEGV_ACCERR;
57
+ break;
58
+ default:
59
+ g_assert_not_reached();
60
+ }
61
+
62
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
63
break;
64
case EXCP_DEBUG:
65
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/tlb_helper.c
68
+++ b/target/arm/tlb_helper.c
69
@@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
70
bool probe, uintptr_t retaddr)
71
{
72
ARMCPU *cpu = ARM_CPU(cs);
73
+ ARMMMUFaultInfo fi = {};
74
75
#ifdef CONFIG_USER_ONLY
76
- cpu->env.exception.vaddress = address;
77
- if (access_type == MMU_INST_FETCH) {
78
- cs->exception_index = EXCP_PREFETCH_ABORT;
79
+ int flags = page_get_flags(useronly_clean_ptr(address));
80
+ if (flags & PAGE_VALID) {
81
+ fi.type = ARMFault_Permission;
82
} else {
83
- cs->exception_index = EXCP_DATA_ABORT;
84
+ fi.type = ARMFault_Translation;
42
}
85
}
43
}
86
- cpu_loop_exit_restore(cs, retaddr);
44
87
+
45
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
88
+ /* now we have a real cpu fault */
46
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
89
+ cpu_restore_state(cs, retaddr, true);
90
+ arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
91
#else
92
hwaddr phys_addr;
93
target_ulong page_size;
94
int prot, ret;
95
MemTxAttrs attrs = {};
96
- ARMMMUFaultInfo fi = {};
97
ARMCacheAttrs cacheattrs = {};
47
98
48
/*
99
/*
49
- * The AN521 needs us to create splitters to feed the IRQ inputs
50
- * for each CPU in the SSE-200 from each device in the board.
51
+ * If this board has more than one CPU, then we need to create splitters
52
+ * to feed the IRQ inputs for each CPU in the SSE from each device in the
53
+ * board. If there is only one CPU, we can just wire the device IRQ
54
+ * directly to the SSE's IRQ input.
55
*/
56
- if (mmc->fpga_type == FPGA_AN521) {
57
+ if (mc->max_cpus > 1) {
58
for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
59
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
60
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
61
--
100
--
62
2.20.1
101
2.20.1
63
102
64
103
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Let add 'max' cpu while work goes on adding newer CPU types than
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Cortex-A72. This allows us to check SVE etc support.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
5
Message-id: 20210212184902.1251044-28-richard.henderson@linaro.org
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Acked-by: Leif Lindholm <leif@nuviainc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210216150122.3830863-3-marcin.juszkiewicz@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
hw/arm/sbsa-ref.c | 1 +
8
linux-user/aarch64/target_signal.h | 2 ++
13
1 file changed, 1 insertion(+)
9
linux-user/aarch64/cpu_loop.c | 3 +++
10
2 files changed, 5 insertions(+)
14
11
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
12
diff --git a/linux-user/aarch64/target_signal.h b/linux-user/aarch64/target_signal.h
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
14
--- a/linux-user/aarch64/target_signal.h
18
+++ b/hw/arm/sbsa-ref.c
15
+++ b/linux-user/aarch64/target_signal.h
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
16
@@ -XXX,XX +XXX,XX @@ typedef struct target_sigaltstack {
20
static const char * const valid_cpus[] = {
17
21
ARM_CPU_TYPE_NAME("cortex-a57"),
18
#include "../generic/signal.h"
22
ARM_CPU_TYPE_NAME("cortex-a72"),
19
23
+ ARM_CPU_TYPE_NAME("max"),
20
+#define TARGET_SEGV_MTESERR 9 /* Synchronous ARM MTE exception */
24
};
21
+
25
22
#define TARGET_ARCH_HAS_SETUP_FRAME
26
static bool cpu_type_valid(const char *cpu)
23
#endif /* AARCH64_TARGET_SIGNAL_H */
24
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/linux-user/aarch64/cpu_loop.c
27
+++ b/linux-user/aarch64/cpu_loop.c
28
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
29
case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
30
info.si_code = TARGET_SEGV_ACCERR;
31
break;
32
+ case 0x11: /* Synchronous Tag Check Fault */
33
+ info.si_code = TARGET_SEGV_MTESERR;
34
+ break;
35
default:
36
g_assert_not_reached();
37
}
27
--
38
--
28
2.20.1
39
2.20.1
29
40
30
41
diff view generated by jsdifflib
1
From: Peter Collingbourne <pcc@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Section D6.7 of the ARM ARM states:
3
The real kernel collects _TIF_MTE_ASYNC_FAULT into the current thread's
4
state on any kernel entry (interrupt, exception etc), and then delivers
5
the signal in advance of resuming the thread.
4
6
5
For the purpose of determining Tag Check Fault handling, unprivileged
7
This means that while the signal won't be delivered immediately, it will
6
load and store instructions are treated as if executed at EL0 when
8
not be delayed forever -- at minimum it will be delivered after the next
7
executed at either:
9
clock interrupt.
8
- EL1, when the Effective value of PSTATE.UAO is 0.
9
- EL2, when both the Effective value of HCR_EL2.{E2H, TGE} is {1, 1}
10
and the Effective value of PSTATE.UAO is 0.
11
10
12
ARM has confirmed a defect in the pseudocode function
11
We don't have a clock interrupt in linux-user, so we issue a cpu_kick
13
AArch64.TagCheckFault that makes it inconsistent with the above
12
to signal a return to the main loop at the end of the current TB.
14
wording. The remedy is to adjust references to PSTATE.EL in that
15
function to instead refer to AArch64.AccessUsesEL(acctype), so
16
that unprivileged instructions use SCTLR_EL1.TCF0 and TFSRE0_EL1.
17
The exception type for synchronous tag check faults remains unchanged.
18
13
19
This patch implements the described change by partially reverting
20
commits 50244cc76abc and cc97b0019bb5.
21
22
Signed-off-by: Peter Collingbourne <pcc@google.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 20210219201820.2672077-1-pcc@google.com
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210212184902.1251044-29-richard.henderson@linaro.org
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
18
---
28
target/arm/helper.c | 2 +-
19
linux-user/aarch64/target_signal.h | 1 +
29
target/arm/mte_helper.c | 13 +++++++++----
20
linux-user/aarch64/cpu_loop.c | 11 +++++++++++
30
2 files changed, 10 insertions(+), 5 deletions(-)
21
target/arm/mte_helper.c | 10 ++++++++++
22
3 files changed, 22 insertions(+)
31
23
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
diff --git a/linux-user/aarch64/target_signal.h b/linux-user/aarch64/target_signal.h
33
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
26
--- a/linux-user/aarch64/target_signal.h
35
+++ b/target/arm/helper.c
27
+++ b/linux-user/aarch64/target_signal.h
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
28
@@ -XXX,XX +XXX,XX @@ typedef struct target_sigaltstack {
37
if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
29
38
&& tbid
30
#include "../generic/signal.h"
39
&& !(env->pstate & PSTATE_TCO)
31
40
- && (sctlr & SCTLR_TCF)
32
+#define TARGET_SEGV_MTEAERR 8 /* Asynchronous ARM MTE error */
41
+ && (sctlr & SCTLR_TCF0)
33
#define TARGET_SEGV_MTESERR 9 /* Synchronous ARM MTE exception */
42
&& allocation_tag_access_enabled(env, 0, sctlr)) {
34
43
flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
35
#define TARGET_ARCH_HAS_SETUP_FRAME
36
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/linux-user/aarch64/cpu_loop.c
39
+++ b/linux-user/aarch64/cpu_loop.c
40
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
41
EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
42
abort();
44
}
43
}
44
+
45
+ /* Check for MTE asynchronous faults */
46
+ if (unlikely(env->cp15.tfsr_el[0])) {
47
+ env->cp15.tfsr_el[0] = 0;
48
+ info.si_signo = TARGET_SIGSEGV;
49
+ info.si_errno = 0;
50
+ info._sifields._sigfault._addr = 0;
51
+ info.si_code = TARGET_SEGV_MTEAERR;
52
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
53
+ }
54
+
55
process_pending_signals(env);
56
/* Exception return on AArch64 always clears the exclusive monitor,
57
* so any return to running guest code implies this.
45
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
58
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
46
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/mte_helper.c
60
--- a/target/arm/mte_helper.c
48
+++ b/target/arm/mte_helper.c
61
+++ b/target/arm/mte_helper.c
49
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
62
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
50
reg_el = regime_el(env, arm_mmu_idx);
63
select = 0;
51
sctlr = env->cp15.sctlr_el[reg_el];
64
}
52
65
env->cp15.tfsr_el[el] |= 1 << select;
53
- el = arm_current_el(env);
66
+#ifdef CONFIG_USER_ONLY
54
- if (el == 0) {
67
+ /*
55
+ switch (arm_mmu_idx) {
68
+ * Stand in for a timer irq, setting _TIF_MTE_ASYNC_FAULT,
56
+ case ARMMMUIdx_E10_0:
69
+ * which then sends a SIGSEGV when the thread is next scheduled.
57
+ case ARMMMUIdx_E20_0:
70
+ * This cpu will return to the main loop at the end of the TB,
58
+ el = 0;
71
+ * which is rather sooner than "normal". But the alternative
59
tcf = extract64(sctlr, 38, 2);
72
+ * is waiting until the next syscall.
60
- } else {
73
+ */
61
+ break;
74
+ qemu_cpu_kick(env_cpu(env));
62
+ default:
75
+#endif
63
+ el = reg_el;
76
break;
64
tcf = extract64(sctlr, 40, 2);
77
65
}
78
default:
66
67
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
68
env->exception.vaddress = dirty_ptr;
69
70
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
71
- syn = syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, is_write, 0x11);
72
+ syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
73
+ is_write, 0x11);
74
raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
75
/* noreturn, but fall through to the assert anyway */
76
77
--
79
--
78
2.20.1
80
2.20.1
79
81
80
82
diff view generated by jsdifflib
1
The AN505 and AN521 have the same device layout, but the AN524 is
1
From: Richard Henderson <richard.henderson@linaro.org>
2
somewhat different. Allow for more than one PPCInfo array, which can
3
be selected based on the board type.
4
2
3
Use the now-saved PAGE_ANON and PAGE_MTE bits,
4
and the per-page saved data.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210212184902.1251044-30-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210215115138.20465-16-peter.maydell@linaro.org
8
---
10
---
9
hw/arm/mps2-tz.c | 16 ++++++++++++++--
11
target/arm/mte_helper.c | 29 +++++++++++++++++++++++++++--
10
1 file changed, 14 insertions(+), 2 deletions(-)
12
1 file changed, 27 insertions(+), 2 deletions(-)
11
13
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2-tz.c
16
--- a/target/arm/mte_helper.c
15
+++ b/hw/arm/mps2-tz.c
17
+++ b/target/arm/mte_helper.c
16
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
18
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
17
MemoryRegion *system_memory = get_system_memory();
19
int tag_size, uintptr_t ra)
18
DeviceState *iotkitdev;
20
{
19
DeviceState *dev_splitter;
21
#ifdef CONFIG_USER_ONLY
20
+ const PPCInfo *ppcs;
22
- /* Tag storage not implemented. */
21
+ int num_ppcs;
23
- return NULL;
22
int i;
24
+ uint64_t clean_ptr = useronly_clean_ptr(ptr);
23
25
+ int flags = page_get_flags(clean_ptr);
24
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
26
+ uint8_t *tags;
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
27
+ uintptr_t index;
26
* + wire up the PPC's control lines to the IoTKit object
28
+
27
*/
29
+ if (!(flags & (ptr_access == MMU_DATA_STORE ? PAGE_WRITE : PAGE_READ))) {
28
30
+ /* SIGSEGV */
29
- const PPCInfo ppcs[] = { {
31
+ arm_cpu_tlb_fill(env_cpu(env), ptr, ptr_size, ptr_access,
30
+ const PPCInfo an505_ppcs[] = { {
32
+ ptr_mmu_idx, false, ra);
31
.name = "apb_ppcexp0",
32
.ports = {
33
{ "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
34
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
35
},
36
};
37
38
- for (i = 0; i < ARRAY_SIZE(ppcs); i++) {
39
+ switch (mmc->fpga_type) {
40
+ case FPGA_AN505:
41
+ case FPGA_AN521:
42
+ ppcs = an505_ppcs;
43
+ num_ppcs = ARRAY_SIZE(an505_ppcs);
44
+ break;
45
+ default:
46
+ g_assert_not_reached();
33
+ g_assert_not_reached();
47
+ }
34
+ }
48
+
35
+
49
+ for (i = 0; i < num_ppcs; i++) {
36
+ /* Require both MAP_ANON and PROT_MTE for the page. */
50
const PPCInfo *ppcinfo = &ppcs[i];
37
+ if (!(flags & PAGE_ANON) || !(flags & PAGE_MTE)) {
51
TZPPC *ppc = &mms->ppc[i];
38
+ return NULL;
52
DeviceState *ppcdev;
39
+ }
40
+
41
+ tags = page_get_target_data(clean_ptr);
42
+ if (tags == NULL) {
43
+ size_t alloc_size = TARGET_PAGE_SIZE >> (LOG2_TAG_GRANULE + 1);
44
+ tags = page_alloc_target_data(clean_ptr, alloc_size);
45
+ assert(tags != NULL);
46
+ }
47
+
48
+ index = extract32(ptr, LOG2_TAG_GRANULE + 1,
49
+ TARGET_PAGE_BITS - LOG2_TAG_GRANULE - 1);
50
+ return tags + index;
51
#else
52
uintptr_t index;
53
CPUIOTLBEntry *iotlbentry;
53
--
54
--
54
2.20.1
55
2.20.1
55
56
56
57
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We will move this code in the next commit. Clean it up
4
first to avoid checkpatch.pl errors.
5
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210221222617.2579610-3-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210212184902.1251044-31-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
7
---
11
target/arm/cpu.c | 12 ++++++++----
8
target/arm/cpu.c | 15 +++++++++++++++
12
1 file changed, 8 insertions(+), 4 deletions(-)
9
1 file changed, 15 insertions(+)
13
10
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
11
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
13
--- a/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
14
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
15
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
19
}
16
* Note that this must match useronly_clean_ptr.
20
17
*/
21
static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
18
env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
22
- /* power_control should be set to maximum latency. Again,
19
+
23
+ /*
20
+ /* Enable MTE */
24
+ * power_control should be set to maximum latency. Again,
21
+ if (cpu_isar_feature(aa64_mte, cpu)) {
25
* default to 0 and set by private hook
22
+ /* Enable tag access, but leave TCF0 as No Effect (0). */
26
*/
23
+ env->cp15.sctlr_el[1] |= SCTLR_ATA0;
27
{ .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
24
+ /*
28
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
25
+ * Exclude all tags, so that tag 0 is always used.
29
set_feature(&cpu->env, ARM_FEATURE_NEON);
26
+ * This corresponds to Linux current->thread.gcr_incl = 0.
30
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
27
+ *
31
set_feature(&cpu->env, ARM_FEATURE_EL3);
28
+ * Set RRND, so that helper_irg() will generate a seed later.
32
- /* Note that A9 supports the MP extensions even for
29
+ * Here in cpu_reset(), the crypto subsystem has not yet been
33
+ /*
30
+ * initialized.
34
+ * Note that A9 supports the MP extensions even for
31
+ */
35
* A9UP and single-core A9MP (which are both different
32
+ env->cp15.gcr_el1 = 0x1ffff;
36
* and valid configurations; we don't model A9UP).
33
+ }
37
*/
34
#else
38
@@ -XXX,XX +XXX,XX @@ static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
35
/* Reset into the highest available EL */
39
{
36
if (arm_feature(env, ARM_FEATURE_EL3)) {
40
MachineState *ms = MACHINE(qdev_get_machine());
41
42
- /* Linux wants the number of processors from here.
43
+ /*
44
+ * Linux wants the number of processors from here.
45
* Might as well set the interrupt-controller bit too.
46
*/
47
return ((ms->smp.cpus - 1) << 24) | (1 << 23);
48
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
49
cpu->isar.id_mmfr1 = 0x40000000;
50
cpu->isar.id_mmfr2 = 0x01240000;
51
cpu->isar.id_mmfr3 = 0x02102211;
52
- /* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
53
+ /*
54
+ * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
55
* table 4-41 gives 0x02101110, which includes the arm div insns.
56
*/
57
cpu->isar.id_isar0 = 0x02101110;
58
--
37
--
59
2.20.1
38
2.20.1
60
39
61
40
diff view generated by jsdifflib
1
MPS3 boards have an extra SWITCH register in the FPGAIO block which
1
From: Richard Henderson <richard.henderson@linaro.org>
2
reports the value of some switches. Implement this, governed by a
3
property the board code can use to specify whether whether it exists.
4
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210212184902.1251044-32-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-7-peter.maydell@linaro.org
9
---
7
---
10
include/hw/misc/mps2-fpgaio.h | 1 +
8
tests/tcg/aarch64/mte.h | 60 +++++++++++++++++++++++++++++++
11
hw/misc/mps2-fpgaio.c | 10 ++++++++++
9
tests/tcg/aarch64/mte-1.c | 28 +++++++++++++++
12
2 files changed, 11 insertions(+)
10
tests/tcg/aarch64/mte-2.c | 45 +++++++++++++++++++++++
11
tests/tcg/aarch64/mte-3.c | 51 ++++++++++++++++++++++++++
12
tests/tcg/aarch64/mte-4.c | 45 +++++++++++++++++++++++
13
tests/tcg/aarch64/Makefile.target | 6 ++++
14
tests/tcg/configure.sh | 4 +++
15
7 files changed, 239 insertions(+)
16
create mode 100644 tests/tcg/aarch64/mte.h
17
create mode 100644 tests/tcg/aarch64/mte-1.c
18
create mode 100644 tests/tcg/aarch64/mte-2.c
19
create mode 100644 tests/tcg/aarch64/mte-3.c
20
create mode 100644 tests/tcg/aarch64/mte-4.c
13
21
14
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
22
diff --git a/tests/tcg/aarch64/mte.h b/tests/tcg/aarch64/mte.h
23
new file mode 100644
24
index XXXXXXX..XXXXXXX
25
--- /dev/null
26
+++ b/tests/tcg/aarch64/mte.h
27
@@ -XXX,XX +XXX,XX @@
28
+/*
29
+ * Linux kernel fallback API definitions for MTE and test helpers.
30
+ *
31
+ * Copyright (c) 2021 Linaro Ltd
32
+ * SPDX-License-Identifier: GPL-2.0-or-later
33
+ */
34
+
35
+#include <assert.h>
36
+#include <string.h>
37
+#include <stdlib.h>
38
+#include <stdio.h>
39
+#include <unistd.h>
40
+#include <signal.h>
41
+#include <sys/mman.h>
42
+#include <sys/prctl.h>
43
+
44
+#ifndef PR_SET_TAGGED_ADDR_CTRL
45
+# define PR_SET_TAGGED_ADDR_CTRL 55
46
+#endif
47
+#ifndef PR_TAGGED_ADDR_ENABLE
48
+# define PR_TAGGED_ADDR_ENABLE (1UL << 0)
49
+#endif
50
+#ifndef PR_MTE_TCF_SHIFT
51
+# define PR_MTE_TCF_SHIFT 1
52
+# define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT)
53
+# define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
54
+# define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
55
+# define PR_MTE_TAG_SHIFT 3
56
+#endif
57
+
58
+#ifndef PROT_MTE
59
+# define PROT_MTE 0x20
60
+#endif
61
+
62
+#ifndef SEGV_MTEAERR
63
+# define SEGV_MTEAERR 8
64
+# define SEGV_MTESERR 9
65
+#endif
66
+
67
+static void enable_mte(int tcf)
68
+{
69
+ int r = prctl(PR_SET_TAGGED_ADDR_CTRL,
70
+ PR_TAGGED_ADDR_ENABLE | tcf | (0xfffe << PR_MTE_TAG_SHIFT),
71
+ 0, 0, 0);
72
+ if (r < 0) {
73
+ perror("PR_SET_TAGGED_ADDR_CTRL");
74
+ exit(2);
75
+ }
76
+}
77
+
78
+static void *alloc_mte_mem(size_t size)
79
+{
80
+ void *p = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_MTE,
81
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
82
+ if (p == MAP_FAILED) {
83
+ perror("mmap PROT_MTE");
84
+ exit(2);
85
+ }
86
+ return p;
87
+}
88
diff --git a/tests/tcg/aarch64/mte-1.c b/tests/tcg/aarch64/mte-1.c
89
new file mode 100644
90
index XXXXXXX..XXXXXXX
91
--- /dev/null
92
+++ b/tests/tcg/aarch64/mte-1.c
93
@@ -XXX,XX +XXX,XX @@
94
+/*
95
+ * Memory tagging, basic pass cases.
96
+ *
97
+ * Copyright (c) 2021 Linaro Ltd
98
+ * SPDX-License-Identifier: GPL-2.0-or-later
99
+ */
100
+
101
+#include "mte.h"
102
+
103
+int main(int ac, char **av)
104
+{
105
+ int *p0, *p1, *p2;
106
+ long c;
107
+
108
+ enable_mte(PR_MTE_TCF_NONE);
109
+ p0 = alloc_mte_mem(sizeof(*p0));
110
+
111
+ asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(1));
112
+ assert(p1 != p0);
113
+ asm("subp %0,%1,%2" : "=r"(c) : "r"(p0), "r"(p1));
114
+ assert(c == 0);
115
+
116
+ asm("stg %0, [%0]" : : "r"(p1));
117
+ asm("ldg %0, [%1]" : "=r"(p2) : "r"(p0), "0"(p0));
118
+ assert(p1 == p2);
119
+
120
+ return 0;
121
+}
122
diff --git a/tests/tcg/aarch64/mte-2.c b/tests/tcg/aarch64/mte-2.c
123
new file mode 100644
124
index XXXXXXX..XXXXXXX
125
--- /dev/null
126
+++ b/tests/tcg/aarch64/mte-2.c
127
@@ -XXX,XX +XXX,XX @@
128
+/*
129
+ * Memory tagging, basic fail cases, synchronous signals.
130
+ *
131
+ * Copyright (c) 2021 Linaro Ltd
132
+ * SPDX-License-Identifier: GPL-2.0-or-later
133
+ */
134
+
135
+#include "mte.h"
136
+
137
+void pass(int sig, siginfo_t *info, void *uc)
138
+{
139
+ assert(info->si_code == SEGV_MTESERR);
140
+ exit(0);
141
+}
142
+
143
+int main(int ac, char **av)
144
+{
145
+ struct sigaction sa;
146
+ int *p0, *p1, *p2;
147
+ long excl = 1;
148
+
149
+ enable_mte(PR_MTE_TCF_SYNC);
150
+ p0 = alloc_mte_mem(sizeof(*p0));
151
+
152
+ /* Create two differently tagged pointers. */
153
+ asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
154
+ asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
155
+ assert(excl != 1);
156
+ asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
157
+ assert(p1 != p2);
158
+
159
+ /* Store the tag from the first pointer. */
160
+ asm("stg %0, [%0]" : : "r"(p1));
161
+
162
+ *p1 = 0;
163
+
164
+ memset(&sa, 0, sizeof(sa));
165
+ sa.sa_sigaction = pass;
166
+ sa.sa_flags = SA_SIGINFO;
167
+ sigaction(SIGSEGV, &sa, NULL);
168
+
169
+ *p2 = 0;
170
+
171
+ abort();
172
+}
173
diff --git a/tests/tcg/aarch64/mte-3.c b/tests/tcg/aarch64/mte-3.c
174
new file mode 100644
175
index XXXXXXX..XXXXXXX
176
--- /dev/null
177
+++ b/tests/tcg/aarch64/mte-3.c
178
@@ -XXX,XX +XXX,XX @@
179
+/*
180
+ * Memory tagging, basic fail cases, asynchronous signals.
181
+ *
182
+ * Copyright (c) 2021 Linaro Ltd
183
+ * SPDX-License-Identifier: GPL-2.0-or-later
184
+ */
185
+
186
+#include "mte.h"
187
+
188
+void pass(int sig, siginfo_t *info, void *uc)
189
+{
190
+ assert(info->si_code == SEGV_MTEAERR);
191
+ exit(0);
192
+}
193
+
194
+int main(int ac, char **av)
195
+{
196
+ struct sigaction sa;
197
+ long *p0, *p1, *p2;
198
+ long excl = 1;
199
+
200
+ enable_mte(PR_MTE_TCF_ASYNC);
201
+ p0 = alloc_mte_mem(sizeof(*p0));
202
+
203
+ /* Create two differently tagged pointers. */
204
+ asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
205
+ asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
206
+ assert(excl != 1);
207
+ asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
208
+ assert(p1 != p2);
209
+
210
+ /* Store the tag from the first pointer. */
211
+ asm("stg %0, [%0]" : : "r"(p1));
212
+
213
+ *p1 = 0;
214
+
215
+ memset(&sa, 0, sizeof(sa));
216
+ sa.sa_sigaction = pass;
217
+ sa.sa_flags = SA_SIGINFO;
218
+ sigaction(SIGSEGV, &sa, NULL);
219
+
220
+ /*
221
+ * Signal for async error will happen eventually.
222
+ * For a real kernel this should be after the next IRQ (e.g. timer).
223
+ * For qemu linux-user, we kick the cpu and exit at the next TB.
224
+ * In either case, loop until this happens (or killed by timeout).
225
+ * For extra sauce, yield, producing EXCP_YIELD to cpu_loop().
226
+ */
227
+ asm("str %0, [%0]; yield" : : "r"(p2));
228
+ while (1);
229
+}
230
diff --git a/tests/tcg/aarch64/mte-4.c b/tests/tcg/aarch64/mte-4.c
231
new file mode 100644
232
index XXXXXXX..XXXXXXX
233
--- /dev/null
234
+++ b/tests/tcg/aarch64/mte-4.c
235
@@ -XXX,XX +XXX,XX @@
236
+/*
237
+ * Memory tagging, re-reading tag checks.
238
+ *
239
+ * Copyright (c) 2021 Linaro Ltd
240
+ * SPDX-License-Identifier: GPL-2.0-or-later
241
+ */
242
+
243
+#include "mte.h"
244
+
245
+void __attribute__((noinline)) tagset(void *p, size_t size)
246
+{
247
+ size_t i;
248
+ for (i = 0; i < size; i += 16) {
249
+ asm("stg %0, [%0]" : : "r"(p + i));
250
+ }
251
+}
252
+
253
+void __attribute__((noinline)) tagcheck(void *p, size_t size)
254
+{
255
+ size_t i;
256
+ void *c;
257
+
258
+ for (i = 0; i < size; i += 16) {
259
+ asm("ldg %0, [%1]" : "=r"(c) : "r"(p + i), "0"(p));
260
+ assert(c == p);
261
+ }
262
+}
263
+
264
+int main(int ac, char **av)
265
+{
266
+ size_t size = getpagesize() * 4;
267
+ long excl = 1;
268
+ int *p0, *p1;
269
+
270
+ enable_mte(PR_MTE_TCF_ASYNC);
271
+ p0 = alloc_mte_mem(size);
272
+
273
+ /* Tag the pointer. */
274
+ asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
275
+
276
+ tagset(p1, size);
277
+ tagcheck(p1, size);
278
+
279
+ return 0;
280
+}
281
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
15
index XXXXXXX..XXXXXXX 100644
282
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/misc/mps2-fpgaio.h
283
--- a/tests/tcg/aarch64/Makefile.target
17
+++ b/include/hw/misc/mps2-fpgaio.h
284
+++ b/tests/tcg/aarch64/Makefile.target
18
@@ -XXX,XX +XXX,XX @@ struct MPS2FPGAIO {
285
@@ -XXX,XX +XXX,XX @@ endif
19
MemoryRegion iomem;
286
# bti-2 tests PROT_BTI, so no special compiler support required.
20
LEDState *led[MPS2FPGAIO_MAX_LEDS];
287
AARCH64_TESTS += bti-2
21
uint32_t num_leds;
288
22
+ bool has_switches;
289
+# MTE Tests
23
290
+ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_MTE),)
24
uint32_t led0;
291
+AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4
25
uint32_t prescale;
292
+mte-%: CFLAGS += -march=armv8.5-a+memtag
26
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
293
+endif
27
index XXXXXXX..XXXXXXX 100644
294
+
28
--- a/hw/misc/mps2-fpgaio.c
295
# Semihosting smoke test for linux-user
29
+++ b/hw/misc/mps2-fpgaio.c
296
AARCH64_TESTS += semihosting
30
@@ -XXX,XX +XXX,XX @@ REG32(CLK100HZ, 0x14)
297
run-semihosting: semihosting
31
REG32(COUNTER, 0x18)
298
diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
32
REG32(PRESCALE, 0x1c)
299
index XXXXXXX..XXXXXXX 100755
33
REG32(PSCNTR, 0x20)
300
--- a/tests/tcg/configure.sh
34
+REG32(SWITCH, 0x28)
301
+++ b/tests/tcg/configure.sh
35
REG32(MISC, 0x4c)
302
@@ -XXX,XX +XXX,XX @@ for target in $target_list; do
36
303
-mbranch-protection=standard -o $TMPE $TMPC; then
37
static uint32_t counter_from_tickoff(int64_t now, int64_t tick_offset, int frq)
304
echo "CROSS_CC_HAS_ARMV8_BTI=y" >> $config_target_mak
38
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
305
fi
39
resync_counter(s);
306
+ if do_compiler "$target_compiler" $target_compiler_cflags \
40
r = s->pscntr;
307
+ -march=armv8.5-a+memtag -o $TMPE $TMPC; then
41
break;
308
+ echo "CROSS_CC_HAS_ARMV8_MTE=y" >> $config_target_mak
42
+ case A_SWITCH:
309
+ fi
43
+ if (!s->has_switches) {
310
;;
44
+ goto bad_offset;
311
esac
45
+ }
46
+ /* User-togglable board switches. We don't model that, so report 0. */
47
+ r = 0;
48
+ break;
49
default:
50
+ bad_offset:
51
qemu_log_mask(LOG_GUEST_ERROR,
52
"MPS2 FPGAIO read: bad offset %x\n", (int) offset);
53
r = 0;
54
@@ -XXX,XX +XXX,XX @@ static Property mps2_fpgaio_properties[] = {
55
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
56
/* Number of LEDs controlled by LED0 register */
57
DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
58
+ DEFINE_PROP_BOOL("has-switches", MPS2FPGAIO, has_switches, false),
59
DEFINE_PROP_END_OF_LIST(),
60
};
61
312
62
--
313
--
63
2.20.1
314
2.20.1
64
315
65
316
diff view generated by jsdifflib
1
Add support for the mps3-an524 board; this is an SSE-200 based FPGA
1
From: Hao Wu <wuhaotsh@google.com>
2
image, like the existing mps2-an521. It has a usefully larger amount
3
of RAM, and a PL031 RTC, as well as some more minor differences.
4
2
5
In real hardware this image runs on a newer generation of the FPGA
3
This commit implements the single-byte mode of the SMBus.
6
board, the MPS3 rather than the older MPS2. Architecturally the two
7
boards are similar, so we implement the MPS3 boards in the mps2-tz.c
8
file as variations of the existing MPS2 boards.
9
4
5
Each Nuvoton SoC has 16 System Management Bus (SMBus). These buses
6
compliant with SMBus and I2C protocol.
7
8
This patch implements the single-byte mode of the SMBus. In this mode,
9
the user sends or receives a byte each time. The SMBus device transmits
10
it to the underlying i2c device and sends an interrupt back to the QEMU
11
guest.
12
13
Reviewed-by: Doug Evans<dje@google.com>
14
Reviewed-by: Tyrong Ting<kfting@nuvoton.com>
15
Signed-off-by: Hao Wu <wuhaotsh@google.com>
16
Reviewed-by: Corey Minyard <cminyard@mvista.com>
17
Message-id: 20210210220426.3577804-2-wuhaotsh@google.com
18
Acked-by: Corey Minyard <cminyard@mvista.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-21-peter.maydell@linaro.org
13
---
20
---
14
hw/arm/mps2-tz.c | 139 +++++++++++++++++++++++++++++++++++++++++++++--
21
docs/system/arm/nuvoton.rst | 2 +-
15
1 file changed, 135 insertions(+), 4 deletions(-)
22
include/hw/arm/npcm7xx.h | 2 +
23
include/hw/i2c/npcm7xx_smbus.h | 88 ++++
24
hw/arm/npcm7xx.c | 68 ++-
25
hw/i2c/npcm7xx_smbus.c | 783 +++++++++++++++++++++++++++++++++
26
hw/i2c/meson.build | 1 +
27
hw/i2c/trace-events | 11 +
28
7 files changed, 938 insertions(+), 17 deletions(-)
29
create mode 100644 include/hw/i2c/npcm7xx_smbus.h
30
create mode 100644 hw/i2c/npcm7xx_smbus.c
16
31
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
32
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
18
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
34
--- a/docs/system/arm/nuvoton.rst
20
+++ b/hw/arm/mps2-tz.c
35
+++ b/docs/system/arm/nuvoton.rst
36
@@ -XXX,XX +XXX,XX @@ Supported devices
37
* GPIO controller
38
* Analog to Digital Converter (ADC)
39
* Pulse Width Modulation (PWM)
40
+ * SMBus controller (SMBF)
41
42
Missing devices
43
---------------
44
@@ -XXX,XX +XXX,XX @@ Missing devices
45
46
* Ethernet controllers (GMAC and EMC)
47
* USB device (USBD)
48
- * SMBus controller (SMBF)
49
* Peripheral SPI controller (PSPI)
50
* SD/MMC host
51
* PECI interface
52
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/include/hw/arm/npcm7xx.h
55
+++ b/include/hw/arm/npcm7xx.h
21
@@ -XXX,XX +XXX,XX @@
56
@@ -XXX,XX +XXX,XX @@
22
* This source file covers the following FPGA images, for TrustZone cores:
57
#include "hw/adc/npcm7xx_adc.h"
23
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
58
#include "hw/cpu/a9mpcore.h"
24
* "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
59
#include "hw/gpio/npcm7xx_gpio.h"
25
+ * "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
60
+#include "hw/i2c/npcm7xx_smbus.h"
26
*
61
#include "hw/mem/npcm7xx_mc.h"
27
* Links to the TRM for the board itself and to the various Application
62
#include "hw/misc/npcm7xx_clk.h"
28
* Notes which document the FPGA images can be found here:
63
#include "hw/misc/npcm7xx_gcr.h"
64
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
65
NPCM7xxMCState mc;
66
NPCM7xxRNGState rng;
67
NPCM7xxGPIOState gpio[8];
68
+ NPCM7xxSMBusState smbus[16];
69
EHCISysBusState ehci;
70
OHCISysBusState ohci;
71
NPCM7xxFIUState fiu[2];
72
diff --git a/include/hw/i2c/npcm7xx_smbus.h b/include/hw/i2c/npcm7xx_smbus.h
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/include/hw/i2c/npcm7xx_smbus.h
29
@@ -XXX,XX +XXX,XX @@
77
@@ -XXX,XX +XXX,XX @@
30
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
78
+/*
31
* Application Note AN521:
79
+ * Nuvoton NPCM7xx SMBus Module.
32
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
80
+ *
33
+ * Application Note AN524:
81
+ * Copyright 2020 Google LLC
34
+ * https://developer.arm.com/documentation/dai0524/latest/
82
+ *
35
*
83
+ * This program is free software; you can redistribute it and/or modify it
36
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
84
+ * under the terms of the GNU General Public License as published by the
37
* (ARM ECM0601256) for the details of some of the device layout:
85
+ * Free Software Foundation; either version 2 of the License, or
38
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
86
+ * (at your option) any later version.
39
- * Similarly, the AN521 uses the SSE-200, and the SSE-200 TRM defines
87
+ *
40
+ * Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
88
+ * This program is distributed in the hope that it will be useful, but WITHOUT
41
* most of the device layout:
89
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
42
* http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
90
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
43
*
91
+ * for more details.
92
+ */
93
+#ifndef NPCM7XX_SMBUS_H
94
+#define NPCM7XX_SMBUS_H
95
+
96
+#include "exec/memory.h"
97
+#include "hw/i2c/i2c.h"
98
+#include "hw/irq.h"
99
+#include "hw/sysbus.h"
100
+
101
+/*
102
+ * Number of addresses this module contains. Do not change this without
103
+ * incrementing the version_id in the vmstate.
104
+ */
105
+#define NPCM7XX_SMBUS_NR_ADDRS 10
106
+
107
+typedef enum NPCM7xxSMBusStatus {
108
+ NPCM7XX_SMBUS_STATUS_IDLE,
109
+ NPCM7XX_SMBUS_STATUS_SENDING,
110
+ NPCM7XX_SMBUS_STATUS_RECEIVING,
111
+ NPCM7XX_SMBUS_STATUS_NEGACK,
112
+ NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE,
113
+ NPCM7XX_SMBUS_STATUS_STOPPING_NEGACK,
114
+} NPCM7xxSMBusStatus;
115
+
116
+/*
117
+ * struct NPCM7xxSMBusState - System Management Bus device state.
118
+ * @bus: The underlying I2C Bus.
119
+ * @irq: GIC interrupt line to fire on events (if enabled).
120
+ * @sda: The serial data register.
121
+ * @st: The status register.
122
+ * @cst: The control status register.
123
+ * @cst2: The control status register 2.
124
+ * @cst3: The control status register 3.
125
+ * @ctl1: The control register 1.
126
+ * @ctl2: The control register 2.
127
+ * @ctl3: The control register 3.
128
+ * @ctl4: The control register 4.
129
+ * @ctl5: The control register 5.
130
+ * @addr: The SMBus module's own addresses on the I2C bus.
131
+ * @scllt: The SCL low time register.
132
+ * @sclht: The SCL high time register.
133
+ * @status: The current status of the SMBus.
134
+ */
135
+typedef struct NPCM7xxSMBusState {
136
+ SysBusDevice parent;
137
+
138
+ MemoryRegion iomem;
139
+
140
+ I2CBus *bus;
141
+ qemu_irq irq;
142
+
143
+ uint8_t sda;
144
+ uint8_t st;
145
+ uint8_t cst;
146
+ uint8_t cst2;
147
+ uint8_t cst3;
148
+ uint8_t ctl1;
149
+ uint8_t ctl2;
150
+ uint8_t ctl3;
151
+ uint8_t ctl4;
152
+ uint8_t ctl5;
153
+ uint8_t addr[NPCM7XX_SMBUS_NR_ADDRS];
154
+
155
+ uint8_t scllt;
156
+ uint8_t sclht;
157
+
158
+ NPCM7xxSMBusStatus status;
159
+} NPCM7xxSMBusState;
160
+
161
+#define TYPE_NPCM7XX_SMBUS "npcm7xx-smbus"
162
+#define NPCM7XX_SMBUS(obj) OBJECT_CHECK(NPCM7xxSMBusState, (obj), \
163
+ TYPE_NPCM7XX_SMBUS)
164
+
165
+#endif /* NPCM7XX_SMBUS_H */
166
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/hw/arm/npcm7xx.c
169
+++ b/hw/arm/npcm7xx.c
170
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
171
NPCM7XX_WDG2_IRQ, /* Timer Module 2 Watchdog */
172
NPCM7XX_EHCI_IRQ = 61,
173
NPCM7XX_OHCI_IRQ = 62,
174
+ NPCM7XX_SMBUS0_IRQ = 64,
175
+ NPCM7XX_SMBUS1_IRQ,
176
+ NPCM7XX_SMBUS2_IRQ,
177
+ NPCM7XX_SMBUS3_IRQ,
178
+ NPCM7XX_SMBUS4_IRQ,
179
+ NPCM7XX_SMBUS5_IRQ,
180
+ NPCM7XX_SMBUS6_IRQ,
181
+ NPCM7XX_SMBUS7_IRQ,
182
+ NPCM7XX_SMBUS8_IRQ,
183
+ NPCM7XX_SMBUS9_IRQ,
184
+ NPCM7XX_SMBUS10_IRQ,
185
+ NPCM7XX_SMBUS11_IRQ,
186
+ NPCM7XX_SMBUS12_IRQ,
187
+ NPCM7XX_SMBUS13_IRQ,
188
+ NPCM7XX_SMBUS14_IRQ,
189
+ NPCM7XX_SMBUS15_IRQ,
190
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
191
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
192
NPCM7XX_GPIO0_IRQ = 116,
193
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_pwm_addr[] = {
194
0xf0104000,
195
};
196
197
+/* Direct memory-mapped access to each SMBus Module. */
198
+static const hwaddr npcm7xx_smbus_addr[] = {
199
+ 0xf0080000,
200
+ 0xf0081000,
201
+ 0xf0082000,
202
+ 0xf0083000,
203
+ 0xf0084000,
204
+ 0xf0085000,
205
+ 0xf0086000,
206
+ 0xf0087000,
207
+ 0xf0088000,
208
+ 0xf0089000,
209
+ 0xf008a000,
210
+ 0xf008b000,
211
+ 0xf008c000,
212
+ 0xf008d000,
213
+ 0xf008e000,
214
+ 0xf008f000,
215
+};
216
+
217
static const struct {
218
hwaddr regs_addr;
219
uint32_t unconnected_pins;
220
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
221
object_initialize_child(obj, "gpio[*]", &s->gpio[i], TYPE_NPCM7XX_GPIO);
222
}
223
224
+ for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
225
+ object_initialize_child(obj, "smbus[*]", &s->smbus[i],
226
+ TYPE_NPCM7XX_SMBUS);
227
+ }
228
+
229
object_initialize_child(obj, "ehci", &s->ehci, TYPE_NPCM7XX_EHCI);
230
object_initialize_child(obj, "ohci", &s->ohci, TYPE_SYSBUS_OHCI);
231
232
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
233
npcm7xx_irq(s, NPCM7XX_GPIO0_IRQ + i));
234
}
235
236
+ /* SMBus modules. Cannot fail. */
237
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_smbus_addr) != ARRAY_SIZE(s->smbus));
238
+ for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
239
+ Object *obj = OBJECT(&s->smbus[i]);
240
+
241
+ sysbus_realize(SYS_BUS_DEVICE(obj), &error_abort);
242
+ sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm7xx_smbus_addr[i]);
243
+ sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0,
244
+ npcm7xx_irq(s, NPCM7XX_SMBUS0_IRQ + i));
245
+ }
246
+
247
/* USB Host */
248
object_property_set_bool(OBJECT(&s->ehci), "companion-enable", true,
249
&error_abort);
250
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
251
create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB);
252
create_unimplemented_device("npcm7xx.kcs", 0xf0007000, 4 * KiB);
253
create_unimplemented_device("npcm7xx.gfxi", 0xf000e000, 4 * KiB);
254
- create_unimplemented_device("npcm7xx.smbus[0]", 0xf0080000, 4 * KiB);
255
- create_unimplemented_device("npcm7xx.smbus[1]", 0xf0081000, 4 * KiB);
256
- create_unimplemented_device("npcm7xx.smbus[2]", 0xf0082000, 4 * KiB);
257
- create_unimplemented_device("npcm7xx.smbus[3]", 0xf0083000, 4 * KiB);
258
- create_unimplemented_device("npcm7xx.smbus[4]", 0xf0084000, 4 * KiB);
259
- create_unimplemented_device("npcm7xx.smbus[5]", 0xf0085000, 4 * KiB);
260
- create_unimplemented_device("npcm7xx.smbus[6]", 0xf0086000, 4 * KiB);
261
- create_unimplemented_device("npcm7xx.smbus[7]", 0xf0087000, 4 * KiB);
262
- create_unimplemented_device("npcm7xx.smbus[8]", 0xf0088000, 4 * KiB);
263
- create_unimplemented_device("npcm7xx.smbus[9]", 0xf0089000, 4 * KiB);
264
- create_unimplemented_device("npcm7xx.smbus[10]", 0xf008a000, 4 * KiB);
265
- create_unimplemented_device("npcm7xx.smbus[11]", 0xf008b000, 4 * KiB);
266
- create_unimplemented_device("npcm7xx.smbus[12]", 0xf008c000, 4 * KiB);
267
- create_unimplemented_device("npcm7xx.smbus[13]", 0xf008d000, 4 * KiB);
268
- create_unimplemented_device("npcm7xx.smbus[14]", 0xf008e000, 4 * KiB);
269
- create_unimplemented_device("npcm7xx.smbus[15]", 0xf008f000, 4 * KiB);
270
create_unimplemented_device("npcm7xx.espi", 0xf009f000, 4 * KiB);
271
create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
272
create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
273
diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
274
new file mode 100644
275
index XXXXXXX..XXXXXXX
276
--- /dev/null
277
+++ b/hw/i2c/npcm7xx_smbus.c
44
@@ -XXX,XX +XXX,XX @@
278
@@ -XXX,XX +XXX,XX @@
45
#include "hw/qdev-clock.h"
279
+/*
46
#include "qom/object.h"
280
+ * Nuvoton NPCM7xx SMBus Module.
47
281
+ *
48
-#define MPS2TZ_NUMIRQ_MAX 92
282
+ * Copyright 2020 Google LLC
49
+#define MPS2TZ_NUMIRQ_MAX 95
283
+ *
50
#define MPS2TZ_RAM_MAX 4
284
+ * This program is free software; you can redistribute it and/or modify it
51
285
+ * under the terms of the GNU General Public License as published by the
52
typedef enum MPS2TZFPGAType {
286
+ * Free Software Foundation; either version 2 of the License, or
53
FPGA_AN505,
287
+ * (at your option) any later version.
54
FPGA_AN521,
288
+ *
55
+ FPGA_AN524,
289
+ * This program is distributed in the hope that it will be useful, but WITHOUT
56
} MPS2TZFPGAType;
290
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
57
291
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
58
/*
292
+ * for more details.
59
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
293
+ */
60
TZPPC ppc[5];
294
+
61
TZMPC mpc[3];
295
+#include "qemu/osdep.h"
62
PL022State spi[5];
296
+
63
- ArmSbconI2CState i2c[4];
297
+#include "hw/i2c/npcm7xx_smbus.h"
64
+ ArmSbconI2CState i2c[5];
298
+#include "migration/vmstate.h"
65
UnimplementedDeviceState i2s_audio;
299
+#include "qemu/bitops.h"
66
UnimplementedDeviceState gpio[4];
300
+#include "qemu/guest-random.h"
67
UnimplementedDeviceState gfx;
301
+#include "qemu/log.h"
68
+ UnimplementedDeviceState cldc;
302
+#include "qemu/module.h"
69
+ UnimplementedDeviceState rtc;
303
+#include "qemu/units.h"
70
PL080State dma[4];
304
+
71
TZMSC msc[4];
305
+#include "trace.h"
72
- CMSDKAPBUART uart[5];
306
+
73
+ CMSDKAPBUART uart[6];
307
+enum NPCM7xxSMBusCommonRegister {
74
SplitIRQ sec_resp_splitter;
308
+ NPCM7XX_SMB_SDA = 0x0,
75
qemu_or_irq uart_irq_orgate;
309
+ NPCM7XX_SMB_ST = 0x2,
76
DeviceState *lan9118;
310
+ NPCM7XX_SMB_CST = 0x4,
77
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
311
+ NPCM7XX_SMB_CTL1 = 0x6,
78
#define TYPE_MPS2TZ_MACHINE "mps2tz"
312
+ NPCM7XX_SMB_ADDR1 = 0x8,
79
#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
313
+ NPCM7XX_SMB_CTL2 = 0xa,
80
#define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
314
+ NPCM7XX_SMB_ADDR2 = 0xc,
81
+#define TYPE_MPS3TZ_AN524_MACHINE MACHINE_TYPE_NAME("mps3-an524")
315
+ NPCM7XX_SMB_CTL3 = 0xe,
82
316
+ NPCM7XX_SMB_CST2 = 0x18,
83
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
317
+ NPCM7XX_SMB_CST3 = 0x19,
84
318
+ NPCM7XX_SMB_VER = 0x1f,
85
@@ -XXX,XX +XXX,XX @@ static const uint32_t an505_oscclk[] = {
86
25000000,
87
};
88
89
+static const uint32_t an524_oscclk[] = {
90
+ 24000000,
91
+ 32000000,
92
+ 50000000,
93
+ 50000000,
94
+ 24576000,
95
+ 23750000,
96
+};
319
+};
97
+
320
+
98
static const RAMInfo an505_raminfo[] = { {
321
+enum NPCM7xxSMBusBank0Register {
99
.name = "ssram-0",
322
+ NPCM7XX_SMB_ADDR3 = 0x10,
100
.base = 0x00000000,
323
+ NPCM7XX_SMB_ADDR7 = 0x11,
101
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
324
+ NPCM7XX_SMB_ADDR4 = 0x12,
102
},
325
+ NPCM7XX_SMB_ADDR8 = 0x13,
103
};
326
+ NPCM7XX_SMB_ADDR5 = 0x14,
104
327
+ NPCM7XX_SMB_ADDR9 = 0x15,
105
+static const RAMInfo an524_raminfo[] = { {
328
+ NPCM7XX_SMB_ADDR6 = 0x16,
106
+ .name = "bram",
329
+ NPCM7XX_SMB_ADDR10 = 0x17,
107
+ .base = 0x00000000,
330
+ NPCM7XX_SMB_CTL4 = 0x1a,
108
+ .size = 512 * KiB,
331
+ NPCM7XX_SMB_CTL5 = 0x1b,
109
+ .mpc = 0,
332
+ NPCM7XX_SMB_SCLLT = 0x1c,
110
+ .mrindex = 0,
333
+ NPCM7XX_SMB_FIF_CTL = 0x1d,
111
+ }, {
334
+ NPCM7XX_SMB_SCLHT = 0x1e,
112
+ .name = "sram",
335
+};
113
+ .base = 0x20000000,
336
+
114
+ .size = 32 * 4 * KiB,
337
+enum NPCM7xxSMBusBank1Register {
115
+ .mpc = 1,
338
+ NPCM7XX_SMB_FIF_CTS = 0x10,
116
+ .mrindex = 1,
339
+ NPCM7XX_SMB_FAIR_PER = 0x11,
117
+ }, {
340
+ NPCM7XX_SMB_TXF_CTL = 0x12,
118
+ /* We don't model QSPI flash yet; for now expose it as simple ROM */
341
+ NPCM7XX_SMB_T_OUT = 0x14,
119
+ .name = "QSPI",
342
+ NPCM7XX_SMB_TXF_STS = 0x1a,
120
+ .base = 0x28000000,
343
+ NPCM7XX_SMB_RXF_STS = 0x1c,
121
+ .size = 8 * MiB,
344
+ NPCM7XX_SMB_RXF_CTL = 0x1e,
122
+ .mpc = 1,
345
+};
123
+ .mrindex = 2,
346
+
124
+ .flags = IS_ROM,
347
+/* ST fields */
125
+ }, {
348
+#define NPCM7XX_SMBST_STP BIT(7)
126
+ .name = "DDR",
349
+#define NPCM7XX_SMBST_SDAST BIT(6)
127
+ .base = 0x60000000,
350
+#define NPCM7XX_SMBST_BER BIT(5)
128
+ .size = 2 * GiB,
351
+#define NPCM7XX_SMBST_NEGACK BIT(4)
129
+ .mpc = 2,
352
+#define NPCM7XX_SMBST_STASTR BIT(3)
130
+ .mrindex = -1,
353
+#define NPCM7XX_SMBST_NMATCH BIT(2)
131
+ }, {
354
+#define NPCM7XX_SMBST_MODE BIT(1)
132
+ .name = NULL,
355
+#define NPCM7XX_SMBST_XMIT BIT(0)
356
+
357
+/* CST fields */
358
+#define NPCM7XX_SMBCST_ARPMATCH BIT(7)
359
+#define NPCM7XX_SMBCST_MATCHAF BIT(6)
360
+#define NPCM7XX_SMBCST_TGSCL BIT(5)
361
+#define NPCM7XX_SMBCST_TSDA BIT(4)
362
+#define NPCM7XX_SMBCST_GCMATCH BIT(3)
363
+#define NPCM7XX_SMBCST_MATCH BIT(2)
364
+#define NPCM7XX_SMBCST_BB BIT(1)
365
+#define NPCM7XX_SMBCST_BUSY BIT(0)
366
+
367
+/* CST2 fields */
368
+#define NPCM7XX_SMBCST2_INTSTS BIT(7)
369
+#define NPCM7XX_SMBCST2_MATCH7F BIT(6)
370
+#define NPCM7XX_SMBCST2_MATCH6F BIT(5)
371
+#define NPCM7XX_SMBCST2_MATCH5F BIT(4)
372
+#define NPCM7XX_SMBCST2_MATCH4F BIT(3)
373
+#define NPCM7XX_SMBCST2_MATCH3F BIT(2)
374
+#define NPCM7XX_SMBCST2_MATCH2F BIT(1)
375
+#define NPCM7XX_SMBCST2_MATCH1F BIT(0)
376
+
377
+/* CST3 fields */
378
+#define NPCM7XX_SMBCST3_EO_BUSY BIT(7)
379
+#define NPCM7XX_SMBCST3_MATCH10F BIT(2)
380
+#define NPCM7XX_SMBCST3_MATCH9F BIT(1)
381
+#define NPCM7XX_SMBCST3_MATCH8F BIT(0)
382
+
383
+/* CTL1 fields */
384
+#define NPCM7XX_SMBCTL1_STASTRE BIT(7)
385
+#define NPCM7XX_SMBCTL1_NMINTE BIT(6)
386
+#define NPCM7XX_SMBCTL1_GCMEN BIT(5)
387
+#define NPCM7XX_SMBCTL1_ACK BIT(4)
388
+#define NPCM7XX_SMBCTL1_EOBINTE BIT(3)
389
+#define NPCM7XX_SMBCTL1_INTEN BIT(2)
390
+#define NPCM7XX_SMBCTL1_STOP BIT(1)
391
+#define NPCM7XX_SMBCTL1_START BIT(0)
392
+
393
+/* CTL2 fields */
394
+#define NPCM7XX_SMBCTL2_SCLFRQ(rv) extract8((rv), 1, 6)
395
+#define NPCM7XX_SMBCTL2_ENABLE BIT(0)
396
+
397
+/* CTL3 fields */
398
+#define NPCM7XX_SMBCTL3_SCL_LVL BIT(7)
399
+#define NPCM7XX_SMBCTL3_SDA_LVL BIT(6)
400
+#define NPCM7XX_SMBCTL3_BNK_SEL BIT(5)
401
+#define NPCM7XX_SMBCTL3_400K_MODE BIT(4)
402
+#define NPCM7XX_SMBCTL3_IDL_START BIT(3)
403
+#define NPCM7XX_SMBCTL3_ARPMEN BIT(2)
404
+#define NPCM7XX_SMBCTL3_SCLFRQ(rv) extract8((rv), 0, 2)
405
+
406
+/* ADDR fields */
407
+#define NPCM7XX_ADDR_EN BIT(7)
408
+#define NPCM7XX_ADDR_A(rv) extract8((rv), 0, 6)
409
+
410
+#define KEEP_OLD_BIT(o, n, b) (((n) & (~(b))) | ((o) & (b)))
411
+#define WRITE_ONE_CLEAR(o, n, b) ((n) & (b) ? (o) & (~(b)) : (o))
412
+
413
+#define NPCM7XX_SMBUS_ENABLED(s) ((s)->ctl2 & NPCM7XX_SMBCTL2_ENABLE)
414
+
415
+/* VERSION fields values, read-only. */
416
+#define NPCM7XX_SMBUS_VERSION_NUMBER 1
417
+#define NPCM7XX_SMBUS_VERSION_FIFO_SUPPORTED 0
418
+
419
+/* Reset values */
420
+#define NPCM7XX_SMB_ST_INIT_VAL 0x00
421
+#define NPCM7XX_SMB_CST_INIT_VAL 0x10
422
+#define NPCM7XX_SMB_CST2_INIT_VAL 0x00
423
+#define NPCM7XX_SMB_CST3_INIT_VAL 0x00
424
+#define NPCM7XX_SMB_CTL1_INIT_VAL 0x00
425
+#define NPCM7XX_SMB_CTL2_INIT_VAL 0x00
426
+#define NPCM7XX_SMB_CTL3_INIT_VAL 0xc0
427
+#define NPCM7XX_SMB_CTL4_INIT_VAL 0x07
428
+#define NPCM7XX_SMB_CTL5_INIT_VAL 0x00
429
+#define NPCM7XX_SMB_ADDR_INIT_VAL 0x00
430
+#define NPCM7XX_SMB_SCLLT_INIT_VAL 0x00
431
+#define NPCM7XX_SMB_SCLHT_INIT_VAL 0x00
432
+
433
+static uint8_t npcm7xx_smbus_get_version(void)
434
+{
435
+ return NPCM7XX_SMBUS_VERSION_FIFO_SUPPORTED << 7 |
436
+ NPCM7XX_SMBUS_VERSION_NUMBER;
437
+}
438
+
439
+static void npcm7xx_smbus_update_irq(NPCM7xxSMBusState *s)
440
+{
441
+ int level;
442
+
443
+ if (s->ctl1 & NPCM7XX_SMBCTL1_INTEN) {
444
+ level = !!((s->ctl1 & NPCM7XX_SMBCTL1_NMINTE &&
445
+ s->st & NPCM7XX_SMBST_NMATCH) ||
446
+ (s->st & NPCM7XX_SMBST_BER) ||
447
+ (s->st & NPCM7XX_SMBST_NEGACK) ||
448
+ (s->st & NPCM7XX_SMBST_SDAST) ||
449
+ (s->ctl1 & NPCM7XX_SMBCTL1_STASTRE &&
450
+ s->st & NPCM7XX_SMBST_SDAST) ||
451
+ (s->ctl1 & NPCM7XX_SMBCTL1_EOBINTE &&
452
+ s->cst3 & NPCM7XX_SMBCST3_EO_BUSY));
453
+
454
+ if (level) {
455
+ s->cst2 |= NPCM7XX_SMBCST2_INTSTS;
456
+ } else {
457
+ s->cst2 &= ~NPCM7XX_SMBCST2_INTSTS;
458
+ }
459
+ qemu_set_irq(s->irq, level);
460
+ }
461
+}
462
+
463
+static void npcm7xx_smbus_nack(NPCM7xxSMBusState *s)
464
+{
465
+ s->st &= ~NPCM7XX_SMBST_SDAST;
466
+ s->st |= NPCM7XX_SMBST_NEGACK;
467
+ s->status = NPCM7XX_SMBUS_STATUS_NEGACK;
468
+}
469
+
470
+static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, uint8_t value)
471
+{
472
+ int rv = i2c_send(s->bus, value);
473
+
474
+ if (rv) {
475
+ npcm7xx_smbus_nack(s);
476
+ } else {
477
+ s->st |= NPCM7XX_SMBST_SDAST;
478
+ }
479
+ trace_npcm7xx_smbus_send_byte((DEVICE(s)->canonical_path), value, !rv);
480
+ npcm7xx_smbus_update_irq(s);
481
+}
482
+
483
+static void npcm7xx_smbus_recv_byte(NPCM7xxSMBusState *s)
484
+{
485
+ s->sda = i2c_recv(s->bus);
486
+ s->st |= NPCM7XX_SMBST_SDAST;
487
+ if (s->st & NPCM7XX_SMBCTL1_ACK) {
488
+ trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
489
+ i2c_nack(s->bus);
490
+ s->st &= NPCM7XX_SMBCTL1_ACK;
491
+ }
492
+ trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path), s->sda);
493
+ npcm7xx_smbus_update_irq(s);
494
+}
495
+
496
+static void npcm7xx_smbus_start(NPCM7xxSMBusState *s)
497
+{
498
+ /*
499
+ * We can start the bus if one of these is true:
500
+ * 1. The bus is idle (so we can request it)
501
+ * 2. We are the occupier (it's a repeated start condition.)
502
+ */
503
+ int available = !i2c_bus_busy(s->bus) ||
504
+ s->status != NPCM7XX_SMBUS_STATUS_IDLE;
505
+
506
+ if (available) {
507
+ s->st |= NPCM7XX_SMBST_MODE | NPCM7XX_SMBST_XMIT | NPCM7XX_SMBST_SDAST;
508
+ s->cst |= NPCM7XX_SMBCST_BUSY;
509
+ } else {
510
+ s->st &= ~NPCM7XX_SMBST_MODE;
511
+ s->cst &= ~NPCM7XX_SMBCST_BUSY;
512
+ s->st |= NPCM7XX_SMBST_BER;
513
+ }
514
+
515
+ trace_npcm7xx_smbus_start(DEVICE(s)->canonical_path, available);
516
+ s->cst |= NPCM7XX_SMBCST_BB;
517
+ s->status = NPCM7XX_SMBUS_STATUS_IDLE;
518
+ npcm7xx_smbus_update_irq(s);
519
+}
520
+
521
+static void npcm7xx_smbus_send_address(NPCM7xxSMBusState *s, uint8_t value)
522
+{
523
+ int recv;
524
+ int rv;
525
+
526
+ recv = value & BIT(0);
527
+ rv = i2c_start_transfer(s->bus, value >> 1, recv);
528
+ trace_npcm7xx_smbus_send_address(DEVICE(s)->canonical_path,
529
+ value >> 1, recv, !rv);
530
+ if (rv) {
531
+ qemu_log_mask(LOG_GUEST_ERROR,
532
+ "%s: requesting i2c bus for 0x%02x failed: %d\n",
533
+ DEVICE(s)->canonical_path, value, rv);
534
+ /* Failed to start transfer. NACK to reject.*/
535
+ if (recv) {
536
+ s->st &= ~NPCM7XX_SMBST_XMIT;
537
+ } else {
538
+ s->st |= NPCM7XX_SMBST_XMIT;
539
+ }
540
+ npcm7xx_smbus_nack(s);
541
+ npcm7xx_smbus_update_irq(s);
542
+ return;
543
+ }
544
+
545
+ s->st &= ~NPCM7XX_SMBST_NEGACK;
546
+ if (recv) {
547
+ s->status = NPCM7XX_SMBUS_STATUS_RECEIVING;
548
+ s->st &= ~NPCM7XX_SMBST_XMIT;
549
+ } else {
550
+ s->status = NPCM7XX_SMBUS_STATUS_SENDING;
551
+ s->st |= NPCM7XX_SMBST_XMIT;
552
+ }
553
+
554
+ if (s->ctl1 & NPCM7XX_SMBCTL1_STASTRE) {
555
+ s->st |= NPCM7XX_SMBST_STASTR;
556
+ if (!recv) {
557
+ s->st |= NPCM7XX_SMBST_SDAST;
558
+ }
559
+ } else if (recv) {
560
+ npcm7xx_smbus_recv_byte(s);
561
+ }
562
+ npcm7xx_smbus_update_irq(s);
563
+}
564
+
565
+static void npcm7xx_smbus_execute_stop(NPCM7xxSMBusState *s)
566
+{
567
+ i2c_end_transfer(s->bus);
568
+ s->st = 0;
569
+ s->cst = 0;
570
+ s->status = NPCM7XX_SMBUS_STATUS_IDLE;
571
+ s->cst3 |= NPCM7XX_SMBCST3_EO_BUSY;
572
+ trace_npcm7xx_smbus_stop(DEVICE(s)->canonical_path);
573
+ npcm7xx_smbus_update_irq(s);
574
+}
575
+
576
+
577
+static void npcm7xx_smbus_stop(NPCM7xxSMBusState *s)
578
+{
579
+ if (s->st & NPCM7XX_SMBST_MODE) {
580
+ switch (s->status) {
581
+ case NPCM7XX_SMBUS_STATUS_RECEIVING:
582
+ case NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE:
583
+ s->status = NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE;
584
+ break;
585
+
586
+ case NPCM7XX_SMBUS_STATUS_NEGACK:
587
+ s->status = NPCM7XX_SMBUS_STATUS_STOPPING_NEGACK;
588
+ break;
589
+
590
+ default:
591
+ npcm7xx_smbus_execute_stop(s);
592
+ break;
593
+ }
594
+ }
595
+}
596
+
597
+static uint8_t npcm7xx_smbus_read_sda(NPCM7xxSMBusState *s)
598
+{
599
+ uint8_t value = s->sda;
600
+
601
+ switch (s->status) {
602
+ case NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE:
603
+ npcm7xx_smbus_execute_stop(s);
604
+ break;
605
+
606
+ case NPCM7XX_SMBUS_STATUS_RECEIVING:
607
+ npcm7xx_smbus_recv_byte(s);
608
+ break;
609
+
610
+ default:
611
+ /* Do nothing */
612
+ break;
613
+ }
614
+
615
+ return value;
616
+}
617
+
618
+static void npcm7xx_smbus_write_sda(NPCM7xxSMBusState *s, uint8_t value)
619
+{
620
+ s->sda = value;
621
+ if (s->st & NPCM7XX_SMBST_MODE) {
622
+ switch (s->status) {
623
+ case NPCM7XX_SMBUS_STATUS_IDLE:
624
+ npcm7xx_smbus_send_address(s, value);
625
+ break;
626
+ case NPCM7XX_SMBUS_STATUS_SENDING:
627
+ npcm7xx_smbus_send_byte(s, value);
628
+ break;
629
+ default:
630
+ qemu_log_mask(LOG_GUEST_ERROR,
631
+ "%s: write to SDA in invalid status %d: %u\n",
632
+ DEVICE(s)->canonical_path, s->status, value);
633
+ break;
634
+ }
635
+ }
636
+}
637
+
638
+static void npcm7xx_smbus_write_st(NPCM7xxSMBusState *s, uint8_t value)
639
+{
640
+ s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_STP);
641
+ s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_BER);
642
+ s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_STASTR);
643
+ s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_NMATCH);
644
+
645
+ if (value & NPCM7XX_SMBST_NEGACK) {
646
+ s->st &= ~NPCM7XX_SMBST_NEGACK;
647
+ if (s->status == NPCM7XX_SMBUS_STATUS_STOPPING_NEGACK) {
648
+ npcm7xx_smbus_execute_stop(s);
649
+ }
650
+ }
651
+
652
+ if (value & NPCM7XX_SMBST_STASTR &&
653
+ s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
654
+ npcm7xx_smbus_recv_byte(s);
655
+ }
656
+
657
+ npcm7xx_smbus_update_irq(s);
658
+}
659
+
660
+static void npcm7xx_smbus_write_cst(NPCM7xxSMBusState *s, uint8_t value)
661
+{
662
+ uint8_t new_value = s->cst;
663
+
664
+ s->cst = WRITE_ONE_CLEAR(new_value, value, NPCM7XX_SMBCST_BB);
665
+ npcm7xx_smbus_update_irq(s);
666
+}
667
+
668
+static void npcm7xx_smbus_write_cst3(NPCM7xxSMBusState *s, uint8_t value)
669
+{
670
+ s->cst3 = WRITE_ONE_CLEAR(s->cst3, value, NPCM7XX_SMBCST3_EO_BUSY);
671
+ npcm7xx_smbus_update_irq(s);
672
+}
673
+
674
+static void npcm7xx_smbus_write_ctl1(NPCM7xxSMBusState *s, uint8_t value)
675
+{
676
+ s->ctl1 = KEEP_OLD_BIT(s->ctl1, value,
677
+ NPCM7XX_SMBCTL1_START | NPCM7XX_SMBCTL1_STOP | NPCM7XX_SMBCTL1_ACK);
678
+
679
+ if (value & NPCM7XX_SMBCTL1_START) {
680
+ npcm7xx_smbus_start(s);
681
+ }
682
+
683
+ if (value & NPCM7XX_SMBCTL1_STOP) {
684
+ npcm7xx_smbus_stop(s);
685
+ }
686
+
687
+ npcm7xx_smbus_update_irq(s);
688
+}
689
+
690
+static void npcm7xx_smbus_write_ctl2(NPCM7xxSMBusState *s, uint8_t value)
691
+{
692
+ s->ctl2 = value;
693
+
694
+ if (!NPCM7XX_SMBUS_ENABLED(s)) {
695
+ /* Disable this SMBus module. */
696
+ s->ctl1 = 0;
697
+ s->st = 0;
698
+ s->cst3 = s->cst3 & (~NPCM7XX_SMBCST3_EO_BUSY);
699
+ s->cst = 0;
700
+ }
701
+}
702
+
703
+static void npcm7xx_smbus_write_ctl3(NPCM7xxSMBusState *s, uint8_t value)
704
+{
705
+ uint8_t old_ctl3 = s->ctl3;
706
+
707
+ /* Write to SDA and SCL bits are ignored. */
708
+ s->ctl3 = KEEP_OLD_BIT(old_ctl3, value,
709
+ NPCM7XX_SMBCTL3_SCL_LVL | NPCM7XX_SMBCTL3_SDA_LVL);
710
+}
711
+
712
+static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
713
+{
714
+ NPCM7xxSMBusState *s = opaque;
715
+ uint64_t value = 0;
716
+ uint8_t bank = s->ctl3 & NPCM7XX_SMBCTL3_BNK_SEL;
717
+
718
+ /* The order of the registers are their order in memory. */
719
+ switch (offset) {
720
+ case NPCM7XX_SMB_SDA:
721
+ value = npcm7xx_smbus_read_sda(s);
722
+ break;
723
+
724
+ case NPCM7XX_SMB_ST:
725
+ value = s->st;
726
+ break;
727
+
728
+ case NPCM7XX_SMB_CST:
729
+ value = s->cst;
730
+ break;
731
+
732
+ case NPCM7XX_SMB_CTL1:
733
+ value = s->ctl1;
734
+ break;
735
+
736
+ case NPCM7XX_SMB_ADDR1:
737
+ value = s->addr[0];
738
+ break;
739
+
740
+ case NPCM7XX_SMB_CTL2:
741
+ value = s->ctl2;
742
+ break;
743
+
744
+ case NPCM7XX_SMB_ADDR2:
745
+ value = s->addr[1];
746
+ break;
747
+
748
+ case NPCM7XX_SMB_CTL3:
749
+ value = s->ctl3;
750
+ break;
751
+
752
+ case NPCM7XX_SMB_CST2:
753
+ value = s->cst2;
754
+ break;
755
+
756
+ case NPCM7XX_SMB_CST3:
757
+ value = s->cst3;
758
+ break;
759
+
760
+ case NPCM7XX_SMB_VER:
761
+ value = npcm7xx_smbus_get_version();
762
+ break;
763
+
764
+ /* This register is either invalid or banked at this point. */
765
+ default:
766
+ if (bank) {
767
+ /* Bank 1 */
768
+ qemu_log_mask(LOG_GUEST_ERROR,
769
+ "%s: read from invalid offset 0x%" HWADDR_PRIx "\n",
770
+ DEVICE(s)->canonical_path, offset);
771
+ } else {
772
+ /* Bank 0 */
773
+ switch (offset) {
774
+ case NPCM7XX_SMB_ADDR3:
775
+ value = s->addr[2];
776
+ break;
777
+
778
+ case NPCM7XX_SMB_ADDR7:
779
+ value = s->addr[6];
780
+ break;
781
+
782
+ case NPCM7XX_SMB_ADDR4:
783
+ value = s->addr[3];
784
+ break;
785
+
786
+ case NPCM7XX_SMB_ADDR8:
787
+ value = s->addr[7];
788
+ break;
789
+
790
+ case NPCM7XX_SMB_ADDR5:
791
+ value = s->addr[4];
792
+ break;
793
+
794
+ case NPCM7XX_SMB_ADDR9:
795
+ value = s->addr[8];
796
+ break;
797
+
798
+ case NPCM7XX_SMB_ADDR6:
799
+ value = s->addr[5];
800
+ break;
801
+
802
+ case NPCM7XX_SMB_ADDR10:
803
+ value = s->addr[9];
804
+ break;
805
+
806
+ case NPCM7XX_SMB_CTL4:
807
+ value = s->ctl4;
808
+ break;
809
+
810
+ case NPCM7XX_SMB_CTL5:
811
+ value = s->ctl5;
812
+ break;
813
+
814
+ case NPCM7XX_SMB_SCLLT:
815
+ value = s->scllt;
816
+ break;
817
+
818
+ case NPCM7XX_SMB_SCLHT:
819
+ value = s->sclht;
820
+ break;
821
+
822
+ default:
823
+ qemu_log_mask(LOG_GUEST_ERROR,
824
+ "%s: read from invalid offset 0x%" HWADDR_PRIx "\n",
825
+ DEVICE(s)->canonical_path, offset);
826
+ break;
827
+ }
828
+ }
829
+ break;
830
+ }
831
+
832
+ trace_npcm7xx_smbus_read(DEVICE(s)->canonical_path, offset, value, size);
833
+
834
+ return value;
835
+}
836
+
837
+static void npcm7xx_smbus_write(void *opaque, hwaddr offset, uint64_t value,
838
+ unsigned size)
839
+{
840
+ NPCM7xxSMBusState *s = opaque;
841
+ uint8_t bank = s->ctl3 & NPCM7XX_SMBCTL3_BNK_SEL;
842
+
843
+ trace_npcm7xx_smbus_write(DEVICE(s)->canonical_path, offset, value, size);
844
+
845
+ /* The order of the registers are their order in memory. */
846
+ switch (offset) {
847
+ case NPCM7XX_SMB_SDA:
848
+ npcm7xx_smbus_write_sda(s, value);
849
+ break;
850
+
851
+ case NPCM7XX_SMB_ST:
852
+ npcm7xx_smbus_write_st(s, value);
853
+ break;
854
+
855
+ case NPCM7XX_SMB_CST:
856
+ npcm7xx_smbus_write_cst(s, value);
857
+ break;
858
+
859
+ case NPCM7XX_SMB_CTL1:
860
+ npcm7xx_smbus_write_ctl1(s, value);
861
+ break;
862
+
863
+ case NPCM7XX_SMB_ADDR1:
864
+ s->addr[0] = value;
865
+ break;
866
+
867
+ case NPCM7XX_SMB_CTL2:
868
+ npcm7xx_smbus_write_ctl2(s, value);
869
+ break;
870
+
871
+ case NPCM7XX_SMB_ADDR2:
872
+ s->addr[1] = value;
873
+ break;
874
+
875
+ case NPCM7XX_SMB_CTL3:
876
+ npcm7xx_smbus_write_ctl3(s, value);
877
+ break;
878
+
879
+ case NPCM7XX_SMB_CST2:
880
+ qemu_log_mask(LOG_GUEST_ERROR,
881
+ "%s: write to read-only reg: offset 0x%" HWADDR_PRIx "\n",
882
+ DEVICE(s)->canonical_path, offset);
883
+ break;
884
+
885
+ case NPCM7XX_SMB_CST3:
886
+ npcm7xx_smbus_write_cst3(s, value);
887
+ break;
888
+
889
+ case NPCM7XX_SMB_VER:
890
+ qemu_log_mask(LOG_GUEST_ERROR,
891
+ "%s: write to read-only reg: offset 0x%" HWADDR_PRIx "\n",
892
+ DEVICE(s)->canonical_path, offset);
893
+ break;
894
+
895
+ /* This register is either invalid or banked at this point. */
896
+ default:
897
+ if (bank) {
898
+ /* Bank 1 */
899
+ qemu_log_mask(LOG_GUEST_ERROR,
900
+ "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
901
+ DEVICE(s)->canonical_path, offset);
902
+ } else {
903
+ /* Bank 0 */
904
+ switch (offset) {
905
+ case NPCM7XX_SMB_ADDR3:
906
+ s->addr[2] = value;
907
+ break;
908
+
909
+ case NPCM7XX_SMB_ADDR7:
910
+ s->addr[6] = value;
911
+ break;
912
+
913
+ case NPCM7XX_SMB_ADDR4:
914
+ s->addr[3] = value;
915
+ break;
916
+
917
+ case NPCM7XX_SMB_ADDR8:
918
+ s->addr[7] = value;
919
+ break;
920
+
921
+ case NPCM7XX_SMB_ADDR5:
922
+ s->addr[4] = value;
923
+ break;
924
+
925
+ case NPCM7XX_SMB_ADDR9:
926
+ s->addr[8] = value;
927
+ break;
928
+
929
+ case NPCM7XX_SMB_ADDR6:
930
+ s->addr[5] = value;
931
+ break;
932
+
933
+ case NPCM7XX_SMB_ADDR10:
934
+ s->addr[9] = value;
935
+ break;
936
+
937
+ case NPCM7XX_SMB_CTL4:
938
+ s->ctl4 = value;
939
+ break;
940
+
941
+ case NPCM7XX_SMB_CTL5:
942
+ s->ctl5 = value;
943
+ break;
944
+
945
+ case NPCM7XX_SMB_SCLLT:
946
+ s->scllt = value;
947
+ break;
948
+
949
+ case NPCM7XX_SMB_SCLHT:
950
+ s->sclht = value;
951
+ break;
952
+
953
+ default:
954
+ qemu_log_mask(LOG_GUEST_ERROR,
955
+ "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
956
+ DEVICE(s)->canonical_path, offset);
957
+ break;
958
+ }
959
+ }
960
+ break;
961
+ }
962
+}
963
+
964
+static const MemoryRegionOps npcm7xx_smbus_ops = {
965
+ .read = npcm7xx_smbus_read,
966
+ .write = npcm7xx_smbus_write,
967
+ .endianness = DEVICE_LITTLE_ENDIAN,
968
+ .valid = {
969
+ .min_access_size = 1,
970
+ .max_access_size = 1,
971
+ .unaligned = false,
133
+ },
972
+ },
134
+};
973
+};
135
+
974
+
136
static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
975
+static void npcm7xx_smbus_enter_reset(Object *obj, ResetType type)
137
{
976
+{
138
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
977
+ NPCM7xxSMBusState *s = NPCM7XX_SMBUS(obj);
139
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
978
+
140
},
979
+ s->st = NPCM7XX_SMB_ST_INIT_VAL;
141
};
980
+ s->cst = NPCM7XX_SMB_CST_INIT_VAL;
142
981
+ s->cst2 = NPCM7XX_SMB_CST2_INIT_VAL;
143
+ const PPCInfo an524_ppcs[] = { {
982
+ s->cst3 = NPCM7XX_SMB_CST3_INIT_VAL;
144
+ .name = "apb_ppcexp0",
983
+ s->ctl1 = NPCM7XX_SMB_CTL1_INIT_VAL;
145
+ .ports = {
984
+ s->ctl2 = NPCM7XX_SMB_CTL2_INIT_VAL;
146
+ { "bram-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
985
+ s->ctl3 = NPCM7XX_SMB_CTL3_INIT_VAL;
147
+ { "qspi-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
986
+ s->ctl4 = NPCM7XX_SMB_CTL4_INIT_VAL;
148
+ { "ddr-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
987
+ s->ctl5 = NPCM7XX_SMB_CTL5_INIT_VAL;
149
+ },
988
+
150
+ }, {
989
+ for (int i = 0; i < NPCM7XX_SMBUS_NR_ADDRS; ++i) {
151
+ .name = "apb_ppcexp1",
990
+ s->addr[i] = NPCM7XX_SMB_ADDR_INIT_VAL;
152
+ .ports = {
991
+ }
153
+ { "i2c0", make_i2c, &mms->i2c[0], 0x41200000, 0x1000 },
992
+ s->scllt = NPCM7XX_SMB_SCLLT_INIT_VAL;
154
+ { "i2c1", make_i2c, &mms->i2c[1], 0x41201000, 0x1000 },
993
+ s->sclht = NPCM7XX_SMB_SCLHT_INIT_VAL;
155
+ { "spi0", make_spi, &mms->spi[0], 0x41202000, 0x1000, { 52 } },
994
+
156
+ { "spi1", make_spi, &mms->spi[1], 0x41203000, 0x1000, { 53 } },
995
+ s->status = NPCM7XX_SMBUS_STATUS_IDLE;
157
+ { "spi2", make_spi, &mms->spi[2], 0x41204000, 0x1000, { 54 } },
996
+}
158
+ { "i2c2", make_i2c, &mms->i2c[2], 0x41205000, 0x1000 },
997
+
159
+ { "i2c3", make_i2c, &mms->i2c[3], 0x41206000, 0x1000 },
998
+static void npcm7xx_smbus_hold_reset(Object *obj)
160
+ { /* port 7 reserved */ },
999
+{
161
+ { "i2c4", make_i2c, &mms->i2c[4], 0x41208000, 0x1000 },
1000
+ NPCM7xxSMBusState *s = NPCM7XX_SMBUS(obj);
162
+ },
1001
+
163
+ }, {
1002
+ qemu_irq_lower(s->irq);
164
+ .name = "apb_ppcexp2",
1003
+}
165
+ .ports = {
1004
+
166
+ { "scc", make_scc, &mms->scc, 0x41300000, 0x1000 },
1005
+static void npcm7xx_smbus_init(Object *obj)
167
+ { "i2s-audio", make_unimp_dev, &mms->i2s_audio,
1006
+{
168
+ 0x41301000, 0x1000 },
1007
+ NPCM7xxSMBusState *s = NPCM7XX_SMBUS(obj);
169
+ { "fpgaio", make_fpgaio, &mms->fpgaio, 0x41302000, 0x1000 },
1008
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
170
+ { "uart0", make_uart, &mms->uart[0], 0x41303000, 0x1000, { 32, 33, 42 } },
1009
+
171
+ { "uart1", make_uart, &mms->uart[1], 0x41304000, 0x1000, { 34, 35, 43 } },
1010
+ sysbus_init_irq(sbd, &s->irq);
172
+ { "uart2", make_uart, &mms->uart[2], 0x41305000, 0x1000, { 36, 37, 44 } },
1011
+ memory_region_init_io(&s->iomem, obj, &npcm7xx_smbus_ops, s,
173
+ { "uart3", make_uart, &mms->uart[3], 0x41306000, 0x1000, { 38, 39, 45 } },
1012
+ "regs", 4 * KiB);
174
+ { "uart4", make_uart, &mms->uart[4], 0x41307000, 0x1000, { 40, 41, 46 } },
1013
+ sysbus_init_mmio(sbd, &s->iomem);
175
+ { "uart5", make_uart, &mms->uart[5], 0x41308000, 0x1000, { 124, 125, 126 } },
1014
+
176
+
1015
+ s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
177
+ { /* port 9 reserved */ },
1016
+ s->status = NPCM7XX_SMBUS_STATUS_IDLE;
178
+ { "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
1017
+}
179
+ { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
1018
+
180
+ },
1019
+static const VMStateDescription vmstate_npcm7xx_smbus = {
181
+ }, {
1020
+ .name = "npcm7xx-smbus",
182
+ .name = "ahb_ppcexp0",
1021
+ .version_id = 0,
183
+ .ports = {
1022
+ .minimum_version_id = 0,
184
+ { "gpio0", make_unimp_dev, &mms->gpio[0], 0x41100000, 0x1000 },
1023
+ .fields = (VMStateField[]) {
185
+ { "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
1024
+ VMSTATE_UINT8(sda, NPCM7xxSMBusState),
186
+ { "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
1025
+ VMSTATE_UINT8(st, NPCM7xxSMBusState),
187
+ { "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
1026
+ VMSTATE_UINT8(cst, NPCM7xxSMBusState),
188
+ { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
1027
+ VMSTATE_UINT8(cst2, NPCM7xxSMBusState),
189
+ },
1028
+ VMSTATE_UINT8(cst3, NPCM7xxSMBusState),
190
+ },
1029
+ VMSTATE_UINT8(ctl1, NPCM7xxSMBusState),
191
+ };
1030
+ VMSTATE_UINT8(ctl2, NPCM7xxSMBusState),
192
+
1031
+ VMSTATE_UINT8(ctl3, NPCM7xxSMBusState),
193
switch (mmc->fpga_type) {
1032
+ VMSTATE_UINT8(ctl4, NPCM7xxSMBusState),
194
case FPGA_AN505:
1033
+ VMSTATE_UINT8(ctl5, NPCM7xxSMBusState),
195
case FPGA_AN521:
1034
+ VMSTATE_UINT8_ARRAY(addr, NPCM7xxSMBusState, NPCM7XX_SMBUS_NR_ADDRS),
196
ppcs = an505_ppcs;
1035
+ VMSTATE_UINT8(scllt, NPCM7xxSMBusState),
197
num_ppcs = ARRAY_SIZE(an505_ppcs);
1036
+ VMSTATE_UINT8(sclht, NPCM7xxSMBusState),
198
break;
1037
+ VMSTATE_END_OF_LIST(),
199
+ case FPGA_AN524:
1038
+ },
200
+ ppcs = an524_ppcs;
201
+ num_ppcs = ARRAY_SIZE(an524_ppcs);
202
+ break;
203
default:
204
g_assert_not_reached();
205
}
206
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
207
mps2tz_set_default_ram_info(mmc);
208
}
209
210
+static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
211
+{
212
+ MachineClass *mc = MACHINE_CLASS(oc);
213
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
214
+
215
+ mc->desc = "ARM MPS3 with AN524 FPGA image for dual Cortex-M33";
216
+ mc->default_cpus = 2;
217
+ mc->min_cpus = mc->default_cpus;
218
+ mc->max_cpus = mc->default_cpus;
219
+ mmc->fpga_type = FPGA_AN524;
220
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
221
+ mmc->scc_id = 0x41045240;
222
+ mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
223
+ mmc->oscclk = an524_oscclk;
224
+ mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
225
+ mmc->fpgaio_num_leds = 10;
226
+ mmc->fpgaio_has_switches = true;
227
+ mmc->numirq = 95;
228
+ mmc->raminfo = an524_raminfo;
229
+ mmc->armsse_type = TYPE_SSE200;
230
+ mps2tz_set_default_ram_info(mmc);
231
+}
232
+
233
static const TypeInfo mps2tz_info = {
234
.name = TYPE_MPS2TZ_MACHINE,
235
.parent = TYPE_MACHINE,
236
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps2tz_an521_info = {
237
.class_init = mps2tz_an521_class_init,
238
};
239
240
+static const TypeInfo mps3tz_an524_info = {
241
+ .name = TYPE_MPS3TZ_AN524_MACHINE,
242
+ .parent = TYPE_MPS2TZ_MACHINE,
243
+ .class_init = mps3tz_an524_class_init,
244
+};
1039
+};
245
+
1040
+
246
static void mps2tz_machine_init(void)
1041
+static void npcm7xx_smbus_class_init(ObjectClass *klass, void *data)
247
{
1042
+{
248
type_register_static(&mps2tz_info);
1043
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
249
type_register_static(&mps2tz_an505_info);
1044
+ DeviceClass *dc = DEVICE_CLASS(klass);
250
type_register_static(&mps2tz_an521_info);
1045
+
251
+ type_register_static(&mps3tz_an524_info);
1046
+ dc->desc = "NPCM7xx System Management Bus";
252
}
1047
+ dc->vmsd = &vmstate_npcm7xx_smbus;
253
1048
+ rc->phases.enter = npcm7xx_smbus_enter_reset;
254
type_init(mps2tz_machine_init);
1049
+ rc->phases.hold = npcm7xx_smbus_hold_reset;
1050
+}
1051
+
1052
+static const TypeInfo npcm7xx_smbus_types[] = {
1053
+ {
1054
+ .name = TYPE_NPCM7XX_SMBUS,
1055
+ .parent = TYPE_SYS_BUS_DEVICE,
1056
+ .instance_size = sizeof(NPCM7xxSMBusState),
1057
+ .class_init = npcm7xx_smbus_class_init,
1058
+ .instance_init = npcm7xx_smbus_init,
1059
+ },
1060
+};
1061
+DEFINE_TYPES(npcm7xx_smbus_types);
1062
diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build
1063
index XXXXXXX..XXXXXXX 100644
1064
--- a/hw/i2c/meson.build
1065
+++ b/hw/i2c/meson.build
1066
@@ -XXX,XX +XXX,XX @@ i2c_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_i2c.c'))
1067
i2c_ss.add(when: 'CONFIG_IMX_I2C', if_true: files('imx_i2c.c'))
1068
i2c_ss.add(when: 'CONFIG_MPC_I2C', if_true: files('mpc_i2c.c'))
1069
i2c_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('microbit_i2c.c'))
1070
+i2c_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_smbus.c'))
1071
i2c_ss.add(when: 'CONFIG_SMBUS_EEPROM', if_true: files('smbus_eeprom.c'))
1072
i2c_ss.add(when: 'CONFIG_VERSATILE_I2C', if_true: files('versatile_i2c.c'))
1073
i2c_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_i2c.c'))
1074
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
1075
index XXXXXXX..XXXXXXX 100644
1076
--- a/hw/i2c/trace-events
1077
+++ b/hw/i2c/trace-events
1078
@@ -XXX,XX +XXX,XX @@ aspeed_i2c_bus_read(uint32_t busid, uint64_t offset, unsigned size, uint64_t val
1079
aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
1080
aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send %d/%d 0x%02x"
1081
aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv %d/%d 0x%02x"
1082
+
1083
+# npcm7xx_smbus.c
1084
+
1085
+npcm7xx_smbus_read(const char *id, uint64_t offset, uint64_t value, unsigned size) "%s offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
1086
+npcm7xx_smbus_write(const char *id, uint64_t offset, uint64_t value, unsigned size) "%s offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
1087
+npcm7xx_smbus_start(const char *id, int success) "%s starting, success: %d"
1088
+npcm7xx_smbus_send_address(const char *id, uint8_t addr, int recv, int success) "%s sending address: 0x%02x, recv: %d, success: %d"
1089
+npcm7xx_smbus_send_byte(const char *id, uint8_t value, int success) "%s send byte: 0x%02x, success: %d"
1090
+npcm7xx_smbus_recv_byte(const char *id, uint8_t value) "%s recv byte: 0x%02x"
1091
+npcm7xx_smbus_stop(const char *id) "%s stopping"
1092
+npcm7xx_smbus_nack(const char *id) "%s nacking"
255
--
1093
--
256
2.20.1
1094
2.20.1
257
1095
258
1096
diff view generated by jsdifflib
1
The function tc6393xb_draw_graphic32() is called in exactly one place,
1
From: Hao Wu <wuhaotsh@google.com>
2
so just inline the function body at its callsite. This allows us to
3
drop the template header entirely.
4
2
5
The code move includes a single added space after 'for' to fix
3
Add I2C temperature sensors for NPCM750 eval board.
6
the coding style.
7
4
5
Reviewed-by: Doug Evans<dje@google.com>
6
Reviewed-by: Tyrong Ting<kfting@nuvoton.com>
7
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20210210220426.3577804-3-wuhaotsh@google.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210215103215.4944-5-peter.maydell@linaro.org
12
---
11
---
13
hw/display/tc6393xb_template.h | 45 ----------------------------------
12
hw/arm/npcm7xx_boards.c | 19 +++++++++++++++++++
14
hw/display/tc6393xb.c | 23 ++++++++++++++---
13
1 file changed, 19 insertions(+)
15
2 files changed, 19 insertions(+), 49 deletions(-)
16
delete mode 100644 hw/display/tc6393xb_template.h
17
14
18
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
19
deleted file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- a/hw/display/tc6393xb_template.h
22
+++ /dev/null
23
@@ -XXX,XX +XXX,XX @@
24
-/*
25
- * Toshiba TC6393XB I/O Controller.
26
- * Found in Sharp Zaurus SL-6000 (tosa) or some
27
- * Toshiba e-Series PDAs.
28
- *
29
- * FB support code. Based on G364 fb emulator
30
- *
31
- * Copyright (c) 2007 Hervé Poussineau
32
- *
33
- * This program is free software; you can redistribute it and/or
34
- * modify it under the terms of the GNU General Public License as
35
- * published by the Free Software Foundation; either version 2 of
36
- * the License, or (at your option) any later version.
37
- *
38
- * This program is distributed in the hope that it will be useful,
39
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
40
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41
- * GNU General Public License for more details.
42
- *
43
- * You should have received a copy of the GNU General Public License along
44
- * with this program; if not, see <http://www.gnu.org/licenses/>.
45
- */
46
-
47
-static void tc6393xb_draw_graphic32(TC6393xbState *s)
48
-{
49
- DisplaySurface *surface = qemu_console_surface(s->con);
50
- int i;
51
- uint16_t *data_buffer;
52
- uint8_t *data_display;
53
-
54
- data_buffer = s->vram_ptr;
55
- data_display = surface_data(surface);
56
- for(i = 0; i < s->scr_height; i++) {
57
- int j;
58
- for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
59
- uint16_t color = *data_buffer;
60
- uint32_t dest_color = rgb_to_pixel32(
61
- ((color & 0xf800) * 0x108) >> 11,
62
- ((color & 0x7e0) * 0x41) >> 9,
63
- ((color & 0x1f) * 0x21) >> 2
64
- );
65
- *(uint32_t *)data_display = dest_color;
66
- }
67
- }
68
-}
69
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
70
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/display/tc6393xb.c
17
--- a/hw/arm/npcm7xx_boards.c
72
+++ b/hw/display/tc6393xb.c
18
+++ b/hw/arm/npcm7xx_boards.c
73
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
19
@@ -XXX,XX +XXX,XX @@ static NPCM7xxState *npcm7xx_create_soc(MachineState *machine,
74
(uint32_t) addr, value & 0xff);
20
return NPCM7XX(obj);
75
}
21
}
76
22
77
-#define BITS 32
23
+static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, uint32_t num)
78
-#include "tc6393xb_template.h"
24
+{
79
-
25
+ g_assert(num < ARRAY_SIZE(soc->smbus));
80
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
26
+ return I2C_BUS(qdev_get_child_bus(DEVICE(&soc->smbus[num]), "i2c-bus"));
27
+}
28
+
29
+static void npcm750_evb_i2c_init(NPCM7xxState *soc)
30
+{
31
+ /* lm75 temperature sensor on SVB, tmp105 is compatible */
32
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 0), "tmp105", 0x48);
33
+ /* lm75 temperature sensor on EB, tmp105 is compatible */
34
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x48);
35
+ /* tmp100 temperature sensor on EB, tmp105 is compatible */
36
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x48);
37
+ /* tmp100 temperature sensor on SVB, tmp105 is compatible */
38
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
39
+}
40
+
41
static void npcm750_evb_init(MachineState *machine)
81
{
42
{
82
- tc6393xb_draw_graphic32(s);
43
NPCM7xxState *soc;
83
+ DisplaySurface *surface = qemu_console_surface(s->con);
44
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_init(MachineState *machine)
84
+ int i;
45
85
+ uint16_t *data_buffer;
46
npcm7xx_load_bootrom(machine, soc);
86
+ uint8_t *data_display;
47
npcm7xx_connect_flash(&soc->fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0));
87
+
48
+ npcm750_evb_i2c_init(soc);
88
+ data_buffer = s->vram_ptr;
49
npcm7xx_load_kernel(machine, soc);
89
+ data_display = surface_data(surface);
90
+ for (i = 0; i < s->scr_height; i++) {
91
+ int j;
92
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
93
+ uint16_t color = *data_buffer;
94
+ uint32_t dest_color = rgb_to_pixel32(
95
+ ((color & 0xf800) * 0x108) >> 11,
96
+ ((color & 0x7e0) * 0x41) >> 9,
97
+ ((color & 0x1f) * 0x21) >> 2
98
+ );
99
+ *(uint32_t *)data_display = dest_color;
100
+ }
101
+ }
102
dpy_gfx_update_full(s->con);
103
}
50
}
104
51
105
--
52
--
106
2.20.1
53
2.20.1
107
54
108
55
diff view generated by jsdifflib
1
The AN524 has more interrupt lines than the AN505 and AN521; make
1
From: Hao Wu <wuhaotsh@google.com>
2
numirq board-specific rather than a compile-time constant.
3
2
4
Since the difference is small (92 on the current boards and 95 on the
3
Add AT24 EEPROM and temperature sensors for GSJ machine.
5
new one) we don't dynamically allocate the cpu_irq_splitter[] array
6
but leave it as a fixed length array whose size is the maximum needed
7
for any of the boards.
8
4
5
Reviewed-by: Doug Evans<dje@google.com>
6
Reviewed-by: Tyrong Ting<kfting@nuvoton.com>
7
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
Message-id: 20210210220426.3577804-4-wuhaotsh@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-10-peter.maydell@linaro.org
13
---
11
---
14
hw/arm/mps2-tz.c | 15 ++++++++++-----
12
hw/arm/npcm7xx_boards.c | 27 +++++++++++++++++++++++++++
15
1 file changed, 10 insertions(+), 5 deletions(-)
13
hw/arm/Kconfig | 1 +
14
2 files changed, 28 insertions(+)
16
15
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
18
--- a/hw/arm/npcm7xx_boards.c
20
+++ b/hw/arm/mps2-tz.c
19
+++ b/hw/arm/npcm7xx_boards.c
21
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
22
#include "hw/qdev-clock.h"
21
#include "exec/address-spaces.h"
23
#include "qom/object.h"
22
#include "hw/arm/npcm7xx.h"
24
23
#include "hw/core/cpu.h"
25
-#define MPS2TZ_NUMIRQ 92
24
+#include "hw/i2c/smbus_eeprom.h"
26
+#define MPS2TZ_NUMIRQ_MAX 92
25
#include "hw/loader.h"
27
26
#include "hw/qdev-properties.h"
28
typedef enum MPS2TZFPGAType {
27
#include "qapi/error.h"
29
FPGA_AN505,
28
@@ -XXX,XX +XXX,XX @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, uint32_t num)
30
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
29
return I2C_BUS(qdev_get_child_bus(DEVICE(&soc->smbus[num]), "i2c-bus"));
31
const uint32_t *oscclk;
30
}
32
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
31
33
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
32
+static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
34
+ int numirq; /* Number of external interrupts */
33
+ uint32_t rsize)
35
const char *armsse_type;
34
+{
36
};
35
+ I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
37
36
+ I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
38
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
37
+ DeviceState *dev = DEVICE(i2c_dev);
39
SplitIRQ sec_resp_splitter;
38
+
40
qemu_or_irq uart_irq_orgate;
39
+ qdev_prop_set_uint32(dev, "rom-size", rsize);
41
DeviceState *lan9118;
40
+ i2c_slave_realize_and_unref(i2c_dev, i2c_bus, &error_abort);
42
- SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
41
+}
43
+ SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
42
+
44
Clock *sysclk;
43
static void npcm750_evb_i2c_init(NPCM7xxState *soc)
45
Clock *s32kclk;
46
};
47
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
48
{
44
{
49
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
45
/* lm75 temperature sensor on SVB, tmp105 is compatible */
50
MachineClass *mc = MACHINE_GET_CLASS(mms);
46
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_i2c_init(NPCM7xxState *soc)
51
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
47
i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
52
53
- assert(irqno < MPS2TZ_NUMIRQ);
54
+ assert(irqno < mmc->numirq);
55
56
if (mc->max_cpus > 1) {
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
59
iotkitdev = DEVICE(&mms->iotkit);
60
object_property_set_link(OBJECT(&mms->iotkit), "memory",
61
OBJECT(system_memory), &error_abort);
62
- qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
63
+ qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
64
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
65
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
66
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
67
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
68
* board. If there is only one CPU, we can just wire the device IRQ
69
* directly to the SSE's IRQ input.
70
*/
71
+ assert(mmc->numirq <= MPS2TZ_NUMIRQ_MAX);
72
if (mc->max_cpus > 1) {
73
- for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
74
+ for (i = 0; i < mmc->numirq; i++) {
75
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
76
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
77
78
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
79
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
80
mmc->fpgaio_num_leds = 2;
81
mmc->fpgaio_has_switches = false;
82
+ mmc->numirq = 92;
83
mmc->armsse_type = TYPE_IOTKIT;
84
}
48
}
85
49
86
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
50
+static void quanta_gsj_i2c_init(NPCM7xxState *soc)
87
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
51
+{
88
mmc->fpgaio_num_leds = 2;
52
+ /* GSJ machine have 4 max31725 temperature sensors, tmp105 is compatible. */
89
mmc->fpgaio_has_switches = false;
53
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x5c);
90
+ mmc->numirq = 92;
54
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x5c);
91
mmc->armsse_type = TYPE_SSE200;
55
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
56
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
57
+
58
+ at24c_eeprom_init(soc, 9, 0x55, 8192);
59
+ at24c_eeprom_init(soc, 10, 0x55, 8192);
60
+
61
+ /* TODO: Add additional i2c devices. */
62
+}
63
+
64
static void npcm750_evb_init(MachineState *machine)
65
{
66
NPCM7xxState *soc;
67
@@ -XXX,XX +XXX,XX @@ static void quanta_gsj_init(MachineState *machine)
68
npcm7xx_load_bootrom(machine, soc);
69
npcm7xx_connect_flash(&soc->fiu[0], 0, "mx25l25635e",
70
drive_get(IF_MTD, 0, 0));
71
+ quanta_gsj_i2c_init(soc);
72
npcm7xx_load_kernel(machine, soc);
92
}
73
}
93
74
75
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/arm/Kconfig
78
+++ b/hw/arm/Kconfig
79
@@ -XXX,XX +XXX,XX @@ config NPCM7XX
80
bool
81
select A9MPCORE
82
select ARM_GIC
83
+ select AT24C # EEPROM
84
select PL310 # cache controller
85
select SERIAL
86
select SSI
94
--
87
--
95
2.20.1
88
2.20.1
96
89
97
90
diff view generated by jsdifflib
1
The AN505 and AN521 have the same layout of RAM; the AN524 does not.
1
From: Hao Wu <wuhaotsh@google.com>
2
Replace the current hard-coding of where the RAM is and which parts
2
3
of it are behind which MPCs with a data-driven approach.
3
This patch adds a QTest for NPCM7XX SMBus's single byte mode. It sends a
4
4
byte to a device in the evaluation board, and verify the retrieved value
5
is equivalent to the sent value.
6
7
Reviewed-by: Doug Evans<dje@google.com>
8
Reviewed-by: Tyrong Ting<kfting@nuvoton.com>
9
Signed-off-by: Hao Wu <wuhaotsh@google.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20210210220426.3577804-5-wuhaotsh@google.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210215115138.20465-17-peter.maydell@linaro.org
8
---
13
---
9
hw/arm/mps2-tz.c | 175 +++++++++++++++++++++++++++++++++++++----------
14
tests/qtest/npcm7xx_smbus-test.c | 352 +++++++++++++++++++++++++++++++
10
1 file changed, 138 insertions(+), 37 deletions(-)
15
tests/qtest/meson.build | 1 +
11
16
2 files changed, 353 insertions(+)
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
create mode 100644 tests/qtest/npcm7xx_smbus-test.c
13
index XXXXXXX..XXXXXXX 100644
18
14
--- a/hw/arm/mps2-tz.c
19
diff --git a/tests/qtest/npcm7xx_smbus-test.c b/tests/qtest/npcm7xx_smbus-test.c
15
+++ b/hw/arm/mps2-tz.c
20
new file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- /dev/null
23
+++ b/tests/qtest/npcm7xx_smbus-test.c
16
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
17
#include "qom/object.h"
18
19
#define MPS2TZ_NUMIRQ_MAX 92
20
+#define MPS2TZ_RAM_MAX 4
21
22
typedef enum MPS2TZFPGAType {
23
FPGA_AN505,
24
FPGA_AN521,
25
} MPS2TZFPGAType;
26
27
+/*
25
+/*
28
+ * Define the layout of RAM in a board, including which parts are
26
+ * QTests for Nuvoton NPCM7xx SMBus Modules.
29
+ * behind which MPCs.
27
+ *
30
+ * mrindex specifies the index into mms->ram[] to use for the backing RAM;
28
+ * Copyright 2020 Google LLC
31
+ * -1 means "use the system RAM".
29
+ *
30
+ * This program is free software; you can redistribute it and/or modify it
31
+ * under the terms of the GNU General Public License as published by the
32
+ * Free Software Foundation; either version 2 of the License, or
33
+ * (at your option) any later version.
34
+ *
35
+ * This program is distributed in the hope that it will be useful, but WITHOUT
36
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38
+ * for more details.
32
+ */
39
+ */
33
+typedef struct RAMInfo {
40
+
34
+ const char *name;
41
+#include "qemu/osdep.h"
35
+ uint32_t base;
42
+#include "qemu/bitops.h"
36
+ uint32_t size;
43
+#include "libqos/i2c.h"
37
+ int mpc; /* MPC number, -1 for "not behind an MPC" */
44
+#include "libqos/libqtest.h"
38
+ int mrindex;
45
+#include "hw/misc/tmp105_regs.h"
39
+ int flags;
46
+
40
+} RAMInfo;
47
+#define NR_SMBUS_DEVICES 16
41
+
48
+#define SMBUS_ADDR(x) (0xf0080000 + 0x1000 * (x))
42
+/*
49
+#define SMBUS_IRQ(x) (64 + (x))
43
+ * Flag values:
50
+
44
+ * IS_ALIAS: this RAM area is an alias to the upstream end of the
51
+#define EVB_DEVICE_ADDR 0x48
45
+ * MPC specified by its .mpc value
52
+#define INVALID_DEVICE_ADDR 0x01
46
+ */
53
+
47
+#define IS_ALIAS 1
54
+const int evb_bus_list[] = {0, 1, 2, 6};
48
+
55
+
49
struct MPS2TZMachineClass {
56
+/* Offsets */
50
MachineClass parent;
57
+enum CommonRegister {
51
MPS2TZFPGAType fpga_type;
58
+ OFFSET_SDA = 0x0,
52
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
59
+ OFFSET_ST = 0x2,
53
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
60
+ OFFSET_CST = 0x4,
54
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
61
+ OFFSET_CTL1 = 0x6,
55
int numirq; /* Number of external interrupts */
62
+ OFFSET_ADDR1 = 0x8,
56
+ const RAMInfo *raminfo;
63
+ OFFSET_CTL2 = 0xa,
57
const char *armsse_type;
64
+ OFFSET_ADDR2 = 0xc,
58
};
65
+ OFFSET_CTL3 = 0xe,
59
66
+ OFFSET_CST2 = 0x18,
60
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
67
+ OFFSET_CST3 = 0x19,
61
MachineState parent;
62
63
ARMSSE iotkit;
64
- MemoryRegion ssram[3];
65
- MemoryRegion ssram1_m;
66
+ MemoryRegion ram[MPS2TZ_RAM_MAX];
67
MPS2SCC scc;
68
MPS2FPGAIO fpgaio;
69
TZPPC ppc[5];
70
- TZMPC ssram_mpc[3];
71
+ TZMPC mpc[3];
72
PL022State spi[5];
73
ArmSbconI2CState i2c[4];
74
UnimplementedDeviceState i2s_audio;
75
@@ -XXX,XX +XXX,XX @@ static const uint32_t an505_oscclk[] = {
76
25000000,
77
};
78
79
+static const RAMInfo an505_raminfo[] = { {
80
+ .name = "ssram-0",
81
+ .base = 0x00000000,
82
+ .size = 0x00400000,
83
+ .mpc = 0,
84
+ .mrindex = 0,
85
+ }, {
86
+ .name = "ssram-1",
87
+ .base = 0x28000000,
88
+ .size = 0x00200000,
89
+ .mpc = 1,
90
+ .mrindex = 1,
91
+ }, {
92
+ .name = "ssram-2",
93
+ .base = 0x28200000,
94
+ .size = 0x00200000,
95
+ .mpc = 2,
96
+ .mrindex = 2,
97
+ }, {
98
+ .name = "ssram-0-alias",
99
+ .base = 0x00400000,
100
+ .size = 0x00400000,
101
+ .mpc = 0,
102
+ .mrindex = 3,
103
+ .flags = IS_ALIAS,
104
+ }, {
105
+ /* Use the largest bit of contiguous RAM as our "system memory" */
106
+ .name = "mps.ram",
107
+ .base = 0x80000000,
108
+ .size = 16 * MiB,
109
+ .mpc = -1,
110
+ .mrindex = -1,
111
+ }, {
112
+ .name = NULL,
113
+ },
114
+};
68
+};
115
+
69
+
116
+static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
70
+enum NPCM7xxSMBusBank0Register {
117
+{
71
+ OFFSET_ADDR3 = 0x10,
118
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
72
+ OFFSET_ADDR7 = 0x11,
119
+ const RAMInfo *p;
73
+ OFFSET_ADDR4 = 0x12,
120
+
74
+ OFFSET_ADDR8 = 0x13,
121
+ for (p = mmc->raminfo; p->name; p++) {
75
+ OFFSET_ADDR5 = 0x14,
122
+ if (p->mpc == mpc && !(p->flags & IS_ALIAS)) {
76
+ OFFSET_ADDR9 = 0x15,
123
+ return p;
77
+ OFFSET_ADDR6 = 0x16,
78
+ OFFSET_ADDR10 = 0x17,
79
+ OFFSET_CTL4 = 0x1a,
80
+ OFFSET_CTL5 = 0x1b,
81
+ OFFSET_SCLLT = 0x1c,
82
+ OFFSET_FIF_CTL = 0x1d,
83
+ OFFSET_SCLHT = 0x1e,
84
+};
85
+
86
+enum NPCM7xxSMBusBank1Register {
87
+ OFFSET_FIF_CTS = 0x10,
88
+ OFFSET_FAIR_PER = 0x11,
89
+ OFFSET_TXF_CTL = 0x12,
90
+ OFFSET_T_OUT = 0x14,
91
+ OFFSET_TXF_STS = 0x1a,
92
+ OFFSET_RXF_STS = 0x1c,
93
+ OFFSET_RXF_CTL = 0x1e,
94
+};
95
+
96
+/* ST fields */
97
+#define ST_STP BIT(7)
98
+#define ST_SDAST BIT(6)
99
+#define ST_BER BIT(5)
100
+#define ST_NEGACK BIT(4)
101
+#define ST_STASTR BIT(3)
102
+#define ST_NMATCH BIT(2)
103
+#define ST_MODE BIT(1)
104
+#define ST_XMIT BIT(0)
105
+
106
+/* CST fields */
107
+#define CST_ARPMATCH BIT(7)
108
+#define CST_MATCHAF BIT(6)
109
+#define CST_TGSCL BIT(5)
110
+#define CST_TSDA BIT(4)
111
+#define CST_GCMATCH BIT(3)
112
+#define CST_MATCH BIT(2)
113
+#define CST_BB BIT(1)
114
+#define CST_BUSY BIT(0)
115
+
116
+/* CST2 fields */
117
+#define CST2_INSTTS BIT(7)
118
+#define CST2_MATCH7F BIT(6)
119
+#define CST2_MATCH6F BIT(5)
120
+#define CST2_MATCH5F BIT(4)
121
+#define CST2_MATCH4F BIT(3)
122
+#define CST2_MATCH3F BIT(2)
123
+#define CST2_MATCH2F BIT(1)
124
+#define CST2_MATCH1F BIT(0)
125
+
126
+/* CST3 fields */
127
+#define CST3_EO_BUSY BIT(7)
128
+#define CST3_MATCH10F BIT(2)
129
+#define CST3_MATCH9F BIT(1)
130
+#define CST3_MATCH8F BIT(0)
131
+
132
+/* CTL1 fields */
133
+#define CTL1_STASTRE BIT(7)
134
+#define CTL1_NMINTE BIT(6)
135
+#define CTL1_GCMEN BIT(5)
136
+#define CTL1_ACK BIT(4)
137
+#define CTL1_EOBINTE BIT(3)
138
+#define CTL1_INTEN BIT(2)
139
+#define CTL1_STOP BIT(1)
140
+#define CTL1_START BIT(0)
141
+
142
+/* CTL2 fields */
143
+#define CTL2_SCLFRQ(rv) extract8((rv), 1, 6)
144
+#define CTL2_ENABLE BIT(0)
145
+
146
+/* CTL3 fields */
147
+#define CTL3_SCL_LVL BIT(7)
148
+#define CTL3_SDA_LVL BIT(6)
149
+#define CTL3_BNK_SEL BIT(5)
150
+#define CTL3_400K_MODE BIT(4)
151
+#define CTL3_IDL_START BIT(3)
152
+#define CTL3_ARPMEN BIT(2)
153
+#define CTL3_SCLFRQ(rv) extract8((rv), 0, 2)
154
+
155
+/* ADDR fields */
156
+#define ADDR_EN BIT(7)
157
+#define ADDR_A(rv) extract8((rv), 0, 6)
158
+
159
+
160
+static void check_running(QTestState *qts, uint64_t base_addr)
161
+{
162
+ g_assert_true(qtest_readb(qts, base_addr + OFFSET_CST) & CST_BUSY);
163
+ g_assert_true(qtest_readb(qts, base_addr + OFFSET_CST) & CST_BB);
164
+}
165
+
166
+static void check_stopped(QTestState *qts, uint64_t base_addr)
167
+{
168
+ uint8_t cst3;
169
+
170
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_ST), ==, 0);
171
+ g_assert_false(qtest_readb(qts, base_addr + OFFSET_CST) & CST_BUSY);
172
+ g_assert_false(qtest_readb(qts, base_addr + OFFSET_CST) & CST_BB);
173
+
174
+ cst3 = qtest_readb(qts, base_addr + OFFSET_CST3);
175
+ g_assert_true(cst3 & CST3_EO_BUSY);
176
+ qtest_writeb(qts, base_addr + OFFSET_CST3, cst3);
177
+ cst3 = qtest_readb(qts, base_addr + OFFSET_CST3);
178
+ g_assert_false(cst3 & CST3_EO_BUSY);
179
+}
180
+
181
+static void enable_bus(QTestState *qts, uint64_t base_addr)
182
+{
183
+ uint8_t ctl2 = qtest_readb(qts, base_addr + OFFSET_CTL2);
184
+
185
+ ctl2 |= CTL2_ENABLE;
186
+ qtest_writeb(qts, base_addr + OFFSET_CTL2, ctl2);
187
+ g_assert_true(qtest_readb(qts, base_addr + OFFSET_CTL2) & CTL2_ENABLE);
188
+}
189
+
190
+static void disable_bus(QTestState *qts, uint64_t base_addr)
191
+{
192
+ uint8_t ctl2 = qtest_readb(qts, base_addr + OFFSET_CTL2);
193
+
194
+ ctl2 &= ~CTL2_ENABLE;
195
+ qtest_writeb(qts, base_addr + OFFSET_CTL2, ctl2);
196
+ g_assert_false(qtest_readb(qts, base_addr + OFFSET_CTL2) & CTL2_ENABLE);
197
+}
198
+
199
+static void start_transfer(QTestState *qts, uint64_t base_addr)
200
+{
201
+ uint8_t ctl1;
202
+
203
+ ctl1 = CTL1_START | CTL1_INTEN | CTL1_STASTRE;
204
+ qtest_writeb(qts, base_addr + OFFSET_CTL1, ctl1);
205
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_CTL1), ==,
206
+ CTL1_INTEN | CTL1_STASTRE | CTL1_INTEN);
207
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_ST), ==,
208
+ ST_MODE | ST_XMIT | ST_SDAST);
209
+ check_running(qts, base_addr);
210
+}
211
+
212
+static void stop_transfer(QTestState *qts, uint64_t base_addr)
213
+{
214
+ uint8_t ctl1 = qtest_readb(qts, base_addr + OFFSET_CTL1);
215
+
216
+ ctl1 &= ~(CTL1_START | CTL1_ACK);
217
+ ctl1 |= CTL1_STOP | CTL1_INTEN | CTL1_EOBINTE;
218
+ qtest_writeb(qts, base_addr + OFFSET_CTL1, ctl1);
219
+ ctl1 = qtest_readb(qts, base_addr + OFFSET_CTL1);
220
+ g_assert_false(ctl1 & CTL1_STOP);
221
+}
222
+
223
+static void send_byte(QTestState *qts, uint64_t base_addr, uint8_t byte)
224
+{
225
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_ST), ==,
226
+ ST_MODE | ST_XMIT | ST_SDAST);
227
+ qtest_writeb(qts, base_addr + OFFSET_SDA, byte);
228
+}
229
+
230
+static uint8_t recv_byte(QTestState *qts, uint64_t base_addr)
231
+{
232
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_ST), ==,
233
+ ST_MODE | ST_SDAST);
234
+ return qtest_readb(qts, base_addr + OFFSET_SDA);
235
+}
236
+
237
+static void send_address(QTestState *qts, uint64_t base_addr, uint8_t addr,
238
+ bool recv, bool valid)
239
+{
240
+ uint8_t encoded_addr = (addr << 1) | (recv ? 1 : 0);
241
+ uint8_t st;
242
+
243
+ qtest_writeb(qts, base_addr + OFFSET_SDA, encoded_addr);
244
+ st = qtest_readb(qts, base_addr + OFFSET_ST);
245
+
246
+ if (valid) {
247
+ if (recv) {
248
+ g_assert_cmphex(st, ==, ST_MODE | ST_SDAST | ST_STASTR);
249
+ } else {
250
+ g_assert_cmphex(st, ==, ST_MODE | ST_XMIT | ST_SDAST | ST_STASTR);
251
+ }
252
+
253
+ qtest_writeb(qts, base_addr + OFFSET_ST, ST_STASTR);
254
+ st = qtest_readb(qts, base_addr + OFFSET_ST);
255
+ if (recv) {
256
+ g_assert_cmphex(st, ==, ST_MODE | ST_SDAST);
257
+ } else {
258
+ g_assert_cmphex(st, ==, ST_MODE | ST_XMIT | ST_SDAST);
259
+ }
260
+ } else {
261
+ if (recv) {
262
+ g_assert_cmphex(st, ==, ST_MODE | ST_NEGACK);
263
+ } else {
264
+ g_assert_cmphex(st, ==, ST_MODE | ST_XMIT | ST_NEGACK);
124
+ }
265
+ }
125
+ }
266
+ }
126
+ /* if raminfo array doesn't have an entry for each MPC this is a bug */
267
+}
127
+ g_assert_not_reached();
268
+
128
+}
269
+static void send_nack(QTestState *qts, uint64_t base_addr)
129
+
270
+{
130
+static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
271
+ uint8_t ctl1 = qtest_readb(qts, base_addr + OFFSET_CTL1);
131
+ const RAMInfo *raminfo)
272
+
132
+{
273
+ ctl1 &= ~(CTL1_START | CTL1_STOP);
133
+ /* Return an initialized MemoryRegion for the RAMInfo. */
274
+ ctl1 |= CTL1_ACK | CTL1_INTEN;
134
+ MemoryRegion *ram;
275
+ qtest_writeb(qts, base_addr + OFFSET_CTL1, ctl1);
135
+
276
+}
136
+ if (raminfo->mrindex < 0) {
277
+
137
+ /* Means this RAMInfo is for QEMU's "system memory" */
278
+/* Check the SMBus's status is set correctly when disabled. */
138
+ MachineState *machine = MACHINE(mms);
279
+static void test_disable_bus(gconstpointer data)
139
+ return machine->ram;
280
+{
281
+ intptr_t index = (intptr_t)data;
282
+ uint64_t base_addr = SMBUS_ADDR(index);
283
+ QTestState *qts = qtest_init("-machine npcm750-evb");
284
+
285
+ disable_bus(qts, base_addr);
286
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_CTL1), ==, 0);
287
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_ST), ==, 0);
288
+ g_assert_false(qtest_readb(qts, base_addr + OFFSET_CST3) & CST3_EO_BUSY);
289
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_CST), ==, 0);
290
+ qtest_quit(qts);
291
+}
292
+
293
+/* Check the SMBus returns a NACK for an invalid address. */
294
+static void test_invalid_addr(gconstpointer data)
295
+{
296
+ intptr_t index = (intptr_t)data;
297
+ uint64_t base_addr = SMBUS_ADDR(index);
298
+ int irq = SMBUS_IRQ(index);
299
+ QTestState *qts = qtest_init("-machine npcm750-evb");
300
+
301
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
302
+ enable_bus(qts, base_addr);
303
+ g_assert_false(qtest_get_irq(qts, irq));
304
+ start_transfer(qts, base_addr);
305
+ send_address(qts, base_addr, INVALID_DEVICE_ADDR, false, false);
306
+ g_assert_true(qtest_get_irq(qts, irq));
307
+ stop_transfer(qts, base_addr);
308
+ check_running(qts, base_addr);
309
+ qtest_writeb(qts, base_addr + OFFSET_ST, ST_NEGACK);
310
+ g_assert_false(qtest_readb(qts, base_addr + OFFSET_ST) & ST_NEGACK);
311
+ check_stopped(qts, base_addr);
312
+ qtest_quit(qts);
313
+}
314
+
315
+/* Check the SMBus can send and receive bytes to a device in single mode. */
316
+static void test_single_mode(gconstpointer data)
317
+{
318
+ intptr_t index = (intptr_t)data;
319
+ uint64_t base_addr = SMBUS_ADDR(index);
320
+ int irq = SMBUS_IRQ(index);
321
+ uint8_t value = 0x60;
322
+ QTestState *qts = qtest_init("-machine npcm750-evb");
323
+
324
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
325
+ enable_bus(qts, base_addr);
326
+
327
+ /* Sending */
328
+ g_assert_false(qtest_get_irq(qts, irq));
329
+ start_transfer(qts, base_addr);
330
+ g_assert_true(qtest_get_irq(qts, irq));
331
+ send_address(qts, base_addr, EVB_DEVICE_ADDR, false, true);
332
+ send_byte(qts, base_addr, TMP105_REG_CONFIG);
333
+ send_byte(qts, base_addr, value);
334
+ stop_transfer(qts, base_addr);
335
+ check_stopped(qts, base_addr);
336
+
337
+ /* Receiving */
338
+ start_transfer(qts, base_addr);
339
+ send_address(qts, base_addr, EVB_DEVICE_ADDR, false, true);
340
+ send_byte(qts, base_addr, TMP105_REG_CONFIG);
341
+ start_transfer(qts, base_addr);
342
+ send_address(qts, base_addr, EVB_DEVICE_ADDR, true, true);
343
+ send_nack(qts, base_addr);
344
+ stop_transfer(qts, base_addr);
345
+ check_running(qts, base_addr);
346
+ g_assert_cmphex(recv_byte(qts, base_addr), ==, value);
347
+ check_stopped(qts, base_addr);
348
+ qtest_quit(qts);
349
+}
350
+
351
+static void smbus_add_test(const char *name, int index, GTestDataFunc fn)
352
+{
353
+ g_autofree char *full_name = g_strdup_printf(
354
+ "npcm7xx_smbus[%d]/%s", index, name);
355
+ qtest_add_data_func(full_name, (void *)(intptr_t)index, fn);
356
+}
357
+#define add_test(name, td) smbus_add_test(#name, td, test_##name)
358
+
359
+int main(int argc, char **argv)
360
+{
361
+ int i;
362
+
363
+ g_test_init(&argc, &argv, NULL);
364
+ g_test_set_nonfatal_assertions();
365
+
366
+ for (i = 0; i < NR_SMBUS_DEVICES; ++i) {
367
+ add_test(disable_bus, i);
368
+ add_test(invalid_addr, i);
140
+ }
369
+ }
141
+
370
+
142
+ assert(raminfo->mrindex < MPS2TZ_RAM_MAX);
371
+ for (i = 0; i < ARRAY_SIZE(evb_bus_list); ++i) {
143
+ ram = &mms->ram[raminfo->mrindex];
372
+ add_test(single_mode, evb_bus_list[i]);
144
+
145
+ memory_region_init_ram(ram, NULL, raminfo->name,
146
+ raminfo->size, &error_fatal);
147
+ return ram;
148
+}
149
+
150
/* Create an alias of an entire original MemoryRegion @orig
151
* located at @base in the memory map.
152
*/
153
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
154
const int *irqs)
155
{
156
TZMPC *mpc = opaque;
157
- int i = mpc - &mms->ssram_mpc[0];
158
- MemoryRegion *ssram = &mms->ssram[i];
159
+ int i = mpc - &mms->mpc[0];
160
MemoryRegion *upstream;
161
- char *mpcname = g_strdup_printf("%s-mpc", name);
162
- static uint32_t ramsize[] = { 0x00400000, 0x00200000, 0x00200000 };
163
- static uint32_t rambase[] = { 0x00000000, 0x28000000, 0x28200000 };
164
+ const RAMInfo *raminfo = find_raminfo_for_mpc(mms, i);
165
+ MemoryRegion *ram = mr_for_raminfo(mms, raminfo);
166
167
- memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);
168
-
169
- object_initialize_child(OBJECT(mms), mpcname, mpc, TYPE_TZ_MPC);
170
- object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ssram),
171
+ object_initialize_child(OBJECT(mms), name, mpc, TYPE_TZ_MPC);
172
+ object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ram),
173
&error_fatal);
174
sysbus_realize(SYS_BUS_DEVICE(mpc), &error_fatal);
175
/* Map the upstream end of the MPC into system memory */
176
upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
177
- memory_region_add_subregion(get_system_memory(), rambase[i], upstream);
178
+ memory_region_add_subregion(get_system_memory(), raminfo->base, upstream);
179
/* and connect its interrupt to the IoTKit */
180
qdev_connect_gpio_out_named(DEVICE(mpc), "irq", 0,
181
qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
182
"mpcexp_status", i));
183
184
- /* The first SSRAM is a special case as it has an alias; accesses to
185
- * the alias region at 0x00400000 must also go to the MPC upstream.
186
- */
187
- if (i == 0) {
188
- make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", upstream, 0x00400000);
189
- }
190
-
191
- g_free(mpcname);
192
/* Return the register interface MR for our caller to map behind the PPC */
193
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
194
}
195
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
196
return sysbus_mmio_get_region(s, 0);
197
}
198
199
+static void create_non_mpc_ram(MPS2TZMachineState *mms)
200
+{
201
+ /*
202
+ * Handle the RAMs which are either not behind MPCs or which are
203
+ * aliases to another MPC.
204
+ */
205
+ const RAMInfo *p;
206
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
207
+
208
+ for (p = mmc->raminfo; p->name; p++) {
209
+ if (p->flags & IS_ALIAS) {
210
+ SysBusDevice *mpc_sbd = SYS_BUS_DEVICE(&mms->mpc[p->mpc]);
211
+ MemoryRegion *upstream = sysbus_mmio_get_region(mpc_sbd, 1);
212
+ make_ram_alias(&mms->ram[p->mrindex], p->name, upstream, p->base);
213
+ } else if (p->mpc == -1) {
214
+ /* RAM not behind an MPC */
215
+ MemoryRegion *mr = mr_for_raminfo(mms, p);
216
+ memory_region_add_subregion(get_system_memory(), p->base, mr);
217
+ }
218
+ }
373
+ }
219
+}
374
+
220
+
375
+ return g_test_run();
221
static void mps2tz_common_init(MachineState *machine)
376
+}
222
{
377
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
223
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
378
index XXXXXXX..XXXXXXX 100644
224
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
379
--- a/tests/qtest/meson.build
225
qdev_connect_gpio_out_named(iotkitdev, "sec_resp_cfg", 0,
380
+++ b/tests/qtest/meson.build
226
qdev_get_gpio_in(dev_splitter, 0));
381
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
227
382
'npcm7xx_gpio-test',
228
- /* The IoTKit sets up much of the memory layout, including
383
'npcm7xx_pwm-test',
229
+ /*
384
'npcm7xx_rng-test',
230
+ * The IoTKit sets up much of the memory layout, including
385
+ 'npcm7xx_smbus-test',
231
* the aliases between secure and non-secure regions in the
386
'npcm7xx_timer-test',
232
- * address space. The FPGA itself contains:
387
'npcm7xx_watchdog_timer-test']
233
- *
388
qtests_arm = \
234
- * 0x00000000..0x003fffff SSRAM1
235
- * 0x00400000..0x007fffff alias of SSRAM1
236
- * 0x28000000..0x283fffff 4MB SSRAM2 + SSRAM3
237
- * 0x40100000..0x4fffffff AHB Master Expansion 1 interface devices
238
- * 0x80000000..0x80ffffff 16MB PSRAM
239
- */
240
-
241
- /* The FPGA images have an odd combination of different RAMs,
242
+ * address space, and also most of the devices in the system.
243
+ * The FPGA itself contains various RAMs and some additional devices.
244
+ * The FPGA images have an odd combination of different RAMs,
245
* because in hardware they are different implementations and
246
* connected to different buses, giving varying performance/size
247
* tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
248
- * call the 16MB our "system memory", as it's the largest lump.
249
+ * call the largest lump our "system memory".
250
*/
251
- memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
252
253
/*
254
* The overflow IRQs for all UARTs are ORed together.
255
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
256
const PPCInfo an505_ppcs[] = { {
257
.name = "apb_ppcexp0",
258
.ports = {
259
- { "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
260
- { "ssram-1", make_mpc, &mms->ssram_mpc[1], 0x58008000, 0x1000 },
261
- { "ssram-2", make_mpc, &mms->ssram_mpc[2], 0x58009000, 0x1000 },
262
+ { "ssram-0-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
263
+ { "ssram-1-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
264
+ { "ssram-2-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
265
},
266
}, {
267
.name = "apb_ppcexp1",
268
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
269
270
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
271
272
+ create_non_mpc_ram(mms);
273
+
274
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
275
}
276
277
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
278
mmc->fpgaio_num_leds = 2;
279
mmc->fpgaio_has_switches = false;
280
mmc->numirq = 92;
281
+ mmc->raminfo = an505_raminfo;
282
mmc->armsse_type = TYPE_IOTKIT;
283
}
284
285
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
286
mmc->fpgaio_num_leds = 2;
287
mmc->fpgaio_has_switches = false;
288
mmc->numirq = 92;
289
+ mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
290
mmc->armsse_type = TYPE_SSE200;
291
}
292
293
--
389
--
294
2.20.1
390
2.20.1
295
391
296
392
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
The STATUS register will be reset to IDLE in
3
This patch implements the FIFO mode of the SMBus module. In FIFO, the
4
cnpcm7xx_smbus_enter_reset(), no need to preset
4
user transmits or receives at most 16 bytes at a time. The FIFO mode
5
it in instance_init().
5
allows the module to transmit large amount of data faster than single
6
byte mode.
6
7
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Since we only added the device in a patch that is only a few commits
8
Reviewed-by: Hao Wu <wuhaotsh@google.com>
9
away in the same patch set. We do not increase the VMstate version
9
Message-id: 20210228224813.312532-1-f4bug@amsat.org
10
number in this special case.
11
12
Reviewed-by: Doug Evans<dje@google.com>
13
Reviewed-by: Tyrong Ting<kfting@nuvoton.com>
14
Signed-off-by: Hao Wu <wuhaotsh@google.com>
15
Reviewed-by: Corey Minyard <cminyard@mvista.com>
16
Message-id: 20210210220426.3577804-6-wuhaotsh@google.com
17
Acked-by: Corey Minyard <cminyard@mvista.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
hw/i2c/npcm7xx_smbus.c | 1 -
20
include/hw/i2c/npcm7xx_smbus.h | 25 +++
13
1 file changed, 1 deletion(-)
21
hw/i2c/npcm7xx_smbus.c | 342 +++++++++++++++++++++++++++++--
22
tests/qtest/npcm7xx_smbus-test.c | 149 +++++++++++++-
23
hw/i2c/trace-events | 1 +
24
4 files changed, 501 insertions(+), 16 deletions(-)
14
25
26
diff --git a/include/hw/i2c/npcm7xx_smbus.h b/include/hw/i2c/npcm7xx_smbus.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/i2c/npcm7xx_smbus.h
29
+++ b/include/hw/i2c/npcm7xx_smbus.h
30
@@ -XXX,XX +XXX,XX @@
31
*/
32
#define NPCM7XX_SMBUS_NR_ADDRS 10
33
34
+/* Size of the FIFO buffer. */
35
+#define NPCM7XX_SMBUS_FIFO_SIZE 16
36
+
37
typedef enum NPCM7xxSMBusStatus {
38
NPCM7XX_SMBUS_STATUS_IDLE,
39
NPCM7XX_SMBUS_STATUS_SENDING,
40
@@ -XXX,XX +XXX,XX @@ typedef enum NPCM7xxSMBusStatus {
41
* @addr: The SMBus module's own addresses on the I2C bus.
42
* @scllt: The SCL low time register.
43
* @sclht: The SCL high time register.
44
+ * @fif_ctl: The FIFO control register.
45
+ * @fif_cts: The FIFO control status register.
46
+ * @fair_per: The fair preriod register.
47
+ * @txf_ctl: The transmit FIFO control register.
48
+ * @t_out: The SMBus timeout register.
49
+ * @txf_sts: The transmit FIFO status register.
50
+ * @rxf_sts: The receive FIFO status register.
51
+ * @rxf_ctl: The receive FIFO control register.
52
+ * @rx_fifo: The FIFO buffer for receiving in FIFO mode.
53
+ * @rx_cur: The current position of rx_fifo.
54
* @status: The current status of the SMBus.
55
*/
56
typedef struct NPCM7xxSMBusState {
57
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxSMBusState {
58
uint8_t scllt;
59
uint8_t sclht;
60
61
+ uint8_t fif_ctl;
62
+ uint8_t fif_cts;
63
+ uint8_t fair_per;
64
+ uint8_t txf_ctl;
65
+ uint8_t t_out;
66
+ uint8_t txf_sts;
67
+ uint8_t rxf_sts;
68
+ uint8_t rxf_ctl;
69
+
70
+ uint8_t rx_fifo[NPCM7XX_SMBUS_FIFO_SIZE];
71
+ uint8_t rx_cur;
72
+
73
NPCM7xxSMBusStatus status;
74
} NPCM7xxSMBusState;
75
15
diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
76
diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
16
index XXXXXXX..XXXXXXX 100644
77
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/npcm7xx_smbus.c
78
--- a/hw/i2c/npcm7xx_smbus.c
18
+++ b/hw/i2c/npcm7xx_smbus.c
79
+++ b/hw/i2c/npcm7xx_smbus.c
19
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_init(Object *obj)
80
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxSMBusBank1Register {
20
sysbus_init_mmio(sbd, &s->iomem);
81
#define NPCM7XX_ADDR_EN BIT(7)
21
82
#define NPCM7XX_ADDR_A(rv) extract8((rv), 0, 6)
22
s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
83
23
- s->status = NPCM7XX_SMBUS_STATUS_IDLE;
84
+/* FIFO Mode Register Fields */
24
}
85
+/* FIF_CTL fields */
25
86
+#define NPCM7XX_SMBFIF_CTL_FIFO_EN BIT(4)
26
static const VMStateDescription vmstate_npcm7xx_smbus = {
87
+#define NPCM7XX_SMBFIF_CTL_FAIR_RDY_IE BIT(2)
88
+#define NPCM7XX_SMBFIF_CTL_FAIR_RDY BIT(1)
89
+#define NPCM7XX_SMBFIF_CTL_FAIR_BUSY BIT(0)
90
+/* FIF_CTS fields */
91
+#define NPCM7XX_SMBFIF_CTS_STR BIT(7)
92
+#define NPCM7XX_SMBFIF_CTS_CLR_FIFO BIT(6)
93
+#define NPCM7XX_SMBFIF_CTS_RFTE_IE BIT(3)
94
+#define NPCM7XX_SMBFIF_CTS_RXF_TXE BIT(1)
95
+/* TXF_CTL fields */
96
+#define NPCM7XX_SMBTXF_CTL_THR_TXIE BIT(6)
97
+#define NPCM7XX_SMBTXF_CTL_TX_THR(rv) extract8((rv), 0, 5)
98
+/* T_OUT fields */
99
+#define NPCM7XX_SMBT_OUT_ST BIT(7)
100
+#define NPCM7XX_SMBT_OUT_IE BIT(6)
101
+#define NPCM7XX_SMBT_OUT_CLKDIV(rv) extract8((rv), 0, 6)
102
+/* TXF_STS fields */
103
+#define NPCM7XX_SMBTXF_STS_TX_THST BIT(6)
104
+#define NPCM7XX_SMBTXF_STS_TX_BYTES(rv) extract8((rv), 0, 5)
105
+/* RXF_STS fields */
106
+#define NPCM7XX_SMBRXF_STS_RX_THST BIT(6)
107
+#define NPCM7XX_SMBRXF_STS_RX_BYTES(rv) extract8((rv), 0, 5)
108
+/* RXF_CTL fields */
109
+#define NPCM7XX_SMBRXF_CTL_THR_RXIE BIT(6)
110
+#define NPCM7XX_SMBRXF_CTL_LAST BIT(5)
111
+#define NPCM7XX_SMBRXF_CTL_RX_THR(rv) extract8((rv), 0, 5)
112
+
113
#define KEEP_OLD_BIT(o, n, b) (((n) & (~(b))) | ((o) & (b)))
114
#define WRITE_ONE_CLEAR(o, n, b) ((n) & (b) ? (o) & (~(b)) : (o))
115
116
#define NPCM7XX_SMBUS_ENABLED(s) ((s)->ctl2 & NPCM7XX_SMBCTL2_ENABLE)
117
+#define NPCM7XX_SMBUS_FIFO_ENABLED(s) ((s)->fif_ctl & \
118
+ NPCM7XX_SMBFIF_CTL_FIFO_EN)
119
120
/* VERSION fields values, read-only. */
121
#define NPCM7XX_SMBUS_VERSION_NUMBER 1
122
-#define NPCM7XX_SMBUS_VERSION_FIFO_SUPPORTED 0
123
+#define NPCM7XX_SMBUS_VERSION_FIFO_SUPPORTED 1
124
125
/* Reset values */
126
#define NPCM7XX_SMB_ST_INIT_VAL 0x00
127
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxSMBusBank1Register {
128
#define NPCM7XX_SMB_ADDR_INIT_VAL 0x00
129
#define NPCM7XX_SMB_SCLLT_INIT_VAL 0x00
130
#define NPCM7XX_SMB_SCLHT_INIT_VAL 0x00
131
+#define NPCM7XX_SMB_FIF_CTL_INIT_VAL 0x00
132
+#define NPCM7XX_SMB_FIF_CTS_INIT_VAL 0x00
133
+#define NPCM7XX_SMB_FAIR_PER_INIT_VAL 0x00
134
+#define NPCM7XX_SMB_TXF_CTL_INIT_VAL 0x00
135
+#define NPCM7XX_SMB_T_OUT_INIT_VAL 0x3f
136
+#define NPCM7XX_SMB_TXF_STS_INIT_VAL 0x00
137
+#define NPCM7XX_SMB_RXF_STS_INIT_VAL 0x00
138
+#define NPCM7XX_SMB_RXF_CTL_INIT_VAL 0x01
139
140
static uint8_t npcm7xx_smbus_get_version(void)
141
{
142
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_update_irq(NPCM7xxSMBusState *s)
143
(s->ctl1 & NPCM7XX_SMBCTL1_STASTRE &&
144
s->st & NPCM7XX_SMBST_SDAST) ||
145
(s->ctl1 & NPCM7XX_SMBCTL1_EOBINTE &&
146
- s->cst3 & NPCM7XX_SMBCST3_EO_BUSY));
147
+ s->cst3 & NPCM7XX_SMBCST3_EO_BUSY) ||
148
+ (s->rxf_ctl & NPCM7XX_SMBRXF_CTL_THR_RXIE &&
149
+ s->rxf_sts & NPCM7XX_SMBRXF_STS_RX_THST) ||
150
+ (s->txf_ctl & NPCM7XX_SMBTXF_CTL_THR_TXIE &&
151
+ s->txf_sts & NPCM7XX_SMBTXF_STS_TX_THST) ||
152
+ (s->fif_cts & NPCM7XX_SMBFIF_CTS_RFTE_IE &&
153
+ s->fif_cts & NPCM7XX_SMBFIF_CTS_RXF_TXE));
154
155
if (level) {
156
s->cst2 |= NPCM7XX_SMBCST2_INTSTS;
157
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_nack(NPCM7xxSMBusState *s)
158
s->status = NPCM7XX_SMBUS_STATUS_NEGACK;
159
}
160
161
+static void npcm7xx_smbus_clear_buffer(NPCM7xxSMBusState *s)
162
+{
163
+ s->fif_cts &= ~NPCM7XX_SMBFIF_CTS_RXF_TXE;
164
+ s->txf_sts = 0;
165
+ s->rxf_sts = 0;
166
+}
167
+
168
static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, uint8_t value)
169
{
170
int rv = i2c_send(s->bus, value);
171
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, uint8_t value)
172
npcm7xx_smbus_nack(s);
173
} else {
174
s->st |= NPCM7XX_SMBST_SDAST;
175
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
176
+ s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
177
+ if (NPCM7XX_SMBTXF_STS_TX_BYTES(s->txf_sts) ==
178
+ NPCM7XX_SMBTXF_CTL_TX_THR(s->txf_ctl)) {
179
+ s->txf_sts = NPCM7XX_SMBTXF_STS_TX_THST;
180
+ } else {
181
+ s->txf_sts = 0;
182
+ }
183
+ }
184
}
185
trace_npcm7xx_smbus_send_byte((DEVICE(s)->canonical_path), value, !rv);
186
npcm7xx_smbus_update_irq(s);
187
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_recv_byte(NPCM7xxSMBusState *s)
188
npcm7xx_smbus_update_irq(s);
189
}
190
191
+static void npcm7xx_smbus_recv_fifo(NPCM7xxSMBusState *s)
192
+{
193
+ uint8_t expected_bytes = NPCM7XX_SMBRXF_CTL_RX_THR(s->rxf_ctl);
194
+ uint8_t received_bytes = NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts);
195
+ uint8_t pos;
196
+
197
+ if (received_bytes == expected_bytes) {
198
+ return;
199
+ }
200
+
201
+ while (received_bytes < expected_bytes &&
202
+ received_bytes < NPCM7XX_SMBUS_FIFO_SIZE) {
203
+ pos = (s->rx_cur + received_bytes) % NPCM7XX_SMBUS_FIFO_SIZE;
204
+ s->rx_fifo[pos] = i2c_recv(s->bus);
205
+ trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path),
206
+ s->rx_fifo[pos]);
207
+ ++received_bytes;
208
+ }
209
+
210
+ trace_npcm7xx_smbus_recv_fifo((DEVICE(s)->canonical_path),
211
+ received_bytes, expected_bytes);
212
+ s->rxf_sts = received_bytes;
213
+ if (unlikely(received_bytes < expected_bytes)) {
214
+ qemu_log_mask(LOG_GUEST_ERROR,
215
+ "%s: invalid rx_thr value: 0x%02x\n",
216
+ DEVICE(s)->canonical_path, expected_bytes);
217
+ return;
218
+ }
219
+
220
+ s->rxf_sts |= NPCM7XX_SMBRXF_STS_RX_THST;
221
+ if (s->rxf_ctl & NPCM7XX_SMBRXF_CTL_LAST) {
222
+ trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
223
+ i2c_nack(s->bus);
224
+ s->rxf_ctl &= ~NPCM7XX_SMBRXF_CTL_LAST;
225
+ }
226
+ if (received_bytes == NPCM7XX_SMBUS_FIFO_SIZE) {
227
+ s->st |= NPCM7XX_SMBST_SDAST;
228
+ s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
229
+ } else if (!(s->rxf_ctl & NPCM7XX_SMBRXF_CTL_THR_RXIE)) {
230
+ s->st |= NPCM7XX_SMBST_SDAST;
231
+ } else {
232
+ s->st &= ~NPCM7XX_SMBST_SDAST;
233
+ }
234
+ npcm7xx_smbus_update_irq(s);
235
+}
236
+
237
+static void npcm7xx_smbus_read_byte_fifo(NPCM7xxSMBusState *s)
238
+{
239
+ uint8_t received_bytes = NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts);
240
+
241
+ if (received_bytes == 0) {
242
+ npcm7xx_smbus_recv_fifo(s);
243
+ return;
244
+ }
245
+
246
+ s->sda = s->rx_fifo[s->rx_cur];
247
+ s->rx_cur = (s->rx_cur + 1u) % NPCM7XX_SMBUS_FIFO_SIZE;
248
+ --s->rxf_sts;
249
+ npcm7xx_smbus_update_irq(s);
250
+}
251
+
252
static void npcm7xx_smbus_start(NPCM7xxSMBusState *s)
253
{
254
/*
255
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_start(NPCM7xxSMBusState *s)
256
if (available) {
257
s->st |= NPCM7XX_SMBST_MODE | NPCM7XX_SMBST_XMIT | NPCM7XX_SMBST_SDAST;
258
s->cst |= NPCM7XX_SMBCST_BUSY;
259
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
260
+ s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
261
+ }
262
} else {
263
s->st &= ~NPCM7XX_SMBST_MODE;
264
s->cst &= ~NPCM7XX_SMBCST_BUSY;
265
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_send_address(NPCM7xxSMBusState *s, uint8_t value)
266
s->st |= NPCM7XX_SMBST_SDAST;
267
}
268
} else if (recv) {
269
- npcm7xx_smbus_recv_byte(s);
270
+ s->st |= NPCM7XX_SMBST_SDAST;
271
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
272
+ npcm7xx_smbus_recv_fifo(s);
273
+ } else {
274
+ npcm7xx_smbus_recv_byte(s);
275
+ }
276
+ } else if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
277
+ s->st |= NPCM7XX_SMBST_SDAST;
278
+ s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
279
}
280
npcm7xx_smbus_update_irq(s);
281
}
282
@@ -XXX,XX +XXX,XX @@ static uint8_t npcm7xx_smbus_read_sda(NPCM7xxSMBusState *s)
283
284
switch (s->status) {
285
case NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE:
286
- npcm7xx_smbus_execute_stop(s);
287
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
288
+ if (NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts) <= 1) {
289
+ npcm7xx_smbus_execute_stop(s);
290
+ }
291
+ if (NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts) == 0) {
292
+ qemu_log_mask(LOG_GUEST_ERROR,
293
+ "%s: read to SDA with an empty rx-fifo buffer, "
294
+ "result undefined: %u\n",
295
+ DEVICE(s)->canonical_path, s->sda);
296
+ break;
297
+ }
298
+ npcm7xx_smbus_read_byte_fifo(s);
299
+ value = s->sda;
300
+ } else {
301
+ npcm7xx_smbus_execute_stop(s);
302
+ }
303
break;
304
305
case NPCM7XX_SMBUS_STATUS_RECEIVING:
306
- npcm7xx_smbus_recv_byte(s);
307
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
308
+ npcm7xx_smbus_read_byte_fifo(s);
309
+ value = s->sda;
310
+ } else {
311
+ npcm7xx_smbus_recv_byte(s);
312
+ }
313
break;
314
315
default:
316
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_write_st(NPCM7xxSMBusState *s, uint8_t value)
317
}
318
319
if (value & NPCM7XX_SMBST_STASTR &&
320
- s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
321
- npcm7xx_smbus_recv_byte(s);
322
+ s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
323
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
324
+ npcm7xx_smbus_recv_fifo(s);
325
+ } else {
326
+ npcm7xx_smbus_recv_byte(s);
327
+ }
328
}
329
330
npcm7xx_smbus_update_irq(s);
331
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_write_ctl2(NPCM7xxSMBusState *s, uint8_t value)
332
s->st = 0;
333
s->cst3 = s->cst3 & (~NPCM7XX_SMBCST3_EO_BUSY);
334
s->cst = 0;
335
+ npcm7xx_smbus_clear_buffer(s);
336
}
337
}
338
339
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_write_ctl3(NPCM7xxSMBusState *s, uint8_t value)
340
NPCM7XX_SMBCTL3_SCL_LVL | NPCM7XX_SMBCTL3_SDA_LVL);
341
}
342
343
+static void npcm7xx_smbus_write_fif_ctl(NPCM7xxSMBusState *s, uint8_t value)
344
+{
345
+ uint8_t new_ctl = value;
346
+
347
+ new_ctl = KEEP_OLD_BIT(s->fif_ctl, new_ctl, NPCM7XX_SMBFIF_CTL_FAIR_RDY);
348
+ new_ctl = WRITE_ONE_CLEAR(new_ctl, value, NPCM7XX_SMBFIF_CTL_FAIR_RDY);
349
+ new_ctl = KEEP_OLD_BIT(s->fif_ctl, new_ctl, NPCM7XX_SMBFIF_CTL_FAIR_BUSY);
350
+ s->fif_ctl = new_ctl;
351
+}
352
+
353
+static void npcm7xx_smbus_write_fif_cts(NPCM7xxSMBusState *s, uint8_t value)
354
+{
355
+ s->fif_cts = WRITE_ONE_CLEAR(s->fif_cts, value, NPCM7XX_SMBFIF_CTS_STR);
356
+ s->fif_cts = WRITE_ONE_CLEAR(s->fif_cts, value, NPCM7XX_SMBFIF_CTS_RXF_TXE);
357
+ s->fif_cts = KEEP_OLD_BIT(value, s->fif_cts, NPCM7XX_SMBFIF_CTS_RFTE_IE);
358
+
359
+ if (value & NPCM7XX_SMBFIF_CTS_CLR_FIFO) {
360
+ npcm7xx_smbus_clear_buffer(s);
361
+ }
362
+}
363
+
364
+static void npcm7xx_smbus_write_txf_ctl(NPCM7xxSMBusState *s, uint8_t value)
365
+{
366
+ s->txf_ctl = value;
367
+}
368
+
369
+static void npcm7xx_smbus_write_t_out(NPCM7xxSMBusState *s, uint8_t value)
370
+{
371
+ uint8_t new_t_out = value;
372
+
373
+ if ((value & NPCM7XX_SMBT_OUT_ST) || (!(s->t_out & NPCM7XX_SMBT_OUT_ST))) {
374
+ new_t_out &= ~NPCM7XX_SMBT_OUT_ST;
375
+ } else {
376
+ new_t_out |= NPCM7XX_SMBT_OUT_ST;
377
+ }
378
+
379
+ s->t_out = new_t_out;
380
+}
381
+
382
+static void npcm7xx_smbus_write_txf_sts(NPCM7xxSMBusState *s, uint8_t value)
383
+{
384
+ s->txf_sts = WRITE_ONE_CLEAR(s->txf_sts, value, NPCM7XX_SMBTXF_STS_TX_THST);
385
+}
386
+
387
+static void npcm7xx_smbus_write_rxf_sts(NPCM7xxSMBusState *s, uint8_t value)
388
+{
389
+ if (value & NPCM7XX_SMBRXF_STS_RX_THST) {
390
+ s->rxf_sts &= ~NPCM7XX_SMBRXF_STS_RX_THST;
391
+ if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
392
+ npcm7xx_smbus_recv_fifo(s);
393
+ }
394
+ }
395
+}
396
+
397
+static void npcm7xx_smbus_write_rxf_ctl(NPCM7xxSMBusState *s, uint8_t value)
398
+{
399
+ uint8_t new_ctl = value;
400
+
401
+ if (!(value & NPCM7XX_SMBRXF_CTL_LAST)) {
402
+ new_ctl = KEEP_OLD_BIT(s->rxf_ctl, new_ctl, NPCM7XX_SMBRXF_CTL_LAST);
403
+ }
404
+ s->rxf_ctl = new_ctl;
405
+}
406
+
407
static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
408
{
409
NPCM7xxSMBusState *s = opaque;
410
@@ -XXX,XX +XXX,XX @@ static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
411
default:
412
if (bank) {
413
/* Bank 1 */
414
- qemu_log_mask(LOG_GUEST_ERROR,
415
- "%s: read from invalid offset 0x%" HWADDR_PRIx "\n",
416
- DEVICE(s)->canonical_path, offset);
417
+ switch (offset) {
418
+ case NPCM7XX_SMB_FIF_CTS:
419
+ value = s->fif_cts;
420
+ break;
421
+
422
+ case NPCM7XX_SMB_FAIR_PER:
423
+ value = s->fair_per;
424
+ break;
425
+
426
+ case NPCM7XX_SMB_TXF_CTL:
427
+ value = s->txf_ctl;
428
+ break;
429
+
430
+ case NPCM7XX_SMB_T_OUT:
431
+ value = s->t_out;
432
+ break;
433
+
434
+ case NPCM7XX_SMB_TXF_STS:
435
+ value = s->txf_sts;
436
+ break;
437
+
438
+ case NPCM7XX_SMB_RXF_STS:
439
+ value = s->rxf_sts;
440
+ break;
441
+
442
+ case NPCM7XX_SMB_RXF_CTL:
443
+ value = s->rxf_ctl;
444
+ break;
445
+
446
+ default:
447
+ qemu_log_mask(LOG_GUEST_ERROR,
448
+ "%s: read from invalid offset 0x%" HWADDR_PRIx "\n",
449
+ DEVICE(s)->canonical_path, offset);
450
+ break;
451
+ }
452
} else {
453
/* Bank 0 */
454
switch (offset) {
455
@@ -XXX,XX +XXX,XX @@ static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
456
value = s->scllt;
457
break;
458
459
+ case NPCM7XX_SMB_FIF_CTL:
460
+ value = s->fif_ctl;
461
+ break;
462
+
463
case NPCM7XX_SMB_SCLHT:
464
value = s->sclht;
465
break;
466
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_write(void *opaque, hwaddr offset, uint64_t value,
467
default:
468
if (bank) {
469
/* Bank 1 */
470
- qemu_log_mask(LOG_GUEST_ERROR,
471
- "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
472
- DEVICE(s)->canonical_path, offset);
473
+ switch (offset) {
474
+ case NPCM7XX_SMB_FIF_CTS:
475
+ npcm7xx_smbus_write_fif_cts(s, value);
476
+ break;
477
+
478
+ case NPCM7XX_SMB_FAIR_PER:
479
+ s->fair_per = value;
480
+ break;
481
+
482
+ case NPCM7XX_SMB_TXF_CTL:
483
+ npcm7xx_smbus_write_txf_ctl(s, value);
484
+ break;
485
+
486
+ case NPCM7XX_SMB_T_OUT:
487
+ npcm7xx_smbus_write_t_out(s, value);
488
+ break;
489
+
490
+ case NPCM7XX_SMB_TXF_STS:
491
+ npcm7xx_smbus_write_txf_sts(s, value);
492
+ break;
493
+
494
+ case NPCM7XX_SMB_RXF_STS:
495
+ npcm7xx_smbus_write_rxf_sts(s, value);
496
+ break;
497
+
498
+ case NPCM7XX_SMB_RXF_CTL:
499
+ npcm7xx_smbus_write_rxf_ctl(s, value);
500
+ break;
501
+
502
+ default:
503
+ qemu_log_mask(LOG_GUEST_ERROR,
504
+ "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
505
+ DEVICE(s)->canonical_path, offset);
506
+ break;
507
+ }
508
} else {
509
/* Bank 0 */
510
switch (offset) {
511
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_write(void *opaque, hwaddr offset, uint64_t value,
512
s->scllt = value;
513
break;
514
515
+ case NPCM7XX_SMB_FIF_CTL:
516
+ npcm7xx_smbus_write_fif_ctl(s, value);
517
+ break;
518
+
519
case NPCM7XX_SMB_SCLHT:
520
s->sclht = value;
521
break;
522
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_enter_reset(Object *obj, ResetType type)
523
s->scllt = NPCM7XX_SMB_SCLLT_INIT_VAL;
524
s->sclht = NPCM7XX_SMB_SCLHT_INIT_VAL;
525
526
+ s->fif_ctl = NPCM7XX_SMB_FIF_CTL_INIT_VAL;
527
+ s->fif_cts = NPCM7XX_SMB_FIF_CTS_INIT_VAL;
528
+ s->fair_per = NPCM7XX_SMB_FAIR_PER_INIT_VAL;
529
+ s->txf_ctl = NPCM7XX_SMB_TXF_CTL_INIT_VAL;
530
+ s->t_out = NPCM7XX_SMB_T_OUT_INIT_VAL;
531
+ s->txf_sts = NPCM7XX_SMB_TXF_STS_INIT_VAL;
532
+ s->rxf_sts = NPCM7XX_SMB_RXF_STS_INIT_VAL;
533
+ s->rxf_ctl = NPCM7XX_SMB_RXF_CTL_INIT_VAL;
534
+
535
+ npcm7xx_smbus_clear_buffer(s);
536
s->status = NPCM7XX_SMBUS_STATUS_IDLE;
537
+ s->rx_cur = 0;
538
}
539
540
static void npcm7xx_smbus_hold_reset(Object *obj)
541
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_npcm7xx_smbus = {
542
VMSTATE_UINT8_ARRAY(addr, NPCM7xxSMBusState, NPCM7XX_SMBUS_NR_ADDRS),
543
VMSTATE_UINT8(scllt, NPCM7xxSMBusState),
544
VMSTATE_UINT8(sclht, NPCM7xxSMBusState),
545
+ VMSTATE_UINT8(fif_ctl, NPCM7xxSMBusState),
546
+ VMSTATE_UINT8(fif_cts, NPCM7xxSMBusState),
547
+ VMSTATE_UINT8(fair_per, NPCM7xxSMBusState),
548
+ VMSTATE_UINT8(txf_ctl, NPCM7xxSMBusState),
549
+ VMSTATE_UINT8(t_out, NPCM7xxSMBusState),
550
+ VMSTATE_UINT8(txf_sts, NPCM7xxSMBusState),
551
+ VMSTATE_UINT8(rxf_sts, NPCM7xxSMBusState),
552
+ VMSTATE_UINT8(rxf_ctl, NPCM7xxSMBusState),
553
+ VMSTATE_UINT8_ARRAY(rx_fifo, NPCM7xxSMBusState,
554
+ NPCM7XX_SMBUS_FIFO_SIZE),
555
+ VMSTATE_UINT8(rx_cur, NPCM7xxSMBusState),
556
VMSTATE_END_OF_LIST(),
557
},
558
};
559
diff --git a/tests/qtest/npcm7xx_smbus-test.c b/tests/qtest/npcm7xx_smbus-test.c
560
index XXXXXXX..XXXXXXX 100644
561
--- a/tests/qtest/npcm7xx_smbus-test.c
562
+++ b/tests/qtest/npcm7xx_smbus-test.c
563
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxSMBusBank1Register {
564
#define ADDR_EN BIT(7)
565
#define ADDR_A(rv) extract8((rv), 0, 6)
566
567
+/* FIF_CTL fields */
568
+#define FIF_CTL_FIFO_EN BIT(4)
569
+
570
+/* FIF_CTS fields */
571
+#define FIF_CTS_CLR_FIFO BIT(6)
572
+#define FIF_CTS_RFTE_IE BIT(3)
573
+#define FIF_CTS_RXF_TXE BIT(1)
574
+
575
+/* TXF_CTL fields */
576
+#define TXF_CTL_THR_TXIE BIT(6)
577
+#define TXF_CTL_TX_THR(rv) extract8((rv), 0, 5)
578
+
579
+/* TXF_STS fields */
580
+#define TXF_STS_TX_THST BIT(6)
581
+#define TXF_STS_TX_BYTES(rv) extract8((rv), 0, 5)
582
+
583
+/* RXF_CTL fields */
584
+#define RXF_CTL_THR_RXIE BIT(6)
585
+#define RXF_CTL_LAST BIT(5)
586
+#define RXF_CTL_RX_THR(rv) extract8((rv), 0, 5)
587
+
588
+/* RXF_STS fields */
589
+#define RXF_STS_RX_THST BIT(6)
590
+#define RXF_STS_RX_BYTES(rv) extract8((rv), 0, 5)
591
+
592
+
593
+static void choose_bank(QTestState *qts, uint64_t base_addr, uint8_t bank)
594
+{
595
+ uint8_t ctl3 = qtest_readb(qts, base_addr + OFFSET_CTL3);
596
+
597
+ if (bank) {
598
+ ctl3 |= CTL3_BNK_SEL;
599
+ } else {
600
+ ctl3 &= ~CTL3_BNK_SEL;
601
+ }
602
+
603
+ qtest_writeb(qts, base_addr + OFFSET_CTL3, ctl3);
604
+}
605
606
static void check_running(QTestState *qts, uint64_t base_addr)
607
{
608
@@ -XXX,XX +XXX,XX @@ static void send_byte(QTestState *qts, uint64_t base_addr, uint8_t byte)
609
qtest_writeb(qts, base_addr + OFFSET_SDA, byte);
610
}
611
612
+static bool check_recv(QTestState *qts, uint64_t base_addr)
613
+{
614
+ uint8_t st, fif_ctl, rxf_ctl, rxf_sts;
615
+ bool fifo;
616
+
617
+ st = qtest_readb(qts, base_addr + OFFSET_ST);
618
+ choose_bank(qts, base_addr, 0);
619
+ fif_ctl = qtest_readb(qts, base_addr + OFFSET_FIF_CTL);
620
+ fifo = fif_ctl & FIF_CTL_FIFO_EN;
621
+ if (!fifo) {
622
+ return st == (ST_MODE | ST_SDAST);
623
+ }
624
+
625
+ choose_bank(qts, base_addr, 1);
626
+ rxf_ctl = qtest_readb(qts, base_addr + OFFSET_RXF_CTL);
627
+ rxf_sts = qtest_readb(qts, base_addr + OFFSET_RXF_STS);
628
+
629
+ if ((rxf_ctl & RXF_CTL_THR_RXIE) && RXF_STS_RX_BYTES(rxf_sts) < 16) {
630
+ return st == ST_MODE;
631
+ } else {
632
+ return st == (ST_MODE | ST_SDAST);
633
+ }
634
+}
635
+
636
static uint8_t recv_byte(QTestState *qts, uint64_t base_addr)
637
{
638
- g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_ST), ==,
639
- ST_MODE | ST_SDAST);
640
+ g_assert_true(check_recv(qts, base_addr));
641
return qtest_readb(qts, base_addr + OFFSET_SDA);
642
}
643
644
@@ -XXX,XX +XXX,XX @@ static void send_address(QTestState *qts, uint64_t base_addr, uint8_t addr,
645
qtest_writeb(qts, base_addr + OFFSET_ST, ST_STASTR);
646
st = qtest_readb(qts, base_addr + OFFSET_ST);
647
if (recv) {
648
- g_assert_cmphex(st, ==, ST_MODE | ST_SDAST);
649
+ g_assert_true(check_recv(qts, base_addr));
650
} else {
651
g_assert_cmphex(st, ==, ST_MODE | ST_XMIT | ST_SDAST);
652
}
653
@@ -XXX,XX +XXX,XX @@ static void send_nack(QTestState *qts, uint64_t base_addr)
654
qtest_writeb(qts, base_addr + OFFSET_CTL1, ctl1);
655
}
656
657
+static void start_fifo_mode(QTestState *qts, uint64_t base_addr)
658
+{
659
+ choose_bank(qts, base_addr, 0);
660
+ qtest_writeb(qts, base_addr + OFFSET_FIF_CTL, FIF_CTL_FIFO_EN);
661
+ g_assert_true(qtest_readb(qts, base_addr + OFFSET_FIF_CTL) &
662
+ FIF_CTL_FIFO_EN);
663
+ choose_bank(qts, base_addr, 1);
664
+ qtest_writeb(qts, base_addr + OFFSET_FIF_CTS,
665
+ FIF_CTS_CLR_FIFO | FIF_CTS_RFTE_IE);
666
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_FIF_CTS), ==,
667
+ FIF_CTS_RFTE_IE);
668
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_TXF_STS), ==, 0);
669
+ g_assert_cmphex(qtest_readb(qts, base_addr + OFFSET_RXF_STS), ==, 0);
670
+}
671
+
672
+static void start_recv_fifo(QTestState *qts, uint64_t base_addr, uint8_t bytes)
673
+{
674
+ choose_bank(qts, base_addr, 1);
675
+ qtest_writeb(qts, base_addr + OFFSET_TXF_CTL, 0);
676
+ qtest_writeb(qts, base_addr + OFFSET_RXF_CTL,
677
+ RXF_CTL_THR_RXIE | RXF_CTL_LAST | bytes);
678
+}
679
+
680
/* Check the SMBus's status is set correctly when disabled. */
681
static void test_disable_bus(gconstpointer data)
682
{
683
@@ -XXX,XX +XXX,XX @@ static void test_single_mode(gconstpointer data)
684
qtest_quit(qts);
685
}
686
687
+/* Check the SMBus can send and receive bytes in FIFO mode. */
688
+static void test_fifo_mode(gconstpointer data)
689
+{
690
+ intptr_t index = (intptr_t)data;
691
+ uint64_t base_addr = SMBUS_ADDR(index);
692
+ int irq = SMBUS_IRQ(index);
693
+ uint8_t value = 0x60;
694
+ QTestState *qts = qtest_init("-machine npcm750-evb");
695
+
696
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
697
+ enable_bus(qts, base_addr);
698
+ start_fifo_mode(qts, base_addr);
699
+ g_assert_false(qtest_get_irq(qts, irq));
700
+
701
+ /* Sending */
702
+ start_transfer(qts, base_addr);
703
+ send_address(qts, base_addr, EVB_DEVICE_ADDR, false, true);
704
+ choose_bank(qts, base_addr, 1);
705
+ g_assert_true(qtest_readb(qts, base_addr + OFFSET_FIF_CTS) &
706
+ FIF_CTS_RXF_TXE);
707
+ qtest_writeb(qts, base_addr + OFFSET_TXF_CTL, TXF_CTL_THR_TXIE);
708
+ send_byte(qts, base_addr, TMP105_REG_CONFIG);
709
+ send_byte(qts, base_addr, value);
710
+ g_assert_true(qtest_readb(qts, base_addr + OFFSET_FIF_CTS) &
711
+ FIF_CTS_RXF_TXE);
712
+ g_assert_true(qtest_readb(qts, base_addr + OFFSET_TXF_STS) &
713
+ TXF_STS_TX_THST);
714
+ g_assert_cmpuint(TXF_STS_TX_BYTES(
715
+ qtest_readb(qts, base_addr + OFFSET_TXF_STS)), ==, 0);
716
+ g_assert_true(qtest_get_irq(qts, irq));
717
+ stop_transfer(qts, base_addr);
718
+ check_stopped(qts, base_addr);
719
+
720
+ /* Receiving */
721
+ start_fifo_mode(qts, base_addr);
722
+ start_transfer(qts, base_addr);
723
+ send_address(qts, base_addr, EVB_DEVICE_ADDR, false, true);
724
+ send_byte(qts, base_addr, TMP105_REG_CONFIG);
725
+ start_transfer(qts, base_addr);
726
+ qtest_writeb(qts, base_addr + OFFSET_FIF_CTS, FIF_CTS_RXF_TXE);
727
+ start_recv_fifo(qts, base_addr, 1);
728
+ send_address(qts, base_addr, EVB_DEVICE_ADDR, true, true);
729
+ g_assert_false(qtest_readb(qts, base_addr + OFFSET_FIF_CTS) &
730
+ FIF_CTS_RXF_TXE);
731
+ g_assert_true(qtest_readb(qts, base_addr + OFFSET_RXF_STS) &
732
+ RXF_STS_RX_THST);
733
+ g_assert_cmpuint(RXF_STS_RX_BYTES(
734
+ qtest_readb(qts, base_addr + OFFSET_RXF_STS)), ==, 1);
735
+ send_nack(qts, base_addr);
736
+ stop_transfer(qts, base_addr);
737
+ check_running(qts, base_addr);
738
+ g_assert_cmphex(recv_byte(qts, base_addr), ==, value);
739
+ g_assert_cmpuint(RXF_STS_RX_BYTES(
740
+ qtest_readb(qts, base_addr + OFFSET_RXF_STS)), ==, 0);
741
+ check_stopped(qts, base_addr);
742
+ qtest_quit(qts);
743
+}
744
+
745
static void smbus_add_test(const char *name, int index, GTestDataFunc fn)
746
{
747
g_autofree char *full_name = g_strdup_printf(
748
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
749
750
for (i = 0; i < ARRAY_SIZE(evb_bus_list); ++i) {
751
add_test(single_mode, evb_bus_list[i]);
752
+ add_test(fifo_mode, evb_bus_list[i]);
753
}
754
755
return g_test_run();
756
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
757
index XXXXXXX..XXXXXXX 100644
758
--- a/hw/i2c/trace-events
759
+++ b/hw/i2c/trace-events
760
@@ -XXX,XX +XXX,XX @@ npcm7xx_smbus_send_byte(const char *id, uint8_t value, int success) "%s send byt
761
npcm7xx_smbus_recv_byte(const char *id, uint8_t value) "%s recv byte: 0x%02x"
762
npcm7xx_smbus_stop(const char *id) "%s stopping"
763
npcm7xx_smbus_nack(const char *id) "%s nacking"
764
+npcm7xx_smbus_recv_fifo(const char *id, uint8_t received, uint8_t expected) "%s recv fifo: received %u, expected %u"
27
--
765
--
28
2.20.1
766
2.20.1
29
767
30
768
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Luc Michel <luc@lmichel.fr>
2
2
3
Set ID_AA64PFR1_EL1.SSBS to 2 and ID_PFR2.SSBS to 1.
3
Also add Damien as a reviewer.
4
4
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
5
Signed-off-by: Luc Michel <luc@lmichel.fr>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Acked-by: Damien Hedde <damien.hedde@greensocs.com>
7
Message-id: 20210216224543.16142-3-rebecca@nuviainc.com
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210211085318.2507-1-luc@lmichel.fr
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/cpu64.c | 5 +++++
11
MAINTAINERS | 11 +++++++++++
11
1 file changed, 5 insertions(+)
12
1 file changed, 11 insertions(+)
12
13
13
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
14
diff --git a/MAINTAINERS b/MAINTAINERS
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu64.c
16
--- a/MAINTAINERS
16
+++ b/target/arm/cpu64.c
17
+++ b/MAINTAINERS
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ F: pc-bios/opensbi-*
18
19
F: .gitlab-ci.d/opensbi.yml
19
t = cpu->isar.id_aa64pfr1;
20
F: .gitlab-ci.d/opensbi/
20
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
21
21
+ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
22
+Clock framework
22
/*
23
+M: Luc Michel <luc@lmichel.fr>
23
* Begin with full support for MTE. This will be downgraded to MTE=0
24
+R: Damien Hedde <damien.hedde@greensocs.com>
24
* during realize if the board provides no tag memory, much like
25
+S: Maintained
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
26
+F: include/hw/clock.h
26
u = FIELD_DP32(u, ID_PFR0, DIT, 1);
27
+F: include/hw/qdev-clock.h
27
cpu->isar.id_pfr0 = u;
28
+F: hw/core/clock.c
28
29
+F: hw/core/clock-vmstate.c
29
+ u = cpu->isar.id_pfr2;
30
+F: hw/core/qdev-clock.c
30
+ u = FIELD_DP32(u, ID_PFR2, SSBS, 1);
31
+F: docs/devel/clocks.rst
31
+ cpu->isar.id_pfr2 = u;
32
+
32
+
33
u = cpu->isar.id_mmfr3;
33
Usermode Emulation
34
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
34
------------------
35
cpu->isar.id_mmfr3 = u;
35
Overall usermode emulation
36
--
36
--
37
2.20.1
37
2.20.1
38
38
39
39
diff view generated by jsdifflib
...
...
4
Only the ones needed by the Linux driver have been implemented.
4
Only the ones needed by the Linux driver have been implemented.
5
See npcm7xx_emc.c for a list of unimplemented features.
5
See npcm7xx_emc.c for a list of unimplemented features.
6
6
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Doug Evans <dje@google.com>
10
Signed-off-by: Doug Evans <dje@google.com>
10
Message-id: 20210218212453.831406-2-dje@google.com
11
Message-id: 20210213002520.1374134-2-dje@google.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
include/hw/net/npcm7xx_emc.h | 286 ++++++++++++
14
include/hw/net/npcm7xx_emc.h | 286 ++++++++++++
14
hw/net/npcm7xx_emc.c | 857 +++++++++++++++++++++++++++++++++++
15
hw/net/npcm7xx_emc.c | 857 +++++++++++++++++++++++++++++++++++
15
hw/net/meson.build | 1 +
16
hw/net/meson.build | 1 +
...
...
diff view generated by jsdifflib
...
...
6
6
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Doug Evans <dje@google.com>
10
Signed-off-by: Doug Evans <dje@google.com>
11
Message-id: 20210218212453.831406-3-dje@google.com
11
Message-id: 20210213002520.1374134-3-dje@google.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
docs/system/arm/nuvoton.rst | 3 ++-
14
docs/system/arm/nuvoton.rst | 3 ++-
15
include/hw/arm/npcm7xx.h | 2 ++
15
include/hw/arm/npcm7xx.h | 2 ++
16
hw/arm/npcm7xx.c | 50 +++++++++++++++++++++++++++++++++++--
16
hw/arm/npcm7xx.c | 50 +++++++++++++++++++++++++++++++++++--
...
...
diff view generated by jsdifflib
1
From: Doug Evans <dje@google.com>
1
From: Doug Evans <dje@google.com>
2
2
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
4
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
4
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Doug Evans <dje@google.com>
6
Signed-off-by: Doug Evans <dje@google.com>
7
Message-id: 20210218212453.831406-4-dje@google.com
7
Message-id: 20210213002520.1374134-4-dje@google.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++
10
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++
11
tests/qtest/meson.build | 3 +-
11
tests/qtest/meson.build | 1 +
12
2 files changed, 864 insertions(+), 1 deletion(-)
12
2 files changed, 863 insertions(+)
13
create mode 100644 tests/qtest/npcm7xx_emc-test.c
13
create mode 100644 tests/qtest/npcm7xx_emc-test.c
14
14
15
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
15
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
16
new file mode 100644
16
new file mode 100644
17
index XXXXXXX..XXXXXXX
17
index XXXXXXX..XXXXXXX
...
...
882
+}
882
+}
883
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
883
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
884
index XXXXXXX..XXXXXXX 100644
884
index XXXXXXX..XXXXXXX 100644
885
--- a/tests/qtest/meson.build
885
--- a/tests/qtest/meson.build
886
+++ b/tests/qtest/meson.build
886
+++ b/tests/qtest/meson.build
887
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
887
@@ -XXX,XX +XXX,XX @@ qtests_sparc64 = \
888
889
qtests_npcm7xx = \
890
['npcm7xx_adc-test',
891
+ 'npcm7xx_emc-test',
892
'npcm7xx_gpio-test',
893
'npcm7xx_pwm-test',
888
'npcm7xx_rng-test',
894
'npcm7xx_rng-test',
889
'npcm7xx_smbus-test',
890
'npcm7xx_timer-test',
891
- 'npcm7xx_watchdog_timer-test']
892
+ 'npcm7xx_watchdog_timer-test'] + \
893
+ (slirp.found() ? ['npcm7xx_emc-test'] : [])
894
qtests_arm = \
895
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
896
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
897
--
895
--
898
2.20.1
896
2.20.1
899
897
900
898
diff view generated by jsdifflib
Deleted patch
1
For a long time now the UI layer has guaranteed that the console
2
surface is always 32 bits per pixel RGB. Remove the legacy dead
3
code from the milkymist display device which was handling the
4
possibility that the console surface was some other format.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215103215.4944-2-peter.maydell@linaro.org
9
---
10
hw/arm/musicpal.c | 64 ++++++++++++++++++-----------------------------
11
1 file changed, 24 insertions(+), 40 deletions(-)
12
13
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/musicpal.c
16
+++ b/hw/arm/musicpal.c
17
@@ -XXX,XX +XXX,XX @@ static uint8_t scale_lcd_color(musicpal_lcd_state *s, uint8_t col)
18
}
19
}
20
21
-#define SET_LCD_PIXEL(depth, type) \
22
-static inline void glue(set_lcd_pixel, depth) \
23
- (musicpal_lcd_state *s, int x, int y, type col) \
24
-{ \
25
- int dx, dy; \
26
- DisplaySurface *surface = qemu_console_surface(s->con); \
27
- type *pixel = &((type *) surface_data(surface))[(y * 128 * 3 + x) * 3]; \
28
-\
29
- for (dy = 0; dy < 3; dy++, pixel += 127 * 3) \
30
- for (dx = 0; dx < 3; dx++, pixel++) \
31
- *pixel = col; \
32
+static inline void set_lcd_pixel32(musicpal_lcd_state *s,
33
+ int x, int y, uint32_t col)
34
+{
35
+ int dx, dy;
36
+ DisplaySurface *surface = qemu_console_surface(s->con);
37
+ uint32_t *pixel =
38
+ &((uint32_t *) surface_data(surface))[(y * 128 * 3 + x) * 3];
39
+
40
+ for (dy = 0; dy < 3; dy++, pixel += 127 * 3) {
41
+ for (dx = 0; dx < 3; dx++, pixel++) {
42
+ *pixel = col;
43
+ }
44
+ }
45
}
46
-SET_LCD_PIXEL(8, uint8_t)
47
-SET_LCD_PIXEL(16, uint16_t)
48
-SET_LCD_PIXEL(32, uint32_t)
49
50
static void lcd_refresh(void *opaque)
51
{
52
musicpal_lcd_state *s = opaque;
53
- DisplaySurface *surface = qemu_console_surface(s->con);
54
int x, y, col;
55
56
- switch (surface_bits_per_pixel(surface)) {
57
- case 0:
58
- return;
59
-#define LCD_REFRESH(depth, func) \
60
- case depth: \
61
- col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
62
- scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
63
- scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
64
- for (x = 0; x < 128; x++) { \
65
- for (y = 0; y < 64; y++) { \
66
- if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
67
- glue(set_lcd_pixel, depth)(s, x, y, col); \
68
- } else { \
69
- glue(set_lcd_pixel, depth)(s, x, y, 0); \
70
- } \
71
- } \
72
- } \
73
- break;
74
- LCD_REFRESH(8, rgb_to_pixel8)
75
- LCD_REFRESH(16, rgb_to_pixel16)
76
- LCD_REFRESH(32, (is_surface_bgr(surface) ?
77
- rgb_to_pixel32bgr : rgb_to_pixel32))
78
- default:
79
- hw_error("unsupported colour depth %i\n",
80
- surface_bits_per_pixel(surface));
81
+ col = rgb_to_pixel32(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff),
82
+ scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff),
83
+ scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff));
84
+ for (x = 0; x < 128; x++) {
85
+ for (y = 0; y < 64; y++) {
86
+ if (s->video_ram[x + (y / 8) * 128] & (1 << (y % 8))) {
87
+ set_lcd_pixel32(s, x, y, col);
88
+ } else {
89
+ set_lcd_pixel32(s, x, y, 0);
90
+ }
91
+ }
92
}
93
94
dpy_gfx_update(s->con, 0, 0, 128*3, 64*3);
95
--
96
2.20.1
97
98
diff view generated by jsdifflib
Deleted patch
1
Now the template header is included only for BITS==32, expand
2
out all the macros that depended on the BITS setting.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215103215.4944-4-peter.maydell@linaro.org
7
---
8
hw/display/tc6393xb_template.h | 35 ++++------------------------------
9
1 file changed, 4 insertions(+), 31 deletions(-)
10
11
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/tc6393xb_template.h
14
+++ b/hw/display/tc6393xb_template.h
15
@@ -XXX,XX +XXX,XX @@
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
-#if BITS == 8
20
-# define SET_PIXEL(addr, color) (*(uint8_t *)addr = color)
21
-#elif BITS == 15 || BITS == 16
22
-# define SET_PIXEL(addr, color) (*(uint16_t *)addr = color)
23
-#elif BITS == 24
24
-# define SET_PIXEL(addr, color) \
25
- do { \
26
- addr[0] = color; \
27
- addr[1] = (color) >> 8; \
28
- addr[2] = (color) >> 16; \
29
- } while (0)
30
-#elif BITS == 32
31
-# define SET_PIXEL(addr, color) (*(uint32_t *)addr = color)
32
-#else
33
-# error unknown bit depth
34
-#endif
35
-
36
-
37
-static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
38
+static void tc6393xb_draw_graphic32(TC6393xbState *s)
39
{
40
DisplaySurface *surface = qemu_console_surface(s->con);
41
int i;
42
@@ -XXX,XX +XXX,XX @@ static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
43
data_buffer = s->vram_ptr;
44
data_display = surface_data(surface);
45
for(i = 0; i < s->scr_height; i++) {
46
-#if (BITS == 16)
47
- memcpy(data_display, data_buffer, s->scr_width * 2);
48
- data_buffer += s->scr_width;
49
- data_display += surface_stride(surface);
50
-#else
51
int j;
52
- for (j = 0; j < s->scr_width; j++, data_display += BITS / 8, data_buffer++) {
53
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
54
uint16_t color = *data_buffer;
55
- uint32_t dest_color = glue(rgb_to_pixel, BITS)(
56
+ uint32_t dest_color = rgb_to_pixel32(
57
((color & 0xf800) * 0x108) >> 11,
58
((color & 0x7e0) * 0x41) >> 9,
59
((color & 0x1f) * 0x21) >> 2
60
);
61
- SET_PIXEL(data_display, dest_color);
62
+ *(uint32_t *)data_display = dest_color;
63
}
64
-#endif
65
}
66
}
67
-
68
-#undef BITS
69
-#undef SET_PIXEL
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
Deleted patch
1
The omap_lcdc template header is already only included once, for
2
DEPTH==32, but it still has all the macro-driven parameterization
3
for other depths. Expand out all the macros in the header.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215103215.4944-6-peter.maydell@linaro.org
9
---
10
hw/display/omap_lcd_template.h | 67 ++++++++++++++--------------------
11
1 file changed, 28 insertions(+), 39 deletions(-)
12
13
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/display/omap_lcd_template.h
16
+++ b/hw/display/omap_lcd_template.h
17
@@ -XXX,XX +XXX,XX @@
18
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
*/
20
21
-#if DEPTH == 32
22
-# define BPP 4
23
-# define PIXEL_TYPE uint32_t
24
-#else
25
-# error unsupport depth
26
-#endif
27
-
28
/*
29
* 2-bit colour
30
*/
31
-static void glue(draw_line2_, DEPTH)(void *opaque,
32
- uint8_t *d, const uint8_t *s, int width, int deststep)
33
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
34
+ int width, int deststep)
35
{
36
uint16_t *pal = opaque;
37
uint8_t v, r, g, b;
38
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
39
r = (pal[v & 3] >> 4) & 0xf0;
40
g = pal[v & 3] & 0xf0;
41
b = (pal[v & 3] << 4) & 0xf0;
42
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
43
- d += BPP;
44
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
45
+ d += 4;
46
v >>= 2;
47
r = (pal[v & 3] >> 4) & 0xf0;
48
g = pal[v & 3] & 0xf0;
49
b = (pal[v & 3] << 4) & 0xf0;
50
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
51
- d += BPP;
52
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
53
+ d += 4;
54
v >>= 2;
55
r = (pal[v & 3] >> 4) & 0xf0;
56
g = pal[v & 3] & 0xf0;
57
b = (pal[v & 3] << 4) & 0xf0;
58
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
59
- d += BPP;
60
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
61
+ d += 4;
62
v >>= 2;
63
r = (pal[v & 3] >> 4) & 0xf0;
64
g = pal[v & 3] & 0xf0;
65
b = (pal[v & 3] << 4) & 0xf0;
66
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
67
- d += BPP;
68
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
69
+ d += 4;
70
s ++;
71
width -= 4;
72
} while (width > 0);
73
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
74
/*
75
* 4-bit colour
76
*/
77
-static void glue(draw_line4_, DEPTH)(void *opaque,
78
- uint8_t *d, const uint8_t *s, int width, int deststep)
79
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
80
+ int width, int deststep)
81
{
82
uint16_t *pal = opaque;
83
uint8_t v, r, g, b;
84
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
85
r = (pal[v & 0xf] >> 4) & 0xf0;
86
g = pal[v & 0xf] & 0xf0;
87
b = (pal[v & 0xf] << 4) & 0xf0;
88
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
89
- d += BPP;
90
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
91
+ d += 4;
92
v >>= 4;
93
r = (pal[v & 0xf] >> 4) & 0xf0;
94
g = pal[v & 0xf] & 0xf0;
95
b = (pal[v & 0xf] << 4) & 0xf0;
96
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
97
- d += BPP;
98
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
99
+ d += 4;
100
s ++;
101
width -= 2;
102
} while (width > 0);
103
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
104
/*
105
* 8-bit colour
106
*/
107
-static void glue(draw_line8_, DEPTH)(void *opaque,
108
- uint8_t *d, const uint8_t *s, int width, int deststep)
109
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
110
+ int width, int deststep)
111
{
112
uint16_t *pal = opaque;
113
uint8_t v, r, g, b;
114
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line8_, DEPTH)(void *opaque,
115
r = (pal[v] >> 4) & 0xf0;
116
g = pal[v] & 0xf0;
117
b = (pal[v] << 4) & 0xf0;
118
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
119
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
120
s ++;
121
- d += BPP;
122
+ d += 4;
123
} while (-- width != 0);
124
}
125
126
/*
127
* 12-bit colour
128
*/
129
-static void glue(draw_line12_, DEPTH)(void *opaque,
130
- uint8_t *d, const uint8_t *s, int width, int deststep)
131
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
132
+ int width, int deststep)
133
{
134
uint16_t v;
135
uint8_t r, g, b;
136
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line12_, DEPTH)(void *opaque,
137
r = (v >> 4) & 0xf0;
138
g = v & 0xf0;
139
b = (v << 4) & 0xf0;
140
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
141
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
142
s += 2;
143
- d += BPP;
144
+ d += 4;
145
} while (-- width != 0);
146
}
147
148
/*
149
* 16-bit colour
150
*/
151
-static void glue(draw_line16_, DEPTH)(void *opaque,
152
- uint8_t *d, const uint8_t *s, int width, int deststep)
153
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
154
+ int width, int deststep)
155
{
156
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
157
memcpy(d, s, width * 2);
158
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line16_, DEPTH)(void *opaque,
159
r = (v >> 8) & 0xf8;
160
g = (v >> 3) & 0xfc;
161
b = (v << 3) & 0xf8;
162
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
163
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
164
s += 2;
165
- d += BPP;
166
+ d += 4;
167
} while (-- width != 0);
168
#endif
169
}
170
-
171
-#undef DEPTH
172
-#undef BPP
173
-#undef PIXEL_TYPE
174
--
175
2.20.1
176
177
diff view generated by jsdifflib
Deleted patch
1
The draw_line16_32() function in the omap_lcdc template header
2
includes an ifdef for the case where HOST_WORDS_BIGENDIAN matches
3
TARGET_WORDS_BIGENDIAN. This is trying to optimise for "source
4
bitmap and destination bitmap format match", but it is broken,
5
because in this function the formats don't match: the source is
6
16-bit colour and the destination is 32-bit colour, so a memcpy()
7
will produce corrupted graphics output. Drop the bogus ifdef.
8
1
9
This bug was introduced in commit ea644cf343129, when we dropped
10
support for DEPTH values other than 32 from the template header.
11
The old #if line was
12
#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
13
and this was mistakenly changed to
14
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
15
rather than deleting the #if as now having an always-false condition.
16
17
Fixes: ea644cf343129
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210215103215.4944-7-peter.maydell@linaro.org
22
---
23
hw/display/omap_lcd_template.h | 4 ----
24
1 file changed, 4 deletions(-)
25
26
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/display/omap_lcd_template.h
29
+++ b/hw/display/omap_lcd_template.h
30
@@ -XXX,XX +XXX,XX @@ static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
31
static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
32
int width, int deststep)
33
{
34
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
35
- memcpy(d, s, width * 2);
36
-#else
37
uint16_t v;
38
uint8_t r, g, b;
39
40
@@ -XXX,XX +XXX,XX @@ static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
41
s += 2;
42
d += 4;
43
} while (-- width != 0);
44
-#endif
45
}
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
The macro draw_line_func is used only once; just expand it.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210215103215.4944-10-peter.maydell@linaro.org
7
---
8
hw/display/omap_lcdc.c | 4 +---
9
1 file changed, 1 insertion(+), 3 deletions(-)
10
11
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/omap_lcdc.c
14
+++ b/hw/display/omap_lcdc.c
15
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
16
qemu_irq_lower(s->irq);
17
}
18
19
-#define draw_line_func drawfn
20
-
21
/*
22
* 2-bit colour
23
*/
24
@@ -XXX,XX +XXX,XX @@ static void omap_update_display(void *opaque)
25
{
26
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
27
DisplaySurface *surface;
28
- draw_line_func draw_line;
29
+ drawfn draw_line;
30
int size, height, first, last;
31
int width, linesize, step, bpp, frame_offset;
32
hwaddr frame_base;
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
Deleted patch
1
For a long time now the UI layer has guaranteed that the console
2
surface is always 32 bits per pixel, RGB. The TCX code already
3
assumes 32bpp, but it still has some checks of is_surface_bgr()
4
in an attempt to support 32bpp BGR. is_surface_bgr() will always
5
return false for the qemu_console_surface(), unless the display
6
device itself has deliberately created an alternate-format
7
surface via a function like qemu_create_displaysurface_from().
8
1
9
Drop the never-used BGR-handling code, and assert that we have
10
a 32-bit surface rather than just doing nothing if it isn't.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210215102149.20513-1-peter.maydell@linaro.org
16
---
17
hw/display/tcx.c | 31 ++++++++-----------------------
18
1 file changed, 8 insertions(+), 23 deletions(-)
19
20
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/display/tcx.c
23
+++ b/hw/display/tcx.c
24
@@ -XXX,XX +XXX,XX @@ static int tcx_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
25
26
static void update_palette_entries(TCXState *s, int start, int end)
27
{
28
- DisplaySurface *surface = qemu_console_surface(s->con);
29
int i;
30
31
for (i = start; i < end; i++) {
32
- if (is_surface_bgr(surface)) {
33
- s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
34
- } else {
35
- s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
36
- }
37
+ s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
38
}
39
tcx_set_dirty(s, 0, memory_region_size(&s->vram_mem));
40
}
41
@@ -XXX,XX +XXX,XX @@ static void tcx_draw_cursor32(TCXState *s1, uint8_t *d,
42
}
43
44
/*
45
- XXX Could be much more optimal:
46
- * detect if line/page/whole screen is in 24 bit mode
47
- * if destination is also BGR, use memcpy
48
- */
49
+ * XXX Could be much more optimal:
50
+ * detect if line/page/whole screen is in 24 bit mode
51
+ */
52
static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,
53
const uint8_t *s, int width,
54
const uint32_t *cplane,
55
const uint32_t *s24)
56
{
57
- DisplaySurface *surface = qemu_console_surface(s1->con);
58
- int x, bgr, r, g, b;
59
+ int x, r, g, b;
60
uint8_t val, *p8;
61
uint32_t *p = (uint32_t *)d;
62
uint32_t dval;
63
- bgr = is_surface_bgr(surface);
64
for(x = 0; x < width; x++, s++, s24++) {
65
if (be32_to_cpu(*cplane) & 0x03000000) {
66
/* 24-bit direct, BGR order */
67
@@ -XXX,XX +XXX,XX @@ static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,
68
b = *p8++;
69
g = *p8++;
70
r = *p8;
71
- if (bgr)
72
- dval = rgb_to_pixel32bgr(r, g, b);
73
- else
74
- dval = rgb_to_pixel32(r, g, b);
75
+ dval = rgb_to_pixel32(r, g, b);
76
} else {
77
/* 8-bit pseudocolor */
78
val = *s;
79
@@ -XXX,XX +XXX,XX @@ static void tcx_update_display(void *opaque)
80
int y, y_start, dd, ds;
81
uint8_t *d, *s;
82
83
- if (surface_bits_per_pixel(surface) != 32) {
84
- return;
85
- }
86
+ assert(surface_bits_per_pixel(surface) == 32);
87
88
page = 0;
89
y_start = -1;
90
@@ -XXX,XX +XXX,XX @@ static void tcx24_update_display(void *opaque)
91
uint8_t *d, *s;
92
uint32_t *cptr, *s24;
93
94
- if (surface_bits_per_pixel(surface) != 32) {
95
- return;
96
- }
97
+ assert(surface_bits_per_pixel(surface) == 32);
98
99
page = 0;
100
y_start = -1;
101
--
102
2.20.1
103
104
diff view generated by jsdifflib
Deleted patch
1
Currently the MPS2 SCC device implements a fixed number of OSCCLK
2
values (3). The variant of this device in the MPS3 AN524 board has 6
3
OSCCLK values. Switch to using a PROP_ARRAY, which allows board code
4
to specify how large the OSCCLK array should be as well as its
5
values.
6
1
7
With a variable-length property array, the SCC no longer specifies
8
default values for the OSCCLKs, so we must set them explicitly in the
9
board code. This defaults are actually incorrect for the an521 and
10
an505; we will correct this bug in a following patch.
11
12
This is a migration compatibility break for all the mps boards.
13
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210215115138.20465-3-peter.maydell@linaro.org
18
---
19
include/hw/misc/mps2-scc.h | 7 +++----
20
hw/arm/mps2-tz.c | 5 +++++
21
hw/arm/mps2.c | 5 +++++
22
hw/misc/mps2-scc.c | 24 +++++++++++++-----------
23
4 files changed, 26 insertions(+), 15 deletions(-)
24
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/misc/mps2-scc.h
28
+++ b/include/hw/misc/mps2-scc.h
29
@@ -XXX,XX +XXX,XX @@
30
#define TYPE_MPS2_SCC "mps2-scc"
31
OBJECT_DECLARE_SIMPLE_TYPE(MPS2SCC, MPS2_SCC)
32
33
-#define NUM_OSCCLK 3
34
-
35
struct MPS2SCC {
36
/*< private >*/
37
SysBusDevice parent_obj;
38
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
39
uint32_t dll;
40
uint32_t aid;
41
uint32_t id;
42
- uint32_t oscclk[NUM_OSCCLK];
43
- uint32_t oscclk_reset[NUM_OSCCLK];
44
+ uint32_t num_oscclk;
45
+ uint32_t *oscclk;
46
+ uint32_t *oscclk_reset;
47
};
48
49
#endif
50
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/mps2-tz.c
53
+++ b/hw/arm/mps2-tz.c
54
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
55
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
56
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
57
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
58
+ /* This will need to be per-FPGA image eventually */
59
+ qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
60
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
61
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
62
+ qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
63
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
64
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
65
}
66
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/mps2.c
69
+++ b/hw/arm/mps2.c
70
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
71
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
72
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
73
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
74
+ /* All these FPGA images have the same OSCCLK configuration */
75
+ qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
76
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
77
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
78
+ qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
79
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
80
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
81
object_initialize_child(OBJECT(mms), "fpgaio",
82
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/misc/mps2-scc.c
85
+++ b/hw/misc/mps2-scc.c
86
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
87
{
88
trace_mps2_scc_cfg_write(function, device, value);
89
90
- if (function != 1 || device >= NUM_OSCCLK) {
91
+ if (function != 1 || device >= s->num_oscclk) {
92
qemu_log_mask(LOG_GUEST_ERROR,
93
"MPS2 SCC config write: bad function %d device %d\n",
94
function, device);
95
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
96
static bool scc_cfg_read(MPS2SCC *s, unsigned function,
97
unsigned device, uint32_t *value)
98
{
99
- if (function != 1 || device >= NUM_OSCCLK) {
100
+ if (function != 1 || device >= s->num_oscclk) {
101
qemu_log_mask(LOG_GUEST_ERROR,
102
"MPS2 SCC config read: bad function %d device %d\n",
103
function, device);
104
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
105
s->cfgctrl = 0x100000;
106
s->cfgstat = 0;
107
s->dll = 0xffff0001;
108
- for (i = 0; i < NUM_OSCCLK; i++) {
109
+ for (i = 0; i < s->num_oscclk; i++) {
110
s->oscclk[i] = s->oscclk_reset[i];
111
}
112
for (i = 0; i < ARRAY_SIZE(s->led); i++) {
113
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
114
LED_COLOR_GREEN, name);
115
g_free(name);
116
}
117
+
118
+ s->oscclk = g_new0(uint32_t, s->num_oscclk);
119
}
120
121
static const VMStateDescription mps2_scc_vmstate = {
122
.name = "mps2-scc",
123
- .version_id = 1,
124
- .minimum_version_id = 1,
125
+ .version_id = 2,
126
+ .minimum_version_id = 2,
127
.fields = (VMStateField[]) {
128
VMSTATE_UINT32(cfg0, MPS2SCC),
129
VMSTATE_UINT32(cfg1, MPS2SCC),
130
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
131
VMSTATE_UINT32(cfgctrl, MPS2SCC),
132
VMSTATE_UINT32(cfgstat, MPS2SCC),
133
VMSTATE_UINT32(dll, MPS2SCC),
134
- VMSTATE_UINT32_ARRAY(oscclk, MPS2SCC, NUM_OSCCLK),
135
+ VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
136
+ 0, vmstate_info_uint32, uint32_t),
137
VMSTATE_END_OF_LIST()
138
}
139
};
140
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
141
DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
142
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
143
DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
144
- /* These are the initial settings for the source clocks on the board.
145
+ /*
146
+ * These are the initial settings for the source clocks on the board.
147
* In hardware they can be configured via a config file read by the
148
* motherboard configuration controller to suit the FPGA image.
149
- * These default values are used by most of the standard FPGA images.
150
*/
151
- DEFINE_PROP_UINT32("oscclk0", MPS2SCC, oscclk_reset[0], 50000000),
152
- DEFINE_PROP_UINT32("oscclk1", MPS2SCC, oscclk_reset[1], 24576000),
153
- DEFINE_PROP_UINT32("oscclk2", MPS2SCC, oscclk_reset[2], 25000000),
154
+ DEFINE_PROP_ARRAY("oscclk", MPS2SCC, num_oscclk, oscclk_reset,
155
+ qdev_prop_uint32, uint32_t),
156
DEFINE_PROP_END_OF_LIST(),
157
};
158
159
--
160
2.20.1
161
162
diff view generated by jsdifflib
Deleted patch
1
We were previously using the default OSCCLK settings, which are
2
correct for the older MPS2 boards (mps2-an385, mps2-an386,
3
mps2-an500, mps2-an511), but wrong for the mps2-an505 and mps2-511
4
implemented in mps2-tz.c. Now we're setting the values explicitly we
5
can fix them to be correct.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210215115138.20465-4-peter.maydell@linaro.org
11
---
12
hw/arm/mps2-tz.c | 4 ++--
13
1 file changed, 2 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
18
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
20
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
21
/* This will need to be per-FPGA image eventually */
22
qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
23
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
24
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
25
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
26
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
27
qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
28
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
29
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
Deleted patch
1
We create an OR gate to wire together the overflow IRQs for all the
2
UARTs on the board; this has to have twice the number of inputs as
3
there are UARTs, since each UART feeds it a TX overflow and an RX
4
overflow interrupt line. Replace the hardcoded '10' with a
5
calculation based on the size of the uart[] array in the
6
MPS2TZMachineState. (We rely on OR gate inputs that are never wired
7
up or asserted being treated as always-zero.)
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210215115138.20465-15-peter.maydell@linaro.org
12
---
13
hw/arm/mps2-tz.c | 11 ++++++++---
14
1 file changed, 8 insertions(+), 3 deletions(-)
15
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mps2-tz.c
19
+++ b/hw/arm/mps2-tz.c
20
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
21
*/
22
memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
23
24
- /* The overflow IRQs for all UARTs are ORed together.
25
+ /*
26
+ * The overflow IRQs for all UARTs are ORed together.
27
* Tx, Rx and "combined" IRQs are sent to the NVIC separately.
28
- * Create the OR gate for this.
29
+ * Create the OR gate for this: it has one input for the TX overflow
30
+ * and one for the RX overflow for each UART we might have.
31
+ * (If the board has fewer than the maximum possible number of UARTs
32
+ * those inputs are never wired up and are treated as always-zero.)
33
*/
34
object_initialize_child(OBJECT(mms), "uart-irq-orgate",
35
&mms->uart_irq_orgate, TYPE_OR_IRQ);
36
- object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines", 10,
37
+ object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines",
38
+ 2 * ARRAY_SIZE(mms->uart),
39
&error_fatal);
40
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
41
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
42
--
43
2.20.1
44
45
diff view generated by jsdifflib