1 | Since v5: | ||
---|---|---|---|
2 | - Introduce QAPI EndianMode | ||
3 | - Update RISCV machine while rebasing | ||
4 | - Fixed INTC use on PPC (Thomas) | ||
5 | - Dropped patch adding more machines (Daniel) | ||
6 | |||
7 | Since v4 & v3: | ||
8 | - Addressed Thomas review comments | ||
9 | |||
10 | Since v2: | ||
11 | - Addressed Richard's review comments | ||
12 | |||
1 | Since v1: | 13 | Since v1: |
2 | - Make device endianness configurable (Edgar) | 14 | - Make device endianness configurable (Edgar) |
3 | - Convert more Xilinx devices | 15 | - Convert more Xilinx devices |
4 | - Avoid preprocessor #if (Richard) | 16 | - Avoid preprocessor #if (Richard) |
5 | - Add R-b tags | 17 | - Add R-b tags |
6 | 18 | ||
7 | Make machines endianness-agnostic, allowing to run a big-endian vCPU | 19 | Philippe Mathieu-Daudé (11): |
8 | on the little-endian 'qemu-system-microblazeel' binary, and a little | 20 | hw/qdev-properties-system: Introduce EndianMode QAPI enum |
9 | endian one on the big-endian 'qemu-system-microblaze' binary. | ||
10 | |||
11 | Tests added, following combinations covered: | ||
12 | - little-endian vCPU using little-endian binary (in-tree) | ||
13 | - little-endian vCPU using big-endian binary (new) | ||
14 | - big-endian vCPU using little-endian binary (new) | ||
15 | - big-endian vCPU using big-endian binary (in-tree) | ||
16 | |||
17 | To make a target endian-agnostic we need to remove the MO_TE uses. | ||
18 | In order to do that, we propagate the MemOp from earlier in the | ||
19 | call stack, or we extract it from the vCPU env (on MicroBlaze the | ||
20 | CPU endianness is exposed by the 'ENDI' bit). | ||
21 | |||
22 | Next step: Look at unifying binaries. | ||
23 | |||
24 | Please review, | ||
25 | |||
26 | Phil. | ||
27 | |||
28 | Philippe Mathieu-Daudé (16): | ||
29 | hw/microblaze: Restrict MemoryRegionOps are implemented as 32-bit | ||
30 | hw/microblaze: Propagate CPU endianness to microblaze_load_kernel() | ||
31 | hw/intc/xilinx_intc: Make device endianness configurable | 21 | hw/intc/xilinx_intc: Make device endianness configurable |
32 | RFC hw/net/xilinx_ethlite: Simplify by having configurable endianness | 22 | hw/net/xilinx_ethlite: Make device endianness configurable |
33 | RFC hw/timer/xilinx_timer: Allow down to 8-bit memory access | ||
34 | hw/timer/xilinx_timer: Make device endianness configurable | 23 | hw/timer/xilinx_timer: Make device endianness configurable |
35 | hw/char/xilinx_uartlite: Make device endianness configurable | 24 | hw/char/xilinx_uartlite: Make device endianness configurable |
36 | hw/ssi/xilinx_spi: Make device endianness configurable | 25 | hw/ssi/xilinx_spi: Make device endianness configurable |
37 | hw/ssi/xilinx_spips: Make device endianness configurable | 26 | tests/functional: Avoid using www.qemu-advent-calendar.org URL |
38 | target/microblaze: Explode MO_TExx -> MO_TE | MO_xx | ||
39 | target/microblaze: Set MO_TE once in do_load() / do_store() | ||
40 | target/microblaze: Introduce mo_endian() helper | ||
41 | target/microblaze: Consider endianness while translating code | ||
42 | hw/microblaze: Support various endianness for s3adsp1800 machines | ||
43 | tests/functional: Explicit endianness of microblaze assets | 27 | tests/functional: Explicit endianness of microblaze assets |
44 | tests/functional: Add microblaze cross-endianness tests | 28 | tests/functional: Allow microblaze tests to take a machine name |
29 | argument | ||
30 | tests/functional: Remove sleep() kludges from microblaze tests | ||
31 | tests/functional: Have microblaze tests inherit common parent class | ||
45 | 32 | ||
46 | hw/microblaze/boot.h | 4 +- | 33 | qapi/common.json | 16 +++++ |
47 | include/hw/ssi/xilinx_spips.h | 1 + | 34 | include/hw/qdev-properties-system.h | 7 +++ |
48 | target/microblaze/cpu.h | 7 +++ | 35 | hw/char/xilinx_uartlite.c | 34 +++++++---- |
49 | hw/arm/xilinx_zynq.c | 1 + | 36 | hw/core/qdev-properties-system.c | 11 ++++ |
50 | hw/arm/xlnx-zynqmp.c | 4 ++ | 37 | hw/intc/xilinx_intc.c | 60 ++++++++++++++----- |
51 | hw/char/xilinx_uartlite.c | 40 +++++++++---- | 38 | hw/microblaze/petalogix_ml605_mmu.c | 3 + |
52 | hw/intc/xilinx_intc.c | 59 +++++++++++++++---- | 39 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 6 ++ |
53 | hw/microblaze/boot.c | 8 +-- | 40 | hw/net/xilinx_ethlite.c | 27 +++++++-- |
54 | hw/microblaze/petalogix_ml605_mmu.c | 4 +- | 41 | hw/ppc/virtex_ml507.c | 2 + |
55 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 59 ++++++++++++++++--- | 42 | hw/riscv/microblaze-v-generic.c | 5 ++ |
56 | hw/microblaze/xlnx-zynqmp-pmu.c | 2 +- | 43 | hw/ssi/xilinx_spi.c | 32 +++++++--- |
57 | hw/net/xilinx_ethlite.c | 52 ++++++++++++---- | 44 | hw/timer/xilinx_timer.c | 43 +++++++++---- |
58 | hw/ppc/virtex_ml507.c | 1 + | 45 | .../functional/test_microblaze_s3adsp1800.py | 35 +++++++++-- |
59 | hw/ssi/xilinx_spi.c | 29 ++++++--- | 46 | .../test_microblazeel_s3adsp1800.py | 32 ++-------- |
60 | hw/ssi/xilinx_spips.c | 46 +++++++++++---- | 47 | 14 files changed, 229 insertions(+), 84 deletions(-) |
61 | hw/timer/xilinx_timer.c | 42 ++++++++++--- | ||
62 | target/microblaze/translate.c | 49 +++++++++------ | ||
63 | .../functional/test_microblaze_s3adsp1800.py | 27 ++++++++- | ||
64 | .../test_microblazeel_s3adsp1800.py | 25 +++++++- | ||
65 | 19 files changed, 358 insertions(+), 102 deletions(-) | ||
66 | 48 | ||
67 | -- | 49 | -- |
68 | 2.45.2 | 50 | 2.47.1 |
51 | |||
52 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | All these MemoryRegionOps read() and write() handlers are | ||
2 | implemented expecting 32-bit accesses. Clarify that setting | ||
3 | .impl.min/max_access_size fields. | ||
4 | 1 | ||
5 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
6 | Reviewed-by: Anton Johansson <anjo@rev.ng> | ||
7 | Message-Id: <20241105130431.22564-8-philmd@linaro.org> | ||
8 | --- | ||
9 | hw/char/xilinx_uartlite.c | 4 ++++ | ||
10 | hw/intc/xilinx_intc.c | 4 ++++ | ||
11 | hw/net/xilinx_ethlite.c | 4 ++++ | ||
12 | hw/timer/xilinx_timer.c | 4 ++++ | ||
13 | 4 files changed, 16 insertions(+) | ||
14 | |||
15 | diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/hw/char/xilinx_uartlite.c | ||
18 | +++ b/hw/char/xilinx_uartlite.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps uart_ops = { | ||
20 | .read = uart_read, | ||
21 | .write = uart_write, | ||
22 | .endianness = DEVICE_NATIVE_ENDIAN, | ||
23 | + .impl = { | ||
24 | + .min_access_size = 4, | ||
25 | + .max_access_size = 4, | ||
26 | + }, | ||
27 | .valid = { | ||
28 | .min_access_size = 1, | ||
29 | .max_access_size = 4 | ||
30 | diff --git a/hw/intc/xilinx_intc.c b/hw/intc/xilinx_intc.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/hw/intc/xilinx_intc.c | ||
33 | +++ b/hw/intc/xilinx_intc.c | ||
34 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps pic_ops = { | ||
35 | .read = pic_read, | ||
36 | .write = pic_write, | ||
37 | .endianness = DEVICE_NATIVE_ENDIAN, | ||
38 | + .impl = { | ||
39 | + .min_access_size = 4, | ||
40 | + .max_access_size = 4, | ||
41 | + }, | ||
42 | .valid = { | ||
43 | .min_access_size = 4, | ||
44 | .max_access_size = 4 | ||
45 | diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c | ||
46 | index XXXXXXX..XXXXXXX 100644 | ||
47 | --- a/hw/net/xilinx_ethlite.c | ||
48 | +++ b/hw/net/xilinx_ethlite.c | ||
49 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps eth_ops = { | ||
50 | .read = eth_read, | ||
51 | .write = eth_write, | ||
52 | .endianness = DEVICE_NATIVE_ENDIAN, | ||
53 | + .impl = { | ||
54 | + .min_access_size = 4, | ||
55 | + .max_access_size = 4, | ||
56 | + }, | ||
57 | .valid = { | ||
58 | .min_access_size = 4, | ||
59 | .max_access_size = 4 | ||
60 | diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c | ||
61 | index XXXXXXX..XXXXXXX 100644 | ||
62 | --- a/hw/timer/xilinx_timer.c | ||
63 | +++ b/hw/timer/xilinx_timer.c | ||
64 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps timer_ops = { | ||
65 | .read = timer_read, | ||
66 | .write = timer_write, | ||
67 | .endianness = DEVICE_NATIVE_ENDIAN, | ||
68 | + .impl = { | ||
69 | + .min_access_size = 4, | ||
70 | + .max_access_size = 4, | ||
71 | + }, | ||
72 | .valid = { | ||
73 | .min_access_size = 4, | ||
74 | .max_access_size = 4 | ||
75 | -- | ||
76 | 2.45.2 | ||
77 | |||
78 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Pass vCPU endianness as argument so we can load kernels | ||
2 | with different endianness (different from the qemu-system-binary | ||
3 | builtin one). | ||
4 | 1 | ||
5 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
6 | Reviewed-by: Anton Johansson <anjo@rev.ng> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> | ||
9 | Message-Id: <20241105130431.22564-9-philmd@linaro.org> | ||
10 | --- | ||
11 | hw/microblaze/boot.h | 4 ++-- | ||
12 | hw/microblaze/boot.c | 8 ++++---- | ||
13 | hw/microblaze/petalogix_ml605_mmu.c | 2 +- | ||
14 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 2 +- | ||
15 | hw/microblaze/xlnx-zynqmp-pmu.c | 2 +- | ||
16 | 5 files changed, 9 insertions(+), 9 deletions(-) | ||
17 | |||
18 | diff --git a/hw/microblaze/boot.h b/hw/microblaze/boot.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/hw/microblaze/boot.h | ||
21 | +++ b/hw/microblaze/boot.h | ||
22 | @@ -XXX,XX +XXX,XX @@ | ||
23 | #define MICROBLAZE_BOOT_H | ||
24 | |||
25 | |||
26 | -void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, | ||
27 | - uint32_t ramsize, | ||
28 | +void microblaze_load_kernel(MicroBlazeCPU *cpu, bool is_little_endian, | ||
29 | + hwaddr ddr_base, uint32_t ramsize, | ||
30 | const char *initrd_filename, | ||
31 | const char *dtb_filename, | ||
32 | void (*machine_cpu_reset)(MicroBlazeCPU *)); | ||
33 | diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/hw/microblaze/boot.c | ||
36 | +++ b/hw/microblaze/boot.c | ||
37 | @@ -XXX,XX +XXX,XX @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr) | ||
38 | return addr - 0x30000000LL; | ||
39 | } | ||
40 | |||
41 | -void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, | ||
42 | - uint32_t ramsize, | ||
43 | +void microblaze_load_kernel(MicroBlazeCPU *cpu, bool is_little_endian, | ||
44 | + hwaddr ddr_base, uint32_t ramsize, | ||
45 | const char *initrd_filename, | ||
46 | const char *dtb_filename, | ||
47 | void (*machine_cpu_reset)(MicroBlazeCPU *)) | ||
48 | @@ -XXX,XX +XXX,XX @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, | ||
49 | /* Boots a kernel elf binary. */ | ||
50 | kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, | ||
51 | &entry, NULL, &high, NULL, | ||
52 | - TARGET_BIG_ENDIAN, EM_MICROBLAZE, 0, 0); | ||
53 | + !is_little_endian, EM_MICROBLAZE, 0, 0); | ||
54 | base32 = entry; | ||
55 | if (base32 == 0xc0000000) { | ||
56 | kernel_size = load_elf(kernel_filename, NULL, | ||
57 | translate_kernel_address, NULL, | ||
58 | &entry, NULL, NULL, NULL, | ||
59 | - TARGET_BIG_ENDIAN, EM_MICROBLAZE, 0, 0); | ||
60 | + !is_little_endian, EM_MICROBLAZE, 0, 0); | ||
61 | } | ||
62 | /* Always boot into physical ram. */ | ||
63 | boot_info.bootstrap_pc = (uint32_t)entry; | ||
64 | diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c | ||
65 | index XXXXXXX..XXXXXXX 100644 | ||
66 | --- a/hw/microblaze/petalogix_ml605_mmu.c | ||
67 | +++ b/hw/microblaze/petalogix_ml605_mmu.c | ||
68 | @@ -XXX,XX +XXX,XX @@ petalogix_ml605_init(MachineState *machine) | ||
69 | cpu->cfg.pvr_regs[5] = 0xc56be000; | ||
70 | cpu->cfg.pvr_regs[10] = 0x0e000000; /* virtex 6 */ | ||
71 | |||
72 | - microblaze_load_kernel(cpu, MEMORY_BASEADDR, ram_size, | ||
73 | + microblaze_load_kernel(cpu, true, MEMORY_BASEADDR, ram_size, | ||
74 | machine->initrd_filename, | ||
75 | BINARY_DEVICE_TREE_FILE, | ||
76 | NULL); | ||
77 | diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c | ||
78 | index XXXXXXX..XXXXXXX 100644 | ||
79 | --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c | ||
80 | +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c | ||
81 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | ||
82 | |||
83 | create_unimplemented_device("xps_gpio", GPIO_BASEADDR, 0x10000); | ||
84 | |||
85 | - microblaze_load_kernel(cpu, ddr_base, ram_size, | ||
86 | + microblaze_load_kernel(cpu, !TARGET_BIG_ENDIAN, ddr_base, ram_size, | ||
87 | machine->initrd_filename, | ||
88 | BINARY_DEVICE_TREE_FILE, | ||
89 | NULL); | ||
90 | diff --git a/hw/microblaze/xlnx-zynqmp-pmu.c b/hw/microblaze/xlnx-zynqmp-pmu.c | ||
91 | index XXXXXXX..XXXXXXX 100644 | ||
92 | --- a/hw/microblaze/xlnx-zynqmp-pmu.c | ||
93 | +++ b/hw/microblaze/xlnx-zynqmp-pmu.c | ||
94 | @@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_pmu_init(MachineState *machine) | ||
95 | qdev_realize(DEVICE(pmu), NULL, &error_fatal); | ||
96 | |||
97 | /* Load the kernel */ | ||
98 | - microblaze_load_kernel(&pmu->cpu, XLNX_ZYNQMP_PMU_RAM_ADDR, | ||
99 | + microblaze_load_kernel(&pmu->cpu, true, XLNX_ZYNQMP_PMU_RAM_ADDR, | ||
100 | machine->ram_size, | ||
101 | machine->initrd_filename, | ||
102 | machine->dtb, | ||
103 | -- | ||
104 | 2.45.2 | diff view generated by jsdifflib |
1 | Replace the DEVICE_NATIVE_ENDIAN MemoryRegionOps by a pair | 1 | Introduce the EndianMode type and the DEFINE_PROP_ENDIAN() macros. |
---|---|---|---|
2 | of DEVICE_LITTLE_ENDIAN / DEVICE_BIG_ENDIAN. | 2 | Endianness can be BIG, LITTLE or unspecified (default). |
3 | Add the "little-endian" property to select the device | ||
4 | endianness, defaulting to little endian. | ||
5 | Set the proper endianness on the single machine using the | ||
6 | device. | ||
7 | 3 | ||
8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 4 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
9 | --- | 5 | --- |
10 | include/hw/ssi/xilinx_spips.h | 1 + | 6 | qapi/common.json | 16 ++++++++++++++++ |
11 | hw/arm/xilinx_zynq.c | 1 + | 7 | include/hw/qdev-properties-system.h | 7 +++++++ |
12 | hw/ssi/xilinx_spips.c | 46 ++++++++++++++++++++++++++--------- | 8 | hw/core/qdev-properties-system.c | 11 +++++++++++ |
13 | 3 files changed, 36 insertions(+), 12 deletions(-) | 9 | 3 files changed, 34 insertions(+) |
14 | 10 | ||
15 | diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h | 11 | diff --git a/qapi/common.json b/qapi/common.json |
16 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/include/hw/ssi/xilinx_spips.h | 13 | --- a/qapi/common.json |
18 | +++ b/include/hw/ssi/xilinx_spips.h | 14 | +++ b/qapi/common.json |
19 | @@ -XXX,XX +XXX,XX @@ typedef struct XilinxQSPIPS XilinxQSPIPS; | 15 | @@ -XXX,XX +XXX,XX @@ |
20 | struct XlnxZynqMPQSPIPS { | 16 | ## |
21 | XilinxQSPIPS parent_obj; | 17 | { 'struct': 'HumanReadableText', |
22 | 18 | 'data': { 'human-readable-text': 'str' } } | |
23 | + bool little_endian_model; | 19 | + |
24 | StreamSink *dma; | 20 | +## |
25 | int gqspi_irqline; | 21 | +# @EndianMode: |
26 | 22 | +# | |
27 | diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c | 23 | +# An enumeration of three options: little, big, and unspecified |
24 | +# | ||
25 | +# @little: Little endianness | ||
26 | +# | ||
27 | +# @big: Big endianness | ||
28 | +# | ||
29 | +# @unspecified: Endianness not specified | ||
30 | +# | ||
31 | +# Since: 10.0 | ||
32 | +## | ||
33 | +{ 'enum': 'EndianMode', | ||
34 | + 'data': [ 'little', 'big', 'unspecified' ] } | ||
35 | diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h | ||
28 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
29 | --- a/hw/arm/xilinx_zynq.c | 37 | --- a/include/hw/qdev-properties-system.h |
30 | +++ b/hw/arm/xilinx_zynq.c | 38 | +++ b/include/hw/qdev-properties-system.h |
31 | @@ -XXX,XX +XXX,XX @@ static inline int zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq, | 39 | @@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_pcie_link_speed; |
32 | int num_ss = is_qspi ? NUM_QSPI_FLASHES : NUM_SPI_FLASHES; | 40 | extern const PropertyInfo qdev_prop_pcie_link_width; |
33 | 41 | extern const PropertyInfo qdev_prop_cpus390entitlement; | |
34 | dev = qdev_new(is_qspi ? "xlnx.ps7-qspi" : "xlnx.ps7-spi"); | 42 | extern const PropertyInfo qdev_prop_iothread_vq_mapping_list; |
35 | + qdev_prop_set_bit(dev, "little-endian", true); | 43 | +extern const PropertyInfo qdev_prop_endian_mode; |
36 | qdev_prop_set_uint8(dev, "num-txrx-bytes", is_qspi ? 4 : 1); | 44 | |
37 | qdev_prop_set_uint8(dev, "num-ss-bits", num_ss); | 45 | #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ |
38 | qdev_prop_set_uint8(dev, "num-busses", num_busses); | 46 | DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) |
39 | diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c | 47 | @@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_iothread_vq_mapping_list; |
48 | DEFINE_PROP(_name, _state, _field, qdev_prop_iothread_vq_mapping_list, \ | ||
49 | IOThreadVirtQueueMappingList *) | ||
50 | |||
51 | +#define DEFINE_PROP_ENDIAN(_name, _state, _field, _default) \ | ||
52 | + DEFINE_PROP_UNSIGNED(_name, _state, _field, _default, \ | ||
53 | + qdev_prop_endian_mode, EndianMode) | ||
54 | +#define DEFINE_PROP_ENDIAN_NODEFAULT(_name, _state, _field) \ | ||
55 | + DEFINE_PROP_ENDIAN(_name, _state, _field, ENDIAN_MODE_UNSPECIFIED) | ||
56 | + | ||
57 | #endif | ||
58 | diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c | ||
40 | index XXXXXXX..XXXXXXX 100644 | 59 | index XXXXXXX..XXXXXXX 100644 |
41 | --- a/hw/ssi/xilinx_spips.c | 60 | --- a/hw/core/qdev-properties-system.c |
42 | +++ b/hw/ssi/xilinx_spips.c | 61 | +++ b/hw/core/qdev-properties-system.c |
43 | @@ -XXX,XX +XXX,XX @@ static MemTxResult lqspi_write(void *opaque, hwaddr offset, uint64_t value, | 62 | @@ -XXX,XX +XXX,XX @@ const PropertyInfo qdev_prop_iothread_vq_mapping_list = { |
44 | return MEMTX_ERROR; | 63 | .set = set_iothread_vq_mapping_list, |
45 | } | 64 | .release = release_iothread_vq_mapping_list, |
46 | |||
47 | -static const MemoryRegionOps lqspi_ops = { | ||
48 | - .read_with_attrs = lqspi_read, | ||
49 | - .write_with_attrs = lqspi_write, | ||
50 | - .endianness = DEVICE_NATIVE_ENDIAN, | ||
51 | - .impl = { | ||
52 | - .min_access_size = 4, | ||
53 | - .max_access_size = 4, | ||
54 | +static const MemoryRegionOps lqspi_ops[2] = { | ||
55 | + { | ||
56 | + .read_with_attrs = lqspi_read, | ||
57 | + .write_with_attrs = lqspi_write, | ||
58 | + .endianness = DEVICE_BIG_ENDIAN, | ||
59 | + .impl = { | ||
60 | + .min_access_size = 4, | ||
61 | + .max_access_size = 4, | ||
62 | + }, | ||
63 | + .valid = { | ||
64 | + .min_access_size = 1, | ||
65 | + .max_access_size = 4 | ||
66 | + }, | ||
67 | }, | ||
68 | - .valid = { | ||
69 | - .min_access_size = 1, | ||
70 | - .max_access_size = 4 | ||
71 | + { | ||
72 | + .read_with_attrs = lqspi_read, | ||
73 | + .write_with_attrs = lqspi_write, | ||
74 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
75 | + .impl = { | ||
76 | + .min_access_size = 4, | ||
77 | + .max_access_size = 4, | ||
78 | + }, | ||
79 | + .valid = { | ||
80 | + .min_access_size = 1, | ||
81 | + .max_access_size = 4, | ||
82 | + }, | ||
83 | } | ||
84 | }; | 65 | }; |
85 | 66 | + | |
86 | @@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_realize(DeviceState *dev, Error **errp) | 67 | +/* --- Endian modes */ |
87 | s->num_txrx_bytes = 4; | 68 | + |
88 | 69 | +const PropertyInfo qdev_prop_endian_mode = { | |
89 | xilinx_spips_realize(dev, errp); | 70 | + .name = "EndianMode", |
90 | - memory_region_init_io(&s->mmlqspi, OBJECT(s), &lqspi_ops, s, "lqspi", | 71 | + .description = "Endian mode, big/little/unspecified", |
91 | - (1 << LQSPI_ADDRESS_BITS) * 2); | 72 | + .enum_table = &EndianMode_lookup, |
92 | + memory_region_init_io(&s->mmlqspi, OBJECT(s), | 73 | + .get = qdev_propinfo_get_enum, |
93 | + &lqspi_ops[s->little_endian_model], | 74 | + .set = qdev_propinfo_set_enum, |
94 | + s, "lqspi", (1 << LQSPI_ADDRESS_BITS) * 2); | 75 | + .set_default_value = qdev_propinfo_set_default_value_enum, |
95 | sysbus_init_mmio(sbd, &s->mmlqspi); | ||
96 | |||
97 | q->lqspi_cached_addr = ~0ULL; | ||
98 | @@ -XXX,XX +XXX,XX @@ static Property xilinx_spips_properties[] = { | ||
99 | DEFINE_PROP_END_OF_LIST(), | ||
100 | }; | ||
101 | |||
102 | +static Property xilinx_qspips_properties[] = { | ||
103 | + DEFINE_PROP_BOOL("little-endian", XilinxQSPIPS, little_endian_model, true), | ||
104 | + DEFINE_PROP_END_OF_LIST(), | ||
105 | +}; | 76 | +}; |
106 | + | ||
107 | static void xilinx_qspips_class_init(ObjectClass *klass, void * data) | ||
108 | { | ||
109 | DeviceClass *dc = DEVICE_CLASS(klass); | ||
110 | XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass); | ||
111 | |||
112 | dc->realize = xilinx_qspips_realize; | ||
113 | + device_class_set_props(dc, xilinx_qspips_properties); | ||
114 | xsc->reg_ops = &qspips_ops; | ||
115 | xsc->reg_size = XLNX_SPIPS_R_MAX * 4; | ||
116 | xsc->rx_fifo_size = RXFF_A_Q; | ||
117 | -- | 77 | -- |
118 | 2.45.2 | 78 | 2.47.1 |
119 | 79 | ||
120 | 80 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
4 | endianness, defaulting to little endian. | 4 | endianness, defaulting to little endian. |
5 | Set the proper endianness for each machine using the device. | 5 | Set the proper endianness for each machine using the device. |
6 | 6 | ||
7 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 7 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
8 | --- | 8 | --- |
9 | hw/intc/xilinx_intc.c | 61 +++++++++++++++++++----- | 9 | hw/intc/xilinx_intc.c | 60 ++++++++++++++++++------ |
10 | hw/microblaze/petalogix_ml605_mmu.c | 1 + | 10 | hw/microblaze/petalogix_ml605_mmu.c | 1 + |
11 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 + | 11 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 3 ++ |
12 | 3 files changed, 50 insertions(+), 13 deletions(-) | 12 | hw/ppc/virtex_ml507.c | 1 + |
13 | hw/riscv/microblaze-v-generic.c | 1 + | ||
14 | 5 files changed, 52 insertions(+), 14 deletions(-) | ||
13 | 15 | ||
14 | diff --git a/hw/intc/xilinx_intc.c b/hw/intc/xilinx_intc.c | 16 | diff --git a/hw/intc/xilinx_intc.c b/hw/intc/xilinx_intc.c |
15 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/hw/intc/xilinx_intc.c | 18 | --- a/hw/intc/xilinx_intc.c |
17 | +++ b/hw/intc/xilinx_intc.c | 19 | +++ b/hw/intc/xilinx_intc.c |
... | ... | ||
23 | + * DS572: LogiCORE IP XPS Interrupt Controller (v2.01a) | 25 | + * DS572: LogiCORE IP XPS Interrupt Controller (v2.01a) |
24 | + * | 26 | + * |
25 | * Permission is hereby granted, free of charge, to any person obtaining a copy | 27 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
26 | * of this software and associated documentation files (the "Software"), to deal | 28 | * of this software and associated documentation files (the "Software"), to deal |
27 | * in the Software without restriction, including without limitation the rights | 29 | * in the Software without restriction, including without limitation the rights |
30 | @@ -XXX,XX +XXX,XX @@ | ||
31 | */ | ||
32 | |||
33 | #include "qemu/osdep.h" | ||
34 | +#include "qapi/error.h" | ||
35 | #include "hw/sysbus.h" | ||
36 | #include "qemu/module.h" | ||
37 | #include "hw/irq.h" | ||
38 | #include "hw/qdev-properties.h" | ||
39 | +#include "hw/qdev-properties-system.h" | ||
40 | #include "qom/object.h" | ||
41 | |||
42 | #define D(x) | ||
28 | @@ -XXX,XX +XXX,XX @@ struct XpsIntc | 43 | @@ -XXX,XX +XXX,XX @@ struct XpsIntc |
29 | { | 44 | { |
30 | SysBusDevice parent_obj; | 45 | SysBusDevice parent_obj; |
31 | 46 | ||
32 | + bool little_endian_model; | 47 | + EndianMode model_endianness; |
33 | MemoryRegion mmio; | 48 | MemoryRegion mmio; |
34 | qemu_irq parent_irq; | 49 | qemu_irq parent_irq; |
35 | 50 | ||
36 | @@ -XXX,XX +XXX,XX @@ static void pic_write(void *opaque, hwaddr addr, | 51 | @@ -XXX,XX +XXX,XX @@ static void pic_write(void *opaque, hwaddr addr, |
37 | update_irq(p); | 52 | update_irq(p); |
... | ... | ||
43 | - .endianness = DEVICE_NATIVE_ENDIAN, | 58 | - .endianness = DEVICE_NATIVE_ENDIAN, |
44 | - .impl = { | 59 | - .impl = { |
45 | - .min_access_size = 4, | 60 | - .min_access_size = 4, |
46 | - .max_access_size = 4, | 61 | - .max_access_size = 4, |
47 | +static const MemoryRegionOps pic_ops[2] = { | 62 | +static const MemoryRegionOps pic_ops[2] = { |
48 | + { | 63 | + [0 ... 1] = { |
49 | + .read = pic_read, | 64 | + .read = pic_read, |
50 | + .write = pic_write, | 65 | + .write = pic_write, |
51 | + .endianness = DEVICE_BIG_ENDIAN, | 66 | + .endianness = DEVICE_BIG_ENDIAN, |
52 | + .impl = { | 67 | + .impl = { |
53 | + .min_access_size = 4, | 68 | + .min_access_size = 4, |
... | ... | ||
66 | + }, | 81 | + }, |
67 | }, | 82 | }, |
68 | - .valid = { | 83 | - .valid = { |
69 | - .min_access_size = 4, | 84 | - .min_access_size = 4, |
70 | - .max_access_size = 4 | 85 | - .max_access_size = 4 |
71 | + { | 86 | - } |
72 | + .read = pic_read, | 87 | + [ENDIAN_MODE_BIG].endianness = DEVICE_BIG_ENDIAN, |
73 | + .write = pic_write, | 88 | + [ENDIAN_MODE_LITTLE].endianness = DEVICE_LITTLE_ENDIAN, |
74 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
75 | + .impl = { | ||
76 | + .min_access_size = 4, | ||
77 | + .max_access_size = 4, | ||
78 | + }, | ||
79 | + .valid = { | ||
80 | + .min_access_size = 4, | ||
81 | + .max_access_size = 4, | ||
82 | + }, | ||
83 | } | ||
84 | }; | 89 | }; |
85 | 90 | ||
91 | static void irq_handler(void *opaque, int irq, int level) | ||
86 | @@ -XXX,XX +XXX,XX @@ static void xilinx_intc_init(Object *obj) | 92 | @@ -XXX,XX +XXX,XX @@ static void xilinx_intc_init(Object *obj) |
87 | 93 | ||
88 | qdev_init_gpio_in(DEVICE(obj), irq_handler, 32); | 94 | qdev_init_gpio_in(DEVICE(obj), irq_handler, 32); |
89 | sysbus_init_irq(SYS_BUS_DEVICE(obj), &p->parent_irq); | 95 | sysbus_init_irq(SYS_BUS_DEVICE(obj), &p->parent_irq); |
90 | - | 96 | - |
... | ... | ||
95 | 101 | ||
96 | +static void xilinx_intc_realize(DeviceState *dev, Error **errp) | 102 | +static void xilinx_intc_realize(DeviceState *dev, Error **errp) |
97 | +{ | 103 | +{ |
98 | + XpsIntc *p = XILINX_INTC(dev); | 104 | + XpsIntc *p = XILINX_INTC(dev); |
99 | + | 105 | + |
106 | + if (p->model_endianness == ENDIAN_MODE_UNSPECIFIED) { | ||
107 | + error_setg(errp, TYPE_XILINX_INTC " property 'endianness'" | ||
108 | + " must be set to 'big' or 'little'"); | ||
109 | + return; | ||
110 | + } | ||
111 | + | ||
100 | + memory_region_init_io(&p->mmio, OBJECT(dev), | 112 | + memory_region_init_io(&p->mmio, OBJECT(dev), |
101 | + &pic_ops[p->little_endian_model], | 113 | + &pic_ops[p->model_endianness], |
102 | + p, "xlnx.xps-intc", | 114 | + p, "xlnx.xps-intc", |
103 | + R_MAX * 4); | 115 | + R_MAX * 4); |
104 | +} | 116 | +} |
105 | + | 117 | + |
106 | static Property xilinx_intc_properties[] = { | 118 | static const Property xilinx_intc_properties[] = { |
107 | + DEFINE_PROP_BOOL("little-endian", XpsIntc, little_endian_model, true), | 119 | + DEFINE_PROP_ENDIAN_NODEFAULT("endianness", XpsIntc, model_endianness), |
108 | DEFINE_PROP_UINT32("kind-of-intr", XpsIntc, c_kind_of_intr, 0), | 120 | DEFINE_PROP_UINT32("kind-of-intr", XpsIntc, c_kind_of_intr, 0), |
109 | DEFINE_PROP_END_OF_LIST(), | ||
110 | }; | 121 | }; |
122 | |||
111 | @@ -XXX,XX +XXX,XX @@ static void xilinx_intc_class_init(ObjectClass *klass, void *data) | 123 | @@ -XXX,XX +XXX,XX @@ static void xilinx_intc_class_init(ObjectClass *klass, void *data) |
112 | { | 124 | { |
113 | DeviceClass *dc = DEVICE_CLASS(klass); | 125 | DeviceClass *dc = DEVICE_CLASS(klass); |
114 | 126 | ||
115 | + dc->realize = xilinx_intc_realize; | 127 | + dc->realize = xilinx_intc_realize; |
... | ... | ||
122 | +++ b/hw/microblaze/petalogix_ml605_mmu.c | 134 | +++ b/hw/microblaze/petalogix_ml605_mmu.c |
123 | @@ -XXX,XX +XXX,XX @@ petalogix_ml605_init(MachineState *machine) | 135 | @@ -XXX,XX +XXX,XX @@ petalogix_ml605_init(MachineState *machine) |
124 | 136 | ||
125 | 137 | ||
126 | dev = qdev_new("xlnx.xps-intc"); | 138 | dev = qdev_new("xlnx.xps-intc"); |
127 | + qdev_prop_set_bit(dev, "little-endian", true); | 139 | + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); |
128 | qdev_prop_set_uint32(dev, "kind-of-intr", 1 << TIMER_IRQ); | 140 | qdev_prop_set_uint32(dev, "kind-of-intr", 1 << TIMER_IRQ); |
129 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | 141 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); |
130 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR); | 142 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR); |
131 | diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c | 143 | diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c |
132 | index XXXXXXX..XXXXXXX 100644 | 144 | index XXXXXXX..XXXXXXX 100644 |
133 | --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c | 145 | --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c |
134 | +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c | 146 | +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c |
135 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | 147 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) |
148 | MemoryRegion *phys_ram = g_new(MemoryRegion, 1); | ||
149 | qemu_irq irq[32]; | ||
150 | MemoryRegion *sysmem = get_system_memory(); | ||
151 | + EndianMode endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG | ||
152 | + : ENDIAN_MODE_LITTLE; | ||
153 | |||
154 | cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU)); | ||
155 | object_property_set_str(OBJECT(cpu), "version", "7.10.d", &error_abort); | ||
156 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | ||
136 | 64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1); | 157 | 64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1); |
137 | 158 | ||
138 | dev = qdev_new("xlnx.xps-intc"); | 159 | dev = qdev_new("xlnx.xps-intc"); |
139 | + qdev_prop_set_bit(dev, "little-endian", !TARGET_BIG_ENDIAN); | 160 | + qdev_prop_set_enum(dev, "endianness", endianness); |
140 | qdev_prop_set_uint32(dev, "kind-of-intr", | 161 | qdev_prop_set_uint32(dev, "kind-of-intr", |
141 | 1 << ETHLITE_IRQ | 1 << UARTLITE_IRQ); | 162 | 1 << ETHLITE_IRQ | 1 << UARTLITE_IRQ); |
142 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | 163 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); |
164 | diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c | ||
165 | index XXXXXXX..XXXXXXX 100644 | ||
166 | --- a/hw/ppc/virtex_ml507.c | ||
167 | +++ b/hw/ppc/virtex_ml507.c | ||
168 | @@ -XXX,XX +XXX,XX @@ static void virtex_init(MachineState *machine) | ||
169 | |||
170 | cpu_irq = qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_INT); | ||
171 | dev = qdev_new("xlnx.xps-intc"); | ||
172 | + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_BIG); | ||
173 | qdev_prop_set_uint32(dev, "kind-of-intr", 0); | ||
174 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
175 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR); | ||
176 | diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c | ||
177 | index XXXXXXX..XXXXXXX 100644 | ||
178 | --- a/hw/riscv/microblaze-v-generic.c | ||
179 | +++ b/hw/riscv/microblaze-v-generic.c | ||
180 | @@ -XXX,XX +XXX,XX @@ static void mb_v_generic_init(MachineState *machine) | ||
181 | memory_region_add_subregion(sysmem, ddr_base, phys_ram); | ||
182 | |||
183 | dev = qdev_new("xlnx.xps-intc"); | ||
184 | + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); | ||
185 | qdev_prop_set_uint32(dev, "kind-of-intr", | ||
186 | 1 << UARTLITE_IRQ); | ||
187 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
143 | -- | 188 | -- |
144 | 2.45.2 | 189 | 2.47.1 |
145 | 190 | ||
146 | 191 | diff view generated by jsdifflib |
1 | The Xilinx 'ethlite' device was added in commit b43848a100 | 1 | Replace the DEVICE_NATIVE_ENDIAN MemoryRegionOps by a pair |
---|---|---|---|
2 | ("xilinx: Add ethlite emulation"), being only built back | 2 | of DEVICE_LITTLE_ENDIAN / DEVICE_BIG_ENDIAN. |
3 | then for a big-endian MicroBlaze target (see commit 72b675caac | 3 | Add the "little-endian" property to select the device |
4 | "microblaze: Hook into the build-system"). | 4 | endianness, defaulting to little endian. |
5 | 5 | Set the proper endianness on the single machine using the | |
6 | I/O endianness access was then clarified in commit d48751ed4f | 6 | device. |
7 | ("xilinx-ethlite: Simplify byteswapping to/from brams"). Here | ||
8 | the 'fix' was to use tswap32(). Since the machine was built as | ||
9 | big-endian target, tswap32() use means the fix was for a little | ||
10 | endian host. While the datasheet (reference added in file header) | ||
11 | is not precise about it, we interpret such change as the device | ||
12 | expects accesses in big-endian order. | ||
13 | |||
14 | Instead of having a double swapping, one in the core memory layer | ||
15 | due to DEVICE_NATIVE_ENDIAN and a second one with the tswap calls, | ||
16 | allow the machine code to select the proper endianness desired, | ||
17 | removing the need of tswap(). | ||
18 | |||
19 | Replace the DEVICE_NATIVE_ENDIAN MemoryRegionOps by a pair of | ||
20 | DEVICE_LITTLE_ENDIAN / DEVICE_BIG_ENDIAN. | ||
21 | Add the "little-endian" property to select the device endianness, | ||
22 | defaulting to little endian. | ||
23 | Set the proper endianness on the single machine using the device. | ||
24 | 7 | ||
25 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
26 | --- | 9 | --- |
27 | RFC until I digest Paolo's review from v1: | 10 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 + |
28 | https://lore.kernel.org/qemu-devel/34f6fe2f-06e0-4e2a-a361-2d662f6814b5@redhat.com/ | 11 | hw/net/xilinx_ethlite.c | 27 ++++++++++++++++++------ |
29 | --- | 12 | hw/riscv/microblaze-v-generic.c | 1 + |
30 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 2 + | 13 | 3 files changed, 23 insertions(+), 6 deletions(-) |
31 | hw/net/xilinx_ethlite.c | 54 +++++++++++++++++------- | ||
32 | 2 files changed, 40 insertions(+), 16 deletions(-) | ||
33 | 14 | ||
34 | diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c | 15 | diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c |
35 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
36 | --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c | 17 | --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c |
37 | +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c | 18 | +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c |
38 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | 19 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) |
39 | sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]); | 20 | sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]); |
40 | 21 | ||
41 | dev = qdev_new("xlnx.xps-ethernetlite"); | 22 | dev = qdev_new("xlnx.xps-ethernetlite"); |
42 | + qdev_prop_set_bit(dev, "little-endian", !TARGET_BIG_ENDIAN); | 23 | + qdev_prop_set_enum(dev, "endianness", endianness); |
43 | qemu_configure_nic_device(dev, true, NULL); | 24 | qemu_configure_nic_device(dev, true, NULL); |
44 | qdev_prop_set_uint32(dev, "tx-ping-pong", 0); | 25 | qdev_prop_set_uint32(dev, "tx-ping-pong", 0); |
45 | qdev_prop_set_uint32(dev, "rx-ping-pong", 0); | 26 | qdev_prop_set_uint32(dev, "rx-ping-pong", 0); |
46 | + qdev_prop_set_bit(dev, "little-endian-model", !TARGET_BIG_ENDIAN); | ||
47 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
48 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ETHLITE_BASEADDR); | ||
49 | sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[ETHLITE_IRQ]); | ||
50 | diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c | 27 | diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c |
51 | index XXXXXXX..XXXXXXX 100644 | 28 | index XXXXXXX..XXXXXXX 100644 |
52 | --- a/hw/net/xilinx_ethlite.c | 29 | --- a/hw/net/xilinx_ethlite.c |
53 | +++ b/hw/net/xilinx_ethlite.c | 30 | +++ b/hw/net/xilinx_ethlite.c |
54 | @@ -XXX,XX +XXX,XX @@ | 31 | @@ -XXX,XX +XXX,XX @@ |
55 | * | ||
56 | * Copyright (c) 2009 Edgar E. Iglesias. | ||
57 | * | ||
58 | + * DS580: https://docs.amd.com/v/u/en-US/xps_ethernetlite | ||
59 | + * LogiCORE IP XPS Ethernet Lite Media Access Controller | ||
60 | + * | ||
61 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
62 | * of this software and associated documentation files (the "Software"), to deal | ||
63 | * in the Software without restriction, including without limitation the rights | ||
64 | @@ -XXX,XX +XXX,XX @@ | ||
65 | #include "qemu/osdep.h" | ||
66 | #include "qemu/module.h" | ||
67 | #include "qom/object.h" | ||
68 | -#include "exec/tswap.h" | ||
69 | #include "hw/sysbus.h" | 32 | #include "hw/sysbus.h" |
70 | #include "hw/irq.h" | 33 | #include "hw/irq.h" |
71 | #include "hw/qdev-properties.h" | 34 | #include "hw/qdev-properties.h" |
72 | @@ -XXX,XX +XXX,XX @@ struct xlx_ethlite | 35 | +#include "hw/qdev-properties-system.h" |
36 | #include "hw/misc/unimp.h" | ||
37 | #include "net/net.h" | ||
38 | #include "trace.h" | ||
39 | @@ -XXX,XX +XXX,XX @@ struct XlnxXpsEthLite | ||
73 | { | 40 | { |
74 | SysBusDevice parent_obj; | 41 | SysBusDevice parent_obj; |
75 | 42 | ||
76 | + bool little_endian_model; | 43 | + EndianMode model_endianness; |
77 | MemoryRegion mmio; | 44 | MemoryRegion container; |
78 | qemu_irq irq; | 45 | qemu_irq irq; |
79 | NICState *nic; | 46 | NICState *nic; |
80 | @@ -XXX,XX +XXX,XX @@ eth_read(void *opaque, hwaddr addr, unsigned int size) | 47 | @@ -XXX,XX +XXX,XX @@ static void port_tx_write(void *opaque, hwaddr addr, uint64_t value, |
81 | break; | ||
82 | |||
83 | default: | ||
84 | - r = tswap32(s->regs[addr]); | ||
85 | + r = s->regs[addr]; | ||
86 | break; | ||
87 | } | ||
88 | + | ||
89 | return r; | ||
90 | } | ||
91 | |||
92 | @@ -XXX,XX +XXX,XX @@ eth_write(void *opaque, hwaddr addr, | ||
93 | break; | ||
94 | |||
95 | default: | ||
96 | - s->regs[addr] = tswap32(value); | ||
97 | + s->regs[addr] = value; | ||
98 | break; | ||
99 | } | 48 | } |
100 | } | 49 | } |
101 | 50 | ||
102 | -static const MemoryRegionOps eth_ops = { | 51 | -static const MemoryRegionOps eth_porttx_ops = { |
103 | - .read = eth_read, | 52 | +static const MemoryRegionOps eth_porttx_ops[2] = { |
104 | - .write = eth_write, | 53 | + [0 ... 1] = { |
105 | - .endianness = DEVICE_NATIVE_ENDIAN, | 54 | .read = port_tx_read, |
106 | - .impl = { | 55 | .write = port_tx_write, |
107 | - .min_access_size = 4, | 56 | - .endianness = DEVICE_NATIVE_ENDIAN, |
108 | - .max_access_size = 4, | 57 | .impl = { |
109 | +static const MemoryRegionOps eth_ops[2] = { | 58 | .min_access_size = 4, |
110 | + { | 59 | .max_access_size = 4, |
111 | + .read = eth_read, | 60 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps eth_porttx_ops = { |
112 | + .write = eth_write, | 61 | .min_access_size = 4, |
113 | + .endianness = DEVICE_BIG_ENDIAN, | 62 | .max_access_size = 4, |
114 | + .impl = { | 63 | }, |
115 | + .min_access_size = 4, | 64 | + }, |
116 | + .max_access_size = 4, | 65 | + [ENDIAN_MODE_BIG].endianness = DEVICE_BIG_ENDIAN, |
117 | + }, | 66 | + [ENDIAN_MODE_LITTLE].endianness = DEVICE_LITTLE_ENDIAN, |
118 | + .valid = { | 67 | }; |
119 | + .min_access_size = 4, | 68 | |
120 | + .max_access_size = 4, | 69 | static uint64_t port_rx_read(void *opaque, hwaddr addr, unsigned int size) |
121 | + }, | 70 | @@ -XXX,XX +XXX,XX @@ static void port_rx_write(void *opaque, hwaddr addr, uint64_t value, |
122 | }, | ||
123 | - .valid = { | ||
124 | - .min_access_size = 4, | ||
125 | - .max_access_size = 4 | ||
126 | + { | ||
127 | + .read = eth_read, | ||
128 | + .write = eth_write, | ||
129 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
130 | + .impl = { | ||
131 | + .min_access_size = 4, | ||
132 | + .max_access_size = 4, | ||
133 | + }, | ||
134 | + .valid = { | ||
135 | + .min_access_size = 4, | ||
136 | + .max_access_size = 4, | ||
137 | + }, | ||
138 | } | 71 | } |
72 | } | ||
73 | |||
74 | -static const MemoryRegionOps eth_portrx_ops = { | ||
75 | +static const MemoryRegionOps eth_portrx_ops[2] = { | ||
76 | + [0 ... 1] = { | ||
77 | .read = port_rx_read, | ||
78 | .write = port_rx_write, | ||
79 | - .endianness = DEVICE_NATIVE_ENDIAN, | ||
80 | .impl = { | ||
81 | .min_access_size = 4, | ||
82 | .max_access_size = 4, | ||
83 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps eth_portrx_ops = { | ||
84 | .min_access_size = 4, | ||
85 | .max_access_size = 4, | ||
86 | }, | ||
87 | + }, | ||
88 | + [ENDIAN_MODE_BIG].endianness = DEVICE_BIG_ENDIAN, | ||
89 | + [ENDIAN_MODE_LITTLE].endianness = DEVICE_LITTLE_ENDIAN, | ||
139 | }; | 90 | }; |
140 | 91 | ||
92 | static bool eth_can_rx(NetClientState *nc) | ||
141 | @@ -XXX,XX +XXX,XX @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) | 93 | @@ -XXX,XX +XXX,XX @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) |
142 | { | 94 | { |
143 | struct xlx_ethlite *s = XILINX_ETHLITE(dev); | 95 | XlnxXpsEthLite *s = XILINX_ETHLITE(dev); |
144 | 96 | ||
145 | + memory_region_init_io(&s->mmio, OBJECT(dev), | 97 | + if (s->model_endianness == ENDIAN_MODE_UNSPECIFIED) { |
146 | + ð_ops[s->little_endian_model], s, | 98 | + error_setg(errp, TYPE_XILINX_ETHLITE " property 'endianness'" |
147 | + "xlnx.xps-ethernetlite", R_MAX * 4); | 99 | + " must be set to 'big' or 'little'"); |
100 | + return; | ||
101 | + } | ||
148 | + | 102 | + |
149 | qemu_macaddr_default_if_unset(&s->conf.macaddr); | 103 | memory_region_init(&s->container, OBJECT(dev), |
150 | s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf, | 104 | "xlnx.xps-ethernetlite", 0x2000); |
151 | object_get_typename(OBJECT(dev)), dev->id, | 105 | |
106 | @@ -XXX,XX +XXX,XX @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) | ||
107 | BUFSZ_MAX, &error_abort); | ||
108 | memory_region_add_subregion(&s->container, 0x0800 * i, &s->port[i].txbuf); | ||
109 | memory_region_init_io(&s->port[i].txio, OBJECT(dev), | ||
110 | - ð_porttx_ops, s, | ||
111 | + ð_porttx_ops[s->model_endianness], s, | ||
112 | i ? "ethlite.tx[1]io" : "ethlite.tx[0]io", | ||
113 | 4 * TX_MAX); | ||
114 | memory_region_add_subregion(&s->container, i ? A_TX_BASE1 : A_TX_BASE0, | ||
115 | @@ -XXX,XX +XXX,XX @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) | ||
116 | memory_region_add_subregion(&s->container, 0x1000 + 0x0800 * i, | ||
117 | &s->port[i].rxbuf); | ||
118 | memory_region_init_io(&s->port[i].rxio, OBJECT(dev), | ||
119 | - ð_portrx_ops, s, | ||
120 | + ð_portrx_ops[s->model_endianness], s, | ||
121 | i ? "ethlite.rx[1]io" : "ethlite.rx[0]io", | ||
122 | 4 * RX_MAX); | ||
123 | memory_region_add_subregion(&s->container, i ? A_RX_BASE1 : A_RX_BASE0, | ||
152 | @@ -XXX,XX +XXX,XX @@ static void xilinx_ethlite_init(Object *obj) | 124 | @@ -XXX,XX +XXX,XX @@ static void xilinx_ethlite_init(Object *obj) |
153 | struct xlx_ethlite *s = XILINX_ETHLITE(obj); | ||
154 | |||
155 | sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); | ||
156 | - | ||
157 | - memory_region_init_io(&s->mmio, obj, ð_ops, s, | ||
158 | - "xlnx.xps-ethernetlite", R_MAX * 4); | ||
159 | sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); | ||
160 | } | 125 | } |
161 | 126 | ||
162 | static Property xilinx_ethlite_properties[] = { | 127 | static const Property xilinx_ethlite_properties[] = { |
163 | + DEFINE_PROP_BOOL("little-endian", struct xlx_ethlite, | 128 | + DEFINE_PROP_ENDIAN_NODEFAULT("endianness", XlnxXpsEthLite, model_endianness), |
164 | + little_endian_model, true), | 129 | DEFINE_PROP_UINT32("tx-ping-pong", XlnxXpsEthLite, c_tx_pingpong, 1), |
165 | DEFINE_PROP_UINT32("tx-ping-pong", struct xlx_ethlite, c_tx_pingpong, 1), | 130 | DEFINE_PROP_UINT32("rx-ping-pong", XlnxXpsEthLite, c_rx_pingpong, 1), |
166 | DEFINE_PROP_UINT32("rx-ping-pong", struct xlx_ethlite, c_rx_pingpong, 1), | 131 | DEFINE_NIC_PROPERTIES(XlnxXpsEthLite, conf), |
167 | DEFINE_NIC_PROPERTIES(struct xlx_ethlite, conf), | 132 | diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c |
133 | index XXXXXXX..XXXXXXX 100644 | ||
134 | --- a/hw/riscv/microblaze-v-generic.c | ||
135 | +++ b/hw/riscv/microblaze-v-generic.c | ||
136 | @@ -XXX,XX +XXX,XX @@ static void mb_v_generic_init(MachineState *machine) | ||
137 | |||
138 | /* Emaclite */ | ||
139 | dev = qdev_new("xlnx.xps-ethernetlite"); | ||
140 | + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); | ||
141 | qemu_configure_nic_device(dev, true, NULL); | ||
142 | qdev_prop_set_uint32(dev, "tx-ping-pong", 0); | ||
143 | qdev_prop_set_uint32(dev, "rx-ping-pong", 0); | ||
168 | -- | 144 | -- |
169 | 2.45.2 | 145 | 2.47.1 |
146 | |||
147 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Allow down to 8-bit access, per the datasheet (reference added | ||
2 | in previous commit): | ||
3 | 1 | ||
4 | "Timer Counter registers are accessed as one of the following types: | ||
5 | • Byte (8 bits) | ||
6 | • Half word (2 bytes) | ||
7 | • Word (4 bytes)" | ||
8 | |||
9 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
10 | Reviewed-by: Anton Johansson <anjo@rev.ng> | ||
11 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> | ||
13 | --- | ||
14 | RFC: This breaks the UART qtest, instead of having TX register | ||
15 | receiving 'T' = 0x54, it receives 0x54000000, converted to '\0' | ||
16 | char. It works if we use SWI instead of SBI (storing 32-bit). | ||
17 | --- | ||
18 | hw/timer/xilinx_timer.c | 2 +- | ||
19 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
20 | |||
21 | diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/hw/timer/xilinx_timer.c | ||
24 | +++ b/hw/timer/xilinx_timer.c | ||
25 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps timer_ops = { | ||
26 | .max_access_size = 4, | ||
27 | }, | ||
28 | .valid = { | ||
29 | - .min_access_size = 4, | ||
30 | + .min_access_size = 1, | ||
31 | .max_access_size = 4 | ||
32 | } | ||
33 | }; | ||
34 | -- | ||
35 | 2.45.2 | ||
36 | |||
37 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
7 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 7 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
8 | --- | 8 | --- |
9 | hw/microblaze/petalogix_ml605_mmu.c | 1 + | 9 | hw/microblaze/petalogix_ml605_mmu.c | 1 + |
10 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 + | 10 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 + |
11 | hw/ppc/virtex_ml507.c | 1 + | 11 | hw/ppc/virtex_ml507.c | 1 + |
12 | hw/timer/xilinx_timer.c | 46 +++++++++++++++++------- | 12 | hw/riscv/microblaze-v-generic.c | 2 ++ |
13 | 4 files changed, 36 insertions(+), 13 deletions(-) | 13 | hw/timer/xilinx_timer.c | 43 +++++++++++++++++------- |
14 | 5 files changed, 35 insertions(+), 13 deletions(-) | ||
14 | 15 | ||
15 | diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c | 16 | diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c |
16 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/hw/microblaze/petalogix_ml605_mmu.c | 18 | --- a/hw/microblaze/petalogix_ml605_mmu.c |
18 | +++ b/hw/microblaze/petalogix_ml605_mmu.c | 19 | +++ b/hw/microblaze/petalogix_ml605_mmu.c |
19 | @@ -XXX,XX +XXX,XX @@ petalogix_ml605_init(MachineState *machine) | 20 | @@ -XXX,XX +XXX,XX @@ petalogix_ml605_init(MachineState *machine) |
20 | 21 | ||
21 | /* 2 timers at irq 2 @ 100 Mhz. */ | 22 | /* 2 timers at irq 2 @ 100 Mhz. */ |
22 | dev = qdev_new("xlnx.xps-timer"); | 23 | dev = qdev_new("xlnx.xps-timer"); |
23 | + qdev_prop_set_bit(dev, "little-endian", true); | 24 | + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); |
24 | qdev_prop_set_uint32(dev, "one-timer-only", 0); | 25 | qdev_prop_set_uint32(dev, "one-timer-only", 0); |
25 | qdev_prop_set_uint32(dev, "clock-frequency", 100 * 1000000); | 26 | qdev_prop_set_uint32(dev, "clock-frequency", 100 * 1000000); |
26 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | 27 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); |
27 | diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c | 28 | diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c |
28 | index XXXXXXX..XXXXXXX 100644 | 29 | index XXXXXXX..XXXXXXX 100644 |
29 | --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c | 30 | --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c |
30 | +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c | 31 | +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c |
31 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | 32 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) |
32 | 33 | ||
33 | /* 2 timers at irq 2 @ 62 Mhz. */ | 34 | /* 2 timers at irq 2 @ 62 Mhz. */ |
34 | dev = qdev_new("xlnx.xps-timer"); | 35 | dev = qdev_new("xlnx.xps-timer"); |
35 | + qdev_prop_set_bit(dev, "little-endian", !TARGET_BIG_ENDIAN); | 36 | + qdev_prop_set_enum(dev, "endianness", endianness); |
36 | qdev_prop_set_uint32(dev, "one-timer-only", 0); | 37 | qdev_prop_set_uint32(dev, "one-timer-only", 0); |
37 | qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000); | 38 | qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000); |
38 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | 39 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); |
39 | diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c | 40 | diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c |
40 | index XXXXXXX..XXXXXXX 100644 | 41 | index XXXXXXX..XXXXXXX 100644 |
41 | --- a/hw/ppc/virtex_ml507.c | 42 | --- a/hw/ppc/virtex_ml507.c |
42 | +++ b/hw/ppc/virtex_ml507.c | 43 | +++ b/hw/ppc/virtex_ml507.c |
43 | @@ -XXX,XX +XXX,XX @@ static void virtex_init(MachineState *machine) | 44 | @@ -XXX,XX +XXX,XX @@ static void virtex_init(MachineState *machine) |
44 | 45 | ||
45 | /* 2 timers at irq 2 @ 62 Mhz. */ | 46 | /* 2 timers at irq 2 @ 62 Mhz. */ |
46 | dev = qdev_new("xlnx.xps-timer"); | 47 | dev = qdev_new("xlnx.xps-timer"); |
47 | + qdev_prop_set_bit(dev, "little-endian", false); | 48 | + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_BIG); |
48 | qdev_prop_set_uint32(dev, "one-timer-only", 0); | 49 | qdev_prop_set_uint32(dev, "one-timer-only", 0); |
49 | qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000); | 50 | qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000); |
51 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
52 | diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c | ||
53 | index XXXXXXX..XXXXXXX 100644 | ||
54 | --- a/hw/riscv/microblaze-v-generic.c | ||
55 | +++ b/hw/riscv/microblaze-v-generic.c | ||
56 | @@ -XXX,XX +XXX,XX @@ static void mb_v_generic_init(MachineState *machine) | ||
57 | |||
58 | /* 2 timers at irq 0 @ 100 Mhz. */ | ||
59 | dev = qdev_new("xlnx.xps-timer"); | ||
60 | + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); | ||
61 | qdev_prop_set_uint32(dev, "one-timer-only", 0); | ||
62 | qdev_prop_set_uint32(dev, "clock-frequency", 100000000); | ||
63 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
64 | @@ -XXX,XX +XXX,XX @@ static void mb_v_generic_init(MachineState *machine) | ||
65 | |||
66 | /* 2 timers at irq 3 @ 100 Mhz. */ | ||
67 | dev = qdev_new("xlnx.xps-timer"); | ||
68 | + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); | ||
69 | qdev_prop_set_uint32(dev, "one-timer-only", 0); | ||
70 | qdev_prop_set_uint32(dev, "clock-frequency", 100000000); | ||
50 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | 71 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); |
51 | diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c | 72 | diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c |
52 | index XXXXXXX..XXXXXXX 100644 | 73 | index XXXXXXX..XXXXXXX 100644 |
53 | --- a/hw/timer/xilinx_timer.c | 74 | --- a/hw/timer/xilinx_timer.c |
54 | +++ b/hw/timer/xilinx_timer.c | 75 | +++ b/hw/timer/xilinx_timer.c |
... | ... | ||
60 | + * LogiCORE IP XPS Timer/Counter (v1.02a) | 81 | + * LogiCORE IP XPS Timer/Counter (v1.02a) |
61 | + * | 82 | + * |
62 | * Permission is hereby granted, free of charge, to any person obtaining a copy | 83 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
63 | * of this software and associated documentation files (the "Software"), to deal | 84 | * of this software and associated documentation files (the "Software"), to deal |
64 | * in the Software without restriction, including without limitation the rights | 85 | * in the Software without restriction, including without limitation the rights |
86 | @@ -XXX,XX +XXX,XX @@ | ||
87 | */ | ||
88 | |||
89 | #include "qemu/osdep.h" | ||
90 | +#include "qapi/error.h" | ||
91 | #include "hw/sysbus.h" | ||
92 | #include "hw/irq.h" | ||
93 | #include "hw/ptimer.h" | ||
94 | #include "hw/qdev-properties.h" | ||
95 | +#include "hw/qdev-properties-system.h" | ||
96 | #include "qemu/log.h" | ||
97 | #include "qemu/module.h" | ||
98 | #include "qom/object.h" | ||
65 | @@ -XXX,XX +XXX,XX @@ struct XpsTimerState | 99 | @@ -XXX,XX +XXX,XX @@ struct XpsTimerState |
66 | { | 100 | { |
67 | SysBusDevice parent_obj; | 101 | SysBusDevice parent_obj; |
68 | 102 | ||
69 | + bool little_endian_model; | 103 | + EndianMode model_endianness; |
70 | MemoryRegion mmio; | 104 | MemoryRegion mmio; |
71 | qemu_irq irq; | 105 | qemu_irq irq; |
72 | uint8_t one_timer_only; | 106 | uint8_t one_timer_only; |
73 | @@ -XXX,XX +XXX,XX @@ timer_write(void *opaque, hwaddr addr, | 107 | @@ -XXX,XX +XXX,XX @@ timer_write(void *opaque, hwaddr addr, |
74 | timer_update_irq(t); | 108 | timer_update_irq(t); |
... | ... | ||
79 | - .write = timer_write, | 113 | - .write = timer_write, |
80 | - .endianness = DEVICE_NATIVE_ENDIAN, | 114 | - .endianness = DEVICE_NATIVE_ENDIAN, |
81 | - .impl = { | 115 | - .impl = { |
82 | - .min_access_size = 4, | 116 | - .min_access_size = 4, |
83 | - .max_access_size = 4, | 117 | - .max_access_size = 4, |
84 | - }, | ||
85 | - .valid = { | ||
86 | - .min_access_size = 1, | ||
87 | - .max_access_size = 4 | ||
88 | +static const MemoryRegionOps timer_ops[2] = { | 118 | +static const MemoryRegionOps timer_ops[2] = { |
89 | + { | 119 | + [0 ... 1] = { |
90 | + .read = timer_read, | 120 | + .read = timer_read, |
91 | + .write = timer_write, | 121 | + .write = timer_write, |
92 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
93 | + .impl = { | 122 | + .impl = { |
94 | + .min_access_size = 4, | 123 | + .min_access_size = 4, |
95 | + .max_access_size = 4, | 124 | + .max_access_size = 4, |
96 | + }, | 125 | + }, |
97 | + .valid = { | 126 | + .valid = { |
98 | + .min_access_size = 1, | ||
99 | + .max_access_size = 4, | ||
100 | + }, | ||
101 | + }, { | ||
102 | + .read = timer_read, | ||
103 | + .write = timer_write, | ||
104 | + .endianness = DEVICE_BIG_ENDIAN, | ||
105 | + .impl = { | ||
106 | + .min_access_size = 4, | 127 | + .min_access_size = 4, |
107 | + .max_access_size = 4, | 128 | + .max_access_size = 4, |
108 | + }, | 129 | + }, |
109 | + .valid = { | 130 | }, |
110 | + .min_access_size = 1, | 131 | - .valid = { |
111 | + .max_access_size = 4, | 132 | - .min_access_size = 4, |
112 | + }, | 133 | - .max_access_size = 4 |
113 | } | 134 | - } |
135 | + [ENDIAN_MODE_BIG].endianness = DEVICE_BIG_ENDIAN, | ||
136 | + [ENDIAN_MODE_LITTLE].endianness = DEVICE_LITTLE_ENDIAN, | ||
114 | }; | 137 | }; |
115 | 138 | ||
139 | static void timer_hit(void *opaque) | ||
140 | @@ -XXX,XX +XXX,XX @@ static void xilinx_timer_realize(DeviceState *dev, Error **errp) | ||
141 | XpsTimerState *t = XILINX_TIMER(dev); | ||
142 | unsigned int i; | ||
143 | |||
144 | + if (t->model_endianness == ENDIAN_MODE_UNSPECIFIED) { | ||
145 | + error_setg(errp, TYPE_XILINX_TIMER " property 'endianness'" | ||
146 | + " must be set to 'big' or 'little'"); | ||
147 | + return; | ||
148 | + } | ||
149 | + | ||
150 | /* Init all the ptimers. */ | ||
151 | t->timers = g_malloc0(sizeof t->timers[0] * num_timers(t)); | ||
152 | for (i = 0; i < num_timers(t); i++) { | ||
116 | @@ -XXX,XX +XXX,XX @@ static void xilinx_timer_realize(DeviceState *dev, Error **errp) | 153 | @@ -XXX,XX +XXX,XX @@ static void xilinx_timer_realize(DeviceState *dev, Error **errp) |
117 | ptimer_transaction_commit(xt->ptimer); | 154 | ptimer_transaction_commit(xt->ptimer); |
118 | } | 155 | } |
119 | 156 | ||
120 | - memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, "xlnx.xps-timer", | 157 | - memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, "xlnx.xps-timer", |
121 | - R_MAX * 4 * num_timers(t)); | 158 | - R_MAX * 4 * num_timers(t)); |
122 | + memory_region_init_io(&t->mmio, OBJECT(t), | 159 | + memory_region_init_io(&t->mmio, OBJECT(t), |
123 | + &timer_ops[t->little_endian_model], t, | 160 | + &timer_ops[t->model_endianness], t, |
124 | + "xlnx.xps-timer", R_MAX * 4 * num_timers(t)); | 161 | + "xlnx.xps-timer", R_MAX * 4 * num_timers(t)); |
125 | sysbus_init_mmio(SYS_BUS_DEVICE(dev), &t->mmio); | 162 | sysbus_init_mmio(SYS_BUS_DEVICE(dev), &t->mmio); |
126 | } | 163 | } |
127 | 164 | ||
128 | @@ -XXX,XX +XXX,XX @@ static void xilinx_timer_init(Object *obj) | 165 | @@ -XXX,XX +XXX,XX @@ static void xilinx_timer_init(Object *obj) |
129 | } | 166 | } |
130 | 167 | ||
131 | static Property xilinx_timer_properties[] = { | 168 | static const Property xilinx_timer_properties[] = { |
132 | + DEFINE_PROP_BOOL("little-endian", XpsTimerState, little_endian_model, true), | 169 | + DEFINE_PROP_ENDIAN_NODEFAULT("endianness", XpsTimerState, model_endianness), |
133 | DEFINE_PROP_UINT32("clock-frequency", XpsTimerState, freq_hz, 62 * 1000000), | 170 | DEFINE_PROP_UINT32("clock-frequency", XpsTimerState, freq_hz, 62 * 1000000), |
134 | DEFINE_PROP_UINT8("one-timer-only", XpsTimerState, one_timer_only, 0), | 171 | DEFINE_PROP_UINT8("one-timer-only", XpsTimerState, one_timer_only, 0), |
135 | DEFINE_PROP_END_OF_LIST(), | 172 | }; |
136 | -- | 173 | -- |
137 | 2.45.2 | 174 | 2.47.1 |
138 | 175 | ||
139 | 176 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
5 | Set the proper endianness on the single machine using the | 5 | Set the proper endianness on the single machine using the |
6 | device. | 6 | device. |
7 | 7 | ||
8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
9 | --- | 9 | --- |
10 | hw/char/xilinx_uartlite.c | 44 ++++++++++++++++-------- | 10 | hw/char/xilinx_uartlite.c | 34 ++++++++++++++++-------- |
11 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 + | 11 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 + |
12 | 2 files changed, 31 insertions(+), 14 deletions(-) | 12 | hw/riscv/microblaze-v-generic.c | 1 + |
13 | 3 files changed, 25 insertions(+), 11 deletions(-) | ||
13 | 14 | ||
14 | diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c | 15 | diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c |
15 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/hw/char/xilinx_uartlite.c | 17 | --- a/hw/char/xilinx_uartlite.c |
17 | +++ b/hw/char/xilinx_uartlite.c | 18 | +++ b/hw/char/xilinx_uartlite.c |
18 | @@ -XXX,XX +XXX,XX @@ | 19 | @@ -XXX,XX +XXX,XX @@ |
20 | |||
21 | #include "qemu/osdep.h" | ||
22 | #include "qemu/log.h" | ||
23 | +#include "qapi/error.h" | ||
24 | #include "hw/char/xilinx_uartlite.h" | ||
25 | #include "hw/irq.h" | ||
26 | #include "hw/qdev-properties.h" | ||
27 | @@ -XXX,XX +XXX,XX @@ | ||
19 | struct XilinxUARTLite { | 28 | struct XilinxUARTLite { |
20 | SysBusDevice parent_obj; | 29 | SysBusDevice parent_obj; |
21 | 30 | ||
22 | + bool little_endian_model; | 31 | + EndianMode model_endianness; |
23 | MemoryRegion mmio; | 32 | MemoryRegion mmio; |
24 | CharBackend chr; | 33 | CharBackend chr; |
25 | qemu_irq irq; | 34 | qemu_irq irq; |
26 | @@ -XXX,XX +XXX,XX @@ uart_write(void *opaque, hwaddr addr, | 35 | @@ -XXX,XX +XXX,XX @@ uart_write(void *opaque, hwaddr addr, |
27 | uart_update_irq(s); | 36 | uart_update_irq(s); |
28 | } | 37 | } |
29 | 38 | ||
30 | -static const MemoryRegionOps uart_ops = { | 39 | -static const MemoryRegionOps uart_ops = { |
31 | - .read = uart_read, | 40 | - .read = uart_read, |
32 | - .write = uart_write, | 41 | - .write = uart_write, |
33 | - .endianness = DEVICE_NATIVE_ENDIAN, | 42 | - .endianness = DEVICE_NATIVE_ENDIAN, |
34 | - .impl = { | ||
35 | - .min_access_size = 4, | ||
36 | - .max_access_size = 4, | ||
37 | - }, | ||
38 | - .valid = { | 43 | - .valid = { |
39 | - .min_access_size = 1, | 44 | - .min_access_size = 1, |
40 | - .max_access_size = 4 | 45 | - .max_access_size = 4 |
46 | - } | ||
41 | +static const MemoryRegionOps uart_ops[2] = { | 47 | +static const MemoryRegionOps uart_ops[2] = { |
42 | + { | 48 | + [0 ... 1] = { |
43 | + .read = uart_read, | 49 | + .read = uart_read, |
44 | + .write = uart_write, | 50 | + .write = uart_write, |
45 | + .endianness = DEVICE_BIG_ENDIAN, | ||
46 | + .impl = { | ||
47 | + .min_access_size = 4, | ||
48 | + .max_access_size = 4, | ||
49 | + }, | ||
50 | + .valid = { | 51 | + .valid = { |
51 | + .min_access_size = 1, | 52 | + .min_access_size = 1, |
52 | + .max_access_size = 4, | 53 | + .max_access_size = 4, |
53 | + }, | 54 | + }, |
54 | + }, { | 55 | + }, |
55 | + .read = uart_read, | 56 | + [ENDIAN_MODE_BIG].endianness = DEVICE_BIG_ENDIAN, |
56 | + .write = uart_write, | 57 | + [ENDIAN_MODE_LITTLE].endianness = DEVICE_LITTLE_ENDIAN, |
57 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
58 | + .impl = { | ||
59 | + .min_access_size = 4, | ||
60 | + .max_access_size = 4, | ||
61 | + }, | ||
62 | + .valid = { | ||
63 | + .min_access_size = 1, | ||
64 | + .max_access_size = 4, | ||
65 | + }, | ||
66 | } | ||
67 | }; | 58 | }; |
68 | 59 | ||
69 | static Property xilinx_uartlite_properties[] = { | 60 | static const Property xilinx_uartlite_properties[] = { |
70 | + DEFINE_PROP_BOOL("little-endian", XilinxUARTLite, little_endian_model, true), | 61 | + DEFINE_PROP_ENDIAN_NODEFAULT("endianness", XilinxUARTLite, model_endianness), |
71 | DEFINE_PROP_CHR("chardev", XilinxUARTLite, chr), | 62 | DEFINE_PROP_CHR("chardev", XilinxUARTLite, chr), |
72 | DEFINE_PROP_END_OF_LIST(), | ||
73 | }; | 63 | }; |
64 | |||
74 | @@ -XXX,XX +XXX,XX @@ static void xilinx_uartlite_realize(DeviceState *dev, Error **errp) | 65 | @@ -XXX,XX +XXX,XX @@ static void xilinx_uartlite_realize(DeviceState *dev, Error **errp) |
75 | { | 66 | { |
76 | XilinxUARTLite *s = XILINX_UARTLITE(dev); | 67 | XilinxUARTLite *s = XILINX_UARTLITE(dev); |
77 | 68 | ||
69 | + if (s->model_endianness == ENDIAN_MODE_UNSPECIFIED) { | ||
70 | + error_setg(errp, TYPE_XILINX_UARTLITE " property 'endianness'" | ||
71 | + " must be set to 'big' or 'little'"); | ||
72 | + return; | ||
73 | + } | ||
74 | + | ||
78 | + memory_region_init_io(&s->mmio, OBJECT(dev), | 75 | + memory_region_init_io(&s->mmio, OBJECT(dev), |
79 | + &uart_ops[s->little_endian_model], | 76 | + &uart_ops[s->model_endianness], |
80 | + s, "xlnx.xps-uartlite", R_MAX * 4); | 77 | + s, "xlnx.xps-uartlite", R_MAX * 4); |
81 | qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, | 78 | qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, |
82 | uart_event, NULL, s, NULL, true); | 79 | uart_event, NULL, s, NULL, true); |
83 | } | 80 | } |
84 | @@ -XXX,XX +XXX,XX @@ static void xilinx_uartlite_init(Object *obj) | 81 | @@ -XXX,XX +XXX,XX @@ static void xilinx_uartlite_init(Object *obj) |
... | ... | ||
97 | +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c | 94 | +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c |
98 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | 95 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) |
99 | } | 96 | } |
100 | 97 | ||
101 | dev = qdev_new(TYPE_XILINX_UARTLITE); | 98 | dev = qdev_new(TYPE_XILINX_UARTLITE); |
102 | + qdev_prop_set_bit(dev, "little-endian", !TARGET_BIG_ENDIAN); | 99 | + qdev_prop_set_enum(dev, "endianness", endianness); |
100 | qdev_prop_set_chr(dev, "chardev", serial_hd(0)); | ||
101 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
102 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR); | ||
103 | diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c | ||
104 | index XXXXXXX..XXXXXXX 100644 | ||
105 | --- a/hw/riscv/microblaze-v-generic.c | ||
106 | +++ b/hw/riscv/microblaze-v-generic.c | ||
107 | @@ -XXX,XX +XXX,XX @@ static void mb_v_generic_init(MachineState *machine) | ||
108 | |||
109 | /* Uartlite */ | ||
110 | dev = qdev_new(TYPE_XILINX_UARTLITE); | ||
111 | + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); | ||
103 | qdev_prop_set_chr(dev, "chardev", serial_hd(0)); | 112 | qdev_prop_set_chr(dev, "chardev", serial_hd(0)); |
104 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | 113 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); |
105 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR); | 114 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR); |
106 | -- | 115 | -- |
107 | 2.45.2 | 116 | 2.47.1 |
108 | 117 | ||
109 | 118 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
5 | Set the proper endianness on the single machine using the | 5 | Set the proper endianness on the single machine using the |
6 | device. | 6 | device. |
7 | 7 | ||
8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
9 | --- | 9 | --- |
10 | hw/arm/xlnx-zynqmp.c | 4 ++++ | 10 | hw/microblaze/petalogix_ml605_mmu.c | 1 + |
11 | hw/ssi/xilinx_spi.c | 29 +++++++++++++++++++++-------- | 11 | hw/ssi/xilinx_spi.c | 32 +++++++++++++++++++++-------- |
12 | 2 files changed, 25 insertions(+), 8 deletions(-) | 12 | 2 files changed, 24 insertions(+), 9 deletions(-) |
13 | 13 | ||
14 | diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c | 14 | diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c |
15 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/hw/arm/xlnx-zynqmp.c | 16 | --- a/hw/microblaze/petalogix_ml605_mmu.c |
17 | +++ b/hw/arm/xlnx-zynqmp.c | 17 | +++ b/hw/microblaze/petalogix_ml605_mmu.c |
18 | @@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) | 18 | @@ -XXX,XX +XXX,XX @@ petalogix_ml605_init(MachineState *machine) |
19 | for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) { | 19 | SSIBus *spi; |
20 | gchar *bus_name; | 20 | |
21 | 21 | dev = qdev_new("xlnx.xps-spi"); | |
22 | + if (!object_property_set_bool(OBJECT(&s->spi[i])), "little-endian", | 22 | + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); |
23 | + true, errp)) { | 23 | qdev_prop_set_uint8(dev, "num-ss-bits", NUM_SPI_FLASHES); |
24 | + return; | 24 | busdev = SYS_BUS_DEVICE(dev); |
25 | + } | 25 | sysbus_realize_and_unref(busdev, &error_fatal); |
26 | if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) { | ||
27 | return; | ||
28 | } | ||
29 | diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c | 26 | diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c |
30 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
31 | --- a/hw/ssi/xilinx_spi.c | 28 | --- a/hw/ssi/xilinx_spi.c |
32 | +++ b/hw/ssi/xilinx_spi.c | 29 | +++ b/hw/ssi/xilinx_spi.c |
30 | @@ -XXX,XX +XXX,XX @@ | ||
31 | */ | ||
32 | |||
33 | #include "qemu/osdep.h" | ||
34 | +#include "qapi/error.h" | ||
35 | #include "hw/sysbus.h" | ||
36 | #include "migration/vmstate.h" | ||
37 | #include "qemu/module.h" | ||
38 | @@ -XXX,XX +XXX,XX @@ | ||
39 | |||
40 | #include "hw/irq.h" | ||
41 | #include "hw/qdev-properties.h" | ||
42 | +#include "hw/qdev-properties-system.h" | ||
43 | #include "hw/ssi/ssi.h" | ||
44 | #include "qom/object.h" | ||
45 | |||
33 | @@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XilinxSPI, XILINX_SPI) | 46 | @@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XilinxSPI, XILINX_SPI) |
34 | struct XilinxSPI { | 47 | struct XilinxSPI { |
35 | SysBusDevice parent_obj; | 48 | SysBusDevice parent_obj; |
36 | 49 | ||
37 | + bool little_endian_model; | 50 | + EndianMode model_endianness; |
38 | MemoryRegion mmio; | 51 | MemoryRegion mmio; |
39 | 52 | ||
40 | qemu_irq irq; | 53 | qemu_irq irq; |
41 | @@ -XXX,XX +XXX,XX @@ done: | 54 | @@ -XXX,XX +XXX,XX @@ done: |
42 | xlx_spi_update_irq(s); | 55 | xlx_spi_update_irq(s); |
... | ... | ||
47 | - .write = spi_write, | 60 | - .write = spi_write, |
48 | - .endianness = DEVICE_NATIVE_ENDIAN, | 61 | - .endianness = DEVICE_NATIVE_ENDIAN, |
49 | - .valid = { | 62 | - .valid = { |
50 | - .min_access_size = 4, | 63 | - .min_access_size = 4, |
51 | - .max_access_size = 4 | 64 | - .max_access_size = 4 |
65 | - } | ||
52 | +static const MemoryRegionOps spi_ops[2] = { | 66 | +static const MemoryRegionOps spi_ops[2] = { |
53 | + { | 67 | + [0 ... 1] = { |
54 | + .read = spi_read, | 68 | + .read = spi_read, |
55 | + .write = spi_write, | 69 | + .write = spi_write, |
56 | + .endianness = DEVICE_BIG_ENDIAN, | ||
57 | + .valid = { | 70 | + .valid = { |
58 | + .min_access_size = 4, | 71 | + .min_access_size = 4, |
59 | + .max_access_size = 4, | 72 | + .max_access_size = 4, |
60 | + }, | 73 | + }, |
61 | + }, { | 74 | + }, |
62 | + .read = spi_read, | 75 | + [ENDIAN_MODE_BIG].endianness = DEVICE_BIG_ENDIAN, |
63 | + .write = spi_write, | 76 | + [ENDIAN_MODE_LITTLE].endianness = DEVICE_LITTLE_ENDIAN, |
64 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
65 | + .valid = { | ||
66 | + .min_access_size = 4, | ||
67 | + .max_access_size = 4, | ||
68 | + }, | ||
69 | } | ||
70 | }; | 77 | }; |
71 | 78 | ||
79 | static void xilinx_spi_realize(DeviceState *dev, Error **errp) | ||
80 | @@ -XXX,XX +XXX,XX @@ static void xilinx_spi_realize(DeviceState *dev, Error **errp) | ||
81 | XilinxSPI *s = XILINX_SPI(dev); | ||
82 | int i; | ||
83 | |||
84 | + if (s->model_endianness == ENDIAN_MODE_UNSPECIFIED) { | ||
85 | + error_setg(errp, TYPE_XILINX_SPI " property 'endianness'" | ||
86 | + " must be set to 'big' or 'little'"); | ||
87 | + return; | ||
88 | + } | ||
89 | + | ||
90 | DB_PRINT("\n"); | ||
91 | |||
92 | s->spi = ssi_create_bus(dev, "spi"); | ||
72 | @@ -XXX,XX +XXX,XX @@ static void xilinx_spi_realize(DeviceState *dev, Error **errp) | 93 | @@ -XXX,XX +XXX,XX @@ static void xilinx_spi_realize(DeviceState *dev, Error **errp) |
73 | sysbus_init_irq(sbd, &s->cs_lines[i]); | 94 | sysbus_init_irq(sbd, &s->cs_lines[i]); |
74 | } | 95 | } |
75 | 96 | ||
76 | - memory_region_init_io(&s->mmio, OBJECT(s), &spi_ops, s, | 97 | - memory_region_init_io(&s->mmio, OBJECT(s), &spi_ops, s, |
77 | + memory_region_init_io(&s->mmio, OBJECT(s), | 98 | + memory_region_init_io(&s->mmio, OBJECT(s), |
78 | + &spi_ops[s->little_endian_model], s, | 99 | + &spi_ops[s->model_endianness], s, |
79 | "xilinx-spi", R_MAX * 4); | 100 | "xilinx-spi", R_MAX * 4); |
80 | sysbus_init_mmio(sbd, &s->mmio); | 101 | sysbus_init_mmio(sbd, &s->mmio); |
81 | 102 | ||
82 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_xilinx_spi = { | 103 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_xilinx_spi = { |
83 | }; | 104 | }; |
84 | 105 | ||
85 | static Property xilinx_spi_properties[] = { | 106 | static const Property xilinx_spi_properties[] = { |
86 | + DEFINE_PROP_BOOL("little-endian", XilinxSPI, little_endian_model, true), | 107 | + DEFINE_PROP_ENDIAN_NODEFAULT("endianness", XilinxSPI, model_endianness), |
87 | DEFINE_PROP_UINT8("num-ss-bits", XilinxSPI, num_cs, 1), | 108 | DEFINE_PROP_UINT8("num-ss-bits", XilinxSPI, num_cs, 1), |
88 | DEFINE_PROP_END_OF_LIST(), | ||
89 | }; | 109 | }; |
110 | |||
90 | -- | 111 | -- |
91 | 2.45.2 | 112 | 2.47.1 |
92 | 113 | ||
93 | 114 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Extract the implicit MO_TE definition in order to replace | ||
2 | it by runtime variable in the next commit. | ||
3 | 1 | ||
4 | Mechanical change using: | ||
5 | |||
6 | $ for n in UW UL UQ UO SW SL SQ; do \ | ||
7 | sed -i -e "s/MO_TE$n/MO_TE | MO_$n/" \ | ||
8 | $(git grep -l MO_TE$n target/microblaze); \ | ||
9 | done | ||
10 | |||
11 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
12 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/microblaze/translate.c | 36 +++++++++++++++++------------------ | ||
16 | 1 file changed, 18 insertions(+), 18 deletions(-) | ||
17 | |||
18 | diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/microblaze/translate.c | ||
21 | +++ b/target/microblaze/translate.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static bool trans_lbui(DisasContext *dc, arg_typeb *arg) | ||
23 | static bool trans_lhu(DisasContext *dc, arg_typea *arg) | ||
24 | { | ||
25 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
26 | - return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false); | ||
27 | + return do_load(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, false); | ||
28 | } | ||
29 | |||
30 | static bool trans_lhur(DisasContext *dc, arg_typea *arg) | ||
31 | { | ||
32 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
33 | - return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, true); | ||
34 | + return do_load(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, true); | ||
35 | } | ||
36 | |||
37 | static bool trans_lhuea(DisasContext *dc, arg_typea *arg) | ||
38 | @@ -XXX,XX +XXX,XX @@ static bool trans_lhuea(DisasContext *dc, arg_typea *arg) | ||
39 | return true; | ||
40 | #else | ||
41 | TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); | ||
42 | - return do_load(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false); | ||
43 | + return do_load(dc, arg->rd, addr, MO_TE | MO_UW, MMU_NOMMU_IDX, false); | ||
44 | #endif | ||
45 | } | ||
46 | |||
47 | static bool trans_lhui(DisasContext *dc, arg_typeb *arg) | ||
48 | { | ||
49 | TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm); | ||
50 | - return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false); | ||
51 | + return do_load(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, false); | ||
52 | } | ||
53 | |||
54 | static bool trans_lw(DisasContext *dc, arg_typea *arg) | ||
55 | { | ||
56 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
57 | - return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false); | ||
58 | + return do_load(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, false); | ||
59 | } | ||
60 | |||
61 | static bool trans_lwr(DisasContext *dc, arg_typea *arg) | ||
62 | { | ||
63 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
64 | - return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, true); | ||
65 | + return do_load(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, true); | ||
66 | } | ||
67 | |||
68 | static bool trans_lwea(DisasContext *dc, arg_typea *arg) | ||
69 | @@ -XXX,XX +XXX,XX @@ static bool trans_lwea(DisasContext *dc, arg_typea *arg) | ||
70 | return true; | ||
71 | #else | ||
72 | TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); | ||
73 | - return do_load(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false); | ||
74 | + return do_load(dc, arg->rd, addr, MO_TE | MO_UL, MMU_NOMMU_IDX, false); | ||
75 | #endif | ||
76 | } | ||
77 | |||
78 | static bool trans_lwi(DisasContext *dc, arg_typeb *arg) | ||
79 | { | ||
80 | TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm); | ||
81 | - return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false); | ||
82 | + return do_load(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, false); | ||
83 | } | ||
84 | |||
85 | static bool trans_lwx(DisasContext *dc, arg_typea *arg) | ||
86 | @@ -XXX,XX +XXX,XX @@ static bool trans_lwx(DisasContext *dc, arg_typea *arg) | ||
87 | /* lwx does not throw unaligned access errors, so force alignment */ | ||
88 | tcg_gen_andi_tl(addr, addr, ~3); | ||
89 | |||
90 | - tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, MO_TEUL); | ||
91 | + tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, MO_TE | MO_UL); | ||
92 | tcg_gen_mov_tl(cpu_res_addr, addr); | ||
93 | |||
94 | if (arg->rd) { | ||
95 | @@ -XXX,XX +XXX,XX @@ static bool trans_sbi(DisasContext *dc, arg_typeb *arg) | ||
96 | static bool trans_sh(DisasContext *dc, arg_typea *arg) | ||
97 | { | ||
98 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
99 | - return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false); | ||
100 | + return do_store(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, false); | ||
101 | } | ||
102 | |||
103 | static bool trans_shr(DisasContext *dc, arg_typea *arg) | ||
104 | { | ||
105 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
106 | - return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, true); | ||
107 | + return do_store(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, true); | ||
108 | } | ||
109 | |||
110 | static bool trans_shea(DisasContext *dc, arg_typea *arg) | ||
111 | @@ -XXX,XX +XXX,XX @@ static bool trans_shea(DisasContext *dc, arg_typea *arg) | ||
112 | return true; | ||
113 | #else | ||
114 | TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); | ||
115 | - return do_store(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false); | ||
116 | + return do_store(dc, arg->rd, addr, MO_TE | MO_UW, MMU_NOMMU_IDX, false); | ||
117 | #endif | ||
118 | } | ||
119 | |||
120 | static bool trans_shi(DisasContext *dc, arg_typeb *arg) | ||
121 | { | ||
122 | TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm); | ||
123 | - return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false); | ||
124 | + return do_store(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, false); | ||
125 | } | ||
126 | |||
127 | static bool trans_sw(DisasContext *dc, arg_typea *arg) | ||
128 | { | ||
129 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
130 | - return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false); | ||
131 | + return do_store(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, false); | ||
132 | } | ||
133 | |||
134 | static bool trans_swr(DisasContext *dc, arg_typea *arg) | ||
135 | { | ||
136 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
137 | - return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, true); | ||
138 | + return do_store(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, true); | ||
139 | } | ||
140 | |||
141 | static bool trans_swea(DisasContext *dc, arg_typea *arg) | ||
142 | @@ -XXX,XX +XXX,XX @@ static bool trans_swea(DisasContext *dc, arg_typea *arg) | ||
143 | return true; | ||
144 | #else | ||
145 | TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); | ||
146 | - return do_store(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false); | ||
147 | + return do_store(dc, arg->rd, addr, MO_TE | MO_UL, MMU_NOMMU_IDX, false); | ||
148 | #endif | ||
149 | } | ||
150 | |||
151 | static bool trans_swi(DisasContext *dc, arg_typeb *arg) | ||
152 | { | ||
153 | TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm); | ||
154 | - return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false); | ||
155 | + return do_store(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, false); | ||
156 | } | ||
157 | |||
158 | static bool trans_swx(DisasContext *dc, arg_typea *arg) | ||
159 | @@ -XXX,XX +XXX,XX @@ static bool trans_swx(DisasContext *dc, arg_typea *arg) | ||
160 | |||
161 | tcg_gen_atomic_cmpxchg_i32(tval, cpu_res_addr, cpu_res_val, | ||
162 | reg_for_write(dc, arg->rd), | ||
163 | - dc->mem_index, MO_TEUL); | ||
164 | + dc->mem_index, MO_TE | MO_UL); | ||
165 | |||
166 | tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_fail); | ||
167 | |||
168 | -- | ||
169 | 2.45.2 | ||
170 | |||
171 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | All callers of do_load() / do_store() set MO_TE flag. | ||
2 | Set it once in the callees. | ||
3 | 1 | ||
4 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
6 | --- | ||
7 | target/microblaze/translate.c | 36 +++++++++++++++++++---------------- | ||
8 | 1 file changed, 20 insertions(+), 16 deletions(-) | ||
9 | |||
10 | diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c | ||
11 | index XXXXXXX..XXXXXXX 100644 | ||
12 | --- a/target/microblaze/translate.c | ||
13 | +++ b/target/microblaze/translate.c | ||
14 | @@ -XXX,XX +XXX,XX @@ static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop, | ||
15 | { | ||
16 | MemOp size = mop & MO_SIZE; | ||
17 | |||
18 | + mop |= MO_TE; | ||
19 | + | ||
20 | /* | ||
21 | * When doing reverse accesses we need to do two things. | ||
22 | * | ||
23 | @@ -XXX,XX +XXX,XX @@ static bool trans_lbui(DisasContext *dc, arg_typeb *arg) | ||
24 | static bool trans_lhu(DisasContext *dc, arg_typea *arg) | ||
25 | { | ||
26 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
27 | - return do_load(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, false); | ||
28 | + return do_load(dc, arg->rd, addr, MO_UW, dc->mem_index, false); | ||
29 | } | ||
30 | |||
31 | static bool trans_lhur(DisasContext *dc, arg_typea *arg) | ||
32 | { | ||
33 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
34 | - return do_load(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, true); | ||
35 | + return do_load(dc, arg->rd, addr, MO_UW, dc->mem_index, true); | ||
36 | } | ||
37 | |||
38 | static bool trans_lhuea(DisasContext *dc, arg_typea *arg) | ||
39 | @@ -XXX,XX +XXX,XX @@ static bool trans_lhuea(DisasContext *dc, arg_typea *arg) | ||
40 | return true; | ||
41 | #else | ||
42 | TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); | ||
43 | - return do_load(dc, arg->rd, addr, MO_TE | MO_UW, MMU_NOMMU_IDX, false); | ||
44 | + return do_load(dc, arg->rd, addr, MO_UW, MMU_NOMMU_IDX, false); | ||
45 | #endif | ||
46 | } | ||
47 | |||
48 | static bool trans_lhui(DisasContext *dc, arg_typeb *arg) | ||
49 | { | ||
50 | TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm); | ||
51 | - return do_load(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, false); | ||
52 | + return do_load(dc, arg->rd, addr, MO_UW, dc->mem_index, false); | ||
53 | } | ||
54 | |||
55 | static bool trans_lw(DisasContext *dc, arg_typea *arg) | ||
56 | { | ||
57 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
58 | - return do_load(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, false); | ||
59 | + return do_load(dc, arg->rd, addr, MO_UL, dc->mem_index, false); | ||
60 | } | ||
61 | |||
62 | static bool trans_lwr(DisasContext *dc, arg_typea *arg) | ||
63 | { | ||
64 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
65 | - return do_load(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, true); | ||
66 | + return do_load(dc, arg->rd, addr, MO_UL, dc->mem_index, true); | ||
67 | } | ||
68 | |||
69 | static bool trans_lwea(DisasContext *dc, arg_typea *arg) | ||
70 | @@ -XXX,XX +XXX,XX @@ static bool trans_lwea(DisasContext *dc, arg_typea *arg) | ||
71 | return true; | ||
72 | #else | ||
73 | TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); | ||
74 | - return do_load(dc, arg->rd, addr, MO_TE | MO_UL, MMU_NOMMU_IDX, false); | ||
75 | + return do_load(dc, arg->rd, addr, MO_UL, MMU_NOMMU_IDX, false); | ||
76 | #endif | ||
77 | } | ||
78 | |||
79 | static bool trans_lwi(DisasContext *dc, arg_typeb *arg) | ||
80 | { | ||
81 | TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm); | ||
82 | - return do_load(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, false); | ||
83 | + return do_load(dc, arg->rd, addr, MO_UL, dc->mem_index, false); | ||
84 | } | ||
85 | |||
86 | static bool trans_lwx(DisasContext *dc, arg_typea *arg) | ||
87 | @@ -XXX,XX +XXX,XX @@ static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop, | ||
88 | { | ||
89 | MemOp size = mop & MO_SIZE; | ||
90 | |||
91 | + mop |= MO_TE; | ||
92 | + | ||
93 | /* | ||
94 | * When doing reverse accesses we need to do two things. | ||
95 | * | ||
96 | @@ -XXX,XX +XXX,XX @@ static bool trans_sbi(DisasContext *dc, arg_typeb *arg) | ||
97 | static bool trans_sh(DisasContext *dc, arg_typea *arg) | ||
98 | { | ||
99 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
100 | - return do_store(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, false); | ||
101 | + return do_store(dc, arg->rd, addr, MO_UW, dc->mem_index, false); | ||
102 | } | ||
103 | |||
104 | static bool trans_shr(DisasContext *dc, arg_typea *arg) | ||
105 | { | ||
106 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
107 | - return do_store(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, true); | ||
108 | + return do_store(dc, arg->rd, addr, MO_UW, dc->mem_index, true); | ||
109 | } | ||
110 | |||
111 | static bool trans_shea(DisasContext *dc, arg_typea *arg) | ||
112 | @@ -XXX,XX +XXX,XX @@ static bool trans_shea(DisasContext *dc, arg_typea *arg) | ||
113 | return true; | ||
114 | #else | ||
115 | TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); | ||
116 | - return do_store(dc, arg->rd, addr, MO_TE | MO_UW, MMU_NOMMU_IDX, false); | ||
117 | + return do_store(dc, arg->rd, addr, MO_UW, MMU_NOMMU_IDX, false); | ||
118 | #endif | ||
119 | } | ||
120 | |||
121 | static bool trans_shi(DisasContext *dc, arg_typeb *arg) | ||
122 | { | ||
123 | TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm); | ||
124 | - return do_store(dc, arg->rd, addr, MO_TE | MO_UW, dc->mem_index, false); | ||
125 | + return do_store(dc, arg->rd, addr, MO_UW, dc->mem_index, false); | ||
126 | } | ||
127 | |||
128 | static bool trans_sw(DisasContext *dc, arg_typea *arg) | ||
129 | { | ||
130 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
131 | - return do_store(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, false); | ||
132 | + return do_store(dc, arg->rd, addr, MO_UL, dc->mem_index, false); | ||
133 | } | ||
134 | |||
135 | static bool trans_swr(DisasContext *dc, arg_typea *arg) | ||
136 | { | ||
137 | TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb); | ||
138 | - return do_store(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, true); | ||
139 | + return do_store(dc, arg->rd, addr, MO_UL, dc->mem_index, true); | ||
140 | } | ||
141 | |||
142 | static bool trans_swea(DisasContext *dc, arg_typea *arg) | ||
143 | @@ -XXX,XX +XXX,XX @@ static bool trans_swea(DisasContext *dc, arg_typea *arg) | ||
144 | return true; | ||
145 | #else | ||
146 | TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); | ||
147 | - return do_store(dc, arg->rd, addr, MO_TE | MO_UL, MMU_NOMMU_IDX, false); | ||
148 | + return do_store(dc, arg->rd, addr, MO_UL, MMU_NOMMU_IDX, false); | ||
149 | #endif | ||
150 | } | ||
151 | |||
152 | static bool trans_swi(DisasContext *dc, arg_typeb *arg) | ||
153 | { | ||
154 | TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm); | ||
155 | - return do_store(dc, arg->rd, addr, MO_TE | MO_UL, dc->mem_index, false); | ||
156 | + return do_store(dc, arg->rd, addr, MO_UL, dc->mem_index, false); | ||
157 | } | ||
158 | |||
159 | static bool trans_swx(DisasContext *dc, arg_typea *arg) | ||
160 | -- | ||
161 | 2.45.2 | ||
162 | |||
163 | diff view generated by jsdifflib |
1 | Introduce an abstract machine parent class which defines | 1 | Avoid fetching assets from www.qemu-advent-calendar.org |
---|---|---|---|
2 | the 'little_endian' property. Duplicate the current machine, | 2 | website, prefer fetching microblaze assets from GitLab servers. |
3 | which endian is tied to the binary endianness, to one big | ||
4 | endian and a little endian machine; updating the machine | ||
5 | description. Keep the current default machine for each binary. | ||
6 | 3 | ||
7 | 'petalogix-s3adsp1800' machine is aliased as: | 4 | Suggested-by: Thomas Huth <thuth@redhat.com> |
8 | - 'petalogix-s3adsp1800-be' on big-endian binary, | ||
9 | - 'petalogix-s3adsp1800-le' on little-endian one. | ||
10 | |||
11 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
12 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 5 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
13 | --- | 6 | --- |
14 | hw/microblaze/petalogix_s3adsp1800_mmu.c | 62 +++++++++++++++++++----- | 7 | tests/functional/test_microblazeel_s3adsp1800.py | 3 ++- |
15 | 1 file changed, 51 insertions(+), 11 deletions(-) | 8 | 1 file changed, 2 insertions(+), 1 deletion(-) |
16 | 9 | ||
17 | diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c | 10 | diff --git a/tests/functional/test_microblazeel_s3adsp1800.py b/tests/functional/test_microblazeel_s3adsp1800.py |
18 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100755 |
19 | --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c | 12 | --- a/tests/functional/test_microblazeel_s3adsp1800.py |
20 | +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c | 13 | +++ b/tests/functional/test_microblazeel_s3adsp1800.py |
21 | @@ -XXX,XX +XXX,XX @@ | 14 | @@ -XXX,XX +XXX,XX @@ class MicroblazeelMachine(QemuSystemTest): |
22 | #define ETHLITE_IRQ 1 | 15 | timeout = 90 |
23 | #define UARTLITE_IRQ 3 | 16 | |
24 | 17 | ASSET_IMAGE = Asset( | |
25 | +typedef struct PetalogixS3adsp1800MachineClass { | 18 | - ('http://www.qemu-advent-calendar.org/2023/download/day13.tar.gz'), |
26 | + MachineClass parent_obj; | 19 | + ('https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/' |
27 | + | 20 | + 'day05.tar.xz'), |
28 | + bool little_endian; | 21 | 'b9b3d43c5dd79db88ada495cc6e0d1f591153fe41355e925d791fbf44de50c22') |
29 | +} PetalogixS3adsp1800MachineClass; | 22 | |
30 | + | 23 | def test_microblazeel_s3adsp1800(self): |
31 | #define TYPE_PETALOGIX_S3ADSP1800_MACHINE \ | ||
32 | - MACHINE_TYPE_NAME("petalogix-s3adsp1800") | ||
33 | + MACHINE_TYPE_NAME("petalogix-s3adsp1800-common") | ||
34 | +DECLARE_CLASS_CHECKERS(PetalogixS3adsp1800MachineClass, | ||
35 | + PETALOGIX_S3ADSP1800_MACHINE, | ||
36 | + TYPE_PETALOGIX_S3ADSP1800_MACHINE) | ||
37 | |||
38 | static void | ||
39 | petalogix_s3adsp1800_init(MachineState *machine) | ||
40 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | ||
41 | MemoryRegion *phys_ram = g_new(MemoryRegion, 1); | ||
42 | qemu_irq irq[32]; | ||
43 | MemoryRegion *sysmem = get_system_memory(); | ||
44 | + PetalogixS3adsp1800MachineClass *pmc; | ||
45 | |||
46 | + pmc = PETALOGIX_S3ADSP1800_MACHINE_GET_CLASS(machine); | ||
47 | cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU)); | ||
48 | object_property_set_str(OBJECT(cpu), "version", "7.10.d", &error_abort); | ||
49 | object_property_set_bool(OBJECT(cpu), "little-endian", | ||
50 | - !TARGET_BIG_ENDIAN, &error_abort); | ||
51 | + pmc->little_endian, &error_abort); | ||
52 | qdev_realize(DEVICE(cpu), NULL, &error_abort); | ||
53 | |||
54 | /* Attach emulated BRAM through the LMB. */ | ||
55 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | ||
56 | 64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1); | ||
57 | |||
58 | dev = qdev_new("xlnx.xps-intc"); | ||
59 | - qdev_prop_set_bit(dev, "little-endian", !TARGET_BIG_ENDIAN); | ||
60 | + qdev_prop_set_bit(dev, "little-endian", pmc->little_endian); | ||
61 | qdev_prop_set_uint32(dev, "kind-of-intr", | ||
62 | 1 << ETHLITE_IRQ | 1 << UARTLITE_IRQ); | ||
63 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
64 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | ||
65 | } | ||
66 | |||
67 | dev = qdev_new(TYPE_XILINX_UARTLITE); | ||
68 | - qdev_prop_set_bit(dev, "little-endian", !TARGET_BIG_ENDIAN); | ||
69 | + qdev_prop_set_bit(dev, "little-endian", pmc->little_endian); | ||
70 | qdev_prop_set_chr(dev, "chardev", serial_hd(0)); | ||
71 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
72 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR); | ||
73 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | ||
74 | |||
75 | /* 2 timers at irq 2 @ 62 Mhz. */ | ||
76 | dev = qdev_new("xlnx.xps-timer"); | ||
77 | - qdev_prop_set_bit(dev, "little-endian", !TARGET_BIG_ENDIAN); | ||
78 | + qdev_prop_set_bit(dev, "little-endian", pmc->little_endian); | ||
79 | qdev_prop_set_uint32(dev, "one-timer-only", 0); | ||
80 | qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000); | ||
81 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
82 | @@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine) | ||
83 | qemu_configure_nic_device(dev, true, NULL); | ||
84 | qdev_prop_set_uint32(dev, "tx-ping-pong", 0); | ||
85 | qdev_prop_set_uint32(dev, "rx-ping-pong", 0); | ||
86 | - qdev_prop_set_bit(dev, "little-endian-model", !TARGET_BIG_ENDIAN); | ||
87 | + qdev_prop_set_bit(dev, "little-endian", pmc->little_endian); | ||
88 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
89 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ETHLITE_BASEADDR); | ||
90 | sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[ETHLITE_IRQ]); | ||
91 | |||
92 | create_unimplemented_device("xps_gpio", GPIO_BASEADDR, 0x10000); | ||
93 | |||
94 | - microblaze_load_kernel(cpu, !TARGET_BIG_ENDIAN, ddr_base, ram_size, | ||
95 | + microblaze_load_kernel(cpu, pmc->little_endian, ddr_base, ram_size, | ||
96 | machine->initrd_filename, | ||
97 | BINARY_DEVICE_TREE_FILE, | ||
98 | NULL); | ||
99 | } | ||
100 | |||
101 | -static void petalogix_s3adsp1800_machine_class_init(ObjectClass *oc, void *data) | ||
102 | +static void petalogix_s3adsp1800_machine_class_init(ObjectClass *oc, | ||
103 | + bool little_endian) | ||
104 | { | ||
105 | MachineClass *mc = MACHINE_CLASS(oc); | ||
106 | + PetalogixS3adsp1800MachineClass *pmc = PETALOGIX_S3ADSP1800_MACHINE_CLASS(oc); | ||
107 | |||
108 | - mc->desc = "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800"; | ||
109 | mc->init = petalogix_s3adsp1800_init; | ||
110 | - mc->is_default = true; | ||
111 | + pmc->little_endian = little_endian; | ||
112 | + mc->desc = little_endian | ||
113 | + ? "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800 (little endian)" | ||
114 | + : "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800 (big endian)"; | ||
115 | + if (little_endian == !TARGET_BIG_ENDIAN) { | ||
116 | + mc->is_default = true; | ||
117 | + mc->alias = "petalogix-s3adsp1800"; | ||
118 | + } | ||
119 | +} | ||
120 | + | ||
121 | +static void petalogix_s3adsp1800_machine_class_init_be(ObjectClass *oc, void *data) | ||
122 | +{ | ||
123 | + petalogix_s3adsp1800_machine_class_init(oc, false); | ||
124 | +} | ||
125 | + | ||
126 | +static void petalogix_s3adsp1800_machine_class_init_le(ObjectClass *oc, void *data) | ||
127 | +{ | ||
128 | + petalogix_s3adsp1800_machine_class_init(oc, true); | ||
129 | } | ||
130 | |||
131 | static const TypeInfo petalogix_s3adsp1800_machine_types[] = { | ||
132 | { | ||
133 | .name = TYPE_PETALOGIX_S3ADSP1800_MACHINE, | ||
134 | .parent = TYPE_MACHINE, | ||
135 | - .class_init = petalogix_s3adsp1800_machine_class_init, | ||
136 | + .abstract = true, | ||
137 | + .class_size = sizeof(PetalogixS3adsp1800MachineClass), | ||
138 | + }, | ||
139 | + { | ||
140 | + .name = MACHINE_TYPE_NAME("petalogix-s3adsp1800-be"), | ||
141 | + .parent = TYPE_PETALOGIX_S3ADSP1800_MACHINE, | ||
142 | + .class_init = petalogix_s3adsp1800_machine_class_init_be, | ||
143 | + }, | ||
144 | + { | ||
145 | + .name = MACHINE_TYPE_NAME("petalogix-s3adsp1800-le"), | ||
146 | + .parent = TYPE_PETALOGIX_S3ADSP1800_MACHINE, | ||
147 | + .class_init = petalogix_s3adsp1800_machine_class_init_le, | ||
148 | }, | ||
149 | }; | ||
150 | |||
151 | -- | 24 | -- |
152 | 2.45.2 | 25 | 2.47.1 |
153 | 26 | ||
154 | 27 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
8 | 8 | ||
9 | These changes will help when adding cross-endian kernel tests. | 9 | These changes will help when adding cross-endian kernel tests. |
10 | 10 | ||
11 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 11 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
12 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 12 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
13 | Reviewed-by: Thomas Huth <thuth@redhat.com> | ||
14 | Message-Id: <20250206131052.30207-13-philmd@linaro.org> | ||
13 | --- | 15 | --- |
14 | tests/functional/test_microblaze_s3adsp1800.py | 6 +++--- | 16 | tests/functional/test_microblaze_s3adsp1800.py | 6 +++--- |
15 | tests/functional/test_microblazeel_s3adsp1800.py | 6 +++--- | 17 | tests/functional/test_microblazeel_s3adsp1800.py | 6 +++--- |
16 | 2 files changed, 6 insertions(+), 6 deletions(-) | 18 | 2 files changed, 6 insertions(+), 6 deletions(-) |
17 | 19 | ||
... | ... | ||
30 | '3ba7439dfbea7af4876662c97f8e1f0cdad9231fc166e4861d17042489270057') | 32 | '3ba7439dfbea7af4876662c97f8e1f0cdad9231fc166e4861d17042489270057') |
31 | 33 | ||
32 | - def test_microblaze_s3adsp1800(self): | 34 | - def test_microblaze_s3adsp1800(self): |
33 | + def test_microblaze_s3adsp1800_be(self): | 35 | + def test_microblaze_s3adsp1800_be(self): |
34 | self.set_machine('petalogix-s3adsp1800') | 36 | self.set_machine('petalogix-s3adsp1800') |
35 | - file_path = self.ASSET_IMAGE.fetch() | 37 | - self.archive_extract(self.ASSET_IMAGE) |
36 | + file_path = self.ASSET_IMAGE_BE.fetch() | 38 | + self.archive_extract(self.ASSET_IMAGE_BE) |
37 | archive_extract(file_path, self.workdir) | ||
38 | self.vm.set_console() | 39 | self.vm.set_console() |
39 | self.vm.add_args('-kernel', self.workdir + '/day17/ballerina.bin') | 40 | self.vm.add_args('-kernel', |
41 | self.scratch_file('day17', 'ballerina.bin')) | ||
40 | diff --git a/tests/functional/test_microblazeel_s3adsp1800.py b/tests/functional/test_microblazeel_s3adsp1800.py | 42 | diff --git a/tests/functional/test_microblazeel_s3adsp1800.py b/tests/functional/test_microblazeel_s3adsp1800.py |
41 | index XXXXXXX..XXXXXXX 100755 | 43 | index XXXXXXX..XXXXXXX 100755 |
42 | --- a/tests/functional/test_microblazeel_s3adsp1800.py | 44 | --- a/tests/functional/test_microblazeel_s3adsp1800.py |
43 | +++ b/tests/functional/test_microblazeel_s3adsp1800.py | 45 | +++ b/tests/functional/test_microblazeel_s3adsp1800.py |
44 | @@ -XXX,XX +XXX,XX @@ class MicroblazeelMachine(QemuSystemTest): | 46 | @@ -XXX,XX +XXX,XX @@ class MicroblazeelMachine(QemuSystemTest): |
45 | 47 | ||
46 | timeout = 90 | 48 | timeout = 90 |
47 | 49 | ||
48 | - ASSET_IMAGE = Asset( | 50 | - ASSET_IMAGE = Asset( |
49 | + ASSET_IMAGE_LE = Asset( | 51 | + ASSET_IMAGE_LE = Asset( |
50 | ('http://www.qemu-advent-calendar.org/2023/download/day13.tar.gz'), | 52 | ('https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/' |
53 | 'day05.tar.xz'), | ||
51 | 'b9b3d43c5dd79db88ada495cc6e0d1f591153fe41355e925d791fbf44de50c22') | 54 | 'b9b3d43c5dd79db88ada495cc6e0d1f591153fe41355e925d791fbf44de50c22') |
52 | 55 | ||
53 | - def test_microblazeel_s3adsp1800(self): | 56 | - def test_microblazeel_s3adsp1800(self): |
54 | + def test_microblazeel_s3adsp1800_le(self): | 57 | + def test_microblazeel_s3adsp1800_le(self): |
55 | self.require_netdev('user') | 58 | self.require_netdev('user') |
56 | self.set_machine('petalogix-s3adsp1800') | 59 | self.set_machine('petalogix-s3adsp1800') |
57 | - file_path = self.ASSET_IMAGE.fetch() | 60 | - self.archive_extract(self.ASSET_IMAGE) |
58 | + file_path = self.ASSET_IMAGE_LE.fetch() | 61 | + self.archive_extract(self.ASSET_IMAGE_LE) |
59 | archive_extract(file_path, self.workdir) | ||
60 | self.vm.set_console() | 62 | self.vm.set_console() |
61 | self.vm.add_args('-kernel', self.workdir + '/day13/xmaton.bin') | 63 | self.vm.add_args('-kernel', self.scratch_file('day13', 'xmaton.bin')) |
64 | tftproot = self.scratch_file('day13') | ||
62 | -- | 65 | -- |
63 | 2.45.2 | 66 | 2.47.1 |
64 | 67 | ||
65 | 68 | diff view generated by jsdifflib |
1 | Copy/paste the current tests, but call the opposite endianness | 1 | Make microblaze tests a bit more generic. |
---|---|---|---|
2 | machines, testing: | ||
3 | - petalogix-s3adsp1800-le machine (little-endian CPU) on the | ||
4 | qemu-system-microblaze binary (big-endian) | ||
5 | - petalogix-s3adsp1800-be machine (big-endian CPU) on the | ||
6 | qemu-system-microblazeel binary (little-endian). | ||
7 | 2 | ||
8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 3 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
9 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Reviewed-by: Thomas Huth <thuth@redhat.com> |
5 | Message-Id: <20250206131052.30207-14-philmd@linaro.org> | ||
10 | --- | 6 | --- |
11 | .../functional/test_microblaze_s3adsp1800.py | 21 +++++++++++++++++++ | 7 | tests/functional/test_microblaze_s3adsp1800.py | 7 +++++-- |
12 | .../test_microblazeel_s3adsp1800.py | 19 +++++++++++++++++ | 8 | tests/functional/test_microblazeel_s3adsp1800.py | 7 +++++-- |
13 | 2 files changed, 40 insertions(+) | 9 | 2 files changed, 10 insertions(+), 4 deletions(-) |
14 | 10 | ||
15 | diff --git a/tests/functional/test_microblaze_s3adsp1800.py b/tests/functional/test_microblaze_s3adsp1800.py | 11 | diff --git a/tests/functional/test_microblaze_s3adsp1800.py b/tests/functional/test_microblaze_s3adsp1800.py |
16 | index XXXXXXX..XXXXXXX 100755 | 12 | index XXXXXXX..XXXXXXX 100755 |
17 | --- a/tests/functional/test_microblaze_s3adsp1800.py | 13 | --- a/tests/functional/test_microblaze_s3adsp1800.py |
18 | +++ b/tests/functional/test_microblaze_s3adsp1800.py | 14 | +++ b/tests/functional/test_microblaze_s3adsp1800.py |
15 | @@ -XXX,XX +XXX,XX @@ class MicroblazeMachine(QemuSystemTest): | ||
16 | 'day17.tar.xz'), | ||
17 | '3ba7439dfbea7af4876662c97f8e1f0cdad9231fc166e4861d17042489270057') | ||
18 | |||
19 | - def test_microblaze_s3adsp1800_be(self): | ||
20 | - self.set_machine('petalogix-s3adsp1800') | ||
21 | + def do_ballerina_be_test(self, machine): | ||
22 | + self.set_machine(machine) | ||
23 | self.archive_extract(self.ASSET_IMAGE_BE) | ||
24 | self.vm.set_console() | ||
25 | self.vm.add_args('-kernel', | ||
19 | @@ -XXX,XX +XXX,XX @@ def test_microblaze_s3adsp1800_be(self): | 26 | @@ -XXX,XX +XXX,XX @@ def test_microblaze_s3adsp1800_be(self): |
20 | # message, that's why we don't test for a later string here. This | 27 | # message, that's why we don't test for a later string here. This |
21 | # needs some investigation by a microblaze wizard one day... | 28 | # needs some investigation by a microblaze wizard one day... |
22 | 29 | ||
23 | + ASSET_IMAGE_LE = Asset( | 30 | + def test_microblaze_s3adsp1800_legacy_be(self): |
24 | + ('http://www.qemu-advent-calendar.org/2023/download/day13.tar.gz'), | 31 | + self.do_ballerina_be_test('petalogix-s3adsp1800') |
25 | + 'b9b3d43c5dd79db88ada495cc6e0d1f591153fe41355e925d791fbf44de50c22') | ||
26 | + | ||
27 | + def test_microblaze_s3adsp1800_le(self): | ||
28 | + self.require_netdev('user') | ||
29 | + self.set_machine('petalogix-s3adsp1800-le') | ||
30 | + file_path = self.ASSET_IMAGE_LE.fetch() | ||
31 | + archive_extract(file_path, self.workdir) | ||
32 | + self.vm.set_console() | ||
33 | + self.vm.add_args('-kernel', self.workdir + '/day13/xmaton.bin') | ||
34 | + self.vm.add_args('-nic', 'user,tftp=' + self.workdir + '/day13/') | ||
35 | + self.vm.launch() | ||
36 | + wait_for_console_pattern(self, 'QEMU Advent Calendar 2023') | ||
37 | + time.sleep(0.1) | ||
38 | + exec_command(self, 'root') | ||
39 | + time.sleep(0.1) | ||
40 | + exec_command_and_wait_for_pattern(self, | ||
41 | + 'tftp -g -r xmaton.png 10.0.2.2 ; md5sum xmaton.png', | ||
42 | + '821cd3cab8efd16ad6ee5acc3642a8ea') | ||
43 | + | 32 | + |
44 | if __name__ == '__main__': | 33 | if __name__ == '__main__': |
45 | QemuSystemTest.main() | 34 | QemuSystemTest.main() |
46 | diff --git a/tests/functional/test_microblazeel_s3adsp1800.py b/tests/functional/test_microblazeel_s3adsp1800.py | 35 | diff --git a/tests/functional/test_microblazeel_s3adsp1800.py b/tests/functional/test_microblazeel_s3adsp1800.py |
47 | index XXXXXXX..XXXXXXX 100755 | 36 | index XXXXXXX..XXXXXXX 100755 |
48 | --- a/tests/functional/test_microblazeel_s3adsp1800.py | 37 | --- a/tests/functional/test_microblazeel_s3adsp1800.py |
49 | +++ b/tests/functional/test_microblazeel_s3adsp1800.py | 38 | +++ b/tests/functional/test_microblazeel_s3adsp1800.py |
39 | @@ -XXX,XX +XXX,XX @@ class MicroblazeelMachine(QemuSystemTest): | ||
40 | 'day05.tar.xz'), | ||
41 | 'b9b3d43c5dd79db88ada495cc6e0d1f591153fe41355e925d791fbf44de50c22') | ||
42 | |||
43 | - def test_microblazeel_s3adsp1800_le(self): | ||
44 | + def do_xmaton_le_test(self, machine): | ||
45 | self.require_netdev('user') | ||
46 | - self.set_machine('petalogix-s3adsp1800') | ||
47 | + self.set_machine(machine) | ||
48 | self.archive_extract(self.ASSET_IMAGE_LE) | ||
49 | self.vm.set_console() | ||
50 | self.vm.add_args('-kernel', self.scratch_file('day13', 'xmaton.bin')) | ||
50 | @@ -XXX,XX +XXX,XX @@ def test_microblazeel_s3adsp1800_le(self): | 51 | @@ -XXX,XX +XXX,XX @@ def test_microblazeel_s3adsp1800_le(self): |
51 | 'tftp -g -r xmaton.png 10.0.2.2 ; md5sum xmaton.png', | 52 | 'tftp -g -r xmaton.png 10.0.2.2 ; md5sum xmaton.png', |
52 | '821cd3cab8efd16ad6ee5acc3642a8ea') | 53 | '821cd3cab8efd16ad6ee5acc3642a8ea') |
53 | 54 | ||
54 | + ASSET_IMAGE_BE = Asset( | 55 | + def test_microblaze_s3adsp1800_legacy_le(self): |
55 | + ('https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/' | 56 | + self.do_xmaton_le_test('petalogix-s3adsp1800') |
56 | + 'day17.tar.xz'), | ||
57 | + '3ba7439dfbea7af4876662c97f8e1f0cdad9231fc166e4861d17042489270057') | ||
58 | + | ||
59 | + def test_microblazeel_s3adsp1800_be(self): | ||
60 | + self.set_machine('petalogix-s3adsp1800-be') | ||
61 | + file_path = self.ASSET_IMAGE_BE.fetch() | ||
62 | + archive_extract(file_path, self.workdir) | ||
63 | + self.vm.set_console() | ||
64 | + self.vm.add_args('-kernel', self.workdir + '/day17/ballerina.bin') | ||
65 | + self.vm.launch() | ||
66 | + wait_for_console_pattern(self, 'This architecture does not have ' | ||
67 | + 'kernel memory protection') | ||
68 | + # Note: | ||
69 | + # The kernel sometimes gets stuck after the "This architecture ..." | ||
70 | + # message, that's why we don't test for a later string here. This | ||
71 | + # needs some investigation by a microblaze wizard one day... | ||
72 | + | 57 | + |
73 | if __name__ == '__main__': | 58 | if __name__ == '__main__': |
74 | QemuSystemTest.main() | 59 | QemuSystemTest.main() |
75 | -- | 60 | -- |
76 | 2.45.2 | 61 | 2.47.1 |
77 | 62 | ||
78 | 63 | diff view generated by jsdifflib |
1 | Consider the CPU ENDI bit, swap instructions when the CPU | 1 | Commit f0ec14c78c4 ("tests/avocado: Fix console data loss") fixed |
---|---|---|---|
2 | endianness doesn't match the binary one. | 2 | QEMUMachine's problem with console, we don't need to use the sleep() |
3 | kludges. | ||
3 | 4 | ||
5 | Suggested-by: Thomas Huth <thuth@redhat.com> | ||
4 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 6 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
7 | Reviewed-by: Thomas Huth <thuth@redhat.com> | ||
5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
9 | Message-Id: <20250206131052.30207-15-philmd@linaro.org> | ||
6 | --- | 10 | --- |
7 | target/microblaze/cpu.h | 7 +++++++ | 11 | tests/functional/test_microblazeel_s3adsp1800.py | 8 +++----- |
8 | target/microblaze/translate.c | 5 +++-- | 12 | 1 file changed, 3 insertions(+), 5 deletions(-) |
9 | 2 files changed, 10 insertions(+), 2 deletions(-) | ||
10 | 13 | ||
11 | diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h | 14 | diff --git a/tests/functional/test_microblazeel_s3adsp1800.py b/tests/functional/test_microblazeel_s3adsp1800.py |
12 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100755 |
13 | --- a/target/microblaze/cpu.h | 16 | --- a/tests/functional/test_microblazeel_s3adsp1800.py |
14 | +++ b/target/microblaze/cpu.h | 17 | +++ b/tests/functional/test_microblazeel_s3adsp1800.py |
15 | @@ -XXX,XX +XXX,XX @@ void mb_tcg_init(void); | 18 | @@ -XXX,XX +XXX,XX @@ |
16 | /* Ensure there is no overlap between the two masks. */ | 19 | # This work is licensed under the terms of the GNU GPL, version 2 or |
17 | QEMU_BUILD_BUG_ON(MSR_TB_MASK & IFLAGS_TB_MASK); | 20 | # later. See the COPYING file in the top-level directory. |
18 | 21 | ||
19 | +static inline bool mb_cpu_is_big_endian(CPUState *cs) | 22 | -import time |
20 | +{ | 23 | -from qemu_test import exec_command, exec_command_and_wait_for_pattern |
21 | + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); | 24 | +from qemu_test import exec_command_and_wait_for_pattern |
22 | + | 25 | from qemu_test import QemuSystemTest, Asset |
23 | + return !cpu->cfg.endi; | 26 | from qemu_test import wait_for_console_pattern |
24 | +} | 27 | |
25 | + | 28 | @@ -XXX,XX +XXX,XX @@ def do_xmaton_le_test(self, machine): |
26 | static inline void cpu_get_tb_cpu_state(CPUMBState *env, vaddr *pc, | 29 | self.vm.add_args('-nic', f'user,tftp={tftproot}') |
27 | uint64_t *cs_base, uint32_t *flags) | 30 | self.vm.launch() |
28 | { | 31 | wait_for_console_pattern(self, 'QEMU Advent Calendar 2023') |
29 | diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c | 32 | - time.sleep(0.1) |
30 | index XXXXXXX..XXXXXXX 100644 | 33 | - exec_command(self, 'root') |
31 | --- a/target/microblaze/translate.c | 34 | - time.sleep(0.1) |
32 | +++ b/target/microblaze/translate.c | 35 | + wait_for_console_pattern(self, 'buildroot login:') |
33 | @@ -XXX,XX +XXX,XX @@ static void record_unaligned_ess(DisasContext *dc, int rd, | 36 | + exec_command_and_wait_for_pattern(self, 'root', '#') |
34 | 37 | exec_command_and_wait_for_pattern(self, | |
35 | static inline MemOp mo_endian(DisasContext *dc) | 38 | 'tftp -g -r xmaton.png 10.0.2.2 ; md5sum xmaton.png', |
36 | { | 39 | '821cd3cab8efd16ad6ee5acc3642a8ea') |
37 | - return MO_TE; | ||
38 | + return dc->cfg->endi ? MO_LE : MO_BE; | ||
39 | } | ||
40 | |||
41 | static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop, | ||
42 | @@ -XXX,XX +XXX,XX @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs) | ||
43 | |||
44 | dc->tb_flags_to_set = 0; | ||
45 | |||
46 | - ir = translator_ldl(cpu_env(cs), &dc->base, dc->base.pc_next); | ||
47 | + ir = translator_ldl_swap(cpu_env(cs), &dc->base, dc->base.pc_next, | ||
48 | + mb_cpu_is_big_endian(cs) != TARGET_BIG_ENDIAN); | ||
49 | if (!decode(dc, ir)) { | ||
50 | trap_illegal(dc, true); | ||
51 | } | ||
52 | -- | 40 | -- |
53 | 2.45.2 | 41 | 2.47.1 |
54 | 42 | ||
55 | 43 | diff view generated by jsdifflib |
1 | mo_endian() returns the target endianness, currently static. | 1 | Have the MicroblazeMachine class being common to both |
---|---|---|---|
2 | MicroblazeBigEndianMachine and MicroblazeLittleEndianMachine | ||
3 | classes. Move the xmaton and ballerina tests to the parent class. | ||
2 | 4 | ||
3 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 5 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 6 | Reviewed-by: Thomas Huth <thuth@redhat.com> |
7 | Message-Id: <20250206131052.30207-16-philmd@linaro.org> | ||
5 | --- | 8 | --- |
6 | target/microblaze/translate.c | 14 ++++++++++---- | 9 | .../functional/test_microblaze_s3adsp1800.py | 24 +++++++++++++++ |
7 | 1 file changed, 10 insertions(+), 4 deletions(-) | 10 | .../test_microblazeel_s3adsp1800.py | 30 ++----------------- |
11 | 2 files changed, 27 insertions(+), 27 deletions(-) | ||
8 | 12 | ||
9 | diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c | 13 | diff --git a/tests/functional/test_microblaze_s3adsp1800.py b/tests/functional/test_microblaze_s3adsp1800.py |
10 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100755 |
11 | --- a/target/microblaze/translate.c | 15 | --- a/tests/functional/test_microblaze_s3adsp1800.py |
12 | +++ b/target/microblaze/translate.c | 16 | +++ b/tests/functional/test_microblaze_s3adsp1800.py |
13 | @@ -XXX,XX +XXX,XX @@ static void record_unaligned_ess(DisasContext *dc, int rd, | 17 | @@ -XXX,XX +XXX,XX @@ |
14 | } | 18 | # This work is licensed under the terms of the GNU GPL, version 2 or |
15 | #endif | 19 | # later. See the COPYING file in the top-level directory. |
16 | 20 | ||
17 | +static inline MemOp mo_endian(DisasContext *dc) | 21 | +from qemu_test import exec_command_and_wait_for_pattern |
18 | +{ | 22 | from qemu_test import QemuSystemTest, Asset |
19 | + return MO_TE; | 23 | from qemu_test import wait_for_console_pattern |
20 | +} | 24 | |
25 | @@ -XXX,XX +XXX,XX @@ class MicroblazeMachine(QemuSystemTest): | ||
26 | 'day17.tar.xz'), | ||
27 | '3ba7439dfbea7af4876662c97f8e1f0cdad9231fc166e4861d17042489270057') | ||
28 | |||
29 | + ASSET_IMAGE_LE = Asset( | ||
30 | + ('https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/' | ||
31 | + 'day05.tar.xz'), | ||
32 | + 'b9b3d43c5dd79db88ada495cc6e0d1f591153fe41355e925d791fbf44de50c22') | ||
21 | + | 33 | + |
22 | static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop, | 34 | def do_ballerina_be_test(self, machine): |
23 | int mem_index, bool rev) | 35 | self.set_machine(machine) |
24 | { | 36 | self.archive_extract(self.ASSET_IMAGE_BE) |
25 | MemOp size = mop & MO_SIZE; | 37 | @@ -XXX,XX +XXX,XX @@ def do_ballerina_be_test(self, machine): |
26 | 38 | # message, that's why we don't test for a later string here. This | |
27 | - mop |= MO_TE; | 39 | # needs some investigation by a microblaze wizard one day... |
28 | + mop |= mo_endian(dc); | 40 | |
29 | 41 | + def do_xmaton_le_test(self, machine): | |
30 | /* | 42 | + self.require_netdev('user') |
31 | * When doing reverse accesses we need to do two things. | 43 | + self.set_machine(machine) |
32 | @@ -XXX,XX +XXX,XX @@ static bool trans_lwx(DisasContext *dc, arg_typea *arg) | 44 | + self.archive_extract(self.ASSET_IMAGE_LE) |
33 | /* lwx does not throw unaligned access errors, so force alignment */ | 45 | + self.vm.set_console() |
34 | tcg_gen_andi_tl(addr, addr, ~3); | 46 | + self.vm.add_args('-kernel', self.scratch_file('day13', 'xmaton.bin')) |
35 | 47 | + tftproot = self.scratch_file('day13') | |
36 | - tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, MO_TE | MO_UL); | 48 | + self.vm.add_args('-nic', f'user,tftp={tftproot}') |
37 | + tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, | 49 | + self.vm.launch() |
38 | + mo_endian(dc) | MO_UL); | 50 | + wait_for_console_pattern(self, 'QEMU Advent Calendar 2023') |
39 | tcg_gen_mov_tl(cpu_res_addr, addr); | 51 | + wait_for_console_pattern(self, 'buildroot login:') |
40 | 52 | + exec_command_and_wait_for_pattern(self, 'root', '#') | |
41 | if (arg->rd) { | 53 | + exec_command_and_wait_for_pattern(self, |
42 | @@ -XXX,XX +XXX,XX @@ static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop, | 54 | + 'tftp -g -r xmaton.png 10.0.2.2 ; md5sum xmaton.png', |
43 | { | 55 | + '821cd3cab8efd16ad6ee5acc3642a8ea') |
44 | MemOp size = mop & MO_SIZE; | 56 | + |
45 | 57 | +class MicroblazeBigEndianMachine(MicroblazeMachine): | |
46 | - mop |= MO_TE; | 58 | + |
47 | + mop |= mo_endian(dc); | 59 | def test_microblaze_s3adsp1800_legacy_be(self): |
48 | 60 | self.do_ballerina_be_test('petalogix-s3adsp1800') | |
49 | /* | 61 | |
50 | * When doing reverse accesses we need to do two things. | 62 | diff --git a/tests/functional/test_microblazeel_s3adsp1800.py b/tests/functional/test_microblazeel_s3adsp1800.py |
51 | @@ -XXX,XX +XXX,XX @@ static bool trans_swx(DisasContext *dc, arg_typea *arg) | 63 | index XXXXXXX..XXXXXXX 100755 |
52 | 64 | --- a/tests/functional/test_microblazeel_s3adsp1800.py | |
53 | tcg_gen_atomic_cmpxchg_i32(tval, cpu_res_addr, cpu_res_val, | 65 | +++ b/tests/functional/test_microblazeel_s3adsp1800.py |
54 | reg_for_write(dc, arg->rd), | 66 | @@ -XXX,XX +XXX,XX @@ |
55 | - dc->mem_index, MO_TE | MO_UL); | 67 | # This work is licensed under the terms of the GNU GPL, version 2 or |
56 | + dc->mem_index, mo_endian(dc) | MO_UL); | 68 | # later. See the COPYING file in the top-level directory. |
57 | 69 | ||
58 | tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_fail); | 70 | -from qemu_test import exec_command_and_wait_for_pattern |
59 | 71 | -from qemu_test import QemuSystemTest, Asset | |
72 | -from qemu_test import wait_for_console_pattern | ||
73 | +from qemu_test import QemuSystemTest | ||
74 | |||
75 | +from test_microblaze_s3adsp1800 import MicroblazeMachine | ||
76 | |||
77 | -class MicroblazeelMachine(QemuSystemTest): | ||
78 | - | ||
79 | - timeout = 90 | ||
80 | - | ||
81 | - ASSET_IMAGE_LE = Asset( | ||
82 | - ('https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/' | ||
83 | - 'day05.tar.xz'), | ||
84 | - 'b9b3d43c5dd79db88ada495cc6e0d1f591153fe41355e925d791fbf44de50c22') | ||
85 | - | ||
86 | - def do_xmaton_le_test(self, machine): | ||
87 | - self.require_netdev('user') | ||
88 | - self.set_machine(machine) | ||
89 | - self.archive_extract(self.ASSET_IMAGE_LE) | ||
90 | - self.vm.set_console() | ||
91 | - self.vm.add_args('-kernel', self.scratch_file('day13', 'xmaton.bin')) | ||
92 | - tftproot = self.scratch_file('day13') | ||
93 | - self.vm.add_args('-nic', f'user,tftp={tftproot}') | ||
94 | - self.vm.launch() | ||
95 | - wait_for_console_pattern(self, 'QEMU Advent Calendar 2023') | ||
96 | - wait_for_console_pattern(self, 'buildroot login:') | ||
97 | - exec_command_and_wait_for_pattern(self, 'root', '#') | ||
98 | - exec_command_and_wait_for_pattern(self, | ||
99 | - 'tftp -g -r xmaton.png 10.0.2.2 ; md5sum xmaton.png', | ||
100 | - '821cd3cab8efd16ad6ee5acc3642a8ea') | ||
101 | +class MicroblazeLittleEndianMachine(MicroblazeMachine): | ||
102 | |||
103 | def test_microblaze_s3adsp1800_legacy_le(self): | ||
104 | self.do_xmaton_le_test('petalogix-s3adsp1800') | ||
60 | -- | 105 | -- |
61 | 2.45.2 | 106 | 2.47.1 |
62 | 107 | ||
63 | 108 | diff view generated by jsdifflib |