1
First arm pullreq of the 5.1 cycle; mostly bugfixes and some
1
The following changes since commit 3db29dcac23da85486704ef9e7a8e7217f7829cd:
2
cleanup patches. The new clock modelling framework is the big
3
thing here.
4
2
5
-- PMM
3
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2023-01-12 13:51:36 +0000)
6
7
The following changes since commit 648db19685b7030aa558a4ddbd3a8e53d8c9a062:
8
9
Merge remote-tracking branch 'remotes/armbru/tags/pull-misc-2020-04-29' into staging (2020-04-29 15:07:33 +0100)
10
4
11
are available in the Git repository at:
5
are available in the Git repository at:
12
6
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200430
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230113
14
8
15
for you to fetch changes up to 1267437e593e85498f9105b3bdab796630d2e83f:
9
for you to fetch changes up to 08899b5c68a55a3780d707e2464073c8f2670d31:
16
10
17
hw/arm: xlnx-zcu102: Disable unsupported FDT firmware nodes (2020-04-30 11:52:29 +0100)
11
target/arm: allow writes to SCR_EL3.HXEn bit when FEAT_HCX is enabled (2023-01-13 13:19:36 +0000)
18
12
19
----------------------------------------------------------------
13
----------------------------------------------------------------
20
target-arm queue:
14
target-arm queue:
21
* xlnx-zdma: Fix endianness handling of descriptor loading
15
hw/arm/stm32f405: correctly describe the memory layout
22
* nrf51: Fix last GPIO CNF address
16
hw/arm: Add Olimex H405 board
23
* gicv3: Use gicr_typer in arm_gicv3_icc_reset
17
cubieboard: Support booting from an SD card image with u-boot on it
24
* msf2: Add EMAC block to SmartFusion2 SoC
18
target/arm: Fix sve_probe_page
25
* New clock modelling framework
19
target/arm: allow writes to SCR_EL3.HXEn bit when FEAT_HCX is enabled
26
* hw/arm: versal: Setup the ADMA with 128bit bus-width
20
various code cleanups
27
* Cadence: gem: fix wraparound in 64bit descriptors
28
* cadence_gem: clear RX control descriptor
29
* target/arm: Vectorize integer comparison vs zero
30
* hw/arm/virt: dt: add kaslr-seed property
31
* hw/arm: xlnx-zcu102: Disable unsupported FDT firmware nodes
32
21
33
----------------------------------------------------------------
22
----------------------------------------------------------------
34
Cameron Esfahani (1):
23
Evgeny Iakovlev (1):
35
nrf51: Fix last GPIO CNF address
24
target/arm: allow writes to SCR_EL3.HXEn bit when FEAT_HCX is enabled
36
25
37
Damien Hedde (7):
26
Felipe Balbi (2):
38
hw/core/clock-vmstate: define a vmstate entry for clock state
27
hw/arm/stm32f405: correctly describe the memory layout
39
qdev: add clock input&output support to devices.
28
hw/arm: Add Olimex H405
40
qdev-clock: introduce an init array to ease the device construction
41
hw/misc/zynq_slcr: add clock generation for uarts
42
hw/char/cadence_uart: add clock support
43
hw/arm/xilinx_zynq: connect uart clocks to slcr
44
qdev-monitor: print the device's clock with info qtree
45
29
46
Edgar E. Iglesias (7):
30
Philippe Mathieu-Daudé (27):
47
dma/xlnx-zdma: Fix descriptor loading (MEM) wrt endianness
31
hw/arm/pxa2xx: Simplify pxa255_init()
48
dma/xlnx-zdma: Fix descriptor loading (REG) wrt endianness
32
hw/arm/pxa2xx: Simplify pxa270_init()
49
hw/arm: versal: Setup the ADMA with 128bit bus-width
33
hw/arm/collie: Use the IEC binary prefix definitions
50
device_tree: Allow name wildcards in qemu_fdt_node_path()
34
hw/arm/collie: Simplify flash creation using for() loop
51
device_tree: Constify compat in qemu_fdt_node_path()
35
hw/arm/gumstix: Improve documentation
52
hw/arm: xlnx-zcu102: Move arm_boot_info into XlnxZCU102
36
hw/arm/gumstix: Use the IEC binary prefix definitions
53
hw/arm: xlnx-zcu102: Disable unsupported FDT firmware nodes
37
hw/arm/mainstone: Use the IEC binary prefix definitions
54
38
hw/arm/musicpal: Use the IEC binary prefix definitions
55
Jerome Forissier (2):
39
hw/arm/omap_sx1: Remove unused 'total_ram' definitions
56
hw/arm/virt: dt: move creation of /secure-chosen to create_fdt()
40
hw/arm/omap_sx1: Use the IEC binary prefix definitions
57
hw/arm/virt: dt: add kaslr-seed property
41
hw/arm/z2: Use the IEC binary prefix definitions
58
42
hw/arm/vexpress: Remove dead code in vexpress_common_init()
59
Keqian Zhu (2):
43
hw/arm: Remove unreachable code calling pflash_cfi01_register()
60
bugfix: Use gicr_typer in arm_gicv3_icc_reset
44
hw/arm/pxa: Avoid forward-declaring PXA2xxI2CState
61
Typo: Correct the name of CPU hotplug memory region
45
hw/gpio/omap_gpio: Add local variable to avoid embedded cast
62
46
hw/arm/omap: Drop useless casts from void * to pointer
63
Peter Maydell (2):
47
hw/gpio/omap_gpio: Use CamelCase for TYPE_OMAP1_GPIO type name
64
hw/core/clock: introduce clock object
48
hw/gpio/omap_gpio: Use CamelCase for TYPE_OMAP2_GPIO type name
65
docs/clocks: add device's clock documentation
49
hw/intc/omap_intc: Use CamelCase for TYPE_OMAP_INTC type name
66
50
hw/arm/stellaris: Drop useless casts from void * to pointer
67
Philippe Mathieu-Daudé (3):
51
hw/arm/stellaris: Use CamelCase for STELLARIS_ADC type name
68
target/arm: Restrict the Address Translate write operation to TCG accel
52
hw/arm/bcm2836: Remove definitions generated by OBJECT_DECLARE_TYPE()
69
target/arm/cpu: Use ARRAY_SIZE() to iterate over ARMCPUInfo[]
53
hw/arm/npcm7xx: Declare QOM macros using OBJECT_DECLARE_SIMPLE_TYPE()
70
target/arm/cpu: Update coding style to make checkpatch.pl happy
54
hw/misc/sbsa_ec: Rename TYPE_SBSA_EC -> TYPE_SBSA_SECURE_EC
71
55
hw/misc/sbsa_ec: Declare QOM macros using OBJECT_DECLARE_SIMPLE_TYPE()
72
Ramon Fried (2):
56
hw/intc/xilinx_intc: Use 'XpsIntc' typedef instead of 'struct xlx_pic'
73
Cadence: gem: fix wraparound in 64bit descriptors
57
hw/timer/xilinx_timer: Use XpsTimerState instead of 'struct timerblock'
74
net: cadence_gem: clear RX control descriptor
75
58
76
Richard Henderson (1):
59
Richard Henderson (1):
77
target/arm: Vectorize integer comparison vs zero
60
target/arm: Fix sve_probe_page
78
61
79
Subbaraya Sundeep (3):
62
Strahinja Jankovic (7):
80
hw/net: Add Smartfusion2 emac block
63
hw/misc: Allwinner-A10 Clock Controller Module Emulation
81
msf2: Add EMAC block to SmartFusion2 SoC
64
hw/misc: Allwinner A10 DRAM Controller Emulation
82
tests/boot_linux_console: Add ethernet test to SmartFusion2
65
{hw/i2c,docs/system/arm}: Allwinner TWI/I2C Emulation
66
hw/misc: AXP209 PMU Emulation
67
hw/arm: Add AXP209 to Cubieboard
68
hw/arm: Allwinner A10 enable SPL load from MMC
69
tests/avocado: Add SD boot test to Cubieboard
83
70
84
Thomas Huth (1):
71
docs/system/arm/cubieboard.rst | 1 +
85
target/arm: Make cpu_register() available for other files
72
docs/system/arm/orangepi.rst | 1 +
73
docs/system/arm/stm32.rst | 1 +
74
configs/devices/arm-softmmu/default.mak | 1 +
75
include/hw/adc/npcm7xx_adc.h | 7 +-
76
include/hw/arm/allwinner-a10.h | 27 ++
77
include/hw/arm/allwinner-h3.h | 3 +
78
include/hw/arm/npcm7xx.h | 18 +-
79
include/hw/arm/omap.h | 24 +-
80
include/hw/arm/pxa.h | 11 +-
81
include/hw/arm/stm32f405_soc.h | 5 +-
82
include/hw/i2c/allwinner-i2c.h | 55 ++++
83
include/hw/i2c/npcm7xx_smbus.h | 7 +-
84
include/hw/misc/allwinner-a10-ccm.h | 67 +++++
85
include/hw/misc/allwinner-a10-dramc.h | 68 +++++
86
include/hw/misc/npcm7xx_clk.h | 2 +-
87
include/hw/misc/npcm7xx_gcr.h | 6 +-
88
include/hw/misc/npcm7xx_mft.h | 7 +-
89
include/hw/misc/npcm7xx_pwm.h | 3 +-
90
include/hw/misc/npcm7xx_rng.h | 6 +-
91
include/hw/net/npcm7xx_emc.h | 5 +-
92
include/hw/sd/npcm7xx_sdhci.h | 4 +-
93
hw/arm/allwinner-a10.c | 40 +++
94
hw/arm/allwinner-h3.c | 11 +-
95
hw/arm/bcm2836.c | 9 +-
96
hw/arm/collie.c | 25 +-
97
hw/arm/cubieboard.c | 11 +
98
hw/arm/gumstix.c | 45 ++--
99
hw/arm/mainstone.c | 37 ++-
100
hw/arm/musicpal.c | 9 +-
101
hw/arm/olimex-stm32-h405.c | 69 +++++
102
hw/arm/omap1.c | 115 ++++----
103
hw/arm/omap2.c | 40 ++-
104
hw/arm/omap_sx1.c | 53 ++--
105
hw/arm/palm.c | 2 +-
106
hw/arm/pxa2xx.c | 8 +-
107
hw/arm/spitz.c | 6 +-
108
hw/arm/stellaris.c | 73 +++--
109
hw/arm/stm32f405_soc.c | 8 +
110
hw/arm/tosa.c | 2 +-
111
hw/arm/versatilepb.c | 6 +-
112
hw/arm/vexpress.c | 10 +-
113
hw/arm/z2.c | 16 +-
114
hw/char/omap_uart.c | 7 +-
115
hw/display/omap_dss.c | 15 +-
116
hw/display/omap_lcdc.c | 9 +-
117
hw/dma/omap_dma.c | 15 +-
118
hw/gpio/omap_gpio.c | 48 ++--
119
hw/i2c/allwinner-i2c.c | 459 ++++++++++++++++++++++++++++++++
120
hw/intc/omap_intc.c | 38 +--
121
hw/intc/xilinx_intc.c | 28 +-
122
hw/misc/allwinner-a10-ccm.c | 224 ++++++++++++++++
123
hw/misc/allwinner-a10-dramc.c | 179 +++++++++++++
124
hw/misc/axp209.c | 238 +++++++++++++++++
125
hw/misc/omap_gpmc.c | 12 +-
126
hw/misc/omap_l4.c | 7 +-
127
hw/misc/omap_sdrc.c | 7 +-
128
hw/misc/omap_tap.c | 5 +-
129
hw/misc/sbsa_ec.c | 12 +-
130
hw/sd/omap_mmc.c | 9 +-
131
hw/ssi/omap_spi.c | 7 +-
132
hw/timer/omap_gptimer.c | 22 +-
133
hw/timer/omap_synctimer.c | 4 +-
134
hw/timer/xilinx_timer.c | 27 +-
135
target/arm/helper.c | 3 +
136
target/arm/sve_helper.c | 14 +-
137
MAINTAINERS | 8 +
138
hw/arm/Kconfig | 9 +
139
hw/arm/meson.build | 1 +
140
hw/i2c/Kconfig | 4 +
141
hw/i2c/meson.build | 1 +
142
hw/i2c/trace-events | 5 +
143
hw/misc/Kconfig | 10 +
144
hw/misc/meson.build | 3 +
145
hw/misc/trace-events | 5 +
146
tests/avocado/boot_linux_console.py | 47 ++++
147
76 files changed, 1951 insertions(+), 455 deletions(-)
148
create mode 100644 include/hw/i2c/allwinner-i2c.h
149
create mode 100644 include/hw/misc/allwinner-a10-ccm.h
150
create mode 100644 include/hw/misc/allwinner-a10-dramc.h
151
create mode 100644 hw/arm/olimex-stm32-h405.c
152
create mode 100644 hw/i2c/allwinner-i2c.c
153
create mode 100644 hw/misc/allwinner-a10-ccm.c
154
create mode 100644 hw/misc/allwinner-a10-dramc.c
155
create mode 100644 hw/misc/axp209.c
86
156
87
hw/core/Makefile.objs | 2 +
88
hw/net/Makefile.objs | 1 +
89
tests/Makefile.include | 1 +
90
include/hw/arm/msf2-soc.h | 2 +
91
include/hw/char/cadence_uart.h | 1 +
92
include/hw/clock.h | 225 +++++++++++++
93
include/hw/gpio/nrf51_gpio.h | 2 +-
94
include/hw/net/msf2-emac.h | 53 +++
95
include/hw/qdev-clock.h | 159 +++++++++
96
include/hw/qdev-core.h | 12 +
97
include/sysemu/device_tree.h | 5 +-
98
target/arm/cpu-qom.h | 9 +-
99
target/arm/helper.h | 27 +-
100
target/arm/translate.h | 5 +
101
device_tree.c | 4 +-
102
hw/acpi/cpu.c | 2 +-
103
hw/arm/msf2-soc.c | 26 +-
104
hw/arm/virt.c | 20 +-
105
hw/arm/xilinx_zynq.c | 57 +++-
106
hw/arm/xlnx-versal.c | 2 +
107
hw/arm/xlnx-zcu102.c | 39 ++-
108
hw/char/cadence_uart.c | 73 +++-
109
hw/core/clock-vmstate.c | 25 ++
110
hw/core/clock.c | 130 ++++++++
111
hw/core/qdev-clock.c | 185 +++++++++++
112
hw/core/qdev.c | 12 +
113
hw/dma/xlnx-zdma.c | 25 +-
114
hw/intc/arm_gicv3_kvm.c | 4 +-
115
hw/misc/zynq_slcr.c | 172 +++++++++-
116
hw/net/cadence_gem.c | 16 +-
117
hw/net/msf2-emac.c | 589 +++++++++++++++++++++++++++++++++
118
qdev-monitor.c | 9 +
119
target/arm/cpu.c | 25 +-
120
target/arm/cpu64.c | 16 +-
121
target/arm/helper.c | 17 +
122
target/arm/neon_helper.c | 24 --
123
target/arm/translate-a64.c | 64 +---
124
target/arm/translate.c | 256 ++++++++++++--
125
target/arm/vec_helper.c | 25 ++
126
MAINTAINERS | 2 +
127
docs/devel/clocks.rst | 391 ++++++++++++++++++++++
128
docs/devel/index.rst | 1 +
129
hw/char/trace-events | 3 +
130
hw/core/trace-events | 7 +
131
tests/acceptance/boot_linux_console.py | 15 +-
132
45 files changed, 2538 insertions(+), 202 deletions(-)
133
create mode 100644 include/hw/clock.h
134
create mode 100644 include/hw/net/msf2-emac.h
135
create mode 100644 include/hw/qdev-clock.h
136
create mode 100644 hw/core/clock-vmstate.c
137
create mode 100644 hw/core/clock.c
138
create mode 100644 hw/core/qdev-clock.c
139
create mode 100644 hw/net/msf2-emac.c
140
create mode 100644 docs/devel/clocks.rst
141
diff view generated by jsdifflib
1
From: Subbaraya Sundeep <sundeep.lkml@gmail.com>
1
From: Felipe Balbi <balbi@kernel.org>
2
2
3
With SmartFusion2 Ethernet MAC model in
3
STM32F405 has 128K of SRAM and another 64K of CCM (Core-coupled
4
place this patch adds the same to SoC.
4
Memory) at a different base address. Correctly describe the memory
5
layout to give existing FW images a chance to run unmodified.
5
6
6
Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
7
Reviewed-by: Alistair Francis <alistair@alistair23.me>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Felipe Balbi <balbi@kernel.org>
9
Message-id: 1587048891-30493-3-git-send-email-sundeep.lkml@gmail.com
10
Message-id: 20221230145733.200496-2-balbi@kernel.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
include/hw/arm/msf2-soc.h | 2 ++
13
include/hw/arm/stm32f405_soc.h | 5 ++++-
13
hw/arm/msf2-soc.c | 26 ++++++++++++++++++++++++--
14
hw/arm/stm32f405_soc.c | 8 ++++++++
14
2 files changed, 26 insertions(+), 2 deletions(-)
15
2 files changed, 12 insertions(+), 1 deletion(-)
15
16
16
diff --git a/include/hw/arm/msf2-soc.h b/include/hw/arm/msf2-soc.h
17
diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/msf2-soc.h
19
--- a/include/hw/arm/stm32f405_soc.h
19
+++ b/include/hw/arm/msf2-soc.h
20
+++ b/include/hw/arm/stm32f405_soc.h
20
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(STM32F405State, STM32F405_SOC)
21
#include "hw/timer/mss-timer.h"
22
#define FLASH_BASE_ADDRESS 0x08000000
22
#include "hw/misc/msf2-sysreg.h"
23
#define FLASH_SIZE (1024 * 1024)
23
#include "hw/ssi/mss-spi.h"
24
#define SRAM_BASE_ADDRESS 0x20000000
24
+#include "hw/net/msf2-emac.h"
25
-#define SRAM_SIZE (192 * 1024)
25
26
+#define SRAM_SIZE (128 * 1024)
26
#define TYPE_MSF2_SOC "msf2-soc"
27
+#define CCM_BASE_ADDRESS 0x10000000
27
#define MSF2_SOC(obj) OBJECT_CHECK(MSF2State, (obj), TYPE_MSF2_SOC)
28
+#define CCM_SIZE (64 * 1024)
28
@@ -XXX,XX +XXX,XX @@ typedef struct MSF2State {
29
29
MSF2SysregState sysreg;
30
struct STM32F405State {
30
MSSTimerState timer;
31
/*< private >*/
31
MSSSpiState spi[MSF2_NUM_SPIS];
32
@@ -XXX,XX +XXX,XX @@ struct STM32F405State {
32
+ MSF2EmacState emac;
33
STM32F2XXADCState adc[STM_NUM_ADCS];
33
} MSF2State;
34
STM32F2XXSPIState spi[STM_NUM_SPIS];
34
35
35
#endif
36
+ MemoryRegion ccm;
36
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
37
MemoryRegion sram;
38
MemoryRegion flash;
39
MemoryRegion flash_alias;
40
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
37
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/msf2-soc.c
42
--- a/hw/arm/stm32f405_soc.c
39
+++ b/hw/arm/msf2-soc.c
43
+++ b/hw/arm/stm32f405_soc.c
40
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@ static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
41
/*
42
* SmartFusion2 SoC emulation.
43
*
44
- * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
45
+ * Copyright (c) 2017-2020 Subbaraya Sundeep <sundeep.lkml@gmail.com>
46
*
47
* Permission is hereby granted, free of charge, to any person obtaining a copy
48
* of this software and associated documentation files (the "Software"), to deal
49
@@ -XXX,XX +XXX,XX @@
50
51
#define MSF2_TIMER_BASE 0x40004000
52
#define MSF2_SYSREG_BASE 0x40038000
53
+#define MSF2_EMAC_BASE 0x40041000
54
55
#define ENVM_BASE_ADDRESS 0x60000000
56
57
#define SRAM_BASE_ADDRESS 0x20000000
58
59
+#define MSF2_EMAC_IRQ 12
60
+
61
#define MSF2_ENVM_MAX_SIZE (512 * KiB)
62
63
/*
64
@@ -XXX,XX +XXX,XX @@ static void m2sxxx_soc_initfn(Object *obj)
65
sysbus_init_child_obj(obj, "spi[*]", &s->spi[i], sizeof(s->spi[i]),
66
TYPE_MSS_SPI);
67
}
45
}
68
+
46
memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, &s->sram);
69
+ sysbus_init_child_obj(obj, "emac", &s->emac, sizeof(s->emac),
47
70
+ TYPE_MSS_EMAC);
48
+ memory_region_init_ram(&s->ccm, NULL, "STM32F405.ccm", CCM_SIZE,
71
+ if (nd_table[0].used) {
49
+ &err);
72
+ qemu_check_nic_model(&nd_table[0], TYPE_MSS_EMAC);
73
+ qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
74
+ }
75
}
76
77
static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
78
@@ -XXX,XX +XXX,XX @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
79
g_free(bus_name);
80
}
81
82
+ dev = DEVICE(&s->emac);
83
+ object_property_set_link(OBJECT(&s->emac), OBJECT(get_system_memory()),
84
+ "ahb-bus", &error_abort);
85
+ object_property_set_bool(OBJECT(&s->emac), true, "realized", &err);
86
+ if (err != NULL) {
50
+ if (err != NULL) {
87
+ error_propagate(errp, err);
51
+ error_propagate(errp, err);
88
+ return;
52
+ return;
89
+ }
53
+ }
90
+ busdev = SYS_BUS_DEVICE(dev);
54
+ memory_region_add_subregion(system_memory, CCM_BASE_ADDRESS, &s->ccm);
91
+ sysbus_mmio_map(busdev, 0, MSF2_EMAC_BASE);
92
+ sysbus_connect_irq(busdev, 0,
93
+ qdev_get_gpio_in(armv7m, MSF2_EMAC_IRQ));
94
+
55
+
95
/* Below devices are not modelled yet. */
56
armv7m = DEVICE(&s->armv7m);
96
create_unimplemented_device("i2c_0", 0x40002000, 0x1000);
57
qdev_prop_set_uint32(armv7m, "num-irq", 96);
97
create_unimplemented_device("dma", 0x40003000, 0x1000);
58
qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
98
@@ -XXX,XX +XXX,XX @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
99
create_unimplemented_device("can", 0x40015000, 0x1000);
100
create_unimplemented_device("rtc", 0x40017000, 0x1000);
101
create_unimplemented_device("apb_config", 0x40020000, 0x10000);
102
- create_unimplemented_device("emac", 0x40041000, 0x1000);
103
create_unimplemented_device("usb", 0x40043000, 0x1000);
104
}
105
106
--
59
--
107
2.20.1
60
2.34.1
108
61
109
62
diff view generated by jsdifflib
1
From: Subbaraya Sundeep <sundeep.lkml@gmail.com>
1
From: Felipe Balbi <balbi@kernel.org>
2
2
3
Modelled Ethernet MAC of Smartfusion2 SoC.
3
Olimex makes a series of low-cost STM32 boards. This commit introduces
4
Micrel KSZ8051 PHY is present on Emcraft's
4
the minimum setup to support SMT32-H405. See [1] for details
5
SOM kit hence same PHY is emulated.
6
5
7
Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
6
[1] https://www.olimex.com/Products/ARM/ST/STM32-H405/
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Felipe Balbi <balbi@kernel.org>
10
Message-id: 1587048891-30493-2-git-send-email-sundeep.lkml@gmail.com
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 20221230145733.200496-3-balbi@kernel.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
hw/net/Makefile.objs | 1 +
14
docs/system/arm/stm32.rst | 1 +
14
include/hw/net/msf2-emac.h | 53 ++++
15
configs/devices/arm-softmmu/default.mak | 1 +
15
hw/net/msf2-emac.c | 589 +++++++++++++++++++++++++++++++++++++
16
hw/arm/olimex-stm32-h405.c | 69 +++++++++++++++++++++++++
16
MAINTAINERS | 2 +
17
MAINTAINERS | 6 +++
17
4 files changed, 645 insertions(+)
18
hw/arm/Kconfig | 4 ++
18
create mode 100644 include/hw/net/msf2-emac.h
19
hw/arm/meson.build | 1 +
19
create mode 100644 hw/net/msf2-emac.c
20
6 files changed, 82 insertions(+)
21
create mode 100644 hw/arm/olimex-stm32-h405.c
20
22
21
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
23
diff --git a/docs/system/arm/stm32.rst b/docs/system/arm/stm32.rst
22
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/net/Makefile.objs
25
--- a/docs/system/arm/stm32.rst
24
+++ b/hw/net/Makefile.objs
26
+++ b/docs/system/arm/stm32.rst
25
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_ROCKER) += rocker/rocker.o rocker/rocker_fp.o \
27
@@ -XXX,XX +XXX,XX @@ The STM32F4 series is based on ARM Cortex-M4F core. This series is pin-to-pin
26
obj-$(call lnot,$(CONFIG_ROCKER)) += rocker/qmp-norocker.o
28
compatible with STM32F2 series. The following machines are based on this chip :
27
29
28
common-obj-$(CONFIG_CAN_BUS) += can/
30
- ``netduinoplus2`` Netduino Plus 2 board with STM32F405RGT6 microcontroller
29
+common-obj-$(CONFIG_MSF2) += msf2-emac.o
31
+- ``olimex-stm32-h405`` Olimex STM32 H405 board with STM32F405RGT6 microcontroller
30
diff --git a/include/hw/net/msf2-emac.h b/include/hw/net/msf2-emac.h
32
33
There are many other STM32 series that are currently not supported by QEMU.
34
35
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
36
index XXXXXXX..XXXXXXX 100644
37
--- a/configs/devices/arm-softmmu/default.mak
38
+++ b/configs/devices/arm-softmmu/default.mak
39
@@ -XXX,XX +XXX,XX @@ CONFIG_COLLIE=y
40
CONFIG_ASPEED_SOC=y
41
CONFIG_NETDUINO2=y
42
CONFIG_NETDUINOPLUS2=y
43
+CONFIG_OLIMEX_STM32_H405=y
44
CONFIG_MPS2=y
45
CONFIG_RASPI=y
46
CONFIG_DIGIC=y
47
diff --git a/hw/arm/olimex-stm32-h405.c b/hw/arm/olimex-stm32-h405.c
31
new file mode 100644
48
new file mode 100644
32
index XXXXXXX..XXXXXXX
49
index XXXXXXX..XXXXXXX
33
--- /dev/null
50
--- /dev/null
34
+++ b/include/hw/net/msf2-emac.h
51
+++ b/hw/arm/olimex-stm32-h405.c
35
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@
36
+/*
53
+/*
37
+ * QEMU model of the Smartfusion2 Ethernet MAC.
54
+ * ST STM32VLDISCOVERY machine
55
+ * Olimex STM32-H405 machine
38
+ *
56
+ *
39
+ * Copyright (c) 2020 Subbaraya Sundeep <sundeep.lkml@gmail.com>.
57
+ * Copyright (c) 2022 Felipe Balbi <balbi@kernel.org>
40
+ *
58
+ *
41
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
59
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
42
+ * of this software and associated documentation files (the "Software"), to deal
60
+ * of this software and associated documentation files (the "Software"), to deal
43
+ * in the Software without restriction, including without limitation the rights
61
+ * in the Software without restriction, including without limitation the rights
44
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
62
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
...
...
55
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
73
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
56
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
74
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
57
+ * THE SOFTWARE.
75
+ * THE SOFTWARE.
58
+ */
76
+ */
59
+
77
+
60
+#include "hw/sysbus.h"
78
+#include "qemu/osdep.h"
61
+#include "exec/memory.h"
79
+#include "qapi/error.h"
62
+#include "net/net.h"
80
+#include "hw/boards.h"
63
+#include "net/eth.h"
81
+#include "hw/qdev-properties.h"
82
+#include "hw/qdev-clock.h"
83
+#include "qemu/error-report.h"
84
+#include "hw/arm/stm32f405_soc.h"
85
+#include "hw/arm/boot.h"
64
+
86
+
65
+#define TYPE_MSS_EMAC "msf2-emac"
87
+/* olimex-stm32-h405 implementation is derived from netduinoplus2 */
66
+#define MSS_EMAC(obj) \
67
+ OBJECT_CHECK(MSF2EmacState, (obj), TYPE_MSS_EMAC)
68
+
88
+
69
+#define R_MAX (0x1a0 / 4)
89
+/* Main SYSCLK frequency in Hz (168MHz) */
70
+#define PHY_MAX_REGS 32
90
+#define SYSCLK_FRQ 168000000ULL
71
+
91
+
72
+typedef struct MSF2EmacState {
92
+static void olimex_stm32_h405_init(MachineState *machine)
73
+ SysBusDevice parent;
93
+{
94
+ DeviceState *dev;
95
+ Clock *sysclk;
74
+
96
+
75
+ MemoryRegion mmio;
97
+ /* This clock doesn't need migration because it is fixed-frequency */
76
+ MemoryRegion *dma_mr;
98
+ sysclk = clock_new(OBJECT(machine), "SYSCLK");
77
+ AddressSpace dma_as;
99
+ clock_set_hz(sysclk, SYSCLK_FRQ);
78
+
100
+
79
+ qemu_irq irq;
101
+ dev = qdev_new(TYPE_STM32F405_SOC);
80
+ NICState *nic;
102
+ qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
81
+ NICConf conf;
103
+ qdev_connect_clock_in(dev, "sysclk", sysclk);
104
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
82
+
105
+
83
+ uint8_t mac_addr[ETH_ALEN];
106
+ armv7m_load_kernel(ARM_CPU(first_cpu),
84
+ uint32_t rx_desc;
107
+ machine->kernel_filename,
85
+ uint16_t phy_regs[PHY_MAX_REGS];
108
+ 0, FLASH_SIZE);
86
+
87
+ uint32_t regs[R_MAX];
88
+} MSF2EmacState;
89
diff --git a/hw/net/msf2-emac.c b/hw/net/msf2-emac.c
90
new file mode 100644
91
index XXXXXXX..XXXXXXX
92
--- /dev/null
93
+++ b/hw/net/msf2-emac.c
94
@@ -XXX,XX +XXX,XX @@
95
+/*
96
+ * QEMU model of the Smartfusion2 Ethernet MAC.
97
+ *
98
+ * Copyright (c) 2020 Subbaraya Sundeep <sundeep.lkml@gmail.com>.
99
+ *
100
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
101
+ * of this software and associated documentation files (the "Software"), to deal
102
+ * in the Software without restriction, including without limitation the rights
103
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
104
+ * copies of the Software, and to permit persons to whom the Software is
105
+ * furnished to do so, subject to the following conditions:
106
+ *
107
+ * The above copyright notice and this permission notice shall be included in
108
+ * all copies or substantial portions of the Software.
109
+ *
110
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
111
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
112
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
113
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
114
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
115
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
116
+ * THE SOFTWARE.
117
+ *
118
+ * Refer to section Ethernet MAC in the document:
119
+ * UG0331: SmartFusion2 Microcontroller Subsystem User Guide
120
+ * Datasheet URL:
121
+ * https://www.microsemi.com/document-portal/cat_view/56661-internal-documents/
122
+ * 56758-soc?lang=en&limit=20&limitstart=220
123
+ */
124
+
125
+#include "qemu/osdep.h"
126
+#include "qemu-common.h"
127
+#include "qemu/log.h"
128
+#include "qapi/error.h"
129
+#include "exec/address-spaces.h"
130
+#include "hw/registerfields.h"
131
+#include "hw/net/msf2-emac.h"
132
+#include "hw/net/mii.h"
133
+#include "hw/irq.h"
134
+#include "hw/qdev-properties.h"
135
+#include "migration/vmstate.h"
136
+
137
+REG32(CFG1, 0x0)
138
+ FIELD(CFG1, RESET, 31, 1)
139
+ FIELD(CFG1, RX_EN, 2, 1)
140
+ FIELD(CFG1, TX_EN, 0, 1)
141
+ FIELD(CFG1, LB_EN, 8, 1)
142
+REG32(CFG2, 0x4)
143
+REG32(IFG, 0x8)
144
+REG32(HALF_DUPLEX, 0xc)
145
+REG32(MAX_FRAME_LENGTH, 0x10)
146
+REG32(MII_CMD, 0x24)
147
+ FIELD(MII_CMD, READ, 0, 1)
148
+REG32(MII_ADDR, 0x28)
149
+ FIELD(MII_ADDR, REGADDR, 0, 5)
150
+ FIELD(MII_ADDR, PHYADDR, 8, 5)
151
+REG32(MII_CTL, 0x2c)
152
+REG32(MII_STS, 0x30)
153
+REG32(STA1, 0x40)
154
+REG32(STA2, 0x44)
155
+REG32(FIFO_CFG0, 0x48)
156
+REG32(FIFO_CFG4, 0x58)
157
+ FIELD(FIFO_CFG4, BCAST, 9, 1)
158
+ FIELD(FIFO_CFG4, MCAST, 8, 1)
159
+REG32(FIFO_CFG5, 0x5C)
160
+ FIELD(FIFO_CFG5, BCAST, 9, 1)
161
+ FIELD(FIFO_CFG5, MCAST, 8, 1)
162
+REG32(DMA_TX_CTL, 0x180)
163
+ FIELD(DMA_TX_CTL, EN, 0, 1)
164
+REG32(DMA_TX_DESC, 0x184)
165
+REG32(DMA_TX_STATUS, 0x188)
166
+ FIELD(DMA_TX_STATUS, PKTCNT, 16, 8)
167
+ FIELD(DMA_TX_STATUS, UNDERRUN, 1, 1)
168
+ FIELD(DMA_TX_STATUS, PKT_SENT, 0, 1)
169
+REG32(DMA_RX_CTL, 0x18c)
170
+ FIELD(DMA_RX_CTL, EN, 0, 1)
171
+REG32(DMA_RX_DESC, 0x190)
172
+REG32(DMA_RX_STATUS, 0x194)
173
+ FIELD(DMA_RX_STATUS, PKTCNT, 16, 8)
174
+ FIELD(DMA_RX_STATUS, OVERFLOW, 2, 1)
175
+ FIELD(DMA_RX_STATUS, PKT_RCVD, 0, 1)
176
+REG32(DMA_IRQ_MASK, 0x198)
177
+REG32(DMA_IRQ, 0x19c)
178
+
179
+#define EMPTY_MASK (1 << 31)
180
+#define PKT_SIZE 0x7FF
181
+#define PHYADDR 0x1
182
+#define MAX_PKT_SIZE 2048
183
+
184
+typedef struct {
185
+ uint32_t pktaddr;
186
+ uint32_t pktsize;
187
+ uint32_t next;
188
+} EmacDesc;
189
+
190
+static uint32_t emac_get_isr(MSF2EmacState *s)
191
+{
192
+ uint32_t ier = s->regs[R_DMA_IRQ_MASK];
193
+ uint32_t tx = s->regs[R_DMA_TX_STATUS] & 0xF;
194
+ uint32_t rx = s->regs[R_DMA_RX_STATUS] & 0xF;
195
+ uint32_t isr = (rx << 4) | tx;
196
+
197
+ s->regs[R_DMA_IRQ] = ier & isr;
198
+ return s->regs[R_DMA_IRQ];
199
+}
109
+}
200
+
110
+
201
+static void emac_update_irq(MSF2EmacState *s)
111
+static void olimex_stm32_h405_machine_init(MachineClass *mc)
202
+{
112
+{
203
+ bool intr = emac_get_isr(s);
113
+ mc->desc = "Olimex STM32-H405 (Cortex-M4)";
114
+ mc->init = olimex_stm32_h405_init;
115
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
204
+
116
+
205
+ qemu_set_irq(s->irq, intr);
117
+ /* SRAM pre-allocated as part of the SoC instantiation */
118
+ mc->default_ram_size = 0;
206
+}
119
+}
207
+
120
+
208
+static void emac_load_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
121
+DEFINE_MACHINE("olimex-stm32-h405", olimex_stm32_h405_machine_init)
209
+{
210
+ address_space_read(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
211
+ /* Convert from LE into host endianness. */
212
+ d->pktaddr = le32_to_cpu(d->pktaddr);
213
+ d->pktsize = le32_to_cpu(d->pktsize);
214
+ d->next = le32_to_cpu(d->next);
215
+}
216
+
217
+static void emac_store_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
218
+{
219
+ /* Convert from host endianness into LE. */
220
+ d->pktaddr = cpu_to_le32(d->pktaddr);
221
+ d->pktsize = cpu_to_le32(d->pktsize);
222
+ d->next = cpu_to_le32(d->next);
223
+
224
+ address_space_write(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
225
+}
226
+
227
+static void msf2_dma_tx(MSF2EmacState *s)
228
+{
229
+ NetClientState *nc = qemu_get_queue(s->nic);
230
+ hwaddr desc = s->regs[R_DMA_TX_DESC];
231
+ uint8_t buf[MAX_PKT_SIZE];
232
+ EmacDesc d;
233
+ int size;
234
+ uint8_t pktcnt;
235
+ uint32_t status;
236
+
237
+ if (!(s->regs[R_CFG1] & R_CFG1_TX_EN_MASK)) {
238
+ return;
239
+ }
240
+
241
+ while (1) {
242
+ emac_load_desc(s, &d, desc);
243
+ if (d.pktsize & EMPTY_MASK) {
244
+ break;
245
+ }
246
+ size = d.pktsize & PKT_SIZE;
247
+ address_space_read(&s->dma_as, d.pktaddr, MEMTXATTRS_UNSPECIFIED,
248
+ buf, size);
249
+ /*
250
+ * This is very basic way to send packets. Ideally there should be
251
+ * a FIFO and packets should be sent out from FIFO only when
252
+ * R_CFG1 bit 0 is set.
253
+ */
254
+ if (s->regs[R_CFG1] & R_CFG1_LB_EN_MASK) {
255
+ nc->info->receive(nc, buf, size);
256
+ } else {
257
+ qemu_send_packet(nc, buf, size);
258
+ }
259
+ d.pktsize |= EMPTY_MASK;
260
+ emac_store_desc(s, &d, desc);
261
+ /* update sent packets count */
262
+ status = s->regs[R_DMA_TX_STATUS];
263
+ pktcnt = FIELD_EX32(status, DMA_TX_STATUS, PKTCNT);
264
+ pktcnt++;
265
+ s->regs[R_DMA_TX_STATUS] = FIELD_DP32(status, DMA_TX_STATUS,
266
+ PKTCNT, pktcnt);
267
+ s->regs[R_DMA_TX_STATUS] |= R_DMA_TX_STATUS_PKT_SENT_MASK;
268
+ desc = d.next;
269
+ }
270
+ s->regs[R_DMA_TX_STATUS] |= R_DMA_TX_STATUS_UNDERRUN_MASK;
271
+ s->regs[R_DMA_TX_CTL] &= ~R_DMA_TX_CTL_EN_MASK;
272
+}
273
+
274
+static void msf2_phy_update_link(MSF2EmacState *s)
275
+{
276
+ /* Autonegotiation status mirrors link status. */
277
+ if (qemu_get_queue(s->nic)->link_down) {
278
+ s->phy_regs[MII_BMSR] &= ~(MII_BMSR_AN_COMP |
279
+ MII_BMSR_LINK_ST);
280
+ } else {
281
+ s->phy_regs[MII_BMSR] |= (MII_BMSR_AN_COMP |
282
+ MII_BMSR_LINK_ST);
283
+ }
284
+}
285
+
286
+static void msf2_phy_reset(MSF2EmacState *s)
287
+{
288
+ memset(&s->phy_regs[0], 0, sizeof(s->phy_regs));
289
+ s->phy_regs[MII_BMCR] = 0x1140;
290
+ s->phy_regs[MII_BMSR] = 0x7968;
291
+ s->phy_regs[MII_PHYID1] = 0x0022;
292
+ s->phy_regs[MII_PHYID2] = 0x1550;
293
+ s->phy_regs[MII_ANAR] = 0x01E1;
294
+ s->phy_regs[MII_ANLPAR] = 0xCDE1;
295
+
296
+ msf2_phy_update_link(s);
297
+}
298
+
299
+static void write_to_phy(MSF2EmacState *s)
300
+{
301
+ uint8_t reg_addr = s->regs[R_MII_ADDR] & R_MII_ADDR_REGADDR_MASK;
302
+ uint8_t phy_addr = (s->regs[R_MII_ADDR] >> R_MII_ADDR_PHYADDR_SHIFT) &
303
+ R_MII_ADDR_REGADDR_MASK;
304
+ uint16_t data = s->regs[R_MII_CTL] & 0xFFFF;
305
+
306
+ if (phy_addr != PHYADDR) {
307
+ return;
308
+ }
309
+
310
+ switch (reg_addr) {
311
+ case MII_BMCR:
312
+ if (data & MII_BMCR_RESET) {
313
+ /* Phy reset */
314
+ msf2_phy_reset(s);
315
+ data &= ~MII_BMCR_RESET;
316
+ }
317
+ if (data & MII_BMCR_AUTOEN) {
318
+ /* Complete autonegotiation immediately */
319
+ data &= ~MII_BMCR_AUTOEN;
320
+ s->phy_regs[MII_BMSR] |= MII_BMSR_AN_COMP;
321
+ }
322
+ break;
323
+ }
324
+
325
+ s->phy_regs[reg_addr] = data;
326
+}
327
+
328
+static uint16_t read_from_phy(MSF2EmacState *s)
329
+{
330
+ uint8_t reg_addr = s->regs[R_MII_ADDR] & R_MII_ADDR_REGADDR_MASK;
331
+ uint8_t phy_addr = (s->regs[R_MII_ADDR] >> R_MII_ADDR_PHYADDR_SHIFT) &
332
+ R_MII_ADDR_REGADDR_MASK;
333
+
334
+ if (phy_addr == PHYADDR) {
335
+ return s->phy_regs[reg_addr];
336
+ } else {
337
+ return 0xFFFF;
338
+ }
339
+}
340
+
341
+static void msf2_emac_do_reset(MSF2EmacState *s)
342
+{
343
+ memset(&s->regs[0], 0, sizeof(s->regs));
344
+ s->regs[R_CFG1] = 0x80000000;
345
+ s->regs[R_CFG2] = 0x00007000;
346
+ s->regs[R_IFG] = 0x40605060;
347
+ s->regs[R_HALF_DUPLEX] = 0x00A1F037;
348
+ s->regs[R_MAX_FRAME_LENGTH] = 0x00000600;
349
+ s->regs[R_FIFO_CFG5] = 0X3FFFF;
350
+
351
+ msf2_phy_reset(s);
352
+}
353
+
354
+static uint64_t emac_read(void *opaque, hwaddr addr, unsigned int size)
355
+{
356
+ MSF2EmacState *s = opaque;
357
+ uint32_t r = 0;
358
+
359
+ addr >>= 2;
360
+
361
+ switch (addr) {
362
+ case R_DMA_IRQ:
363
+ r = emac_get_isr(s);
364
+ break;
365
+ default:
366
+ if (addr >= ARRAY_SIZE(s->regs)) {
367
+ qemu_log_mask(LOG_GUEST_ERROR,
368
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
369
+ addr * 4);
370
+ return r;
371
+ }
372
+ r = s->regs[addr];
373
+ break;
374
+ }
375
+ return r;
376
+}
377
+
378
+static void emac_write(void *opaque, hwaddr addr, uint64_t val64,
379
+ unsigned int size)
380
+{
381
+ MSF2EmacState *s = opaque;
382
+ uint32_t value = val64;
383
+ uint32_t enreqbits;
384
+ uint8_t pktcnt;
385
+
386
+ addr >>= 2;
387
+ switch (addr) {
388
+ case R_DMA_TX_CTL:
389
+ s->regs[addr] = value;
390
+ if (value & R_DMA_TX_CTL_EN_MASK) {
391
+ msf2_dma_tx(s);
392
+ }
393
+ break;
394
+ case R_DMA_RX_CTL:
395
+ s->regs[addr] = value;
396
+ if (value & R_DMA_RX_CTL_EN_MASK) {
397
+ s->rx_desc = s->regs[R_DMA_RX_DESC];
398
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
399
+ }
400
+ break;
401
+ case R_CFG1:
402
+ s->regs[addr] = value;
403
+ if (value & R_CFG1_RESET_MASK) {
404
+ msf2_emac_do_reset(s);
405
+ }
406
+ break;
407
+ case R_FIFO_CFG0:
408
+ /*
409
+ * For our implementation, turning on modules is instantaneous,
410
+ * so the states requested via the *ENREQ bits appear in the
411
+ * *ENRPLY bits immediately. Also the reset bits to reset PE-MCXMAC
412
+ * module are not emulated here since it deals with start of frames,
413
+ * inter-packet gap and control frames.
414
+ */
415
+ enreqbits = extract32(value, 8, 5);
416
+ s->regs[addr] = deposit32(value, 16, 5, enreqbits);
417
+ break;
418
+ case R_DMA_TX_DESC:
419
+ if (value & 0x3) {
420
+ qemu_log_mask(LOG_GUEST_ERROR, "Tx Descriptor address should be"
421
+ " 32 bit aligned\n");
422
+ }
423
+ /* Ignore [1:0] bits */
424
+ s->regs[addr] = value & ~3;
425
+ break;
426
+ case R_DMA_RX_DESC:
427
+ if (value & 0x3) {
428
+ qemu_log_mask(LOG_GUEST_ERROR, "Rx Descriptor address should be"
429
+ " 32 bit aligned\n");
430
+ }
431
+ /* Ignore [1:0] bits */
432
+ s->regs[addr] = value & ~3;
433
+ break;
434
+ case R_DMA_TX_STATUS:
435
+ if (value & R_DMA_TX_STATUS_UNDERRUN_MASK) {
436
+ s->regs[addr] &= ~R_DMA_TX_STATUS_UNDERRUN_MASK;
437
+ }
438
+ if (value & R_DMA_TX_STATUS_PKT_SENT_MASK) {
439
+ pktcnt = FIELD_EX32(s->regs[addr], DMA_TX_STATUS, PKTCNT);
440
+ pktcnt--;
441
+ s->regs[addr] = FIELD_DP32(s->regs[addr], DMA_TX_STATUS,
442
+ PKTCNT, pktcnt);
443
+ if (pktcnt == 0) {
444
+ s->regs[addr] &= ~R_DMA_TX_STATUS_PKT_SENT_MASK;
445
+ }
446
+ }
447
+ break;
448
+ case R_DMA_RX_STATUS:
449
+ if (value & R_DMA_RX_STATUS_OVERFLOW_MASK) {
450
+ s->regs[addr] &= ~R_DMA_RX_STATUS_OVERFLOW_MASK;
451
+ }
452
+ if (value & R_DMA_RX_STATUS_PKT_RCVD_MASK) {
453
+ pktcnt = FIELD_EX32(s->regs[addr], DMA_RX_STATUS, PKTCNT);
454
+ pktcnt--;
455
+ s->regs[addr] = FIELD_DP32(s->regs[addr], DMA_RX_STATUS,
456
+ PKTCNT, pktcnt);
457
+ if (pktcnt == 0) {
458
+ s->regs[addr] &= ~R_DMA_RX_STATUS_PKT_RCVD_MASK;
459
+ }
460
+ }
461
+ break;
462
+ case R_DMA_IRQ:
463
+ break;
464
+ case R_MII_CMD:
465
+ if (value & R_MII_CMD_READ_MASK) {
466
+ s->regs[R_MII_STS] = read_from_phy(s);
467
+ }
468
+ break;
469
+ case R_MII_CTL:
470
+ s->regs[addr] = value;
471
+ write_to_phy(s);
472
+ break;
473
+ case R_STA1:
474
+ s->regs[addr] = value;
475
+ /*
476
+ * R_STA1 [31:24] : octet 1 of mac address
477
+ * R_STA1 [23:16] : octet 2 of mac address
478
+ * R_STA1 [15:8] : octet 3 of mac address
479
+ * R_STA1 [7:0] : octet 4 of mac address
480
+ */
481
+ stl_be_p(s->mac_addr, value);
482
+ break;
483
+ case R_STA2:
484
+ s->regs[addr] = value;
485
+ /*
486
+ * R_STA2 [31:24] : octet 5 of mac address
487
+ * R_STA2 [23:16] : octet 6 of mac address
488
+ */
489
+ stw_be_p(s->mac_addr + 4, value >> 16);
490
+ break;
491
+ default:
492
+ if (addr >= ARRAY_SIZE(s->regs)) {
493
+ qemu_log_mask(LOG_GUEST_ERROR,
494
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
495
+ addr * 4);
496
+ return;
497
+ }
498
+ s->regs[addr] = value;
499
+ break;
500
+ }
501
+ emac_update_irq(s);
502
+}
503
+
504
+static const MemoryRegionOps emac_ops = {
505
+ .read = emac_read,
506
+ .write = emac_write,
507
+ .endianness = DEVICE_NATIVE_ENDIAN,
508
+ .impl = {
509
+ .min_access_size = 4,
510
+ .max_access_size = 4
511
+ }
512
+};
513
+
514
+static bool emac_can_rx(NetClientState *nc)
515
+{
516
+ MSF2EmacState *s = qemu_get_nic_opaque(nc);
517
+
518
+ return (s->regs[R_CFG1] & R_CFG1_RX_EN_MASK) &&
519
+ (s->regs[R_DMA_RX_CTL] & R_DMA_RX_CTL_EN_MASK);
520
+}
521
+
522
+static bool addr_filter_ok(MSF2EmacState *s, const uint8_t *buf)
523
+{
524
+ /* The broadcast MAC address: FF:FF:FF:FF:FF:FF */
525
+ const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF,
526
+ 0xFF, 0xFF };
527
+ bool bcast_en = true;
528
+ bool mcast_en = true;
529
+
530
+ if (s->regs[R_FIFO_CFG5] & R_FIFO_CFG5_BCAST_MASK) {
531
+ bcast_en = true; /* Broadcast dont care for drop circuitry */
532
+ } else if (s->regs[R_FIFO_CFG4] & R_FIFO_CFG4_BCAST_MASK) {
533
+ bcast_en = false;
534
+ }
535
+
536
+ if (s->regs[R_FIFO_CFG5] & R_FIFO_CFG5_MCAST_MASK) {
537
+ mcast_en = true; /* Multicast dont care for drop circuitry */
538
+ } else if (s->regs[R_FIFO_CFG4] & R_FIFO_CFG4_MCAST_MASK) {
539
+ mcast_en = false;
540
+ }
541
+
542
+ if (!memcmp(buf, broadcast_addr, sizeof(broadcast_addr))) {
543
+ return bcast_en;
544
+ }
545
+
546
+ if (buf[0] & 1) {
547
+ return mcast_en;
548
+ }
549
+
550
+ return !memcmp(buf, s->mac_addr, sizeof(s->mac_addr));
551
+}
552
+
553
+static ssize_t emac_rx(NetClientState *nc, const uint8_t *buf, size_t size)
554
+{
555
+ MSF2EmacState *s = qemu_get_nic_opaque(nc);
556
+ EmacDesc d;
557
+ uint8_t pktcnt;
558
+ uint32_t status;
559
+
560
+ if (size > (s->regs[R_MAX_FRAME_LENGTH] & 0xFFFF)) {
561
+ return size;
562
+ }
563
+ if (!addr_filter_ok(s, buf)) {
564
+ return size;
565
+ }
566
+
567
+ emac_load_desc(s, &d, s->rx_desc);
568
+
569
+ if (d.pktsize & EMPTY_MASK) {
570
+ address_space_write(&s->dma_as, d.pktaddr, MEMTXATTRS_UNSPECIFIED,
571
+ buf, size & PKT_SIZE);
572
+ d.pktsize = size & PKT_SIZE;
573
+ emac_store_desc(s, &d, s->rx_desc);
574
+ /* update received packets count */
575
+ status = s->regs[R_DMA_RX_STATUS];
576
+ pktcnt = FIELD_EX32(status, DMA_RX_STATUS, PKTCNT);
577
+ pktcnt++;
578
+ s->regs[R_DMA_RX_STATUS] = FIELD_DP32(status, DMA_RX_STATUS,
579
+ PKTCNT, pktcnt);
580
+ s->regs[R_DMA_RX_STATUS] |= R_DMA_RX_STATUS_PKT_RCVD_MASK;
581
+ s->rx_desc = d.next;
582
+ } else {
583
+ s->regs[R_DMA_RX_CTL] &= ~R_DMA_RX_CTL_EN_MASK;
584
+ s->regs[R_DMA_RX_STATUS] |= R_DMA_RX_STATUS_OVERFLOW_MASK;
585
+ }
586
+ emac_update_irq(s);
587
+ return size;
588
+}
589
+
590
+static void msf2_emac_reset(DeviceState *dev)
591
+{
592
+ MSF2EmacState *s = MSS_EMAC(dev);
593
+
594
+ msf2_emac_do_reset(s);
595
+}
596
+
597
+static void emac_set_link(NetClientState *nc)
598
+{
599
+ MSF2EmacState *s = qemu_get_nic_opaque(nc);
600
+
601
+ msf2_phy_update_link(s);
602
+}
603
+
604
+static NetClientInfo net_msf2_emac_info = {
605
+ .type = NET_CLIENT_DRIVER_NIC,
606
+ .size = sizeof(NICState),
607
+ .can_receive = emac_can_rx,
608
+ .receive = emac_rx,
609
+ .link_status_changed = emac_set_link,
610
+};
611
+
612
+static void msf2_emac_realize(DeviceState *dev, Error **errp)
613
+{
614
+ MSF2EmacState *s = MSS_EMAC(dev);
615
+
616
+ if (!s->dma_mr) {
617
+ error_setg(errp, "MSS_EMAC 'ahb-bus' link not set");
618
+ return;
619
+ }
620
+
621
+ address_space_init(&s->dma_as, s->dma_mr, "emac-ahb");
622
+
623
+ qemu_macaddr_default_if_unset(&s->conf.macaddr);
624
+ s->nic = qemu_new_nic(&net_msf2_emac_info, &s->conf,
625
+ object_get_typename(OBJECT(dev)), dev->id, s);
626
+ qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
627
+}
628
+
629
+static void msf2_emac_init(Object *obj)
630
+{
631
+ MSF2EmacState *s = MSS_EMAC(obj);
632
+
633
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
634
+
635
+ memory_region_init_io(&s->mmio, obj, &emac_ops, s,
636
+ "msf2-emac", R_MAX * 4);
637
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
638
+}
639
+
640
+static Property msf2_emac_properties[] = {
641
+ DEFINE_PROP_LINK("ahb-bus", MSF2EmacState, dma_mr,
642
+ TYPE_MEMORY_REGION, MemoryRegion *),
643
+ DEFINE_NIC_PROPERTIES(MSF2EmacState, conf),
644
+ DEFINE_PROP_END_OF_LIST(),
645
+};
646
+
647
+static const VMStateDescription vmstate_msf2_emac = {
648
+ .name = TYPE_MSS_EMAC,
649
+ .version_id = 1,
650
+ .minimum_version_id = 1,
651
+ .fields = (VMStateField[]) {
652
+ VMSTATE_UINT8_ARRAY(mac_addr, MSF2EmacState, ETH_ALEN),
653
+ VMSTATE_UINT32(rx_desc, MSF2EmacState),
654
+ VMSTATE_UINT16_ARRAY(phy_regs, MSF2EmacState, PHY_MAX_REGS),
655
+ VMSTATE_UINT32_ARRAY(regs, MSF2EmacState, R_MAX),
656
+ VMSTATE_END_OF_LIST()
657
+ }
658
+};
659
+
660
+static void msf2_emac_class_init(ObjectClass *klass, void *data)
661
+{
662
+ DeviceClass *dc = DEVICE_CLASS(klass);
663
+
664
+ dc->realize = msf2_emac_realize;
665
+ dc->reset = msf2_emac_reset;
666
+ dc->vmsd = &vmstate_msf2_emac;
667
+ device_class_set_props(dc, msf2_emac_properties);
668
+}
669
+
670
+static const TypeInfo msf2_emac_info = {
671
+ .name = TYPE_MSS_EMAC,
672
+ .parent = TYPE_SYS_BUS_DEVICE,
673
+ .instance_size = sizeof(MSF2EmacState),
674
+ .instance_init = msf2_emac_init,
675
+ .class_init = msf2_emac_class_init,
676
+};
677
+
678
+static void msf2_emac_register_types(void)
679
+{
680
+ type_register_static(&msf2_emac_info);
681
+}
682
+
683
+type_init(msf2_emac_register_types)
684
diff --git a/MAINTAINERS b/MAINTAINERS
122
diff --git a/MAINTAINERS b/MAINTAINERS
685
index XXXXXXX..XXXXXXX 100644
123
index XXXXXXX..XXXXXXX 100644
686
--- a/MAINTAINERS
124
--- a/MAINTAINERS
687
+++ b/MAINTAINERS
125
+++ b/MAINTAINERS
688
@@ -XXX,XX +XXX,XX @@ F: include/hw/arm/msf2-soc.h
126
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
689
F: include/hw/misc/msf2-sysreg.h
127
S: Maintained
690
F: include/hw/timer/mss-timer.h
128
F: hw/arm/netduinoplus2.c
691
F: include/hw/ssi/mss-spi.h
129
692
+F: hw/net/msf2-emac.c
130
+Olimex STM32 H405
693
+F: include/hw/net/msf2-emac.h
131
+M: Felipe Balbi <balbi@kernel.org>
694
132
+L: qemu-arm@nongnu.org
695
Emcraft M2S-FG484
133
+S: Maintained
134
+F: hw/arm/olimex-stm32-h405.c
135
+
136
SmartFusion2
696
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
137
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
138
M: Peter Maydell <peter.maydell@linaro.org>
139
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
140
index XXXXXXX..XXXXXXX 100644
141
--- a/hw/arm/Kconfig
142
+++ b/hw/arm/Kconfig
143
@@ -XXX,XX +XXX,XX @@ config NETDUINOPLUS2
144
bool
145
select STM32F405_SOC
146
147
+config OLIMEX_STM32_H405
148
+ bool
149
+ select STM32F405_SOC
150
+
151
config NSERIES
152
bool
153
select OMAP
154
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
155
index XXXXXXX..XXXXXXX 100644
156
--- a/hw/arm/meson.build
157
+++ b/hw/arm/meson.build
158
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
159
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
160
arm_ss.add(when: 'CONFIG_NETDUINO2', if_true: files('netduino2.c'))
161
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
162
+arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
163
arm_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx.c', 'npcm7xx_boards.c'))
164
arm_ss.add(when: 'CONFIG_NSERIES', if_true: files('nseries.c'))
165
arm_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c'))
697
--
166
--
698
2.20.1
167
2.34.1
699
168
700
169
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
Add functions to easily handle clocks with devices.
3
During SPL boot several Clock Controller Module (CCM) registers are
4
Clock inputs and outputs should be used to handle clock propagation
4
read, most important are PLL and Tuning, as well as divisor registers.
5
between devices.
6
The API is very similar the GPIO API.
7
5
8
This is based on the original work of Frederic Konrad.
6
This patch adds these registers and initializes reset values from user's
7
guide.
9
8
10
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
9
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
13
Message-id: 20200406135251.157596-4-damien.hedde@greensocs.com
12
Message-id: 20221226220303.14420-2-strahinja.p.jankovic@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
14
---
16
hw/core/Makefile.objs | 2 +-
15
include/hw/arm/allwinner-a10.h | 2 +
17
tests/Makefile.include | 1 +
16
include/hw/misc/allwinner-a10-ccm.h | 67 +++++++++
18
include/hw/qdev-clock.h | 104 +++++++++++++++++++++++++
17
hw/arm/allwinner-a10.c | 7 +
19
include/hw/qdev-core.h | 12 +++
18
hw/misc/allwinner-a10-ccm.c | 224 ++++++++++++++++++++++++++++
20
hw/core/qdev-clock.c | 168 ++++++++++++++++++++++++++++++++++++++++
19
hw/arm/Kconfig | 1 +
21
hw/core/qdev.c | 12 +++
20
hw/misc/Kconfig | 3 +
22
6 files changed, 298 insertions(+), 1 deletion(-)
21
hw/misc/meson.build | 1 +
23
create mode 100644 include/hw/qdev-clock.h
22
7 files changed, 305 insertions(+)
24
create mode 100644 hw/core/qdev-clock.c
23
create mode 100644 include/hw/misc/allwinner-a10-ccm.h
24
create mode 100644 hw/misc/allwinner-a10-ccm.c
25
25
26
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
26
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
27
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/core/Makefile.objs
28
--- a/include/hw/arm/allwinner-a10.h
29
+++ b/hw/core/Makefile.objs
29
+++ b/include/hw/arm/allwinner-a10.h
30
@@ -XXX,XX +XXX,XX @@ common-obj-y += hotplug.o
30
@@ -XXX,XX +XXX,XX @@
31
common-obj-y += vmstate-if.o
31
#include "hw/usb/hcd-ohci.h"
32
# irq.o needed for qdev GPIO handling:
32
#include "hw/usb/hcd-ehci.h"
33
common-obj-y += irq.o
33
#include "hw/rtc/allwinner-rtc.h"
34
-common-obj-y += clock.o
34
+#include "hw/misc/allwinner-a10-ccm.h"
35
+common-obj-y += clock.o qdev-clock.o
35
36
36
#include "target/arm/cpu.h"
37
common-obj-$(CONFIG_SOFTMMU) += reset.o
37
#include "qom/object.h"
38
common-obj-$(CONFIG_SOFTMMU) += qdev-fw.o
38
@@ -XXX,XX +XXX,XX @@ struct AwA10State {
39
diff --git a/tests/Makefile.include b/tests/Makefile.include
39
/*< public >*/
40
index XXXXXXX..XXXXXXX 100644
40
41
--- a/tests/Makefile.include
41
ARMCPU cpu;
42
+++ b/tests/Makefile.include
42
+ AwA10ClockCtlState ccm;
43
@@ -XXX,XX +XXX,XX @@ tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
43
AwA10PITState timer;
44
    hw/core/fw-path-provider.o \
44
AwA10PICState intc;
45
    hw/core/reset.o \
45
AwEmacState emac;
46
    hw/core/vmstate-if.o \
46
diff --git a/include/hw/misc/allwinner-a10-ccm.h b/include/hw/misc/allwinner-a10-ccm.h
47
+    hw/core/clock.o hw/core/qdev-clock.o \
48
    $(test-qapi-obj-y)
49
tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
50
    migration/vmstate.o migration/vmstate-types.o migration/qemu-file.o \
51
diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h
52
new file mode 100644
47
new file mode 100644
53
index XXXXXXX..XXXXXXX
48
index XXXXXXX..XXXXXXX
54
--- /dev/null
49
--- /dev/null
55
+++ b/include/hw/qdev-clock.h
50
+++ b/include/hw/misc/allwinner-a10-ccm.h
56
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@
57
+/*
52
+/*
58
+ * Device's clock input and output
53
+ * Allwinner A10 Clock Control Module emulation
59
+ *
54
+ *
60
+ * Copyright GreenSocs 2016-2020
55
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
61
+ *
56
+ *
62
+ * Authors:
57
+ * This file is derived from Allwinner H3 CCU,
63
+ * Frederic Konrad
58
+ * by Niek Linnenbank.
64
+ * Damien Hedde
59
+ *
65
+ *
60
+ * This program is free software: you can redistribute it and/or modify
66
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
61
+ * it under the terms of the GNU General Public License as published by
67
+ * See the COPYING file in the top-level directory.
62
+ * the Free Software Foundation, either version 2 of the License, or
63
+ * (at your option) any later version.
64
+ *
65
+ * This program is distributed in the hope that it will be useful,
66
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
67
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
68
+ * GNU General Public License for more details.
69
+ *
70
+ * You should have received a copy of the GNU General Public License
71
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
68
+ */
72
+ */
69
+
73
+
70
+#ifndef QDEV_CLOCK_H
74
+#ifndef HW_MISC_ALLWINNER_A10_CCM_H
71
+#define QDEV_CLOCK_H
75
+#define HW_MISC_ALLWINNER_A10_CCM_H
72
+
76
+
73
+#include "hw/clock.h"
77
+#include "qom/object.h"
78
+#include "hw/sysbus.h"
74
+
79
+
75
+/**
80
+/**
76
+ * qdev_init_clock_in:
81
+ * @name Constants
77
+ * @dev: the device to add an input clock to
82
+ * @{
78
+ * @name: the name of the clock (can't be NULL).
79
+ * @callback: optional callback to be called on update or NULL.
80
+ * @opaque: argument for the callback
81
+ * @returns: a pointer to the newly added clock
82
+ *
83
+ * Add an input clock to device @dev as a clock named @name.
84
+ * This adds a child<> property.
85
+ * The callback will be called with @opaque as opaque parameter.
86
+ */
83
+ */
87
+Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
84
+
88
+ ClockCallback *callback, void *opaque);
85
+/** Size of register I/O address space used by CCM device */
86
+#define AW_A10_CCM_IOSIZE (0x400)
87
+
88
+/** Total number of known registers */
89
+#define AW_A10_CCM_REGS_NUM (AW_A10_CCM_IOSIZE / sizeof(uint32_t))
90
+
91
+/** @} */
89
+
92
+
90
+/**
93
+/**
91
+ * qdev_init_clock_out:
94
+ * @name Object model
92
+ * @dev: the device to add an output clock to
95
+ * @{
93
+ * @name: the name of the clock (can't be NULL).
94
+ * @returns: a pointer to the newly added clock
95
+ *
96
+ * Add an output clock to device @dev as a clock named @name.
97
+ * This adds a child<> property.
98
+ */
96
+ */
99
+Clock *qdev_init_clock_out(DeviceState *dev, const char *name);
97
+
98
+#define TYPE_AW_A10_CCM "allwinner-a10-ccm"
99
+OBJECT_DECLARE_SIMPLE_TYPE(AwA10ClockCtlState, AW_A10_CCM)
100
+
101
+/** @} */
100
+
102
+
101
+/**
103
+/**
102
+ * qdev_get_clock_in:
104
+ * Allwinner A10 CCM object instance state.
103
+ * @dev: the device which has the clock
104
+ * @name: the name of the clock (can't be NULL).
105
+ * @returns: a pointer to the clock
106
+ *
107
+ * Get the input clock @name from @dev or NULL if does not exist.
108
+ */
105
+ */
109
+Clock *qdev_get_clock_in(DeviceState *dev, const char *name);
106
+struct AwA10ClockCtlState {
110
+
107
+ /*< private >*/
111
+/**
108
+ SysBusDevice parent_obj;
112
+ * qdev_get_clock_out:
109
+ /*< public >*/
113
+ * @dev: the device which has the clock
110
+
114
+ * @name: the name of the clock (can't be NULL).
111
+ /** Maps I/O registers in physical memory */
115
+ * @returns: a pointer to the clock
112
+ MemoryRegion iomem;
116
+ *
113
+
117
+ * Get the output clock @name from @dev or NULL if does not exist.
114
+ /** Array of hardware registers */
118
+ */
115
+ uint32_t regs[AW_A10_CCM_REGS_NUM];
119
+Clock *qdev_get_clock_out(DeviceState *dev, const char *name);
116
+};
120
+
117
+
121
+/**
118
+#endif /* HW_MISC_ALLWINNER_H3_CCU_H */
122
+ * qdev_connect_clock_in:
119
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
123
+ * @dev: a device
124
+ * @name: the name of an input clock in @dev
125
+ * @source: the source clock (an output clock of another device for example)
126
+ *
127
+ * Set the source clock of input clock @name of device @dev to @source.
128
+ * @source period update will be propagated to @name clock.
129
+ */
130
+static inline void qdev_connect_clock_in(DeviceState *dev, const char *name,
131
+ Clock *source)
132
+{
133
+ clock_set_source(qdev_get_clock_in(dev, name), source);
134
+}
135
+
136
+/**
137
+ * qdev_alias_clock:
138
+ * @dev: the device which has the clock
139
+ * @name: the name of the clock in @dev (can't be NULL)
140
+ * @alias_dev: the device to add the clock
141
+ * @alias_name: the name of the clock in @container
142
+ * @returns: a pointer to the clock
143
+ *
144
+ * Add a clock @alias_name in @alias_dev which is an alias of the clock @name
145
+ * in @dev. The direction _in_ or _out_ will the same as the original.
146
+ * An alias clock must not be modified or used by @alias_dev and should
147
+ * typically be only only for device composition purpose.
148
+ */
149
+Clock *qdev_alias_clock(DeviceState *dev, const char *name,
150
+ DeviceState *alias_dev, const char *alias_name);
151
+
152
+/**
153
+ * qdev_finalize_clocklist:
154
+ * @dev: the device being finalized
155
+ *
156
+ * Clear the clocklist from @dev. Only used internally in qdev.
157
+ */
158
+void qdev_finalize_clocklist(DeviceState *dev);
159
+
160
+#endif /* QDEV_CLOCK_H */
161
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
162
index XXXXXXX..XXXXXXX 100644
120
index XXXXXXX..XXXXXXX 100644
163
--- a/include/hw/qdev-core.h
121
--- a/hw/arm/allwinner-a10.c
164
+++ b/include/hw/qdev-core.h
122
+++ b/hw/arm/allwinner-a10.c
165
@@ -XXX,XX +XXX,XX @@ struct NamedGPIOList {
123
@@ -XXX,XX +XXX,XX @@
166
QLIST_ENTRY(NamedGPIOList) node;
124
#include "hw/usb/hcd-ohci.h"
167
};
125
168
126
#define AW_A10_MMC0_BASE 0x01c0f000
169
+typedef struct Clock Clock;
127
+#define AW_A10_CCM_BASE 0x01c20000
170
+typedef struct NamedClockList NamedClockList;
128
#define AW_A10_PIC_REG_BASE 0x01c20400
171
+
129
#define AW_A10_PIT_REG_BASE 0x01c20c00
172
+struct NamedClockList {
130
#define AW_A10_UART0_REG_BASE 0x01c28000
173
+ char *name;
131
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
174
+ Clock *clock;
132
175
+ bool output;
133
object_initialize_child(obj, "timer", &s->timer, TYPE_AW_A10_PIT);
176
+ bool alias;
134
177
+ QLIST_ENTRY(NamedClockList) node;
135
+ object_initialize_child(obj, "ccm", &s->ccm, TYPE_AW_A10_CCM);
178
+};
136
+
179
+
137
object_initialize_child(obj, "emac", &s->emac, TYPE_AW_EMAC);
180
/**
138
181
* DeviceState:
139
object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI);
182
* @realized: Indicates whether the device has been fully constructed.
140
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
183
@@ -XXX,XX +XXX,XX @@ struct DeviceState {
141
memory_region_add_subregion(get_system_memory(), 0x00000000, &s->sram_a);
184
bool allow_unplug_during_migration;
142
create_unimplemented_device("a10-sram-ctrl", 0x01c00000, 4 * KiB);
185
BusState *parent_bus;
143
186
QLIST_HEAD(, NamedGPIOList) gpios;
144
+ /* Clock Control Module */
187
+ QLIST_HEAD(, NamedClockList) clocks;
145
+ sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_fatal);
188
QLIST_HEAD(, BusState) child_bus;
146
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, AW_A10_CCM_BASE);
189
int num_child_bus;
147
+
190
int instance_id_alias;
148
/* FIXME use qdev NIC properties instead of nd_table[] */
191
diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c
149
if (nd_table[0].used) {
150
qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
151
diff --git a/hw/misc/allwinner-a10-ccm.c b/hw/misc/allwinner-a10-ccm.c
192
new file mode 100644
152
new file mode 100644
193
index XXXXXXX..XXXXXXX
153
index XXXXXXX..XXXXXXX
194
--- /dev/null
154
--- /dev/null
195
+++ b/hw/core/qdev-clock.c
155
+++ b/hw/misc/allwinner-a10-ccm.c
196
@@ -XXX,XX +XXX,XX @@
156
@@ -XXX,XX +XXX,XX @@
197
+/*
157
+/*
198
+ * Device's clock input and output
158
+ * Allwinner A10 Clock Control Module emulation
199
+ *
159
+ *
200
+ * Copyright GreenSocs 2016-2020
160
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
201
+ *
161
+ *
202
+ * Authors:
162
+ * This file is derived from Allwinner H3 CCU,
203
+ * Frederic Konrad
163
+ * by Niek Linnenbank.
204
+ * Damien Hedde
164
+ *
205
+ *
165
+ * This program is free software: you can redistribute it and/or modify
206
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
166
+ * it under the terms of the GNU General Public License as published by
207
+ * See the COPYING file in the top-level directory.
167
+ * the Free Software Foundation, either version 2 of the License, or
168
+ * (at your option) any later version.
169
+ *
170
+ * This program is distributed in the hope that it will be useful,
171
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
172
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
173
+ * GNU General Public License for more details.
174
+ *
175
+ * You should have received a copy of the GNU General Public License
176
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
208
+ */
177
+ */
209
+
178
+
210
+#include "qemu/osdep.h"
179
+#include "qemu/osdep.h"
211
+#include "hw/qdev-clock.h"
180
+#include "qemu/units.h"
212
+#include "hw/qdev-core.h"
181
+#include "hw/sysbus.h"
213
+#include "qapi/error.h"
182
+#include "migration/vmstate.h"
214
+
183
+#include "qemu/log.h"
215
+/*
184
+#include "qemu/module.h"
216
+ * qdev_init_clocklist:
185
+#include "hw/misc/allwinner-a10-ccm.h"
217
+ * Add a new clock in a device
186
+
218
+ */
187
+/* CCM register offsets */
219
+static NamedClockList *qdev_init_clocklist(DeviceState *dev, const char *name,
188
+enum {
220
+ bool output, Clock *clk)
189
+ REG_PLL1_CFG = 0x0000, /* PLL1 Control */
221
+{
190
+ REG_PLL1_TUN = 0x0004, /* PLL1 Tuning */
222
+ NamedClockList *ncl;
191
+ REG_PLL2_CFG = 0x0008, /* PLL2 Control */
223
+
192
+ REG_PLL2_TUN = 0x000C, /* PLL2 Tuning */
224
+ /*
193
+ REG_PLL3_CFG = 0x0010, /* PLL3 Control */
225
+ * Clock must be added before realize() so that we can compute the
194
+ REG_PLL4_CFG = 0x0018, /* PLL4 Control */
226
+ * clock's canonical path during device_realize().
195
+ REG_PLL5_CFG = 0x0020, /* PLL5 Control */
227
+ */
196
+ REG_PLL5_TUN = 0x0024, /* PLL5 Tuning */
228
+ assert(!dev->realized);
197
+ REG_PLL6_CFG = 0x0028, /* PLL6 Control */
229
+
198
+ REG_PLL6_TUN = 0x002C, /* PLL6 Tuning */
230
+ /*
199
+ REG_PLL7_CFG = 0x0030, /* PLL7 Control */
231
+ * The ncl structure is freed by qdev_finalize_clocklist() which will
200
+ REG_PLL1_TUN2 = 0x0038, /* PLL1 Tuning2 */
232
+ * be called during @dev's device_finalize().
201
+ REG_PLL5_TUN2 = 0x003C, /* PLL5 Tuning2 */
233
+ */
202
+ REG_PLL8_CFG = 0x0040, /* PLL8 Control */
234
+ ncl = g_new0(NamedClockList, 1);
203
+ REG_OSC24M_CFG = 0x0050, /* OSC24M Control */
235
+ ncl->name = g_strdup(name);
204
+ REG_CPU_AHB_APB0_CFG = 0x0054, /* CPU, AHB and APB0 Divide Ratio */
236
+ ncl->output = output;
205
+};
237
+ ncl->alias = (clk != NULL);
206
+
238
+
207
+#define REG_INDEX(offset) (offset / sizeof(uint32_t))
239
+ /*
208
+
240
+ * Trying to create a clock whose name clashes with some other
209
+/* CCM register reset values */
241
+ * clock or property is a bug in the caller and we will abort().
210
+enum {
242
+ */
211
+ REG_PLL1_CFG_RST = 0x21005000,
243
+ if (clk == NULL) {
212
+ REG_PLL1_TUN_RST = 0x0A101000,
244
+ clk = CLOCK(object_new(TYPE_CLOCK));
213
+ REG_PLL2_CFG_RST = 0x08100010,
245
+ object_property_add_child(OBJECT(dev), name, OBJECT(clk), &error_abort);
214
+ REG_PLL2_TUN_RST = 0x00000000,
246
+ if (output) {
215
+ REG_PLL3_CFG_RST = 0x0010D063,
247
+ /*
216
+ REG_PLL4_CFG_RST = 0x21009911,
248
+ * Remove object_new()'s initial reference.
217
+ REG_PLL5_CFG_RST = 0x11049280,
249
+ * Note that for inputs, the reference created by object_new()
218
+ REG_PLL5_TUN_RST = 0x14888000,
250
+ * will be deleted in qdev_finalize_clocklist().
219
+ REG_PLL6_CFG_RST = 0x21009911,
251
+ */
220
+ REG_PLL6_TUN_RST = 0x00000000,
252
+ object_unref(OBJECT(clk));
221
+ REG_PLL7_CFG_RST = 0x0010D063,
253
+ }
222
+ REG_PLL1_TUN2_RST = 0x00000000,
254
+ } else {
223
+ REG_PLL5_TUN2_RST = 0x00000000,
255
+ object_property_add_link(OBJECT(dev), name,
224
+ REG_PLL8_CFG_RST = 0x21009911,
256
+ object_get_typename(OBJECT(clk)),
225
+ REG_OSC24M_CFG_RST = 0x00138013,
257
+ (Object **) &ncl->clock,
226
+ REG_CPU_AHB_APB0_CFG_RST = 0x00010010,
258
+ NULL, OBJ_PROP_LINK_STRONG, &error_abort);
227
+};
228
+
229
+static uint64_t allwinner_a10_ccm_read(void *opaque, hwaddr offset,
230
+ unsigned size)
231
+{
232
+ const AwA10ClockCtlState *s = AW_A10_CCM(opaque);
233
+ const uint32_t idx = REG_INDEX(offset);
234
+
235
+ switch (offset) {
236
+ case REG_PLL1_CFG:
237
+ case REG_PLL1_TUN:
238
+ case REG_PLL2_CFG:
239
+ case REG_PLL2_TUN:
240
+ case REG_PLL3_CFG:
241
+ case REG_PLL4_CFG:
242
+ case REG_PLL5_CFG:
243
+ case REG_PLL5_TUN:
244
+ case REG_PLL6_CFG:
245
+ case REG_PLL6_TUN:
246
+ case REG_PLL7_CFG:
247
+ case REG_PLL1_TUN2:
248
+ case REG_PLL5_TUN2:
249
+ case REG_PLL8_CFG:
250
+ case REG_OSC24M_CFG:
251
+ case REG_CPU_AHB_APB0_CFG:
252
+ break;
253
+ case 0x158 ... AW_A10_CCM_IOSIZE:
254
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
255
+ __func__, (uint32_t)offset);
256
+ return 0;
257
+ default:
258
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented read offset 0x%04x\n",
259
+ __func__, (uint32_t)offset);
260
+ return 0;
259
+ }
261
+ }
260
+
262
+
261
+ ncl->clock = clk;
263
+ return s->regs[idx];
262
+
264
+}
263
+ QLIST_INSERT_HEAD(&dev->clocks, ncl, node);
265
+
264
+ return ncl;
266
+static void allwinner_a10_ccm_write(void *opaque, hwaddr offset,
265
+}
267
+ uint64_t val, unsigned size)
266
+
268
+{
267
+void qdev_finalize_clocklist(DeviceState *dev)
269
+ AwA10ClockCtlState *s = AW_A10_CCM(opaque);
268
+{
270
+ const uint32_t idx = REG_INDEX(offset);
269
+ /* called by @dev's device_finalize() */
271
+
270
+ NamedClockList *ncl, *ncl_next;
272
+ switch (offset) {
271
+
273
+ case REG_PLL1_CFG:
272
+ QLIST_FOREACH_SAFE(ncl, &dev->clocks, node, ncl_next) {
274
+ case REG_PLL1_TUN:
273
+ QLIST_REMOVE(ncl, node);
275
+ case REG_PLL2_CFG:
274
+ if (!ncl->output && !ncl->alias) {
276
+ case REG_PLL2_TUN:
275
+ /*
277
+ case REG_PLL3_CFG:
276
+ * We kept a reference on the input clock to ensure it lives up to
278
+ case REG_PLL4_CFG:
277
+ * this point so we can safely remove the callback.
279
+ case REG_PLL5_CFG:
278
+ * It avoids having a callback to a deleted object if ncl->clock
280
+ case REG_PLL5_TUN:
279
+ * is still referenced somewhere else (eg: by a clock output).
281
+ case REG_PLL6_CFG:
280
+ */
282
+ case REG_PLL6_TUN:
281
+ clock_clear_callback(ncl->clock);
283
+ case REG_PLL7_CFG:
282
+ object_unref(OBJECT(ncl->clock));
284
+ case REG_PLL1_TUN2:
283
+ }
285
+ case REG_PLL5_TUN2:
284
+ g_free(ncl->name);
286
+ case REG_PLL8_CFG:
285
+ g_free(ncl);
287
+ case REG_OSC24M_CFG:
288
+ case REG_CPU_AHB_APB0_CFG:
289
+ break;
290
+ case 0x158 ... AW_A10_CCM_IOSIZE:
291
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
292
+ __func__, (uint32_t)offset);
293
+ break;
294
+ default:
295
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented write offset 0x%04x\n",
296
+ __func__, (uint32_t)offset);
297
+ break;
286
+ }
298
+ }
287
+}
299
+
288
+
300
+ s->regs[idx] = (uint32_t) val;
289
+Clock *qdev_init_clock_out(DeviceState *dev, const char *name)
301
+}
290
+{
302
+
291
+ NamedClockList *ncl;
303
+static const MemoryRegionOps allwinner_a10_ccm_ops = {
292
+
304
+ .read = allwinner_a10_ccm_read,
293
+ assert(name);
305
+ .write = allwinner_a10_ccm_write,
294
+
306
+ .endianness = DEVICE_NATIVE_ENDIAN,
295
+ ncl = qdev_init_clocklist(dev, name, true, NULL);
307
+ .valid = {
296
+
308
+ .min_access_size = 4,
297
+ return ncl->clock;
309
+ .max_access_size = 4,
298
+}
310
+ },
299
+
311
+ .impl.min_access_size = 4,
300
+Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
312
+};
301
+ ClockCallback *callback, void *opaque)
313
+
302
+{
314
+static void allwinner_a10_ccm_reset_enter(Object *obj, ResetType type)
303
+ NamedClockList *ncl;
315
+{
304
+
316
+ AwA10ClockCtlState *s = AW_A10_CCM(obj);
305
+ assert(name);
317
+
306
+
318
+ /* Set default values for registers */
307
+ ncl = qdev_init_clocklist(dev, name, false, NULL);
319
+ s->regs[REG_INDEX(REG_PLL1_CFG)] = REG_PLL1_CFG_RST;
308
+
320
+ s->regs[REG_INDEX(REG_PLL1_TUN)] = REG_PLL1_TUN_RST;
309
+ if (callback) {
321
+ s->regs[REG_INDEX(REG_PLL2_CFG)] = REG_PLL2_CFG_RST;
310
+ clock_set_callback(ncl->clock, callback, opaque);
322
+ s->regs[REG_INDEX(REG_PLL2_TUN)] = REG_PLL2_TUN_RST;
323
+ s->regs[REG_INDEX(REG_PLL3_CFG)] = REG_PLL3_CFG_RST;
324
+ s->regs[REG_INDEX(REG_PLL4_CFG)] = REG_PLL4_CFG_RST;
325
+ s->regs[REG_INDEX(REG_PLL5_CFG)] = REG_PLL5_CFG_RST;
326
+ s->regs[REG_INDEX(REG_PLL5_TUN)] = REG_PLL5_TUN_RST;
327
+ s->regs[REG_INDEX(REG_PLL6_CFG)] = REG_PLL6_CFG_RST;
328
+ s->regs[REG_INDEX(REG_PLL6_TUN)] = REG_PLL6_TUN_RST;
329
+ s->regs[REG_INDEX(REG_PLL7_CFG)] = REG_PLL7_CFG_RST;
330
+ s->regs[REG_INDEX(REG_PLL1_TUN2)] = REG_PLL1_TUN2_RST;
331
+ s->regs[REG_INDEX(REG_PLL5_TUN2)] = REG_PLL5_TUN2_RST;
332
+ s->regs[REG_INDEX(REG_PLL8_CFG)] = REG_PLL8_CFG_RST;
333
+ s->regs[REG_INDEX(REG_OSC24M_CFG)] = REG_OSC24M_CFG_RST;
334
+ s->regs[REG_INDEX(REG_CPU_AHB_APB0_CFG)] = REG_CPU_AHB_APB0_CFG_RST;
335
+}
336
+
337
+static void allwinner_a10_ccm_init(Object *obj)
338
+{
339
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
340
+ AwA10ClockCtlState *s = AW_A10_CCM(obj);
341
+
342
+ /* Memory mapping */
343
+ memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_a10_ccm_ops, s,
344
+ TYPE_AW_A10_CCM, AW_A10_CCM_IOSIZE);
345
+ sysbus_init_mmio(sbd, &s->iomem);
346
+}
347
+
348
+static const VMStateDescription allwinner_a10_ccm_vmstate = {
349
+ .name = "allwinner-a10-ccm",
350
+ .version_id = 1,
351
+ .minimum_version_id = 1,
352
+ .fields = (VMStateField[]) {
353
+ VMSTATE_UINT32_ARRAY(regs, AwA10ClockCtlState, AW_A10_CCM_REGS_NUM),
354
+ VMSTATE_END_OF_LIST()
311
+ }
355
+ }
312
+ return ncl->clock;
356
+};
313
+}
357
+
314
+
358
+static void allwinner_a10_ccm_class_init(ObjectClass *klass, void *data)
315
+static NamedClockList *qdev_get_clocklist(DeviceState *dev, const char *name)
359
+{
316
+{
360
+ DeviceClass *dc = DEVICE_CLASS(klass);
317
+ NamedClockList *ncl;
361
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
318
+
362
+
319
+ QLIST_FOREACH(ncl, &dev->clocks, node) {
363
+ rc->phases.enter = allwinner_a10_ccm_reset_enter;
320
+ if (strcmp(name, ncl->name) == 0) {
364
+ dc->vmsd = &allwinner_a10_ccm_vmstate;
321
+ return ncl;
365
+}
322
+ }
366
+
323
+ }
367
+static const TypeInfo allwinner_a10_ccm_info = {
324
+
368
+ .name = TYPE_AW_A10_CCM,
325
+ return NULL;
369
+ .parent = TYPE_SYS_BUS_DEVICE,
326
+}
370
+ .instance_init = allwinner_a10_ccm_init,
327
+
371
+ .instance_size = sizeof(AwA10ClockCtlState),
328
+Clock *qdev_get_clock_in(DeviceState *dev, const char *name)
372
+ .class_init = allwinner_a10_ccm_class_init,
329
+{
373
+};
330
+ NamedClockList *ncl;
374
+
331
+
375
+static void allwinner_a10_ccm_register(void)
332
+ assert(name);
376
+{
333
+
377
+ type_register_static(&allwinner_a10_ccm_info);
334
+ ncl = qdev_get_clocklist(dev, name);
378
+}
335
+ assert(!ncl->output);
379
+
336
+
380
+type_init(allwinner_a10_ccm_register)
337
+ return ncl->clock;
381
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
338
+}
339
+
340
+Clock *qdev_get_clock_out(DeviceState *dev, const char *name)
341
+{
342
+ NamedClockList *ncl;
343
+
344
+ assert(name);
345
+
346
+ ncl = qdev_get_clocklist(dev, name);
347
+ assert(ncl->output);
348
+
349
+ return ncl->clock;
350
+}
351
+
352
+Clock *qdev_alias_clock(DeviceState *dev, const char *name,
353
+ DeviceState *alias_dev, const char *alias_name)
354
+{
355
+ NamedClockList *ncl;
356
+
357
+ assert(name && alias_name);
358
+
359
+ ncl = qdev_get_clocklist(dev, name);
360
+
361
+ qdev_init_clocklist(alias_dev, alias_name, ncl->output, ncl->clock);
362
+
363
+ return ncl->clock;
364
+}
365
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
366
index XXXXXXX..XXXXXXX 100644
382
index XXXXXXX..XXXXXXX 100644
367
--- a/hw/core/qdev.c
383
--- a/hw/arm/Kconfig
368
+++ b/hw/core/qdev.c
384
+++ b/hw/arm/Kconfig
369
@@ -XXX,XX +XXX,XX @@
385
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
370
#include "hw/qdev-properties.h"
386
select AHCI
371
#include "hw/boards.h"
387
select ALLWINNER_A10_PIT
372
#include "hw/sysbus.h"
388
select ALLWINNER_A10_PIC
373
+#include "hw/qdev-clock.h"
389
+ select ALLWINNER_A10_CCM
374
#include "migration/vmstate.h"
390
select ALLWINNER_EMAC
375
#include "trace.h"
391
select SERIAL
376
392
select UNIMP
377
@@ -XXX,XX +XXX,XX @@ static void device_set_realized(Object *obj, bool value, Error **errp)
393
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
378
DeviceClass *dc = DEVICE_GET_CLASS(dev);
394
index XXXXXXX..XXXXXXX 100644
379
HotplugHandler *hotplug_ctrl;
395
--- a/hw/misc/Kconfig
380
BusState *bus;
396
+++ b/hw/misc/Kconfig
381
+ NamedClockList *ncl;
397
@@ -XXX,XX +XXX,XX @@ config VIRT_CTRL
382
Error *local_err = NULL;
398
config LASI
383
bool unattached_parent = false;
399
bool
384
static int unattached_count;
400
385
@@ -XXX,XX +XXX,XX @@ static void device_set_realized(Object *obj, bool value, Error **errp)
401
+config ALLWINNER_A10_CCM
386
*/
402
+ bool
387
g_free(dev->canonical_path);
403
+
388
dev->canonical_path = object_get_canonical_path(OBJECT(dev));
404
source macio/Kconfig
389
+ QLIST_FOREACH(ncl, &dev->clocks, node) {
405
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
390
+ if (ncl->alias) {
406
index XXXXXXX..XXXXXXX 100644
391
+ continue;
407
--- a/hw/misc/meson.build
392
+ } else {
408
+++ b/hw/misc/meson.build
393
+ clock_setup_canonical_path(ncl->clock);
409
@@ -XXX,XX +XXX,XX @@ subdir('macio')
394
+ }
410
395
+ }
411
softmmu_ss.add(when: 'CONFIG_IVSHMEM_DEVICE', if_true: files('ivshmem.c'))
396
412
397
if (qdev_get_vmsd(dev)) {
413
+softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_CCM', if_true: files('allwinner-a10-ccm.c'))
398
if (vmstate_register_with_alias_id(VMSTATE_IF(dev),
414
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-ccu.c'))
399
@@ -XXX,XX +XXX,XX @@ static void device_initfn(Object *obj)
415
specific_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-cpucfg.c'))
400
dev->allow_unplug_during_migration = false;
416
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-dramc.c'))
401
402
QLIST_INIT(&dev->gpios);
403
+ QLIST_INIT(&dev->clocks);
404
}
405
406
static void device_post_init(Object *obj)
407
@@ -XXX,XX +XXX,XX @@ static void device_finalize(Object *obj)
408
*/
409
}
410
411
+ qdev_finalize_clocklist(dev);
412
+
413
/* Only send event if the device had been completely realized */
414
if (dev->pending_deleted_event) {
415
g_assert(dev->canonical_path);
416
--
417
--
417
2.20.1
418
2.34.1
418
419
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
3
During SPL boot several DRAM Controller registers are used. Most
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
important registers are those related to DRAM initialization and
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
calibration, where SPL initiates process and waits until certain bit is
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
set/cleared.
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
8
Message-id: 20200406135251.157596-3-damien.hedde@greensocs.com
8
This patch adds these registers, initializes reset values from user's
9
guide and updates state of registers as SPL expects it.
10
11
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
12
13
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
14
Message-id: 20221226220303.14420-3-strahinja.p.jankovic@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
hw/core/Makefile.objs | 1 +
17
include/hw/arm/allwinner-a10.h | 2 +
12
include/hw/clock.h | 9 +++++++++
18
include/hw/misc/allwinner-a10-dramc.h | 68 ++++++++++
13
hw/core/clock-vmstate.c | 25 +++++++++++++++++++++++++
19
hw/arm/allwinner-a10.c | 7 +
14
3 files changed, 35 insertions(+)
20
hw/misc/allwinner-a10-dramc.c | 179 ++++++++++++++++++++++++++
15
create mode 100644 hw/core/clock-vmstate.c
21
hw/arm/Kconfig | 1 +
16
22
hw/misc/Kconfig | 3 +
17
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
23
hw/misc/meson.build | 1 +
18
index XXXXXXX..XXXXXXX 100644
24
7 files changed, 261 insertions(+)
19
--- a/hw/core/Makefile.objs
25
create mode 100644 include/hw/misc/allwinner-a10-dramc.h
20
+++ b/hw/core/Makefile.objs
26
create mode 100644 hw/misc/allwinner-a10-dramc.c
21
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_SOFTMMU) += null-machine.o
27
22
common-obj-$(CONFIG_SOFTMMU) += loader.o
28
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
23
common-obj-$(CONFIG_SOFTMMU) += machine-hmp-cmds.o
29
index XXXXXXX..XXXXXXX 100644
24
common-obj-$(CONFIG_SOFTMMU) += numa.o
30
--- a/include/hw/arm/allwinner-a10.h
25
+common-obj-$(CONFIG_SOFTMMU) += clock-vmstate.o
31
+++ b/include/hw/arm/allwinner-a10.h
26
obj-$(CONFIG_SOFTMMU) += machine-qmp-cmds.o
32
@@ -XXX,XX +XXX,XX @@
27
33
#include "hw/usb/hcd-ehci.h"
28
common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
34
#include "hw/rtc/allwinner-rtc.h"
29
diff --git a/include/hw/clock.h b/include/hw/clock.h
35
#include "hw/misc/allwinner-a10-ccm.h"
30
index XXXXXXX..XXXXXXX 100644
36
+#include "hw/misc/allwinner-a10-dramc.h"
31
--- a/include/hw/clock.h
37
32
+++ b/include/hw/clock.h
38
#include "target/arm/cpu.h"
33
@@ -XXX,XX +XXX,XX @@ struct Clock {
39
#include "qom/object.h"
34
QLIST_ENTRY(Clock) sibling;
40
@@ -XXX,XX +XXX,XX @@ struct AwA10State {
35
};
41
36
42
ARMCPU cpu;
37
+/*
43
AwA10ClockCtlState ccm;
38
+ * vmstate description entry to be added in device vmsd.
44
+ AwA10DramControllerState dramc;
39
+ */
45
AwA10PITState timer;
40
+extern const VMStateDescription vmstate_clock;
46
AwA10PICState intc;
41
+#define VMSTATE_CLOCK(field, state) \
47
AwEmacState emac;
42
+ VMSTATE_CLOCK_V(field, state, 0)
48
diff --git a/include/hw/misc/allwinner-a10-dramc.h b/include/hw/misc/allwinner-a10-dramc.h
43
+#define VMSTATE_CLOCK_V(field, state, version) \
44
+ VMSTATE_STRUCT_POINTER_V(field, state, version, vmstate_clock, Clock)
45
+
46
/**
47
* clock_setup_canonical_path:
48
* @clk: clock
49
diff --git a/hw/core/clock-vmstate.c b/hw/core/clock-vmstate.c
50
new file mode 100644
49
new file mode 100644
51
index XXXXXXX..XXXXXXX
50
index XXXXXXX..XXXXXXX
52
--- /dev/null
51
--- /dev/null
53
+++ b/hw/core/clock-vmstate.c
52
+++ b/include/hw/misc/allwinner-a10-dramc.h
54
@@ -XXX,XX +XXX,XX @@
53
@@ -XXX,XX +XXX,XX @@
55
+/*
54
+/*
56
+ * Clock migration structure
55
+ * Allwinner A10 DRAM Controller emulation
57
+ *
56
+ *
58
+ * Copyright GreenSocs 2019-2020
57
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
59
+ *
58
+ *
60
+ * Authors:
59
+ * This file is derived from Allwinner H3 DRAMC,
61
+ * Damien Hedde
60
+ * by Niek Linnenbank.
62
+ *
61
+ *
63
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
62
+ * This program is free software: you can redistribute it and/or modify
64
+ * See the COPYING file in the top-level directory.
63
+ * it under the terms of the GNU General Public License as published by
64
+ * the Free Software Foundation, either version 2 of the License, or
65
+ * (at your option) any later version.
66
+ *
67
+ * This program is distributed in the hope that it will be useful,
68
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
69
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
70
+ * GNU General Public License for more details.
71
+ *
72
+ * You should have received a copy of the GNU General Public License
73
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
74
+ */
75
+
76
+#ifndef HW_MISC_ALLWINNER_A10_DRAMC_H
77
+#define HW_MISC_ALLWINNER_A10_DRAMC_H
78
+
79
+#include "qom/object.h"
80
+#include "hw/sysbus.h"
81
+#include "hw/register.h"
82
+
83
+/**
84
+ * @name Constants
85
+ * @{
86
+ */
87
+
88
+/** Size of register I/O address space used by DRAMC device */
89
+#define AW_A10_DRAMC_IOSIZE (0x1000)
90
+
91
+/** Total number of known registers */
92
+#define AW_A10_DRAMC_REGS_NUM (AW_A10_DRAMC_IOSIZE / sizeof(uint32_t))
93
+
94
+/** @} */
95
+
96
+/**
97
+ * @name Object model
98
+ * @{
99
+ */
100
+
101
+#define TYPE_AW_A10_DRAMC "allwinner-a10-dramc"
102
+OBJECT_DECLARE_SIMPLE_TYPE(AwA10DramControllerState, AW_A10_DRAMC)
103
+
104
+/** @} */
105
+
106
+/**
107
+ * Allwinner A10 DRAMC object instance state.
108
+ */
109
+struct AwA10DramControllerState {
110
+ /*< private >*/
111
+ SysBusDevice parent_obj;
112
+ /*< public >*/
113
+
114
+ /** Maps I/O registers in physical memory */
115
+ MemoryRegion iomem;
116
+
117
+ /** Array of hardware registers */
118
+ uint32_t regs[AW_A10_DRAMC_REGS_NUM];
119
+};
120
+
121
+#endif /* HW_MISC_ALLWINNER_A10_DRAMC_H */
122
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/arm/allwinner-a10.c
125
+++ b/hw/arm/allwinner-a10.c
126
@@ -XXX,XX +XXX,XX @@
127
#include "hw/boards.h"
128
#include "hw/usb/hcd-ohci.h"
129
130
+#define AW_A10_DRAMC_BASE 0x01c01000
131
#define AW_A10_MMC0_BASE 0x01c0f000
132
#define AW_A10_CCM_BASE 0x01c20000
133
#define AW_A10_PIC_REG_BASE 0x01c20400
134
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
135
136
object_initialize_child(obj, "ccm", &s->ccm, TYPE_AW_A10_CCM);
137
138
+ object_initialize_child(obj, "dramc", &s->dramc, TYPE_AW_A10_DRAMC);
139
+
140
object_initialize_child(obj, "emac", &s->emac, TYPE_AW_EMAC);
141
142
object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI);
143
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
144
sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_fatal);
145
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, AW_A10_CCM_BASE);
146
147
+ /* DRAM Control Module */
148
+ sysbus_realize(SYS_BUS_DEVICE(&s->dramc), &error_fatal);
149
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->dramc), 0, AW_A10_DRAMC_BASE);
150
+
151
/* FIXME use qdev NIC properties instead of nd_table[] */
152
if (nd_table[0].used) {
153
qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
154
diff --git a/hw/misc/allwinner-a10-dramc.c b/hw/misc/allwinner-a10-dramc.c
155
new file mode 100644
156
index XXXXXXX..XXXXXXX
157
--- /dev/null
158
+++ b/hw/misc/allwinner-a10-dramc.c
159
@@ -XXX,XX +XXX,XX @@
160
+/*
161
+ * Allwinner A10 DRAM Controller emulation
162
+ *
163
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
164
+ *
165
+ * This file is derived from Allwinner H3 DRAMC,
166
+ * by Niek Linnenbank.
167
+ *
168
+ * This program is free software: you can redistribute it and/or modify
169
+ * it under the terms of the GNU General Public License as published by
170
+ * the Free Software Foundation, either version 2 of the License, or
171
+ * (at your option) any later version.
172
+ *
173
+ * This program is distributed in the hope that it will be useful,
174
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
175
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
176
+ * GNU General Public License for more details.
177
+ *
178
+ * You should have received a copy of the GNU General Public License
179
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
65
+ */
180
+ */
66
+
181
+
67
+#include "qemu/osdep.h"
182
+#include "qemu/osdep.h"
183
+#include "qemu/units.h"
184
+#include "hw/sysbus.h"
68
+#include "migration/vmstate.h"
185
+#include "migration/vmstate.h"
69
+#include "hw/clock.h"
186
+#include "qemu/log.h"
70
+
187
+#include "qemu/module.h"
71
+const VMStateDescription vmstate_clock = {
188
+#include "hw/misc/allwinner-a10-dramc.h"
72
+ .name = "clock",
189
+
73
+ .version_id = 0,
190
+/* DRAMC register offsets */
74
+ .minimum_version_id = 0,
191
+enum {
192
+ REG_SDR_CCR = 0x0000,
193
+ REG_SDR_ZQCR0 = 0x00a8,
194
+ REG_SDR_ZQSR = 0x00b0
195
+};
196
+
197
+#define REG_INDEX(offset) (offset / sizeof(uint32_t))
198
+
199
+/* DRAMC register flags */
200
+enum {
201
+ REG_SDR_CCR_DATA_TRAINING = (1 << 30),
202
+ REG_SDR_CCR_DRAM_INIT = (1 << 31),
203
+};
204
+enum {
205
+ REG_SDR_ZQSR_ZCAL = (1 << 31),
206
+};
207
+
208
+/* DRAMC register reset values */
209
+enum {
210
+ REG_SDR_CCR_RESET = 0x80020000,
211
+ REG_SDR_ZQCR0_RESET = 0x07b00000,
212
+ REG_SDR_ZQSR_RESET = 0x80000000
213
+};
214
+
215
+static uint64_t allwinner_a10_dramc_read(void *opaque, hwaddr offset,
216
+ unsigned size)
217
+{
218
+ const AwA10DramControllerState *s = AW_A10_DRAMC(opaque);
219
+ const uint32_t idx = REG_INDEX(offset);
220
+
221
+ switch (offset) {
222
+ case REG_SDR_CCR:
223
+ case REG_SDR_ZQCR0:
224
+ case REG_SDR_ZQSR:
225
+ break;
226
+ case 0x2e4 ... AW_A10_DRAMC_IOSIZE:
227
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
228
+ __func__, (uint32_t)offset);
229
+ return 0;
230
+ default:
231
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented read offset 0x%04x\n",
232
+ __func__, (uint32_t)offset);
233
+ return 0;
234
+ }
235
+
236
+ return s->regs[idx];
237
+}
238
+
239
+static void allwinner_a10_dramc_write(void *opaque, hwaddr offset,
240
+ uint64_t val, unsigned size)
241
+{
242
+ AwA10DramControllerState *s = AW_A10_DRAMC(opaque);
243
+ const uint32_t idx = REG_INDEX(offset);
244
+
245
+ switch (offset) {
246
+ case REG_SDR_CCR:
247
+ if (val & REG_SDR_CCR_DRAM_INIT) {
248
+ /* Clear DRAM_INIT to indicate process is done. */
249
+ val &= ~REG_SDR_CCR_DRAM_INIT;
250
+ }
251
+ if (val & REG_SDR_CCR_DATA_TRAINING) {
252
+ /* Clear DATA_TRAINING to indicate process is done. */
253
+ val &= ~REG_SDR_CCR_DATA_TRAINING;
254
+ }
255
+ break;
256
+ case REG_SDR_ZQCR0:
257
+ /* Set ZCAL in ZQSR to indicate calibration is done. */
258
+ s->regs[REG_INDEX(REG_SDR_ZQSR)] |= REG_SDR_ZQSR_ZCAL;
259
+ break;
260
+ case 0x2e4 ... AW_A10_DRAMC_IOSIZE:
261
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
262
+ __func__, (uint32_t)offset);
263
+ break;
264
+ default:
265
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented write offset 0x%04x\n",
266
+ __func__, (uint32_t)offset);
267
+ break;
268
+ }
269
+
270
+ s->regs[idx] = (uint32_t) val;
271
+}
272
+
273
+static const MemoryRegionOps allwinner_a10_dramc_ops = {
274
+ .read = allwinner_a10_dramc_read,
275
+ .write = allwinner_a10_dramc_write,
276
+ .endianness = DEVICE_NATIVE_ENDIAN,
277
+ .valid = {
278
+ .min_access_size = 4,
279
+ .max_access_size = 4,
280
+ },
281
+ .impl.min_access_size = 4,
282
+};
283
+
284
+static void allwinner_a10_dramc_reset_enter(Object *obj, ResetType type)
285
+{
286
+ AwA10DramControllerState *s = AW_A10_DRAMC(obj);
287
+
288
+ /* Set default values for registers */
289
+ s->regs[REG_INDEX(REG_SDR_CCR)] = REG_SDR_CCR_RESET;
290
+ s->regs[REG_INDEX(REG_SDR_ZQCR0)] = REG_SDR_ZQCR0_RESET;
291
+ s->regs[REG_INDEX(REG_SDR_ZQSR)] = REG_SDR_ZQSR_RESET;
292
+}
293
+
294
+static void allwinner_a10_dramc_init(Object *obj)
295
+{
296
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
297
+ AwA10DramControllerState *s = AW_A10_DRAMC(obj);
298
+
299
+ /* Memory mapping */
300
+ memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_a10_dramc_ops, s,
301
+ TYPE_AW_A10_DRAMC, AW_A10_DRAMC_IOSIZE);
302
+ sysbus_init_mmio(sbd, &s->iomem);
303
+}
304
+
305
+static const VMStateDescription allwinner_a10_dramc_vmstate = {
306
+ .name = "allwinner-a10-dramc",
307
+ .version_id = 1,
308
+ .minimum_version_id = 1,
75
+ .fields = (VMStateField[]) {
309
+ .fields = (VMStateField[]) {
76
+ VMSTATE_UINT64(period, Clock),
310
+ VMSTATE_UINT32_ARRAY(regs, AwA10DramControllerState,
311
+ AW_A10_DRAMC_REGS_NUM),
77
+ VMSTATE_END_OF_LIST()
312
+ VMSTATE_END_OF_LIST()
78
+ }
313
+ }
79
+};
314
+};
315
+
316
+static void allwinner_a10_dramc_class_init(ObjectClass *klass, void *data)
317
+{
318
+ DeviceClass *dc = DEVICE_CLASS(klass);
319
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
320
+
321
+ rc->phases.enter = allwinner_a10_dramc_reset_enter;
322
+ dc->vmsd = &allwinner_a10_dramc_vmstate;
323
+}
324
+
325
+static const TypeInfo allwinner_a10_dramc_info = {
326
+ .name = TYPE_AW_A10_DRAMC,
327
+ .parent = TYPE_SYS_BUS_DEVICE,
328
+ .instance_init = allwinner_a10_dramc_init,
329
+ .instance_size = sizeof(AwA10DramControllerState),
330
+ .class_init = allwinner_a10_dramc_class_init,
331
+};
332
+
333
+static void allwinner_a10_dramc_register(void)
334
+{
335
+ type_register_static(&allwinner_a10_dramc_info);
336
+}
337
+
338
+type_init(allwinner_a10_dramc_register)
339
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
340
index XXXXXXX..XXXXXXX 100644
341
--- a/hw/arm/Kconfig
342
+++ b/hw/arm/Kconfig
343
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
344
select ALLWINNER_A10_PIT
345
select ALLWINNER_A10_PIC
346
select ALLWINNER_A10_CCM
347
+ select ALLWINNER_A10_DRAMC
348
select ALLWINNER_EMAC
349
select SERIAL
350
select UNIMP
351
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
352
index XXXXXXX..XXXXXXX 100644
353
--- a/hw/misc/Kconfig
354
+++ b/hw/misc/Kconfig
355
@@ -XXX,XX +XXX,XX @@ config LASI
356
config ALLWINNER_A10_CCM
357
bool
358
359
+config ALLWINNER_A10_DRAMC
360
+ bool
361
+
362
source macio/Kconfig
363
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
364
index XXXXXXX..XXXXXXX 100644
365
--- a/hw/misc/meson.build
366
+++ b/hw/misc/meson.build
367
@@ -XXX,XX +XXX,XX @@ subdir('macio')
368
softmmu_ss.add(when: 'CONFIG_IVSHMEM_DEVICE', if_true: files('ivshmem.c'))
369
370
softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_CCM', if_true: files('allwinner-a10-ccm.c'))
371
+softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_DRAMC', if_true: files('allwinner-a10-dramc.c'))
372
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-ccu.c'))
373
specific_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-cpucfg.c'))
374
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-dramc.c'))
80
--
375
--
81
2.20.1
376
2.34.1
82
83
diff view generated by jsdifflib
1
This object may be used to represent a clock inside a clock tree.
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
A clock may be connected to another clock so that it receives update,
3
This patch implements Allwinner TWI/I2C controller emulation. Only
4
through a callback, whenever the source/parent clock is updated.
4
master-mode functionality is implemented.
5
5
6
Although only the root clock of a clock tree controls the values
6
The SPL boot for Cubieboard expects AXP209 PMIC on TWI0/I2C0 bus, so this is
7
(represented as periods) of all clocks in tree, each clock holds
7
first part enabling the TWI/I2C bus operation.
8
a local state containing the current value so that it can be fetched
9
independently. It will allows us to fullfill migration requirements
10
by migrating each clock independently of others.
11
8
12
This is based on the original work of Frederic Konrad.
9
Since both Allwinner A10 and H3 use the same module, it is added for
10
both boards.
13
11
14
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
12
Docs are also updated for Cubieboard and Orangepi-PC board to indicate
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
I2C availability.
16
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
14
17
Message-id: 20200406135251.157596-2-damien.hedde@greensocs.com
15
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
18
[PMM: Use uint64_t rather than unsigned long long in trace events;
16
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
19
the dtrace backend can't handle the latter]
17
Message-id: 20221226220303.14420-4-strahinja.p.jankovic@gmail.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
19
---
22
hw/core/Makefile.objs | 1 +
20
docs/system/arm/cubieboard.rst | 1 +
23
include/hw/clock.h | 216 ++++++++++++++++++++++++++++++++++++++++++
21
docs/system/arm/orangepi.rst | 1 +
24
hw/core/clock.c | 130 +++++++++++++++++++++++++
22
include/hw/arm/allwinner-a10.h | 2 +
25
hw/core/trace-events | 7 ++
23
include/hw/arm/allwinner-h3.h | 3 +
26
4 files changed, 354 insertions(+)
24
include/hw/i2c/allwinner-i2c.h | 55 ++++
27
create mode 100644 include/hw/clock.h
25
hw/arm/allwinner-a10.c | 8 +
28
create mode 100644 hw/core/clock.c
26
hw/arm/allwinner-h3.c | 11 +-
27
hw/i2c/allwinner-i2c.c | 459 +++++++++++++++++++++++++++++++++
28
hw/arm/Kconfig | 2 +
29
hw/i2c/Kconfig | 4 +
30
hw/i2c/meson.build | 1 +
31
hw/i2c/trace-events | 5 +
32
12 files changed, 551 insertions(+), 1 deletion(-)
33
create mode 100644 include/hw/i2c/allwinner-i2c.h
34
create mode 100644 hw/i2c/allwinner-i2c.c
29
35
30
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
36
diff --git a/docs/system/arm/cubieboard.rst b/docs/system/arm/cubieboard.rst
31
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/core/Makefile.objs
38
--- a/docs/system/arm/cubieboard.rst
33
+++ b/hw/core/Makefile.objs
39
+++ b/docs/system/arm/cubieboard.rst
34
@@ -XXX,XX +XXX,XX @@ common-obj-y += hotplug.o
40
@@ -XXX,XX +XXX,XX @@ Emulated devices:
35
common-obj-y += vmstate-if.o
41
- SDHCI
36
# irq.o needed for qdev GPIO handling:
42
- USB controller
37
common-obj-y += irq.o
43
- SATA controller
38
+common-obj-y += clock.o
44
+- TWI (I2C) controller
39
45
diff --git a/docs/system/arm/orangepi.rst b/docs/system/arm/orangepi.rst
40
common-obj-$(CONFIG_SOFTMMU) += reset.o
46
index XXXXXXX..XXXXXXX 100644
41
common-obj-$(CONFIG_SOFTMMU) += qdev-fw.o
47
--- a/docs/system/arm/orangepi.rst
42
diff --git a/include/hw/clock.h b/include/hw/clock.h
48
+++ b/docs/system/arm/orangepi.rst
49
@@ -XXX,XX +XXX,XX @@ The Orange Pi PC machine supports the following devices:
50
* Clock Control Unit
51
* System Control module
52
* Security Identifier device
53
+ * TWI (I2C)
54
55
Limitations
56
"""""""""""
57
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/include/hw/arm/allwinner-a10.h
60
+++ b/include/hw/arm/allwinner-a10.h
61
@@ -XXX,XX +XXX,XX @@
62
#include "hw/rtc/allwinner-rtc.h"
63
#include "hw/misc/allwinner-a10-ccm.h"
64
#include "hw/misc/allwinner-a10-dramc.h"
65
+#include "hw/i2c/allwinner-i2c.h"
66
67
#include "target/arm/cpu.h"
68
#include "qom/object.h"
69
@@ -XXX,XX +XXX,XX @@ struct AwA10State {
70
AwEmacState emac;
71
AllwinnerAHCIState sata;
72
AwSdHostState mmc0;
73
+ AWI2CState i2c0;
74
AwRtcState rtc;
75
MemoryRegion sram_a;
76
EHCISysBusState ehci[AW_A10_NUM_USB];
77
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
78
index XXXXXXX..XXXXXXX 100644
79
--- a/include/hw/arm/allwinner-h3.h
80
+++ b/include/hw/arm/allwinner-h3.h
81
@@ -XXX,XX +XXX,XX @@
82
#include "hw/sd/allwinner-sdhost.h"
83
#include "hw/net/allwinner-sun8i-emac.h"
84
#include "hw/rtc/allwinner-rtc.h"
85
+#include "hw/i2c/allwinner-i2c.h"
86
#include "target/arm/cpu.h"
87
#include "sysemu/block-backend.h"
88
89
@@ -XXX,XX +XXX,XX @@ enum {
90
AW_H3_DEV_UART2,
91
AW_H3_DEV_UART3,
92
AW_H3_DEV_EMAC,
93
+ AW_H3_DEV_TWI0,
94
AW_H3_DEV_DRAMCOM,
95
AW_H3_DEV_DRAMCTL,
96
AW_H3_DEV_DRAMPHY,
97
@@ -XXX,XX +XXX,XX @@ struct AwH3State {
98
AwH3SysCtrlState sysctrl;
99
AwSidState sid;
100
AwSdHostState mmc0;
101
+ AWI2CState i2c0;
102
AwSun8iEmacState emac;
103
AwRtcState rtc;
104
GICState gic;
105
diff --git a/include/hw/i2c/allwinner-i2c.h b/include/hw/i2c/allwinner-i2c.h
43
new file mode 100644
106
new file mode 100644
44
index XXXXXXX..XXXXXXX
107
index XXXXXXX..XXXXXXX
45
--- /dev/null
108
--- /dev/null
46
+++ b/include/hw/clock.h
109
+++ b/include/hw/i2c/allwinner-i2c.h
47
@@ -XXX,XX +XXX,XX @@
110
@@ -XXX,XX +XXX,XX @@
48
+/*
111
+/*
49
+ * Hardware Clocks
112
+ * Allwinner I2C Bus Serial Interface registers definition
50
+ *
113
+ *
51
+ * Copyright GreenSocs 2016-2020
114
+ * Copyright (C) 2022 Strahinja Jankovic. <strahinja.p.jankovic@gmail.com>
52
+ *
115
+ *
53
+ * Authors:
116
+ * This file is derived from IMX I2C controller,
54
+ * Frederic Konrad
117
+ * by Jean-Christophe DUBOIS .
55
+ * Damien Hedde
118
+ *
56
+ *
119
+ * This program is free software; you can redistribute it and/or modify it
57
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
120
+ * under the terms of the GNU General Public License as published by the
58
+ * See the COPYING file in the top-level directory.
121
+ * Free Software Foundation; either version 2 of the License, or
122
+ * (at your option) any later version.
123
+ *
124
+ * This program is distributed in the hope that it will be useful, but WITHOUT
125
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
126
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
127
+ * for more details.
128
+ *
129
+ * You should have received a copy of the GNU General Public License along
130
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
131
+ *
59
+ */
132
+ */
60
+
133
+
61
+#ifndef QEMU_HW_CLOCK_H
134
+#ifndef ALLWINNER_I2C_H
62
+#define QEMU_HW_CLOCK_H
135
+#define ALLWINNER_I2C_H
63
+
136
+
137
+#include "hw/sysbus.h"
64
+#include "qom/object.h"
138
+#include "qom/object.h"
65
+#include "qemu/queue.h"
139
+
66
+
140
+#define TYPE_AW_I2C "allwinner.i2c"
67
+#define TYPE_CLOCK "clock"
141
+OBJECT_DECLARE_SIMPLE_TYPE(AWI2CState, AW_I2C)
68
+#define CLOCK(obj) OBJECT_CHECK(Clock, (obj), TYPE_CLOCK)
142
+
69
+
143
+#define AW_I2C_MEM_SIZE 0x24
70
+typedef void ClockCallback(void *opaque);
144
+
71
+
145
+struct AWI2CState {
72
+/*
73
+ * clock store a value representing the clock's period in 2^-32ns unit.
74
+ * It can represent:
75
+ * + periods from 2^-32ns up to 4seconds
76
+ * + frequency from ~0.25Hz 2e10Ghz
77
+ * Resolution of frequency representation decreases with frequency:
78
+ * + at 100MHz, resolution is ~2mHz
79
+ * + at 1Ghz, resolution is ~0.2Hz
80
+ * + at 10Ghz, resolution is ~20Hz
81
+ */
82
+#define CLOCK_SECOND (1000000000llu << 32)
83
+
84
+/*
85
+ * macro helpers to convert to hertz / nanosecond
86
+ */
87
+#define CLOCK_PERIOD_FROM_NS(ns) ((ns) * (CLOCK_SECOND / 1000000000llu))
88
+#define CLOCK_PERIOD_TO_NS(per) ((per) / (CLOCK_SECOND / 1000000000llu))
89
+#define CLOCK_PERIOD_FROM_HZ(hz) (((hz) != 0) ? CLOCK_SECOND / (hz) : 0u)
90
+#define CLOCK_PERIOD_TO_HZ(per) (((per) != 0) ? CLOCK_SECOND / (per) : 0u)
91
+
92
+/**
93
+ * Clock:
94
+ * @parent_obj: parent class
95
+ * @period: unsigned integer representing the period of the clock
96
+ * @canonical_path: clock path string cache (used for trace purpose)
97
+ * @callback: called when clock changes
98
+ * @callback_opaque: argument for @callback
99
+ * @source: source (or parent in clock tree) of the clock
100
+ * @children: list of clocks connected to this one (it is their source)
101
+ * @sibling: structure used to form a clock list
102
+ */
103
+
104
+typedef struct Clock Clock;
105
+
106
+struct Clock {
107
+ /*< private >*/
146
+ /*< private >*/
108
+ Object parent_obj;
147
+ SysBusDevice parent_obj;
109
+
148
+
110
+ /* all fields are private and should not be modified directly */
149
+ /*< public >*/
111
+
150
+ MemoryRegion iomem;
112
+ /* fields */
151
+ I2CBus *bus;
113
+ uint64_t period;
152
+ qemu_irq irq;
114
+ char *canonical_path;
153
+
115
+ ClockCallback *callback;
154
+ uint8_t addr;
116
+ void *callback_opaque;
155
+ uint8_t xaddr;
117
+
156
+ uint8_t data;
118
+ /* Clocks are organized in a clock tree */
157
+ uint8_t cntr;
119
+ Clock *source;
158
+ uint8_t stat;
120
+ QLIST_HEAD(, Clock) children;
159
+ uint8_t ccr;
121
+ QLIST_ENTRY(Clock) sibling;
160
+ uint8_t srst;
161
+ uint8_t efr;
162
+ uint8_t lcr;
122
+};
163
+};
123
+
164
+
124
+/**
165
+#endif /* ALLWINNER_I2C_H */
125
+ * clock_setup_canonical_path:
166
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
126
+ * @clk: clock
167
index XXXXXXX..XXXXXXX 100644
127
+ *
168
--- a/hw/arm/allwinner-a10.c
128
+ * compute the canonical path of the clock (used by log messages)
169
+++ b/hw/arm/allwinner-a10.c
129
+ */
170
@@ -XXX,XX +XXX,XX @@
130
+void clock_setup_canonical_path(Clock *clk);
171
#define AW_A10_OHCI_BASE 0x01c14400
131
+
172
#define AW_A10_SATA_BASE 0x01c18000
132
+/**
173
#define AW_A10_RTC_BASE 0x01c20d00
133
+ * clock_set_callback:
174
+#define AW_A10_I2C0_BASE 0x01c2ac00
134
+ * @clk: the clock to register the callback into
175
135
+ * @cb: the callback function
176
static void aw_a10_init(Object *obj)
136
+ * @opaque: the argument to the callback
177
{
137
+ *
178
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
138
+ * Register a callback called on every clock update.
179
139
+ */
180
object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI);
140
+void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque);
181
141
+
182
+ object_initialize_child(obj, "i2c0", &s->i2c0, TYPE_AW_I2C);
142
+/**
183
+
143
+ * clock_clear_callback:
184
if (machine_usb(current_machine)) {
144
+ * @clk: the clock to delete the callback from
185
int i;
145
+ *
186
146
+ * Unregister the callback registered with clock_set_callback.
187
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
147
+ */
188
/* RTC */
148
+void clock_clear_callback(Clock *clk);
189
sysbus_realize(SYS_BUS_DEVICE(&s->rtc), &error_fatal);
149
+
190
sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->rtc), 0, AW_A10_RTC_BASE, 10);
150
+/**
191
+
151
+ * clock_set_source:
192
+ /* I2C */
152
+ * @clk: the clock.
193
+ sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal);
153
+ * @src: the source clock
194
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, AW_A10_I2C0_BASE);
154
+ *
195
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0, qdev_get_gpio_in(dev, 7));
155
+ * Setup @src as the clock source of @clk. The current @src period
196
}
156
+ * value is also copied to @clk and its subtree but no callback is
197
157
+ * called.
198
static void aw_a10_class_init(ObjectClass *oc, void *data)
158
+ * Further @src update will be propagated to @clk and its subtree.
199
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
159
+ */
200
index XXXXXXX..XXXXXXX 100644
160
+void clock_set_source(Clock *clk, Clock *src);
201
--- a/hw/arm/allwinner-h3.c
161
+
202
+++ b/hw/arm/allwinner-h3.c
162
+/**
203
@@ -XXX,XX +XXX,XX @@ const hwaddr allwinner_h3_memmap[] = {
163
+ * clock_set:
204
[AW_H3_DEV_UART1] = 0x01c28400,
164
+ * @clk: the clock to initialize.
205
[AW_H3_DEV_UART2] = 0x01c28800,
165
+ * @value: the clock's value, 0 means unclocked
206
[AW_H3_DEV_UART3] = 0x01c28c00,
166
+ *
207
+ [AW_H3_DEV_TWI0] = 0x01c2ac00,
167
+ * Set the local cached period value of @clk to @value.
208
[AW_H3_DEV_EMAC] = 0x01c30000,
168
+ */
209
[AW_H3_DEV_DRAMCOM] = 0x01c62000,
169
+void clock_set(Clock *clk, uint64_t value);
210
[AW_H3_DEV_DRAMCTL] = 0x01c63000,
170
+
211
@@ -XXX,XX +XXX,XX @@ struct AwH3Unimplemented {
171
+static inline void clock_set_hz(Clock *clk, unsigned hz)
212
{ "uart1", 0x01c28400, 1 * KiB },
172
+{
213
{ "uart2", 0x01c28800, 1 * KiB },
173
+ clock_set(clk, CLOCK_PERIOD_FROM_HZ(hz));
214
{ "uart3", 0x01c28c00, 1 * KiB },
174
+}
215
- { "twi0", 0x01c2ac00, 1 * KiB },
175
+
216
{ "twi1", 0x01c2b000, 1 * KiB },
176
+static inline void clock_set_ns(Clock *clk, unsigned ns)
217
{ "twi2", 0x01c2b400, 1 * KiB },
177
+{
218
{ "scr", 0x01c2c400, 1 * KiB },
178
+ clock_set(clk, CLOCK_PERIOD_FROM_NS(ns));
219
@@ -XXX,XX +XXX,XX @@ enum {
179
+}
220
AW_H3_GIC_SPI_UART1 = 1,
180
+
221
AW_H3_GIC_SPI_UART2 = 2,
181
+/**
222
AW_H3_GIC_SPI_UART3 = 3,
182
+ * clock_propagate:
223
+ AW_H3_GIC_SPI_TWI0 = 6,
183
+ * @clk: the clock
224
AW_H3_GIC_SPI_TIMER0 = 18,
184
+ *
225
AW_H3_GIC_SPI_TIMER1 = 19,
185
+ * Propagate the clock period that has been previously configured using
226
AW_H3_GIC_SPI_MMC0 = 60,
186
+ * @clock_set(). This will update recursively all connected clocks.
227
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_init(Object *obj)
187
+ * It is an error to call this function on a clock which has a source.
228
"ram-size");
188
+ * Note: this function must not be called during device inititialization
229
189
+ * or migration.
230
object_initialize_child(obj, "rtc", &s->rtc, TYPE_AW_RTC_SUN6I);
190
+ */
231
+
191
+void clock_propagate(Clock *clk);
232
+ object_initialize_child(obj, "twi0", &s->i2c0, TYPE_AW_I2C);
192
+
233
}
193
+/**
234
194
+ * clock_update:
235
static void allwinner_h3_realize(DeviceState *dev, Error **errp)
195
+ * @clk: the clock to update.
236
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
196
+ * @value: the new clock's value, 0 means unclocked
237
sysbus_realize(SYS_BUS_DEVICE(&s->rtc), &error_fatal);
197
+ *
238
sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, s->memmap[AW_H3_DEV_RTC]);
198
+ * Update the @clk to the new @value. All connected clocks will be informed
239
199
+ * of this update. This is equivalent to call @clock_set() then
240
+ /* I2C */
200
+ * @clock_propagate().
241
+ sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal);
201
+ */
242
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, s->memmap[AW_H3_DEV_TWI0]);
202
+static inline void clock_update(Clock *clk, uint64_t value)
243
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0,
203
+{
244
+ qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_TWI0));
204
+ clock_set(clk, value);
245
+
205
+ clock_propagate(clk);
246
/* Unimplemented devices */
206
+}
247
for (i = 0; i < ARRAY_SIZE(unimplemented); i++) {
207
+
248
create_unimplemented_device(unimplemented[i].device_name,
208
+static inline void clock_update_hz(Clock *clk, unsigned hz)
249
diff --git a/hw/i2c/allwinner-i2c.c b/hw/i2c/allwinner-i2c.c
209
+{
210
+ clock_update(clk, CLOCK_PERIOD_FROM_HZ(hz));
211
+}
212
+
213
+static inline void clock_update_ns(Clock *clk, unsigned ns)
214
+{
215
+ clock_update(clk, CLOCK_PERIOD_FROM_NS(ns));
216
+}
217
+
218
+/**
219
+ * clock_get:
220
+ * @clk: the clk to fetch the clock
221
+ *
222
+ * @return: the current period.
223
+ */
224
+static inline uint64_t clock_get(const Clock *clk)
225
+{
226
+ return clk->period;
227
+}
228
+
229
+static inline unsigned clock_get_hz(Clock *clk)
230
+{
231
+ return CLOCK_PERIOD_TO_HZ(clock_get(clk));
232
+}
233
+
234
+static inline unsigned clock_get_ns(Clock *clk)
235
+{
236
+ return CLOCK_PERIOD_TO_NS(clock_get(clk));
237
+}
238
+
239
+/**
240
+ * clock_is_enabled:
241
+ * @clk: a clock
242
+ *
243
+ * @return: true if the clock is running.
244
+ */
245
+static inline bool clock_is_enabled(const Clock *clk)
246
+{
247
+ return clock_get(clk) != 0;
248
+}
249
+
250
+static inline void clock_init(Clock *clk, uint64_t value)
251
+{
252
+ clock_set(clk, value);
253
+}
254
+static inline void clock_init_hz(Clock *clk, uint64_t value)
255
+{
256
+ clock_set_hz(clk, value);
257
+}
258
+static inline void clock_init_ns(Clock *clk, uint64_t value)
259
+{
260
+ clock_set_ns(clk, value);
261
+}
262
+
263
+#endif /* QEMU_HW_CLOCK_H */
264
diff --git a/hw/core/clock.c b/hw/core/clock.c
265
new file mode 100644
250
new file mode 100644
266
index XXXXXXX..XXXXXXX
251
index XXXXXXX..XXXXXXX
267
--- /dev/null
252
--- /dev/null
268
+++ b/hw/core/clock.c
253
+++ b/hw/i2c/allwinner-i2c.c
269
@@ -XXX,XX +XXX,XX @@
254
@@ -XXX,XX +XXX,XX @@
270
+/*
255
+/*
271
+ * Hardware Clocks
256
+ * Allwinner I2C Bus Serial Interface Emulation
272
+ *
257
+ *
273
+ * Copyright GreenSocs 2016-2020
258
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
274
+ *
259
+ *
275
+ * Authors:
260
+ * This file is derived from IMX I2C controller,
276
+ * Frederic Konrad
261
+ * by Jean-Christophe DUBOIS .
277
+ * Damien Hedde
262
+ *
278
+ *
263
+ * This program is free software; you can redistribute it and/or modify it
279
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
264
+ * under the terms of the GNU General Public License as published by the
280
+ * See the COPYING file in the top-level directory.
265
+ * Free Software Foundation; either version 2 of the License, or
266
+ * (at your option) any later version.
267
+ *
268
+ * This program is distributed in the hope that it will be useful, but WITHOUT
269
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
270
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
271
+ * for more details.
272
+ *
273
+ * You should have received a copy of the GNU General Public License along
274
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
275
+ *
276
+ * SPDX-License-Identifier: MIT
281
+ */
277
+ */
282
+
278
+
283
+#include "qemu/osdep.h"
279
+#include "qemu/osdep.h"
284
+#include "hw/clock.h"
280
+#include "hw/i2c/allwinner-i2c.h"
281
+#include "hw/irq.h"
282
+#include "migration/vmstate.h"
283
+#include "hw/i2c/i2c.h"
284
+#include "qemu/log.h"
285
+#include "trace.h"
285
+#include "trace.h"
286
+
286
+#include "qemu/module.h"
287
+#define CLOCK_PATH(_clk) (_clk->canonical_path)
287
+
288
+
288
+/* Allwinner I2C memory map */
289
+void clock_setup_canonical_path(Clock *clk)
289
+#define TWI_ADDR_REG 0x00 /* slave address register */
290
+{
290
+#define TWI_XADDR_REG 0x04 /* extended slave address register */
291
+ g_free(clk->canonical_path);
291
+#define TWI_DATA_REG 0x08 /* data register */
292
+ clk->canonical_path = object_get_canonical_path(OBJECT(clk));
292
+#define TWI_CNTR_REG 0x0c /* control register */
293
+}
293
+#define TWI_STAT_REG 0x10 /* status register */
294
+
294
+#define TWI_CCR_REG 0x14 /* clock control register */
295
+void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque)
295
+#define TWI_SRST_REG 0x18 /* software reset register */
296
+{
296
+#define TWI_EFR_REG 0x1c /* enhance feature register */
297
+ clk->callback = cb;
297
+#define TWI_LCR_REG 0x20 /* line control register */
298
+ clk->callback_opaque = opaque;
298
+
299
+}
299
+/* Used only in slave mode, do not set */
300
+
300
+#define TWI_ADDR_RESET 0
301
+void clock_clear_callback(Clock *clk)
301
+#define TWI_XADDR_RESET 0
302
+{
302
+
303
+ clock_set_callback(clk, NULL, NULL);
303
+/* Data register */
304
+}
304
+#define TWI_DATA_MASK 0xFF
305
+
305
+#define TWI_DATA_RESET 0
306
+void clock_set(Clock *clk, uint64_t period)
306
+
307
+{
307
+/* Control register */
308
+ trace_clock_set(CLOCK_PATH(clk), CLOCK_PERIOD_TO_NS(clk->period),
308
+#define TWI_CNTR_INT_EN (1 << 7)
309
+ CLOCK_PERIOD_TO_NS(period));
309
+#define TWI_CNTR_BUS_EN (1 << 6)
310
+ clk->period = period;
310
+#define TWI_CNTR_M_STA (1 << 5)
311
+}
311
+#define TWI_CNTR_M_STP (1 << 4)
312
+
312
+#define TWI_CNTR_INT_FLAG (1 << 3)
313
+static void clock_propagate_period(Clock *clk, bool call_callbacks)
313
+#define TWI_CNTR_A_ACK (1 << 2)
314
+{
314
+#define TWI_CNTR_MASK 0xFC
315
+ Clock *child;
315
+#define TWI_CNTR_RESET 0
316
+
316
+
317
+ QLIST_FOREACH(child, &clk->children, sibling) {
317
+/* Status register */
318
+ if (child->period != clk->period) {
318
+#define TWI_STAT_MASK 0xF8
319
+ child->period = clk->period;
319
+#define TWI_STAT_RESET 0xF8
320
+ trace_clock_update(CLOCK_PATH(child), CLOCK_PATH(clk),
320
+
321
+ CLOCK_PERIOD_TO_NS(clk->period),
321
+/* Clock register */
322
+ call_callbacks);
322
+#define TWI_CCR_CLK_M_MASK 0x78
323
+ if (call_callbacks && child->callback) {
323
+#define TWI_CCR_CLK_N_MASK 0x07
324
+ child->callback(child->callback_opaque);
324
+#define TWI_CCR_MASK 0x7F
325
+ }
325
+#define TWI_CCR_RESET 0
326
+ clock_propagate_period(child, call_callbacks);
326
+
327
+/* Soft reset */
328
+#define TWI_SRST_MASK 0x01
329
+#define TWI_SRST_RESET 0
330
+
331
+/* Enhance feature */
332
+#define TWI_EFR_MASK 0x03
333
+#define TWI_EFR_RESET 0
334
+
335
+/* Line control */
336
+#define TWI_LCR_SCL_STATE (1 << 5)
337
+#define TWI_LCR_SDA_STATE (1 << 4)
338
+#define TWI_LCR_SCL_CTL (1 << 3)
339
+#define TWI_LCR_SCL_CTL_EN (1 << 2)
340
+#define TWI_LCR_SDA_CTL (1 << 1)
341
+#define TWI_LCR_SDA_CTL_EN (1 << 0)
342
+#define TWI_LCR_MASK 0x3F
343
+#define TWI_LCR_RESET 0x3A
344
+
345
+/* Status value in STAT register is shifted by 3 bits */
346
+#define TWI_STAT_SHIFT 3
347
+#define STAT_FROM_STA(x) ((x) << TWI_STAT_SHIFT)
348
+#define STAT_TO_STA(x) ((x) >> TWI_STAT_SHIFT)
349
+
350
+enum {
351
+ STAT_BUS_ERROR = 0,
352
+ /* Master mode */
353
+ STAT_M_STA_TX,
354
+ STAT_M_RSTA_TX,
355
+ STAT_M_ADDR_WR_ACK,
356
+ STAT_M_ADDR_WR_NACK,
357
+ STAT_M_DATA_TX_ACK,
358
+ STAT_M_DATA_TX_NACK,
359
+ STAT_M_ARB_LOST,
360
+ STAT_M_ADDR_RD_ACK,
361
+ STAT_M_ADDR_RD_NACK,
362
+ STAT_M_DATA_RX_ACK,
363
+ STAT_M_DATA_RX_NACK,
364
+ /* Slave mode */
365
+ STAT_S_ADDR_WR_ACK,
366
+ STAT_S_ARB_LOST_AW_ACK,
367
+ STAT_S_GCA_ACK,
368
+ STAT_S_ARB_LOST_GCA_ACK,
369
+ STAT_S_DATA_RX_SA_ACK,
370
+ STAT_S_DATA_RX_SA_NACK,
371
+ STAT_S_DATA_RX_GCA_ACK,
372
+ STAT_S_DATA_RX_GCA_NACK,
373
+ STAT_S_STP_RSTA,
374
+ STAT_S_ADDR_RD_ACK,
375
+ STAT_S_ARB_LOST_AR_ACK,
376
+ STAT_S_DATA_TX_ACK,
377
+ STAT_S_DATA_TX_NACK,
378
+ STAT_S_LB_TX_ACK,
379
+ /* Master mode, 10-bit */
380
+ STAT_M_2ND_ADDR_WR_ACK,
381
+ STAT_M_2ND_ADDR_WR_NACK,
382
+ /* Idle */
383
+ STAT_IDLE = 0x1f
384
+} TWI_STAT_STA;
385
+
386
+static const char *allwinner_i2c_get_regname(unsigned offset)
387
+{
388
+ switch (offset) {
389
+ case TWI_ADDR_REG:
390
+ return "ADDR";
391
+ case TWI_XADDR_REG:
392
+ return "XADDR";
393
+ case TWI_DATA_REG:
394
+ return "DATA";
395
+ case TWI_CNTR_REG:
396
+ return "CNTR";
397
+ case TWI_STAT_REG:
398
+ return "STAT";
399
+ case TWI_CCR_REG:
400
+ return "CCR";
401
+ case TWI_SRST_REG:
402
+ return "SRST";
403
+ case TWI_EFR_REG:
404
+ return "EFR";
405
+ case TWI_LCR_REG:
406
+ return "LCR";
407
+ default:
408
+ return "[?]";
409
+ }
410
+}
411
+
412
+static inline bool allwinner_i2c_is_reset(AWI2CState *s)
413
+{
414
+ return s->srst & TWI_SRST_MASK;
415
+}
416
+
417
+static inline bool allwinner_i2c_bus_is_enabled(AWI2CState *s)
418
+{
419
+ return s->cntr & TWI_CNTR_BUS_EN;
420
+}
421
+
422
+static inline bool allwinner_i2c_interrupt_is_enabled(AWI2CState *s)
423
+{
424
+ return s->cntr & TWI_CNTR_INT_EN;
425
+}
426
+
427
+static void allwinner_i2c_reset_hold(Object *obj)
428
+{
429
+ AWI2CState *s = AW_I2C(obj);
430
+
431
+ if (STAT_TO_STA(s->stat) != STAT_IDLE) {
432
+ i2c_end_transfer(s->bus);
433
+ }
434
+
435
+ s->addr = TWI_ADDR_RESET;
436
+ s->xaddr = TWI_XADDR_RESET;
437
+ s->data = TWI_DATA_RESET;
438
+ s->cntr = TWI_CNTR_RESET;
439
+ s->stat = TWI_STAT_RESET;
440
+ s->ccr = TWI_CCR_RESET;
441
+ s->srst = TWI_SRST_RESET;
442
+ s->efr = TWI_EFR_RESET;
443
+ s->lcr = TWI_LCR_RESET;
444
+}
445
+
446
+static inline void allwinner_i2c_raise_interrupt(AWI2CState *s)
447
+{
448
+ /*
449
+ * Raise an interrupt if the device is not reset and it is configured
450
+ * to generate some interrupts.
451
+ */
452
+ if (!allwinner_i2c_is_reset(s) && allwinner_i2c_bus_is_enabled(s)) {
453
+ if (STAT_TO_STA(s->stat) != STAT_IDLE) {
454
+ s->cntr |= TWI_CNTR_INT_FLAG;
455
+ if (allwinner_i2c_interrupt_is_enabled(s)) {
456
+ qemu_irq_raise(s->irq);
457
+ }
327
+ }
458
+ }
328
+ }
459
+ }
329
+}
460
+}
330
+
461
+
331
+void clock_propagate(Clock *clk)
462
+static uint64_t allwinner_i2c_read(void *opaque, hwaddr offset,
332
+{
463
+ unsigned size)
333
+ assert(clk->source == NULL);
464
+{
334
+ trace_clock_propagate(CLOCK_PATH(clk));
465
+ uint16_t value;
335
+ clock_propagate_period(clk, true);
466
+ AWI2CState *s = AW_I2C(opaque);
336
+}
467
+
337
+
468
+ switch (offset) {
338
+void clock_set_source(Clock *clk, Clock *src)
469
+ case TWI_ADDR_REG:
339
+{
470
+ value = s->addr;
340
+ /* changing clock source is not supported */
471
+ break;
341
+ assert(!clk->source);
472
+ case TWI_XADDR_REG:
342
+
473
+ value = s->xaddr;
343
+ trace_clock_set_source(CLOCK_PATH(clk), CLOCK_PATH(src));
474
+ break;
344
+
475
+ case TWI_DATA_REG:
345
+ clk->period = src->period;
476
+ if ((STAT_TO_STA(s->stat) == STAT_M_ADDR_RD_ACK) ||
346
+ QLIST_INSERT_HEAD(&src->children, clk, sibling);
477
+ (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_ACK) ||
347
+ clk->source = src;
478
+ (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_NACK)) {
348
+ clock_propagate_period(clk, false);
479
+ /* Get the next byte */
349
+}
480
+ s->data = i2c_recv(s->bus);
350
+
481
+
351
+static void clock_disconnect(Clock *clk)
482
+ if (s->cntr & TWI_CNTR_A_ACK) {
352
+{
483
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_ACK);
353
+ if (clk->source == NULL) {
484
+ } else {
354
+ return;
485
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_NACK);
486
+ }
487
+ allwinner_i2c_raise_interrupt(s);
488
+ }
489
+ value = s->data;
490
+ break;
491
+ case TWI_CNTR_REG:
492
+ value = s->cntr;
493
+ break;
494
+ case TWI_STAT_REG:
495
+ value = s->stat;
496
+ /*
497
+ * If polling when reading then change state to indicate data
498
+ * is available
499
+ */
500
+ if (STAT_TO_STA(s->stat) == STAT_M_ADDR_RD_ACK) {
501
+ if (s->cntr & TWI_CNTR_A_ACK) {
502
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_ACK);
503
+ } else {
504
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_NACK);
505
+ }
506
+ allwinner_i2c_raise_interrupt(s);
507
+ }
508
+ break;
509
+ case TWI_CCR_REG:
510
+ value = s->ccr;
511
+ break;
512
+ case TWI_SRST_REG:
513
+ value = s->srst;
514
+ break;
515
+ case TWI_EFR_REG:
516
+ value = s->efr;
517
+ break;
518
+ case TWI_LCR_REG:
519
+ value = s->lcr;
520
+ break;
521
+ default:
522
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
523
+ HWADDR_PRIx "\n", TYPE_AW_I2C, __func__, offset);
524
+ value = 0;
525
+ break;
355
+ }
526
+ }
356
+
527
+
357
+ trace_clock_disconnect(CLOCK_PATH(clk));
528
+ trace_allwinner_i2c_read(allwinner_i2c_get_regname(offset), offset, value);
358
+
529
+
359
+ clk->source = NULL;
530
+ return (uint64_t)value;
360
+ QLIST_REMOVE(clk, sibling);
531
+}
361
+}
532
+
362
+
533
+static void allwinner_i2c_write(void *opaque, hwaddr offset,
363
+static void clock_initfn(Object *obj)
534
+ uint64_t value, unsigned size)
364
+{
535
+{
365
+ Clock *clk = CLOCK(obj);
536
+ AWI2CState *s = AW_I2C(opaque);
366
+
537
+
367
+ QLIST_INIT(&clk->children);
538
+ value &= 0xff;
368
+}
539
+
369
+
540
+ trace_allwinner_i2c_write(allwinner_i2c_get_regname(offset), offset, value);
370
+static void clock_finalizefn(Object *obj)
541
+
371
+{
542
+ switch (offset) {
372
+ Clock *clk = CLOCK(obj);
543
+ case TWI_ADDR_REG:
373
+ Clock *child, *next;
544
+ s->addr = (uint8_t)value;
374
+
545
+ break;
375
+ /* clear our list of children */
546
+ case TWI_XADDR_REG:
376
+ QLIST_FOREACH_SAFE(child, &clk->children, sibling, next) {
547
+ s->xaddr = (uint8_t)value;
377
+ clock_disconnect(child);
548
+ break;
549
+ case TWI_DATA_REG:
550
+ /* If the device is in reset or not enabled, nothing to do */
551
+ if (allwinner_i2c_is_reset(s) || (!allwinner_i2c_bus_is_enabled(s))) {
552
+ break;
553
+ }
554
+
555
+ s->data = value & TWI_DATA_MASK;
556
+
557
+ switch (STAT_TO_STA(s->stat)) {
558
+ case STAT_M_STA_TX:
559
+ case STAT_M_RSTA_TX:
560
+ /* Send address */
561
+ if (i2c_start_transfer(s->bus, extract32(s->data, 1, 7),
562
+ extract32(s->data, 0, 1))) {
563
+ /* If non zero is returned, the address is not valid */
564
+ s->stat = STAT_FROM_STA(STAT_M_ADDR_WR_NACK);
565
+ } else {
566
+ /* Determine if read of write */
567
+ if (extract32(s->data, 0, 1)) {
568
+ s->stat = STAT_FROM_STA(STAT_M_ADDR_RD_ACK);
569
+ } else {
570
+ s->stat = STAT_FROM_STA(STAT_M_ADDR_WR_ACK);
571
+ }
572
+ allwinner_i2c_raise_interrupt(s);
573
+ }
574
+ break;
575
+ case STAT_M_ADDR_WR_ACK:
576
+ case STAT_M_DATA_TX_ACK:
577
+ if (i2c_send(s->bus, s->data)) {
578
+ /* If the target return non zero then end the transfer */
579
+ s->stat = STAT_FROM_STA(STAT_M_DATA_TX_NACK);
580
+ i2c_end_transfer(s->bus);
581
+ } else {
582
+ s->stat = STAT_FROM_STA(STAT_M_DATA_TX_ACK);
583
+ allwinner_i2c_raise_interrupt(s);
584
+ }
585
+ break;
586
+ default:
587
+ break;
588
+ }
589
+ break;
590
+ case TWI_CNTR_REG:
591
+ if (!allwinner_i2c_is_reset(s)) {
592
+ /* Do something only if not in software reset */
593
+ s->cntr = value & TWI_CNTR_MASK;
594
+
595
+ /* Check if start condition should be sent */
596
+ if (s->cntr & TWI_CNTR_M_STA) {
597
+ /* Update status */
598
+ if (STAT_TO_STA(s->stat) == STAT_IDLE) {
599
+ /* Send start condition */
600
+ s->stat = STAT_FROM_STA(STAT_M_STA_TX);
601
+ } else {
602
+ /* Send repeated start condition */
603
+ s->stat = STAT_FROM_STA(STAT_M_RSTA_TX);
604
+ }
605
+ /* Clear start condition */
606
+ s->cntr &= ~TWI_CNTR_M_STA;
607
+ }
608
+ if (s->cntr & TWI_CNTR_M_STP) {
609
+ /* Update status */
610
+ i2c_end_transfer(s->bus);
611
+ s->stat = STAT_FROM_STA(STAT_IDLE);
612
+ s->cntr &= ~TWI_CNTR_M_STP;
613
+ }
614
+ if ((s->cntr & TWI_CNTR_INT_FLAG) == 0) {
615
+ /* Interrupt flag cleared */
616
+ qemu_irq_lower(s->irq);
617
+ }
618
+ if ((s->cntr & TWI_CNTR_A_ACK) == 0) {
619
+ if (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_ACK) {
620
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_NACK);
621
+ }
622
+ } else {
623
+ if (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_NACK) {
624
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_ACK);
625
+ }
626
+ }
627
+ allwinner_i2c_raise_interrupt(s);
628
+
629
+ }
630
+ break;
631
+ case TWI_CCR_REG:
632
+ s->ccr = value & TWI_CCR_MASK;
633
+ break;
634
+ case TWI_SRST_REG:
635
+ if (((value & TWI_SRST_MASK) == 0) && (s->srst & TWI_SRST_MASK)) {
636
+ /* Perform reset */
637
+ allwinner_i2c_reset_hold(OBJECT(s));
638
+ }
639
+ s->srst = value & TWI_SRST_MASK;
640
+ break;
641
+ case TWI_EFR_REG:
642
+ s->efr = value & TWI_EFR_MASK;
643
+ break;
644
+ case TWI_LCR_REG:
645
+ s->lcr = value & TWI_LCR_MASK;
646
+ break;
647
+ default:
648
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
649
+ HWADDR_PRIx "\n", TYPE_AW_I2C, __func__, offset);
650
+ break;
378
+ }
651
+ }
379
+
652
+}
380
+ /* remove us from source's children list */
653
+
381
+ clock_disconnect(clk);
654
+static const MemoryRegionOps allwinner_i2c_ops = {
382
+
655
+ .read = allwinner_i2c_read,
383
+ g_free(clk->canonical_path);
656
+ .write = allwinner_i2c_write,
384
+}
657
+ .valid.min_access_size = 1,
385
+
658
+ .valid.max_access_size = 4,
386
+static const TypeInfo clock_info = {
659
+ .endianness = DEVICE_NATIVE_ENDIAN,
387
+ .name = TYPE_CLOCK,
388
+ .parent = TYPE_OBJECT,
389
+ .instance_size = sizeof(Clock),
390
+ .instance_init = clock_initfn,
391
+ .instance_finalize = clock_finalizefn,
392
+};
660
+};
393
+
661
+
394
+static void clock_register_types(void)
662
+static const VMStateDescription allwinner_i2c_vmstate = {
395
+{
663
+ .name = TYPE_AW_I2C,
396
+ type_register_static(&clock_info);
664
+ .version_id = 1,
397
+}
665
+ .minimum_version_id = 1,
398
+
666
+ .fields = (VMStateField[]) {
399
+type_init(clock_register_types)
667
+ VMSTATE_UINT8(addr, AWI2CState),
400
diff --git a/hw/core/trace-events b/hw/core/trace-events
668
+ VMSTATE_UINT8(xaddr, AWI2CState),
401
index XXXXXXX..XXXXXXX 100644
669
+ VMSTATE_UINT8(data, AWI2CState),
402
--- a/hw/core/trace-events
670
+ VMSTATE_UINT8(cntr, AWI2CState),
403
+++ b/hw/core/trace-events
671
+ VMSTATE_UINT8(ccr, AWI2CState),
404
@@ -XXX,XX +XXX,XX @@ resettable_phase_exit_begin(void *obj, const char *objtype, unsigned count, int
672
+ VMSTATE_UINT8(srst, AWI2CState),
405
resettable_phase_exit_exec(void *obj, const char *objtype, int has_method) "obj=%p(%s) method=%d"
673
+ VMSTATE_UINT8(efr, AWI2CState),
406
resettable_phase_exit_end(void *obj, const char *objtype, unsigned count) "obj=%p(%s) count=%d"
674
+ VMSTATE_UINT8(lcr, AWI2CState),
407
resettable_transitional_function(void *obj, const char *objtype) "obj=%p(%s)"
675
+ VMSTATE_END_OF_LIST()
408
+
676
+ }
409
+# clock.c
677
+};
410
+clock_set_source(const char *clk, const char *src) "'%s', src='%s'"
678
+
411
+clock_disconnect(const char *clk) "'%s'"
679
+static void allwinner_i2c_realize(DeviceState *dev, Error **errp)
412
+clock_set(const char *clk, uint64_t old, uint64_t new) "'%s', ns=%"PRIu64"->%"PRIu64
680
+{
413
+clock_propagate(const char *clk) "'%s'"
681
+ AWI2CState *s = AW_I2C(dev);
414
+clock_update(const char *clk, const char *src, uint64_t val, int cb) "'%s', src='%s', ns=%"PRIu64", cb=%d"
682
+
683
+ memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_i2c_ops, s,
684
+ TYPE_AW_I2C, AW_I2C_MEM_SIZE);
685
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
686
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
687
+ s->bus = i2c_init_bus(dev, "i2c");
688
+}
689
+
690
+static void allwinner_i2c_class_init(ObjectClass *klass, void *data)
691
+{
692
+ DeviceClass *dc = DEVICE_CLASS(klass);
693
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
694
+
695
+ rc->phases.hold = allwinner_i2c_reset_hold;
696
+ dc->vmsd = &allwinner_i2c_vmstate;
697
+ dc->realize = allwinner_i2c_realize;
698
+ dc->desc = "Allwinner I2C Controller";
699
+}
700
+
701
+static const TypeInfo allwinner_i2c_type_info = {
702
+ .name = TYPE_AW_I2C,
703
+ .parent = TYPE_SYS_BUS_DEVICE,
704
+ .instance_size = sizeof(AWI2CState),
705
+ .class_init = allwinner_i2c_class_init,
706
+};
707
+
708
+static void allwinner_i2c_register_types(void)
709
+{
710
+ type_register_static(&allwinner_i2c_type_info);
711
+}
712
+
713
+type_init(allwinner_i2c_register_types)
714
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
715
index XXXXXXX..XXXXXXX 100644
716
--- a/hw/arm/Kconfig
717
+++ b/hw/arm/Kconfig
718
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
719
select ALLWINNER_A10_CCM
720
select ALLWINNER_A10_DRAMC
721
select ALLWINNER_EMAC
722
+ select ALLWINNER_I2C
723
select SERIAL
724
select UNIMP
725
726
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_H3
727
bool
728
select ALLWINNER_A10_PIT
729
select ALLWINNER_SUN8I_EMAC
730
+ select ALLWINNER_I2C
731
select SERIAL
732
select ARM_TIMER
733
select ARM_GIC
734
diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
735
index XXXXXXX..XXXXXXX 100644
736
--- a/hw/i2c/Kconfig
737
+++ b/hw/i2c/Kconfig
738
@@ -XXX,XX +XXX,XX @@ config MPC_I2C
739
bool
740
select I2C
741
742
+config ALLWINNER_I2C
743
+ bool
744
+ select I2C
745
+
746
config PCA954X
747
bool
748
select I2C
749
diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build
750
index XXXXXXX..XXXXXXX 100644
751
--- a/hw/i2c/meson.build
752
+++ b/hw/i2c/meson.build
753
@@ -XXX,XX +XXX,XX @@ i2c_ss.add(when: 'CONFIG_BITBANG_I2C', if_true: files('bitbang_i2c.c'))
754
i2c_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_i2c.c'))
755
i2c_ss.add(when: 'CONFIG_IMX_I2C', if_true: files('imx_i2c.c'))
756
i2c_ss.add(when: 'CONFIG_MPC_I2C', if_true: files('mpc_i2c.c'))
757
+i2c_ss.add(when: 'CONFIG_ALLWINNER_I2C', if_true: files('allwinner-i2c.c'))
758
i2c_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('microbit_i2c.c'))
759
i2c_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_smbus.c'))
760
i2c_ss.add(when: 'CONFIG_SMBUS_EEPROM', if_true: files('smbus_eeprom.c'))
761
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
762
index XXXXXXX..XXXXXXX 100644
763
--- a/hw/i2c/trace-events
764
+++ b/hw/i2c/trace-events
765
@@ -XXX,XX +XXX,XX @@ i2c_send_async(uint8_t address, uint8_t data) "send_async(addr:0x%02x) data:0x%0
766
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
767
i2c_ack(void) ""
768
769
+# allwinner_i2c.c
770
+
771
+allwinner_i2c_read(const char* reg_name, uint64_t offset, uint64_t value) "read %s [0x%" PRIx64 "]: -> 0x%" PRIx64
772
+allwinner_i2c_write(const char* reg_name, uint64_t offset, uint64_t value) "write %s [0x%" PRIx64 "]: <- 0x%" PRIx64
773
+
774
# aspeed_i2c.c
775
776
aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, uint32_t intr_status) "handling cmd=0x%x %s count=%d intr=0x%x"
415
--
777
--
416
2.20.1
778
2.34.1
417
418
diff view generated by jsdifflib
1
Add the documentation about the clock inputs and outputs in devices.
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
This is based on the original work of Frederic Konrad.
3
This patch adds minimal support for AXP-209 PMU.
4
Most important is chip ID since U-Boot SPL expects version 0x1. Besides
5
the chip ID register, reset values for two more registers used by A10
6
U-Boot SPL are covered.
4
7
5
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
8
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20221226220303.14420-5-strahinja.p.jankovic@gmail.com
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Message-id: 20200406135251.157596-6-damien.hedde@greensocs.com
9
[PMM: Editing pass for minor grammar, style and Sphinx
10
formatting fixes]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
12
---
14
docs/devel/clocks.rst | 391 ++++++++++++++++++++++++++++++++++++++++++
13
hw/misc/axp209.c | 238 +++++++++++++++++++++++++++++++++++++++++++
15
docs/devel/index.rst | 1 +
14
MAINTAINERS | 2 +
16
2 files changed, 392 insertions(+)
15
hw/misc/Kconfig | 4 +
17
create mode 100644 docs/devel/clocks.rst
16
hw/misc/meson.build | 1 +
17
hw/misc/trace-events | 5 +
18
5 files changed, 250 insertions(+)
19
create mode 100644 hw/misc/axp209.c
18
20
19
diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
21
diff --git a/hw/misc/axp209.c b/hw/misc/axp209.c
20
new file mode 100644
22
new file mode 100644
21
index XXXXXXX..XXXXXXX
23
index XXXXXXX..XXXXXXX
22
--- /dev/null
24
--- /dev/null
23
+++ b/docs/devel/clocks.rst
25
+++ b/hw/misc/axp209.c
24
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@
25
+Modelling a clock tree in QEMU
27
+/*
26
+==============================
28
+ * AXP-209 PMU Emulation
27
+
29
+ *
28
+What are clocks?
30
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
29
+----------------
31
+ *
30
+
32
+ * Permission is hereby granted, free of charge, to any person obtaining a
31
+Clocks are QOM objects developed for the purpose of modelling the
33
+ * copy of this software and associated documentation files (the "Software"),
32
+distribution of clocks in QEMU.
34
+ * to deal in the Software without restriction, including without limitation
33
+
35
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34
+They allow us to model the clock distribution of a platform and detect
36
+ * and/or sell copies of the Software, and to permit persons to whom the
35
+configuration errors in the clock tree such as badly configured PLL, clock
37
+ * Software is furnished to do so, subject to the following conditions:
36
+source selection or disabled clock.
38
+ *
37
+
39
+ * The above copyright notice and this permission notice shall be included in
38
+The object is *Clock* and its QOM name is ``clock`` (in C code, the macro
40
+ * all copies or substantial portions of the Software.
39
+``TYPE_CLOCK``).
41
+ *
40
+
42
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
+Clocks are typically used with devices where they are used to model inputs
43
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
+and outputs. They are created in a similar way to GPIOs. Inputs and outputs
44
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
43
+of different devices can be connected together.
45
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44
+
46
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
45
+In these cases a Clock object is a child of a Device object, but this
47
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
46
+is not a requirement. Clocks can be independent of devices. For
48
+ * DEALINGS IN THE SOFTWARE.
47
+example it is possible to create a clock outside of any device to
49
+ *
48
+model the main clock source of a machine.
50
+ * SPDX-License-Identifier: MIT
49
+
51
+ */
50
+Here is an example of clocks::
52
+
51
+
53
+#include "qemu/osdep.h"
52
+ +---------+ +----------------------+ +--------------+
54
+#include "qemu/log.h"
53
+ | Clock 1 | | Device B | | Device C |
55
+#include "trace.h"
54
+ | | | +-------+ +-------+ | | +-------+ |
56
+#include "hw/i2c/i2c.h"
55
+ | |>>-+-->>|Clock 2| |Clock 3|>>--->>|Clock 6| |
57
+#include "migration/vmstate.h"
56
+ +---------+ | | | (in) | | (out) | | | | (in) | |
58
+
57
+ | | +-------+ +-------+ | | +-------+ |
59
+#define TYPE_AXP209_PMU "axp209_pmu"
58
+ | | +-------+ | +--------------+
60
+
59
+ | | |Clock 4|>>
61
+#define AXP209(obj) \
60
+ | | | (out) | | +--------------+
62
+ OBJECT_CHECK(AXP209I2CState, (obj), TYPE_AXP209_PMU)
61
+ | | +-------+ | | Device D |
63
+
62
+ | | +-------+ | | +-------+ |
64
+/* registers */
63
+ | | |Clock 5|>>--->>|Clock 7| |
65
+enum {
64
+ | | | (out) | | | | (in) | |
66
+ REG_POWER_STATUS = 0x0u,
65
+ | | +-------+ | | +-------+ |
67
+ REG_OPERATING_MODE,
66
+ | +----------------------+ | |
68
+ REG_OTG_VBUS_STATUS,
67
+ | | +-------+ |
69
+ REG_CHIP_VERSION,
68
+ +----------------------------->>|Clock 8| |
70
+ REG_DATA_CACHE_0,
69
+ | | (in) | |
71
+ REG_DATA_CACHE_1,
70
+ | +-------+ |
72
+ REG_DATA_CACHE_2,
71
+ +--------------+
73
+ REG_DATA_CACHE_3,
72
+
74
+ REG_DATA_CACHE_4,
73
+Clocks are defined in the ``include/hw/clock.h`` header and device
75
+ REG_DATA_CACHE_5,
74
+related functions are defined in the ``include/hw/qdev-clock.h``
76
+ REG_DATA_CACHE_6,
75
+header.
77
+ REG_DATA_CACHE_7,
76
+
78
+ REG_DATA_CACHE_8,
77
+The clock state
79
+ REG_DATA_CACHE_9,
78
+---------------
80
+ REG_DATA_CACHE_A,
79
+
81
+ REG_DATA_CACHE_B,
80
+The state of a clock is its period; it is stored as an integer
82
+ REG_POWER_OUTPUT_CTRL = 0x12u,
81
+representing it in units of 2 :sup:`-32` ns. The special value of 0 is used to
83
+ REG_DC_DC2_OUT_V_CTRL = 0x23u,
82
+represent the clock being inactive or gated. The clocks do not model
84
+ REG_DC_DC2_DVS_CTRL = 0x25u,
83
+the signal itself (pin toggling) or other properties such as the duty
85
+ REG_DC_DC3_OUT_V_CTRL = 0x27u,
84
+cycle.
86
+ REG_LDO2_4_OUT_V_CTRL,
85
+
87
+ REG_LDO3_OUT_V_CTRL,
86
+All clocks contain this state: outputs as well as inputs. This allows
88
+ REG_VBUS_CH_MGMT = 0x30u,
87
+the current period of a clock to be fetched at any time. When a clock
89
+ REG_SHUTDOWN_V_CTRL,
88
+is updated, the value is immediately propagated to all connected
90
+ REG_SHUTDOWN_CTRL,
89
+clocks in the tree.
91
+ REG_CHARGE_CTRL_1,
90
+
92
+ REG_CHARGE_CTRL_2,
91
+To ease interaction with clocks, helpers with a unit suffix are defined for
93
+ REG_SPARE_CHARGE_CTRL,
92
+every clock state setter or getter. The suffixes are:
94
+ REG_PEK_KEY_CTRL,
93
+
95
+ REG_DC_DC_FREQ_SET,
94
+- ``_ns`` for handling periods in nanoseconds
96
+ REG_CHR_TEMP_TH_SET,
95
+- ``_hz`` for handling frequencies in hertz
97
+ REG_CHR_HIGH_TEMP_TH_CTRL,
96
+
98
+ REG_IPSOUT_WARN_L1,
97
+The 0 period value is converted to 0 in hertz and vice versa. 0 always means
99
+ REG_IPSOUT_WARN_L2,
98
+that the clock is disabled.
100
+ REG_DISCHR_TEMP_TH_SET,
99
+
101
+ REG_DISCHR_HIGH_TEMP_TH_CTRL,
100
+Adding a new clock
102
+ REG_IRQ_BANK_1_CTRL = 0x40u,
101
+------------------
103
+ REG_IRQ_BANK_2_CTRL,
102
+
104
+ REG_IRQ_BANK_3_CTRL,
103
+Adding clocks to a device must be done during the init method of the Device
105
+ REG_IRQ_BANK_4_CTRL,
104
+instance.
106
+ REG_IRQ_BANK_5_CTRL,
105
+
107
+ REG_IRQ_BANK_1_STAT = 0x48u,
106
+To add an input clock to a device, the function ``qdev_init_clock_in()``
108
+ REG_IRQ_BANK_2_STAT,
107
+must be used. It takes the name, a callback and an opaque parameter
109
+ REG_IRQ_BANK_3_STAT,
108
+for the callback (this will be explained in a following section).
110
+ REG_IRQ_BANK_4_STAT,
109
+Output is simpler; only the name is required. Typically::
111
+ REG_IRQ_BANK_5_STAT,
110
+
112
+ REG_ADC_ACIN_V_H = 0x56u,
111
+ qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev);
113
+ REG_ADC_ACIN_V_L,
112
+ qdev_init_clock_out(DEVICE(dev), "clk_out");
114
+ REG_ADC_ACIN_CURR_H,
113
+
115
+ REG_ADC_ACIN_CURR_L,
114
+Both functions return the created Clock pointer, which should be saved in the
116
+ REG_ADC_VBUS_V_H,
115
+device's state structure for further use.
117
+ REG_ADC_VBUS_V_L,
116
+
118
+ REG_ADC_VBUS_CURR_H,
117
+These objects will be automatically deleted by the QOM reference mechanism.
119
+ REG_ADC_VBUS_CURR_L,
118
+
120
+ REG_ADC_INT_TEMP_H,
119
+Note that it is possible to create a static array describing clock inputs and
121
+ REG_ADC_INT_TEMP_L,
120
+outputs. The function ``qdev_init_clocks()`` must be called with the array as
122
+ REG_ADC_TEMP_SENS_V_H = 0x62u,
121
+parameter to initialize the clocks: it has the same behaviour as calling the
123
+ REG_ADC_TEMP_SENS_V_L,
122
+``qdev_init_clock_in/out()`` for each clock in the array. To ease the array
124
+ REG_ADC_BAT_V_H = 0x78u,
123
+construction, some macros are defined in ``include/hw/qdev-clock.h``.
125
+ REG_ADC_BAT_V_L,
124
+As an example, the following creates 2 clocks to a device: one input and one
126
+ REG_ADC_BAT_DISCHR_CURR_H,
125
+output.
127
+ REG_ADC_BAT_DISCHR_CURR_L,
126
+
128
+ REG_ADC_BAT_CHR_CURR_H,
127
+.. code-block:: c
129
+ REG_ADC_BAT_CHR_CURR_L,
128
+
130
+ REG_ADC_IPSOUT_V_H,
129
+ /* device structure containing pointers to the clock objects */
131
+ REG_ADC_IPSOUT_V_L,
130
+ typedef struct MyDeviceState {
132
+ REG_DC_DC_MOD_SEL = 0x80u,
131
+ DeviceState parent_obj;
133
+ REG_ADC_EN_1,
132
+ Clock *clk_in;
134
+ REG_ADC_EN_2,
133
+ Clock *clk_out;
135
+ REG_ADC_SR_CTRL,
134
+ } MyDeviceState;
136
+ REG_ADC_IN_RANGE,
135
+
137
+ REG_GPIO1_ADC_IRQ_RISING_TH,
136
+ /*
138
+ REG_GPIO1_ADC_IRQ_FALLING_TH,
137
+ * callback for the input clock (see "Callback on input clock
139
+ REG_TIMER_CTRL = 0x8au,
138
+ * change" section below for more information).
140
+ REG_VBUS_CTRL_MON_SRP,
139
+ */
141
+ REG_OVER_TEMP_SHUTDOWN = 0x8fu,
140
+ static void clk_in_callback(void *opaque);
142
+ REG_GPIO0_FEAT_SET,
141
+
143
+ REG_GPIO_OUT_HIGH_SET,
142
+ /*
144
+ REG_GPIO1_FEAT_SET,
143
+ * static array describing clocks:
145
+ REG_GPIO2_FEAT_SET,
144
+ * + a clock input named "clk_in", whose pointer is stored in
146
+ REG_GPIO_SIG_STATE_SET_MON,
145
+ * the clk_in field of a MyDeviceState structure with callback
147
+ REG_GPIO3_SET,
146
+ * clk_in_callback.
148
+ REG_COULOMB_CNTR_CTRL = 0xb8u,
147
+ * + a clock output named "clk_out" whose pointer is stored in
149
+ REG_POWER_MEAS_RES,
148
+ * the clk_out field of a MyDeviceState structure.
150
+ NR_REGS
149
+ */
151
+};
150
+ static const ClockPortInitArray mydev_clocks = {
152
+
151
+ QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback),
153
+#define AXP209_CHIP_VERSION_ID (0x01)
152
+ QDEV_CLOCK_OUT(MyDeviceState, clk_out),
154
+#define AXP209_DC_DC2_OUT_V_CTRL_RESET (0x16)
153
+ QDEV_CLOCK_END
155
+#define AXP209_IRQ_BANK_1_CTRL_RESET (0xd8)
154
+ };
156
+
155
+
157
+/* A simple I2C slave which returns values of ID or CNT register. */
156
+ /* device initialization function */
158
+typedef struct AXP209I2CState {
157
+ static void mydev_init(Object *obj)
159
+ /*< private >*/
158
+ {
160
+ I2CSlave i2c;
159
+ /* cast to MyDeviceState */
161
+ /*< public >*/
160
+ MyDeviceState *mydev = MYDEVICE(obj);
162
+ uint8_t regs[NR_REGS]; /* peripheral registers */
161
+ /* create and fill the pointer fields in the MyDeviceState */
163
+ uint8_t ptr; /* current register index */
162
+ qdev_init_clocks(mydev, mydev_clocks);
164
+ uint8_t count; /* counter used for tx/rx */
163
+ [...]
165
+} AXP209I2CState;
166
+
167
+/* Reset all counters and load ID register */
168
+static void axp209_reset_enter(Object *obj, ResetType type)
169
+{
170
+ AXP209I2CState *s = AXP209(obj);
171
+
172
+ memset(s->regs, 0, NR_REGS);
173
+ s->ptr = 0;
174
+ s->count = 0;
175
+ s->regs[REG_CHIP_VERSION] = AXP209_CHIP_VERSION_ID;
176
+ s->regs[REG_DC_DC2_OUT_V_CTRL] = AXP209_DC_DC2_OUT_V_CTRL_RESET;
177
+ s->regs[REG_IRQ_BANK_1_CTRL] = AXP209_IRQ_BANK_1_CTRL_RESET;
178
+}
179
+
180
+/* Handle events from master. */
181
+static int axp209_event(I2CSlave *i2c, enum i2c_event event)
182
+{
183
+ AXP209I2CState *s = AXP209(i2c);
184
+
185
+ s->count = 0;
186
+
187
+ return 0;
188
+}
189
+
190
+/* Called when master requests read */
191
+static uint8_t axp209_rx(I2CSlave *i2c)
192
+{
193
+ AXP209I2CState *s = AXP209(i2c);
194
+ uint8_t ret = 0xff;
195
+
196
+ if (s->ptr < NR_REGS) {
197
+ ret = s->regs[s->ptr++];
164
+ }
198
+ }
165
+
199
+
166
+An alternative way to create a clock is to simply call
200
+ trace_axp209_rx(s->ptr - 1, ret);
167
+``object_new(TYPE_CLOCK)``. In that case the clock will neither be an
201
+
168
+input nor an output of a device. After the whole QOM hierarchy of the
202
+ return ret;
169
+clock has been set ``clock_setup_canonical_path()`` should be called.
203
+}
170
+
204
+
171
+At creation, the period of the clock is 0: the clock is disabled. You can
205
+/*
172
+change it using ``clock_set_ns()`` or ``clock_set_hz()``.
206
+ * Called when master sends write.
173
+
207
+ * Update ptr with byte 0, then perform write with second byte.
174
+Note that if you are creating a clock with a fixed period which will never
208
+ */
175
+change (for example the main clock source of a board), then you'll have
209
+static int axp209_tx(I2CSlave *i2c, uint8_t data)
176
+nothing else to do. This value will be propagated to other clocks when
210
+{
177
+connecting the clocks together and devices will fetch the right value during
211
+ AXP209I2CState *s = AXP209(i2c);
178
+the first reset.
212
+
179
+
213
+ if (s->count == 0) {
180
+Retrieving clocks from a device
214
+ /* Store register address */
181
+-------------------------------
215
+ s->ptr = data;
182
+
216
+ s->count++;
183
+``qdev_get_clock_in()`` and ``dev_get_clock_out()`` are available to
217
+ trace_axp209_select(data);
184
+get the clock inputs or outputs of a device. For example:
218
+ } else {
185
+
219
+ trace_axp209_tx(s->ptr, data);
186
+.. code-block:: c
220
+ if (s->ptr == REG_DC_DC2_OUT_V_CTRL) {
187
+
221
+ s->regs[s->ptr++] = data;
188
+ Clock *clk = qdev_get_clock_in(DEVICE(mydev), "clk_in");
222
+ }
189
+
190
+or:
191
+
192
+.. code-block:: c
193
+
194
+ Clock *clk = qdev_get_clock_out(DEVICE(mydev), "clk_out");
195
+
196
+Connecting two clocks together
197
+------------------------------
198
+
199
+To connect two clocks together, use the ``clock_set_source()`` function.
200
+Given two clocks ``clk1``, and ``clk2``, ``clock_set_source(clk2, clk1);``
201
+configures ``clk2`` to follow the ``clk1`` period changes. Every time ``clk1``
202
+is updated, ``clk2`` will be updated too.
203
+
204
+When connecting clock between devices, prefer using the
205
+``qdev_connect_clock_in()`` function to set the source of an input
206
+device clock. For example, to connect the input clock ``clk2`` of
207
+``devB`` to the output clock ``clk1`` of ``devA``, do:
208
+
209
+.. code-block:: c
210
+
211
+ qdev_connect_clock_in(devB, "clk2", qdev_get_clock_out(devA, "clk1"))
212
+
213
+We used ``qdev_get_clock_out()`` above, but any clock can drive an
214
+input clock, even another input clock. The following diagram shows
215
+some examples of connections. Note also that a clock can drive several
216
+other clocks.
217
+
218
+::
219
+
220
+ +------------+ +--------------------------------------------------+
221
+ | Device A | | Device B |
222
+ | | | +---------------------+ |
223
+ | | | | Device C | |
224
+ | +-------+ | | +-------+ | +-------+ +-------+ | +-------+ |
225
+ | |Clock 1|>>-->>|Clock 2|>>+-->>|Clock 3| |Clock 5|>>>>|Clock 6|>>
226
+ | | (out) | | | | (in) | | | | (in) | | (out) | | | (out) | |
227
+ | +-------+ | | +-------+ | | +-------+ +-------+ | +-------+ |
228
+ +------------+ | | +---------------------+ |
229
+ | | |
230
+ | | +--------------+ |
231
+ | | | Device D | |
232
+ | | | +-------+ | |
233
+ | +-->>|Clock 4| | |
234
+ | | | (in) | | |
235
+ | | +-------+ | |
236
+ | +--------------+ |
237
+ +--------------------------------------------------+
238
+
239
+In the above example, when *Clock 1* is updated by *Device A*, three
240
+clocks get the new clock period value: *Clock 2*, *Clock 3* and *Clock 4*.
241
+
242
+It is not possible to disconnect a clock or to change the clock connection
243
+after it is connected.
244
+
245
+Unconnected input clocks
246
+------------------------
247
+
248
+A newly created input clock is disabled (period of 0). This means the
249
+clock will be considered as disabled until the period is updated. If
250
+the clock remains unconnected it will always keep its initial value
251
+of 0. If this is not the desired behaviour, ``clock_set()``,
252
+``clock_set_ns()`` or ``clock_set_hz()`` should be called on the Clock
253
+object during device instance init. For example:
254
+
255
+.. code-block:: c
256
+
257
+ clk = qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback,
258
+ dev);
259
+ /* set initial value to 10ns / 100MHz */
260
+ clock_set_ns(clk, 10);
261
+
262
+Fetching clock frequency/period
263
+-------------------------------
264
+
265
+To get the current state of a clock, use the functions ``clock_get()``,
266
+``clock_get_ns()`` or ``clock_get_hz()``.
267
+
268
+It is also possible to register a callback on clock frequency changes.
269
+Here is an example:
270
+
271
+.. code-block:: c
272
+
273
+ void clock_callback(void *opaque) {
274
+ MyDeviceState *s = (MyDeviceState *) opaque;
275
+ /*
276
+ * 'opaque' is the argument passed to qdev_init_clock_in();
277
+ * usually this will be the device state pointer.
278
+ */
279
+
280
+ /* do something with the new period */
281
+ fprintf(stdout, "device new period is %" PRIu64 "ns\n",
282
+ clock_get_ns(dev->my_clk_input));
283
+ }
223
+ }
284
+
224
+
285
+Changing a clock period
225
+ return 0;
286
+-----------------------
226
+}
287
+
227
+
288
+A device can change its outputs using the ``clock_update()``,
228
+static const VMStateDescription vmstate_axp209 = {
289
+``clock_update_ns()`` or ``clock_update_hz()`` function. It will trigger
229
+ .name = TYPE_AXP209_PMU,
290
+updates on every connected input.
230
+ .version_id = 1,
291
+
231
+ .fields = (VMStateField[]) {
292
+For example, let's say that we have an output clock *clkout* and we
232
+ VMSTATE_UINT8_ARRAY(regs, AXP209I2CState, NR_REGS),
293
+have a pointer to it in the device state because we did the following
233
+ VMSTATE_UINT8(count, AXP209I2CState),
294
+in init phase:
234
+ VMSTATE_UINT8(ptr, AXP209I2CState),
295
+
235
+ VMSTATE_END_OF_LIST()
296
+.. code-block:: c
297
+
298
+ dev->clkout = qdev_init_clock_out(DEVICE(dev), "clkout");
299
+
300
+Then at any time (apart from the cases listed below), it is possible to
301
+change the clock value by doing:
302
+
303
+.. code-block:: c
304
+
305
+ clock_update_hz(dev->clkout, 1000 * 1000 * 1000); /* 1GHz */
306
+
307
+Because updating a clock may trigger any side effects through
308
+connected clocks and their callbacks, this operation must be done
309
+while holding the qemu io lock.
310
+
311
+For the same reason, one can update clocks only when it is allowed to have
312
+side effects on other objects. In consequence, it is forbidden:
313
+
314
+* during migration,
315
+* and in the enter phase of reset.
316
+
317
+Note that calling ``clock_update[_ns|_hz]()`` is equivalent to calling
318
+``clock_set[_ns|_hz]()`` (with the same arguments) then
319
+``clock_propagate()`` on the clock. Thus, setting the clock value can
320
+be separated from triggering the side-effects. This is often required
321
+to factorize code to handle reset and migration in devices.
322
+
323
+Aliasing clocks
324
+---------------
325
+
326
+Sometimes, one needs to forward, or inherit, a clock from another
327
+device. Typically, when doing device composition, a device might
328
+expose a sub-device's clock without interfering with it. The function
329
+``qdev_alias_clock()`` can be used to achieve this behaviour. Note
330
+that it is possible to expose the clock under a different name.
331
+``qdev_alias_clock()`` works for both input and output clocks.
332
+
333
+For example, if device B is a child of device A,
334
+``device_a_instance_init()`` may do something like this:
335
+
336
+.. code-block:: c
337
+
338
+ void device_a_instance_init(Object *obj)
339
+ {
340
+ AState *A = DEVICE_A(obj);
341
+ BState *B;
342
+ /* create object B as child of A */
343
+ [...]
344
+ qdev_alias_clock(B, "clk", A, "b_clk");
345
+ /*
346
+ * Now A has a clock "b_clk" which is an alias to
347
+ * the clock "clk" of its child B.
348
+ */
349
+ }
236
+ }
350
+
237
+};
351
+This function does not return any clock object. The new clock has the
238
+
352
+same direction (input or output) as the original one. This function
239
+static void axp209_class_init(ObjectClass *oc, void *data)
353
+only adds a link to the existing clock. In the above example, object B
240
+{
354
+remains the only object allowed to use the clock and device A must not
241
+ DeviceClass *dc = DEVICE_CLASS(oc);
355
+try to change the clock period or set a callback to the clock. This
242
+ I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc);
356
+diagram describes the example with an input clock::
243
+ ResettableClass *rc = RESETTABLE_CLASS(oc);
357
+
244
+
358
+ +--------------------------+
245
+ rc->phases.enter = axp209_reset_enter;
359
+ | Device A |
246
+ dc->vmsd = &vmstate_axp209;
360
+ | +--------------+ |
247
+ isc->event = axp209_event;
361
+ | | Device B | |
248
+ isc->recv = axp209_rx;
362
+ | | +-------+ | |
249
+ isc->send = axp209_tx;
363
+ >>"b_clk">>>| "clk" | | |
250
+}
364
+ | (in) | | (in) | | |
251
+
365
+ | | +-------+ | |
252
+static const TypeInfo axp209_info = {
366
+ | +--------------+ |
253
+ .name = TYPE_AXP209_PMU,
367
+ +--------------------------+
254
+ .parent = TYPE_I2C_SLAVE,
368
+
255
+ .instance_size = sizeof(AXP209I2CState),
369
+Migration
256
+ .class_init = axp209_class_init
370
+---------
257
+};
371
+
258
+
372
+Clock state is not migrated automatically. Every device must handle its
259
+static void axp209_register_devices(void)
373
+clock migration. Alias clocks must not be migrated.
260
+{
374
+
261
+ type_register_static(&axp209_info);
375
+To ensure clock states are restored correctly during migration, there
262
+}
376
+are two solutions.
263
+
377
+
264
+type_init(axp209_register_devices);
378
+Clock states can be migrated by adding an entry into the device
265
diff --git a/MAINTAINERS b/MAINTAINERS
379
+vmstate description. You should use the ``VMSTATE_CLOCK`` macro for this.
380
+This is typically used to migrate an input clock state. For example:
381
+
382
+.. code-block:: c
383
+
384
+ MyDeviceState {
385
+ DeviceState parent_obj;
386
+ [...] /* some fields */
387
+ Clock *clk;
388
+ };
389
+
390
+ VMStateDescription my_device_vmstate = {
391
+ .name = "my_device",
392
+ .fields = (VMStateField[]) {
393
+ [...], /* other migrated fields */
394
+ VMSTATE_CLOCK(clk, MyDeviceState),
395
+ VMSTATE_END_OF_LIST()
396
+ }
397
+ };
398
+
399
+The second solution is to restore the clock state using information already
400
+at our disposal. This can be used to restore output clock states using the
401
+device state. The functions ``clock_set[_ns|_hz]()`` can be used during the
402
+``post_load()`` migration callback.
403
+
404
+When adding clock support to an existing device, if you care about
405
+migration compatibility you will need to be careful, as simply adding
406
+a ``VMSTATE_CLOCK()`` line will break compatibility. Instead, you can
407
+put the ``VMSTATE_CLOCK()`` line into a vmstate subsection with a
408
+suitable ``needed`` function, and use ``clock_set()`` in a
409
+``pre_load()`` function to set the default value that will be used if
410
+the source virtual machine in the migration does not send the clock
411
+state.
412
+
413
+Care should be taken not to use ``clock_update[_ns|_hz]()`` or
414
+``clock_propagate()`` during the whole migration procedure because it
415
+will trigger side effects to other devices in an unknown state.
416
diff --git a/docs/devel/index.rst b/docs/devel/index.rst
417
index XXXXXXX..XXXXXXX 100644
266
index XXXXXXX..XXXXXXX 100644
418
--- a/docs/devel/index.rst
267
--- a/MAINTAINERS
419
+++ b/docs/devel/index.rst
268
+++ b/MAINTAINERS
420
@@ -XXX,XX +XXX,XX @@ Contents:
269
@@ -XXX,XX +XXX,XX @@ ARM Machines
421
bitops
270
Allwinner-a10
422
reset
271
M: Beniamino Galvani <b.galvani@gmail.com>
423
s390-dasd-ipl
272
M: Peter Maydell <peter.maydell@linaro.org>
424
+ clocks
273
+R: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
274
L: qemu-arm@nongnu.org
275
S: Odd Fixes
276
F: hw/*/allwinner*
277
F: include/hw/*/allwinner*
278
F: hw/arm/cubieboard.c
279
F: docs/system/arm/cubieboard.rst
280
+F: hw/misc/axp209.c
281
282
Allwinner-h3
283
M: Niek Linnenbank <nieklinnenbank@gmail.com>
284
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
285
index XXXXXXX..XXXXXXX 100644
286
--- a/hw/misc/Kconfig
287
+++ b/hw/misc/Kconfig
288
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10_CCM
289
config ALLWINNER_A10_DRAMC
290
bool
291
292
+config AXP209_PMU
293
+ bool
294
+ depends on I2C
295
+
296
source macio/Kconfig
297
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
298
index XXXXXXX..XXXXXXX 100644
299
--- a/hw/misc/meson.build
300
+++ b/hw/misc/meson.build
301
@@ -XXX,XX +XXX,XX @@ specific_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-cpucfg.c'
302
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-dramc.c'))
303
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-sysctrl.c'))
304
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-sid.c'))
305
+softmmu_ss.add(when: 'CONFIG_AXP209_PMU', if_true: files('axp209.c'))
306
softmmu_ss.add(when: 'CONFIG_REALVIEW', if_true: files('arm_sysctl.c'))
307
softmmu_ss.add(when: 'CONFIG_NSERIES', if_true: files('cbus.c'))
308
softmmu_ss.add(when: 'CONFIG_ECCMEMCTL', if_true: files('eccmemctl.c'))
309
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
310
index XXXXXXX..XXXXXXX 100644
311
--- a/hw/misc/trace-events
312
+++ b/hw/misc/trace-events
313
@@ -XXX,XX +XXX,XX @@ allwinner_sid_write(uint64_t offset, uint64_t data, unsigned size) "offset 0x%"
314
avr_power_read(uint8_t value) "power_reduc read value:%u"
315
avr_power_write(uint8_t value) "power_reduc write value:%u"
316
317
+# axp209.c
318
+axp209_rx(uint8_t reg, uint8_t data) "Read reg 0x%" PRIx8 " : 0x%" PRIx8
319
+axp209_select(uint8_t reg) "Accessing reg 0x%" PRIx8
320
+axp209_tx(uint8_t reg, uint8_t data) "Write reg 0x%" PRIx8 " : 0x%" PRIx8
321
+
322
# eccmemctl.c
323
ecc_mem_writel_mer(uint32_t val) "Write memory enable 0x%08x"
324
ecc_mem_writel_mdr(uint32_t val) "Write memory delay 0x%08x"
425
--
325
--
426
2.20.1
326
2.34.1
427
428
diff view generated by jsdifflib
New patch
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
1
2
3
SPL Boot for Cubieboard expects AXP209 connected to I2C0 bus.
4
5
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
6
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20221226220303.14420-6-strahinja.p.jankovic@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/cubieboard.c | 6 ++++++
12
hw/arm/Kconfig | 1 +
13
2 files changed, 7 insertions(+)
14
15
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/cubieboard.c
18
+++ b/hw/arm/cubieboard.c
19
@@ -XXX,XX +XXX,XX @@
20
#include "hw/boards.h"
21
#include "hw/qdev-properties.h"
22
#include "hw/arm/allwinner-a10.h"
23
+#include "hw/i2c/i2c.h"
24
25
static struct arm_boot_info cubieboard_binfo = {
26
.loader_start = AW_A10_SDRAM_BASE,
27
@@ -XXX,XX +XXX,XX @@ static void cubieboard_init(MachineState *machine)
28
BlockBackend *blk;
29
BusState *bus;
30
DeviceState *carddev;
31
+ I2CBus *i2c;
32
33
/* BIOS is not supported by this board */
34
if (machine->firmware) {
35
@@ -XXX,XX +XXX,XX @@ static void cubieboard_init(MachineState *machine)
36
exit(1);
37
}
38
39
+ /* Connect AXP 209 */
40
+ i2c = I2C_BUS(qdev_get_child_bus(DEVICE(&a10->i2c0), "i2c"));
41
+ i2c_slave_create_simple(i2c, "axp209_pmu", 0x34);
42
+
43
/* Retrieve SD bus */
44
di = drive_get(IF_SD, 0, 0);
45
blk = di ? blk_by_legacy_dinfo(di) : NULL;
46
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/Kconfig
49
+++ b/hw/arm/Kconfig
50
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
51
select ALLWINNER_A10_DRAMC
52
select ALLWINNER_EMAC
53
select ALLWINNER_I2C
54
+ select AXP209_PMU
55
select SERIAL
56
select UNIMP
57
58
--
59
2.34.1
60
61
diff view generated by jsdifflib
New patch
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
1
2
3
This patch enables copying of SPL from MMC if `-kernel` parameter is not
4
passed when starting QEMU. SPL is copied to SRAM_A.
5
6
The approach is reused from Allwinner H3 implementation.
7
8
Tested with Armbian and custom Yocto image.
9
10
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
11
12
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
13
Message-id: 20221226220303.14420-7-strahinja.p.jankovic@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/arm/allwinner-a10.h | 21 +++++++++++++++++++++
17
hw/arm/allwinner-a10.c | 18 ++++++++++++++++++
18
hw/arm/cubieboard.c | 5 +++++
19
3 files changed, 44 insertions(+)
20
21
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/allwinner-a10.h
24
+++ b/include/hw/arm/allwinner-a10.h
25
@@ -XXX,XX +XXX,XX @@
26
#include "hw/misc/allwinner-a10-ccm.h"
27
#include "hw/misc/allwinner-a10-dramc.h"
28
#include "hw/i2c/allwinner-i2c.h"
29
+#include "sysemu/block-backend.h"
30
31
#include "target/arm/cpu.h"
32
#include "qom/object.h"
33
@@ -XXX,XX +XXX,XX @@ struct AwA10State {
34
OHCISysBusState ohci[AW_A10_NUM_USB];
35
};
36
37
+/**
38
+ * Emulate Boot ROM firmware setup functionality.
39
+ *
40
+ * A real Allwinner A10 SoC contains a Boot ROM
41
+ * which is the first code that runs right after
42
+ * the SoC is powered on. The Boot ROM is responsible
43
+ * for loading user code (e.g. a bootloader) from any
44
+ * of the supported external devices and writing the
45
+ * downloaded code to internal SRAM. After loading the SoC
46
+ * begins executing the code written to SRAM.
47
+ *
48
+ * This function emulates the Boot ROM by copying 32 KiB
49
+ * of data at offset 8 KiB from the given block device and writes it to
50
+ * the start of the first internal SRAM memory.
51
+ *
52
+ * @s: Allwinner A10 state object pointer
53
+ * @blk: Block backend device object pointer
54
+ */
55
+void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk);
56
+
57
#endif
58
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/allwinner-a10.c
61
+++ b/hw/arm/allwinner-a10.c
62
@@ -XXX,XX +XXX,XX @@
63
#include "sysemu/sysemu.h"
64
#include "hw/boards.h"
65
#include "hw/usb/hcd-ohci.h"
66
+#include "hw/loader.h"
67
68
+#define AW_A10_SRAM_A_BASE 0x00000000
69
#define AW_A10_DRAMC_BASE 0x01c01000
70
#define AW_A10_MMC0_BASE 0x01c0f000
71
#define AW_A10_CCM_BASE 0x01c20000
72
@@ -XXX,XX +XXX,XX @@
73
#define AW_A10_RTC_BASE 0x01c20d00
74
#define AW_A10_I2C0_BASE 0x01c2ac00
75
76
+void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk)
77
+{
78
+ const int64_t rom_size = 32 * KiB;
79
+ g_autofree uint8_t *buffer = g_new0(uint8_t, rom_size);
80
+
81
+ if (blk_pread(blk, 8 * KiB, rom_size, buffer, 0) < 0) {
82
+ error_setg(&error_fatal, "%s: failed to read BlockBackend data",
83
+ __func__);
84
+ return;
85
+ }
86
+
87
+ rom_add_blob("allwinner-a10.bootrom", buffer, rom_size,
88
+ rom_size, AW_A10_SRAM_A_BASE,
89
+ NULL, NULL, NULL, NULL, false);
90
+}
91
+
92
static void aw_a10_init(Object *obj)
93
{
94
AwA10State *s = AW_A10(obj);
95
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/hw/arm/cubieboard.c
98
+++ b/hw/arm/cubieboard.c
99
@@ -XXX,XX +XXX,XX @@ static void cubieboard_init(MachineState *machine)
100
memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
101
machine->ram);
102
103
+ /* Load target kernel or start using BootROM */
104
+ if (!machine->kernel_filename && blk && blk_is_available(blk)) {
105
+ /* Use Boot ROM to copy data from SD card to SRAM */
106
+ allwinner_a10_bootrom_setup(a10, blk);
107
+ }
108
/* TODO create and connect IDE devices for ide_drive_get() */
109
110
cubieboard_binfo.ram_size = machine->ram_size;
111
--
112
2.34.1
diff view generated by jsdifflib
New patch
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
1
2
3
Cubieboard now can boot directly from SD card, without the need to pass
4
`-kernel` parameter. Update Avocado tests to cover this functionality.
5
6
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
7
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
8
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Message-id: 20221226220303.14420-8-strahinja.p.jankovic@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
tests/avocado/boot_linux_console.py | 47 +++++++++++++++++++++++++++++
13
1 file changed, 47 insertions(+)
14
15
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
16
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/avocado/boot_linux_console.py
18
+++ b/tests/avocado/boot_linux_console.py
19
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_sata(self):
20
'sda')
21
# cubieboard's reboot is not functioning; omit reboot test.
22
23
+ @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
24
+ def test_arm_cubieboard_openwrt_22_03_2(self):
25
+ """
26
+ :avocado: tags=arch:arm
27
+ :avocado: tags=machine:cubieboard
28
+ :avocado: tags=device:sd
29
+ """
30
+
31
+ # This test download a 7.5 MiB compressed image and expand it
32
+ # to 126 MiB.
33
+ image_url = ('https://downloads.openwrt.org/releases/22.03.2/targets/'
34
+ 'sunxi/cortexa8/openwrt-22.03.2-sunxi-cortexa8-'
35
+ 'cubietech_a10-cubieboard-ext4-sdcard.img.gz')
36
+ image_hash = ('94b5ecbfbc0b3b56276e5146b899eafa'
37
+ '2ac5dc2d08733d6705af9f144f39f554')
38
+ image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash,
39
+ algorithm='sha256')
40
+ image_path = archive.extract(image_path_gz, self.workdir)
41
+ image_pow2ceil_expand(image_path)
42
+
43
+ self.vm.set_console()
44
+ self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw',
45
+ '-nic', 'user',
46
+ '-no-reboot')
47
+ self.vm.launch()
48
+
49
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
50
+ 'usbcore.nousb '
51
+ 'noreboot')
52
+
53
+ self.wait_for_console_pattern('U-Boot SPL')
54
+
55
+ interrupt_interactive_console_until_pattern(
56
+ self, 'Hit any key to stop autoboot:', '=>')
57
+ exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
58
+ kernel_command_line + "'", '=>')
59
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
60
+
61
+ self.wait_for_console_pattern(
62
+ 'Please press Enter to activate this console.')
63
+
64
+ exec_command_and_wait_for_pattern(self, ' ', 'root@')
65
+
66
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
67
+ 'Allwinner sun4i/sun5i')
68
+ # cubieboard's reboot is not functioning; omit reboot test.
69
+
70
@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
71
def test_arm_quanta_gsj(self):
72
"""
73
--
74
2.34.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Fix descriptor loading from memory wrt host endianness.
3
Don't dereference CPUTLBEntryFull until we verify that
4
the page is valid. Move the other user-only info field
5
updates after the valid check to match.
4
6
5
Reported-by: Peter Maydell <peter.maydell@linaro.org>
7
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1412
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20200404122718.25111-2-edgar.iglesias@gmail.com
11
Message-id: 20230104190056.305143-1-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/dma/xlnx-zdma.c | 11 +++++++----
14
target/arm/sve_helper.c | 14 +++++++++-----
13
1 file changed, 7 insertions(+), 4 deletions(-)
15
1 file changed, 9 insertions(+), 5 deletions(-)
14
16
15
diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c
17
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/dma/xlnx-zdma.c
19
--- a/target/arm/sve_helper.c
18
+++ b/hw/dma/xlnx-zdma.c
20
+++ b/target/arm/sve_helper.c
19
@@ -XXX,XX +XXX,XX @@ static void zdma_put_regaddr64(XlnxZDMA *s, unsigned int basereg, uint64_t addr)
21
@@ -XXX,XX +XXX,XX @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
20
s->regs[basereg + 1] = addr >> 32;
22
#ifdef CONFIG_USER_ONLY
21
}
23
flags = probe_access_flags(env, addr, access_type, mmu_idx, nofault,
22
24
&info->host, retaddr);
23
-static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr, void *buf)
25
- memset(&info->attrs, 0, sizeof(info->attrs));
24
+static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr,
26
- /* Require both ANON and MTE; see allocation_tag_mem(). */
25
+ XlnxZDMADescr *descr)
27
- info->tagged = (flags & PAGE_ANON) && (flags & PAGE_MTE);
26
{
28
#else
27
/* ZDMA descriptors must be aligned to their own size. */
29
CPUTLBEntryFull *full;
28
if (addr % sizeof(XlnxZDMADescr)) {
30
flags = probe_access_full(env, addr, access_type, mmu_idx, nofault,
29
qemu_log_mask(LOG_GUEST_ERROR,
31
&info->host, &full, retaddr);
30
"zdma: unaligned descriptor at %" PRIx64,
32
- info->attrs = full->attrs;
31
addr);
33
- info->tagged = full->pte_attrs == 0xf0;
32
- memset(buf, 0x0, sizeof(XlnxZDMADescr));
34
#endif
33
+ memset(descr, 0x0, sizeof(XlnxZDMADescr));
35
info->flags = flags;
34
s->error = true;
36
37
@@ -XXX,XX +XXX,XX @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
35
return false;
38
return false;
36
}
39
}
37
40
38
- address_space_read(s->dma_as, addr, s->attr, buf, sizeof(XlnxZDMADescr));
41
+#ifdef CONFIG_USER_ONLY
39
+ descr->addr = address_space_ldq_le(s->dma_as, addr, s->attr, NULL);
42
+ memset(&info->attrs, 0, sizeof(info->attrs));
40
+ descr->size = address_space_ldl_le(s->dma_as, addr + 8, s->attr, NULL);
43
+ /* Require both ANON and MTE; see allocation_tag_mem(). */
41
+ descr->attr = address_space_ldl_le(s->dma_as, addr + 12, s->attr, NULL);
44
+ info->tagged = (flags & PAGE_ANON) && (flags & PAGE_MTE);
45
+#else
46
+ info->attrs = full->attrs;
47
+ info->tagged = full->pte_attrs == 0xf0;
48
+#endif
49
+
50
/* Ensure that info->host[] is relative to addr, not addr + mem_off. */
51
info->host -= mem_off;
42
return true;
52
return true;
43
}
44
45
@@ -XXX,XX +XXX,XX @@ static void zdma_update_descr_addr(XlnxZDMA *s, bool type,
46
} else {
47
addr = zdma_get_regaddr64(s, basereg);
48
addr += sizeof(s->dsc_dst);
49
- address_space_read(s->dma_as, addr, s->attr, (void *) &next, 8);
50
+ next = address_space_ldq_le(s->dma_as, addr, s->attr, NULL);
51
}
52
53
zdma_put_regaddr64(s, basereg, next);
54
--
53
--
55
2.20.1
54
2.34.1
56
55
57
56
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Disable unsupported FDT firmware nodes if a user passes us
3
Since pxa255_init() must map the device in the system memory,
4
a DTB with nodes enabled that the machine cannot support
4
there is no point in passing get_system_memory() by argument.
5
due to lack of EL3 or EL2 support.
6
5
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200423121114.4274-5-edgar.iglesias@gmail.com
8
Message-id: 20230109115316.2235-2-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/xlnx-zcu102.c | 30 ++++++++++++++++++++++++++++++
11
include/hw/arm/pxa.h | 2 +-
13
1 file changed, 30 insertions(+)
12
hw/arm/gumstix.c | 3 +--
13
hw/arm/pxa2xx.c | 4 +++-
14
hw/arm/tosa.c | 2 +-
15
4 files changed, 6 insertions(+), 5 deletions(-)
14
16
15
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
17
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-zcu102.c
19
--- a/include/hw/arm/pxa.h
18
+++ b/hw/arm/xlnx-zcu102.c
20
+++ b/include/hw/arm/pxa.h
21
@@ -XXX,XX +XXX,XX @@ struct PXA2xxI2SState {
22
23
PXA2xxState *pxa270_init(MemoryRegion *address_space, unsigned int sdram_size,
24
const char *revision);
25
-PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size);
26
+PXA2xxState *pxa255_init(unsigned int sdram_size);
27
28
#endif /* PXA_H */
29
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/gumstix.c
32
+++ b/hw/arm/gumstix.c
33
@@ -XXX,XX +XXX,XX @@ static void connex_init(MachineState *machine)
34
{
35
PXA2xxState *cpu;
36
DriveInfo *dinfo;
37
- MemoryRegion *address_space_mem = get_system_memory();
38
39
uint32_t connex_rom = 0x01000000;
40
uint32_t connex_ram = 0x04000000;
41
42
- cpu = pxa255_init(address_space_mem, connex_ram);
43
+ cpu = pxa255_init(connex_ram);
44
45
dinfo = drive_get(IF_PFLASH, 0, 0);
46
if (!dinfo && !qtest_enabled()) {
47
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/pxa2xx.c
50
+++ b/hw/arm/pxa2xx.c
19
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@
20
#include "qemu/error-report.h"
52
#include "qemu/error-report.h"
21
#include "qemu/log.h"
53
#include "qemu/module.h"
22
#include "sysemu/qtest.h"
54
#include "qapi/error.h"
23
+#include "sysemu/device_tree.h"
55
+#include "exec/address-spaces.h"
24
56
#include "cpu.h"
25
typedef struct XlnxZCU102 {
57
#include "hw/sysbus.h"
26
MachineState parent_obj;
58
#include "migration/vmstate.h"
27
@@ -XXX,XX +XXX,XX @@ static void zcu102_set_virt(Object *obj, bool value, Error **errp)
59
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
28
s->virt = value;
29
}
60
}
30
61
31
+static void zcu102_modify_dtb(const struct arm_boot_info *binfo, void *fdt)
62
/* Initialise a PXA255 integrated chip (ARM based core). */
32
+{
63
-PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
33
+ XlnxZCU102 *s = container_of(binfo, XlnxZCU102, binfo);
64
+PXA2xxState *pxa255_init(unsigned int sdram_size)
34
+ bool method_is_hvc;
35
+ char **node_path;
36
+ const char *r;
37
+ int prop_len;
38
+ int i;
39
+
40
+ /* If EL3 is enabled, we keep all firmware nodes active. */
41
+ if (!s->secure) {
42
+ node_path = qemu_fdt_node_path(fdt, NULL, "xlnx,zynqmp-firmware",
43
+ &error_fatal);
44
+
45
+ for (i = 0; node_path && node_path[i]; i++) {
46
+ r = qemu_fdt_getprop(fdt, node_path[i], "method", &prop_len, NULL);
47
+ method_is_hvc = r && !strcmp("hvc", r);
48
+
49
+ /* Allow HVC based firmware if EL2 is enabled. */
50
+ if (method_is_hvc && s->virt) {
51
+ continue;
52
+ }
53
+ qemu_fdt_setprop_string(fdt, node_path[i], "status", "disabled");
54
+ }
55
+ g_strfreev(node_path);
56
+ }
57
+}
58
+
59
static void xlnx_zcu102_init(MachineState *machine)
60
{
65
{
61
XlnxZCU102 *s = ZCU102_MACHINE(machine);
66
+ MemoryRegion *address_space = get_system_memory();
62
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_init(MachineState *machine)
67
PXA2xxState *s;
63
68
int i;
64
s->binfo.ram_size = ram_size;
69
DriveInfo *dinfo;
65
s->binfo.loader_start = 0;
70
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
66
+ s->binfo.modify_dtb = zcu102_modify_dtb;
71
index XXXXXXX..XXXXXXX 100644
67
arm_load_kernel(s->soc.boot_cpu_ptr, machine, &s->binfo);
72
--- a/hw/arm/tosa.c
68
}
73
+++ b/hw/arm/tosa.c
69
74
@@ -XXX,XX +XXX,XX @@ static void tosa_init(MachineState *machine)
75
TC6393xbState *tmio;
76
DeviceState *scp0, *scp1;
77
78
- mpu = pxa255_init(address_space_mem, tosa_binfo.ram_size);
79
+ mpu = pxa255_init(tosa_binfo.ram_size);
80
81
memory_region_init_rom(rom, NULL, "tosa.rom", TOSA_ROM, &error_fatal);
82
memory_region_add_subregion(address_space_mem, 0, rom);
70
--
83
--
71
2.20.1
84
2.34.1
72
85
73
86
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Move arm_boot_info into XlnxZCU102.
3
Since pxa270_init() must map the device in the system memory,
4
there is no point in passing get_system_memory() by argument.
4
5
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200423121114.4274-4-edgar.iglesias@gmail.com
8
Message-id: 20230109115316.2235-3-philmd@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
hw/arm/xlnx-zcu102.c | 9 +++++----
11
include/hw/arm/pxa.h | 3 +--
11
1 file changed, 5 insertions(+), 4 deletions(-)
12
hw/arm/gumstix.c | 3 +--
13
hw/arm/mainstone.c | 10 ++++------
14
hw/arm/pxa2xx.c | 4 ++--
15
hw/arm/spitz.c | 6 ++----
16
hw/arm/z2.c | 3 +--
17
6 files changed, 11 insertions(+), 18 deletions(-)
12
18
13
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
19
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/xlnx-zcu102.c
21
--- a/include/hw/arm/pxa.h
16
+++ b/hw/arm/xlnx-zcu102.c
22
+++ b/include/hw/arm/pxa.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct XlnxZCU102 {
23
@@ -XXX,XX +XXX,XX @@ struct PXA2xxI2SState {
18
24
19
bool secure;
25
# define PA_FMT            "0x%08lx"
20
bool virt;
26
21
+
27
-PXA2xxState *pxa270_init(MemoryRegion *address_space, unsigned int sdram_size,
22
+ struct arm_boot_info binfo;
28
- const char *revision);
23
} XlnxZCU102;
29
+PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision);
24
30
PXA2xxState *pxa255_init(unsigned int sdram_size);
25
#define TYPE_ZCU102_MACHINE MACHINE_TYPE_NAME("xlnx-zcu102")
31
26
#define ZCU102_MACHINE(obj) \
32
#endif /* PXA_H */
27
OBJECT_CHECK(XlnxZCU102, (obj), TYPE_ZCU102_MACHINE)
33
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
28
34
index XXXXXXX..XXXXXXX 100644
29
-static struct arm_boot_info xlnx_zcu102_binfo;
35
--- a/hw/arm/gumstix.c
30
36
+++ b/hw/arm/gumstix.c
31
static bool zcu102_get_secure(Object *obj, Error **errp)
37
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
32
{
38
{
33
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_init(MachineState *machine)
39
PXA2xxState *cpu;
34
40
DriveInfo *dinfo;
35
/* TODO create and connect IDE devices for ide_drive_get() */
41
- MemoryRegion *address_space_mem = get_system_memory();
36
42
37
- xlnx_zcu102_binfo.ram_size = ram_size;
43
uint32_t verdex_rom = 0x02000000;
38
- xlnx_zcu102_binfo.loader_start = 0;
44
uint32_t verdex_ram = 0x10000000;
39
- arm_load_kernel(s->soc.boot_cpu_ptr, machine, &xlnx_zcu102_binfo);
45
40
+ s->binfo.ram_size = ram_size;
46
- cpu = pxa270_init(address_space_mem, verdex_ram, machine->cpu_type);
41
+ s->binfo.loader_start = 0;
47
+ cpu = pxa270_init(verdex_ram, machine->cpu_type);
42
+ arm_load_kernel(s->soc.boot_cpu_ptr, machine, &s->binfo);
48
49
dinfo = drive_get(IF_PFLASH, 0, 0);
50
if (!dinfo && !qtest_enabled()) {
51
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/arm/mainstone.c
54
+++ b/hw/arm/mainstone.c
55
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info mainstone_binfo = {
56
.ram_size = 0x04000000,
57
};
58
59
-static void mainstone_common_init(MemoryRegion *address_space_mem,
60
- MachineState *machine,
61
+static void mainstone_common_init(MachineState *machine,
62
enum mainstone_model_e model, int arm_id)
63
{
64
uint32_t sector_len = 256 * 1024;
65
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
66
MemoryRegion *rom = g_new(MemoryRegion, 1);
67
68
/* Setup CPU & memory */
69
- mpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size,
70
- machine->cpu_type);
71
+ mpu = pxa270_init(mainstone_binfo.ram_size, machine->cpu_type);
72
memory_region_init_rom(rom, NULL, "mainstone.rom", MAINSTONE_ROM,
73
&error_fatal);
74
- memory_region_add_subregion(address_space_mem, 0, rom);
75
+ memory_region_add_subregion(get_system_memory(), 0x00000000, rom);
76
77
/* There are two 32MiB flash devices on the board */
78
for (i = 0; i < 2; i ++) {
79
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
80
81
static void mainstone_init(MachineState *machine)
82
{
83
- mainstone_common_init(get_system_memory(), machine, mainstone, 0x196);
84
+ mainstone_common_init(machine, mainstone, 0x196);
43
}
85
}
44
86
45
static void xlnx_zcu102_machine_instance_init(Object *obj)
87
static void mainstone2_machine_init(MachineClass *mc)
88
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/hw/arm/pxa2xx.c
91
+++ b/hw/arm/pxa2xx.c
92
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_reset(void *opaque, int line, int level)
93
}
94
95
/* Initialise a PXA270 integrated chip (ARM based core). */
96
-PXA2xxState *pxa270_init(MemoryRegion *address_space,
97
- unsigned int sdram_size, const char *cpu_type)
98
+PXA2xxState *pxa270_init(unsigned int sdram_size, const char *cpu_type)
99
{
100
+ MemoryRegion *address_space = get_system_memory();
101
PXA2xxState *s;
102
int i;
103
DriveInfo *dinfo;
104
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/arm/spitz.c
107
+++ b/hw/arm/spitz.c
108
@@ -XXX,XX +XXX,XX @@ static void spitz_common_init(MachineState *machine)
109
SpitzMachineState *sms = SPITZ_MACHINE(machine);
110
enum spitz_model_e model = smc->model;
111
PXA2xxState *mpu;
112
- MemoryRegion *address_space_mem = get_system_memory();
113
MemoryRegion *rom = g_new(MemoryRegion, 1);
114
115
/* Setup CPU & memory */
116
- mpu = pxa270_init(address_space_mem, spitz_binfo.ram_size,
117
- machine->cpu_type);
118
+ mpu = pxa270_init(spitz_binfo.ram_size, machine->cpu_type);
119
sms->mpu = mpu;
120
121
sl_flash_register(mpu, (model == spitz) ? FLASH_128M : FLASH_1024M);
122
123
memory_region_init_rom(rom, NULL, "spitz.rom", SPITZ_ROM, &error_fatal);
124
- memory_region_add_subregion(address_space_mem, 0, rom);
125
+ memory_region_add_subregion(get_system_memory(), 0, rom);
126
127
/* Setup peripherals */
128
spitz_keyboard_register(mpu);
129
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/arm/z2.c
132
+++ b/hw/arm/z2.c
133
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aer915_info = {
134
135
static void z2_init(MachineState *machine)
136
{
137
- MemoryRegion *address_space_mem = get_system_memory();
138
uint32_t sector_len = 0x10000;
139
PXA2xxState *mpu;
140
DriveInfo *dinfo;
141
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
142
DeviceState *wm;
143
144
/* Setup CPU & memory */
145
- mpu = pxa270_init(address_space_mem, z2_binfo.ram_size, machine->cpu_type);
146
+ mpu = pxa270_init(z2_binfo.ram_size, machine->cpu_type);
147
148
dinfo = drive_get(IF_PFLASH, 0, 0);
149
if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
46
--
150
--
47
2.20.1
151
2.34.1
48
152
49
153
diff view generated by jsdifflib
1
From: Keqian Zhu <zhukeqian1@huawei.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Replace "acpi-mem-hotplug" with "acpi-cpu-hotplug"
3
IEC binary prefixes ease code review: the unit is explicit.
4
4
5
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
5
Add definitions for RAM / Flash / Flash blocksize.
6
Message-id: 20200413091552.62748-4-zhukeqian1@huawei.com
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109115316.2235-4-philmd@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
hw/acpi/cpu.c | 2 +-
12
hw/arm/collie.c | 16 ++++++++++------
11
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 10 insertions(+), 6 deletions(-)
12
14
13
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
15
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/acpi/cpu.c
17
--- a/hw/arm/collie.c
16
+++ b/hw/acpi/cpu.c
18
+++ b/hw/arm/collie.c
17
@@ -XXX,XX +XXX,XX @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
19
@@ -XXX,XX +XXX,XX @@
18
state->devs[i].arch_id = id_list->cpus[i].arch_id;
20
#include "cpu.h"
19
}
21
#include "qom/object.h"
20
memory_region_init_io(&state->ctrl_reg, owner, &cpu_hotplug_ops, state,
22
21
- "acpi-mem-hotplug", ACPI_CPU_HOTPLUG_REG_LEN);
23
+#define RAM_SIZE (512 * MiB)
22
+ "acpi-cpu-hotplug", ACPI_CPU_HOTPLUG_REG_LEN);
24
+#define FLASH_SIZE (32 * MiB)
23
memory_region_add_subregion(as, base_addr, &state->ctrl_reg);
25
+#define FLASH_SECTOR_SIZE (64 * KiB)
26
+
27
struct CollieMachineState {
28
MachineState parent;
29
30
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(CollieMachineState, COLLIE_MACHINE)
31
32
static struct arm_boot_info collie_binfo = {
33
.loader_start = SA_SDCS0,
34
- .ram_size = 0x20000000,
35
+ .ram_size = RAM_SIZE,
36
};
37
38
static void collie_init(MachineState *machine)
39
@@ -XXX,XX +XXX,XX @@ static void collie_init(MachineState *machine)
40
memory_region_add_subregion(get_system_memory(), SA_SDCS0, machine->ram);
41
42
dinfo = drive_get(IF_PFLASH, 0, 0);
43
- pflash_cfi01_register(SA_CS0, "collie.fl1", 0x02000000,
44
+ pflash_cfi01_register(SA_CS0, "collie.fl1", FLASH_SIZE,
45
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
46
- 64 * KiB, 4, 0x00, 0x00, 0x00, 0x00, 0);
47
+ FLASH_SECTOR_SIZE, 4, 0x00, 0x00, 0x00, 0x00, 0);
48
49
dinfo = drive_get(IF_PFLASH, 0, 1);
50
- pflash_cfi01_register(SA_CS1, "collie.fl2", 0x02000000,
51
+ pflash_cfi01_register(SA_CS1, "collie.fl2", FLASH_SIZE,
52
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
53
- 64 * KiB, 4, 0x00, 0x00, 0x00, 0x00, 0);
54
+ FLASH_SECTOR_SIZE, 4, 0x00, 0x00, 0x00, 0x00, 0);
55
56
sysbus_create_simple("scoop", 0x40800000, NULL);
57
58
@@ -XXX,XX +XXX,XX @@ static void collie_machine_class_init(ObjectClass *oc, void *data)
59
mc->init = collie_init;
60
mc->ignore_memory_transaction_failures = true;
61
mc->default_cpu_type = ARM_CPU_TYPE_NAME("sa1110");
62
- mc->default_ram_size = 0x20000000;
63
+ mc->default_ram_size = RAM_SIZE;
64
mc->default_ram_id = "strongarm.sdram";
24
}
65
}
25
66
26
--
67
--
27
2.20.1
68
2.34.1
28
69
29
70
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Setup the ADMA with 128bit bus-width. This matters when
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
FIXED BURST mode is used.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
5
Message-id: 20230109115316.2235-5-philmd@linaro.org
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200417153800.27399-2-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
hw/arm/xlnx-versal.c | 2 ++
8
hw/arm/collie.c | 17 +++++++----------
13
1 file changed, 2 insertions(+)
9
1 file changed, 7 insertions(+), 10 deletions(-)
14
10
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
11
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
13
--- a/hw/arm/collie.c
18
+++ b/hw/arm/xlnx-versal.c
14
+++ b/hw/arm/collie.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
15
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info collie_binfo = {
20
16
21
dev = qdev_create(NULL, "xlnx.zdma");
17
static void collie_init(MachineState *machine)
22
s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
18
{
23
+ object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
19
- DriveInfo *dinfo;
24
+ &error_abort);
20
MachineClass *mc = MACHINE_GET_CLASS(machine);
25
object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
21
CollieMachineState *cms = COLLIE_MACHINE(machine);
26
qdev_init_nofail(dev);
22
23
@@ -XXX,XX +XXX,XX @@ static void collie_init(MachineState *machine)
24
25
memory_region_add_subregion(get_system_memory(), SA_SDCS0, machine->ram);
26
27
- dinfo = drive_get(IF_PFLASH, 0, 0);
28
- pflash_cfi01_register(SA_CS0, "collie.fl1", FLASH_SIZE,
29
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
30
- FLASH_SECTOR_SIZE, 4, 0x00, 0x00, 0x00, 0x00, 0);
31
-
32
- dinfo = drive_get(IF_PFLASH, 0, 1);
33
- pflash_cfi01_register(SA_CS1, "collie.fl2", FLASH_SIZE,
34
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
35
- FLASH_SECTOR_SIZE, 4, 0x00, 0x00, 0x00, 0x00, 0);
36
+ for (unsigned i = 0; i < 2; i++) {
37
+ DriveInfo *dinfo = drive_get(IF_PFLASH, 0, i);
38
+ pflash_cfi01_register(i ? SA_CS1 : SA_CS0,
39
+ i ? "collie.fl2" : "collie.fl1", FLASH_SIZE,
40
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
41
+ FLASH_SECTOR_SIZE, 4, 0x00, 0x00, 0x00, 0x00, 0);
42
+ }
43
44
sysbus_create_simple("scoop", 0x40800000, NULL);
27
45
28
--
46
--
29
2.20.1
47
2.34.1
30
48
31
49
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
Add a comment describing the Connex uses a Numonyx RC28F128J3F75
4
flash, and the Verdex uses a Micron RC28F256P30TFA.
5
6
Correct the Verdex machine description (we model the 'Pro' board).
7
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230109115316.2235-6-philmd@linaro.org
11
Message-Id: <20200223231044.8003-3-philmd@redhat.com>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/gumstix.c | 6 ++++--
15
1 file changed, 4 insertions(+), 2 deletions(-)
16
17
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/gumstix.c
20
+++ b/hw/arm/gumstix.c
21
@@ -XXX,XX +XXX,XX @@
22
* Contributions after 2012-01-13 are licensed under the terms of the
23
* GNU GPL, version 2 or (at your option) any later version.
24
*/
25
-
26
+
27
/*
28
* Example usage:
29
*
30
@@ -XXX,XX +XXX,XX @@ static void connex_init(MachineState *machine)
31
exit(1);
32
}
33
34
+ /* Numonyx RC28F128J3F75 */
35
if (!pflash_cfi01_register(0x00000000, "connext.rom", connex_rom,
36
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
37
sector_len, 2, 0, 0, 0, 0, 0)) {
38
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
39
exit(1);
40
}
41
42
+ /* Micron RC28F256P30TFA */
43
if (!pflash_cfi01_register(0x00000000, "verdex.rom", verdex_rom,
44
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
45
sector_len, 2, 0, 0, 0, 0, 0)) {
46
@@ -XXX,XX +XXX,XX @@ static void verdex_class_init(ObjectClass *oc, void *data)
47
{
48
MachineClass *mc = MACHINE_CLASS(oc);
49
50
- mc->desc = "Gumstix Verdex (PXA270)";
51
+ mc->desc = "Gumstix Verdex Pro XL6P COMs (PXA270)";
52
mc->init = verdex_init;
53
mc->ignore_memory_transaction_failures = true;
54
mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
55
--
56
2.34.1
57
58
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
IEC binary prefixes ease code review: the unit is explicit.
4
5
Add definitions for RAM / Flash / Flash blocksize.
6
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109115316.2235-7-philmd@linaro.org
10
Message-Id: <20200223231044.8003-3-philmd@redhat.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/gumstix.c | 27 ++++++++++++++-------------
14
1 file changed, 14 insertions(+), 13 deletions(-)
15
16
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/gumstix.c
19
+++ b/hw/arm/gumstix.c
20
@@ -XXX,XX +XXX,XX @@
21
*/
22
23
#include "qemu/osdep.h"
24
+#include "qemu/units.h"
25
#include "qemu/error-report.h"
26
#include "hw/arm/pxa.h"
27
#include "net/net.h"
28
@@ -XXX,XX +XXX,XX @@
29
#include "sysemu/qtest.h"
30
#include "cpu.h"
31
32
-static const int sector_len = 128 * 1024;
33
+#define CONNEX_FLASH_SIZE (16 * MiB)
34
+#define CONNEX_RAM_SIZE (64 * MiB)
35
+
36
+#define VERDEX_FLASH_SIZE (32 * MiB)
37
+#define VERDEX_RAM_SIZE (256 * MiB)
38
+
39
+#define FLASH_SECTOR_SIZE (128 * KiB)
40
41
static void connex_init(MachineState *machine)
42
{
43
PXA2xxState *cpu;
44
DriveInfo *dinfo;
45
46
- uint32_t connex_rom = 0x01000000;
47
- uint32_t connex_ram = 0x04000000;
48
-
49
- cpu = pxa255_init(connex_ram);
50
+ cpu = pxa255_init(CONNEX_RAM_SIZE);
51
52
dinfo = drive_get(IF_PFLASH, 0, 0);
53
if (!dinfo && !qtest_enabled()) {
54
@@ -XXX,XX +XXX,XX @@ static void connex_init(MachineState *machine)
55
}
56
57
/* Numonyx RC28F128J3F75 */
58
- if (!pflash_cfi01_register(0x00000000, "connext.rom", connex_rom,
59
+ if (!pflash_cfi01_register(0x00000000, "connext.rom", CONNEX_FLASH_SIZE,
60
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
61
- sector_len, 2, 0, 0, 0, 0, 0)) {
62
+ FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0)) {
63
error_report("Error registering flash memory");
64
exit(1);
65
}
66
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
67
PXA2xxState *cpu;
68
DriveInfo *dinfo;
69
70
- uint32_t verdex_rom = 0x02000000;
71
- uint32_t verdex_ram = 0x10000000;
72
-
73
- cpu = pxa270_init(verdex_ram, machine->cpu_type);
74
+ cpu = pxa270_init(VERDEX_RAM_SIZE, machine->cpu_type);
75
76
dinfo = drive_get(IF_PFLASH, 0, 0);
77
if (!dinfo && !qtest_enabled()) {
78
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
79
}
80
81
/* Micron RC28F256P30TFA */
82
- if (!pflash_cfi01_register(0x00000000, "verdex.rom", verdex_rom,
83
+ if (!pflash_cfi01_register(0x00000000, "verdex.rom", VERDEX_FLASH_SIZE,
84
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
85
- sector_len, 2, 0, 0, 0, 0, 0)) {
86
+ FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0)) {
87
error_report("Error registering flash memory");
88
exit(1);
89
}
90
--
91
2.34.1
92
93
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Make compat in qemu_fdt_node_path() const char *.
3
IEC binary prefixes ease code review: the unit is explicit.
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Add the FLASH_SECTOR_SIZE definition.
6
Message-id: 20200423121114.4274-3-edgar.iglesias@gmail.com
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109115316.2235-8-philmd@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
include/sysemu/device_tree.h | 2 +-
12
hw/arm/mainstone.c | 18 ++++++++++--------
11
device_tree.c | 2 +-
13
1 file changed, 10 insertions(+), 8 deletions(-)
12
2 files changed, 2 insertions(+), 2 deletions(-)
13
14
14
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
15
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/include/sysemu/device_tree.h
17
--- a/hw/arm/mainstone.c
17
+++ b/include/sysemu/device_tree.h
18
+++ b/hw/arm/mainstone.c
18
@@ -XXX,XX +XXX,XX @@ void *load_device_tree_from_sysfs(void);
19
@@ -XXX,XX +XXX,XX @@
19
* @name may be NULL to wildcard names and only match compatibility
20
* GNU GPL, version 2 or (at your option) any later version.
20
* strings.
21
*/
21
*/
22
-char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
22
#include "qemu/osdep.h"
23
+char **qemu_fdt_node_path(void *fdt, const char *name, const char *compat,
23
+#include "qemu/units.h"
24
Error **errp);
24
#include "qemu/error-report.h"
25
25
#include "qapi/error.h"
26
/**
26
#include "hw/arm/pxa.h"
27
diff --git a/device_tree.c b/device_tree.c
27
@@ -XXX,XX +XXX,XX @@ static const struct keymap map[0xE0] = {
28
index XXXXXXX..XXXXXXX 100644
28
29
--- a/device_tree.c
29
enum mainstone_model_e { mainstone };
30
+++ b/device_tree.c
30
31
@@ -XXX,XX +XXX,XX @@ char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp)
31
-#define MAINSTONE_RAM    0x04000000
32
return path_array;
32
-#define MAINSTONE_ROM    0x00800000
33
}
33
-#define MAINSTONE_FLASH    0x02000000
34
34
+#define MAINSTONE_RAM_SIZE (64 * MiB)
35
-char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
35
+#define MAINSTONE_ROM_SIZE (8 * MiB)
36
+char **qemu_fdt_node_path(void *fdt, const char *name, const char *compat,
36
+#define MAINSTONE_FLASH_SIZE (32 * MiB)
37
Error **errp)
37
38
static struct arm_boot_info mainstone_binfo = {
39
.loader_start = PXA2XX_SDRAM_BASE,
40
- .ram_size = 0x04000000,
41
+ .ram_size = MAINSTONE_RAM_SIZE,
42
};
43
44
+#define FLASH_SECTOR_SIZE (256 * KiB)
45
+
46
static void mainstone_common_init(MachineState *machine,
47
enum mainstone_model_e model, int arm_id)
38
{
48
{
39
int offset, len, ret;
49
- uint32_t sector_len = 256 * 1024;
50
hwaddr mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };
51
PXA2xxState *mpu;
52
DeviceState *mst_irq;
53
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MachineState *machine,
54
55
/* Setup CPU & memory */
56
mpu = pxa270_init(mainstone_binfo.ram_size, machine->cpu_type);
57
- memory_region_init_rom(rom, NULL, "mainstone.rom", MAINSTONE_ROM,
58
+ memory_region_init_rom(rom, NULL, "mainstone.rom", MAINSTONE_ROM_SIZE,
59
&error_fatal);
60
memory_region_add_subregion(get_system_memory(), 0x00000000, rom);
61
62
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MachineState *machine,
63
dinfo = drive_get(IF_PFLASH, 0, i);
64
if (!pflash_cfi01_register(mainstone_flash_base[i],
65
i ? "mainstone.flash1" : "mainstone.flash0",
66
- MAINSTONE_FLASH,
67
+ MAINSTONE_FLASH_SIZE,
68
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
69
- sector_len, 4, 0, 0, 0, 0, 0)) {
70
+ FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
71
error_report("Error registering flash memory");
72
exit(1);
73
}
40
--
74
--
41
2.20.1
75
2.34.1
42
76
43
77
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
We will move this code in the next commit. Clean it up
3
IEC binary prefixes ease code review: the unit is explicit.
4
first to avoid checkpatch.pl errors.
5
4
5
Add the FLASH_SECTOR_SIZE definition.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20230109115316.2235-9-philmd@linaro.org
8
Message-id: 20200423073358.27155-5-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/cpu.c | 9 ++++++---
12
hw/arm/musicpal.c | 9 ++++++---
12
1 file changed, 6 insertions(+), 3 deletions(-)
13
1 file changed, 6 insertions(+), 3 deletions(-)
13
14
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
17
--- a/hw/arm/musicpal.c
17
+++ b/target/arm/cpu.c
18
+++ b/hw/arm/musicpal.c
18
@@ -XXX,XX +XXX,XX @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
19
@@ -XXX,XX +XXX,XX @@
19
CPUARMState *env = &cpu->env;
20
*/
20
bool ret = false;
21
21
22
#include "qemu/osdep.h"
22
- /* ARMv7-M interrupt masking works differently than -A or -R.
23
+#include "qemu/units.h"
23
+ /*
24
#include "qapi/error.h"
24
+ * ARMv7-M interrupt masking works differently than -A or -R.
25
#include "cpu.h"
25
* There is no FIQ/IRQ distinction. Instead of I and F bits
26
#include "hw/sysbus.h"
26
* masking FIQ and IRQ interrupts, an exception is taken only
27
@@ -XXX,XX +XXX,XX @@ static const TypeInfo musicpal_key_info = {
27
* if it is higher priority than the current execution priority
28
.class_init = musicpal_key_class_init,
28
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
29
};
29
static void arm1136_r2_initfn(Object *obj)
30
30
{
31
+#define FLASH_SECTOR_SIZE (64 * KiB)
31
ARMCPU *cpu = ARM_CPU(obj);
32
+
32
- /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
33
static struct arm_boot_info musicpal_binfo = {
33
+ /*
34
.loader_start = 0x0,
34
+ * What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
35
.board_id = 0x20e,
35
* older core than plain "arm1136". In particular this does not
36
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
36
* have the v6K features.
37
BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
37
* These ID register values are correct for 1136 but may be wrong
38
38
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
39
flash_size = blk_getlength(blk);
39
{ .name = "arm926", .initfn = arm926_initfn },
40
- if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&
40
{ .name = "arm946", .initfn = arm946_initfn },
41
- flash_size != 32*1024*1024) {
41
{ .name = "arm1026", .initfn = arm1026_initfn },
42
+ if (flash_size != 8 * MiB && flash_size != 16 * MiB &&
42
- /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
43
+ flash_size != 32 * MiB) {
43
+ /*
44
error_report("Invalid flash image size");
44
+ * What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
45
exit(1);
45
* older core than plain "arm1136". In particular this does not
46
}
46
* have the v6K features.
47
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
47
*/
48
*/
49
pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
50
"musicpal.flash", flash_size,
51
- blk, 0x10000,
52
+ blk, FLASH_SECTOR_SIZE,
53
MP_FLASH_SIZE_MAX / flash_size,
54
2, 0x00BF, 0x236D, 0x0000, 0x0000,
55
0x5555, 0x2AAA, 0);
48
--
56
--
49
2.20.1
57
2.34.1
50
58
51
59
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Allow name wildcards in qemu_fdt_node_path(). This is useful
3
The total_ram_v1/total_ram_v2 definitions were never used.
4
to find all nodes with a given compatibility string.
5
4
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200423121114.4274-2-edgar.iglesias@gmail.com
7
Message-id: 20230109115316.2235-10-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
include/sysemu/device_tree.h | 3 +++
10
hw/arm/omap_sx1.c | 2 --
12
device_tree.c | 2 +-
11
1 file changed, 2 deletions(-)
13
2 files changed, 4 insertions(+), 1 deletion(-)
14
12
15
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
13
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/include/sysemu/device_tree.h
15
--- a/hw/arm/omap_sx1.c
18
+++ b/include/sysemu/device_tree.h
16
+++ b/hw/arm/omap_sx1.c
19
@@ -XXX,XX +XXX,XX @@ void *load_device_tree_from_sysfs(void);
17
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps static_ops = {
20
* NULL. If there is no error but no matching node was found, the
18
#define flash0_size    (16 * 1024 * 1024)
21
* returned array contains a single element equal to NULL. If an error
19
#define flash1_size    ( 8 * 1024 * 1024)
22
* was encountered when parsing the blob, the function returns NULL
20
#define flash2_size    (32 * 1024 * 1024)
23
+ *
21
-#define total_ram_v1    (sdram_size + flash0_size + flash1_size + OMAP15XX_SRAM_SIZE)
24
+ * @name may be NULL to wildcard names and only match compatibility
22
-#define total_ram_v2    (sdram_size + flash2_size + OMAP15XX_SRAM_SIZE)
25
+ * strings.
23
26
*/
24
static struct arm_boot_info sx1_binfo = {
27
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
25
.loader_start = OMAP_EMIFF_BASE,
28
Error **errp);
29
diff --git a/device_tree.c b/device_tree.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/device_tree.c
32
+++ b/device_tree.c
33
@@ -XXX,XX +XXX,XX @@ char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
34
offset = len;
35
break;
36
}
37
- if (!strcmp(iter_name, name)) {
38
+ if (!name || !strcmp(iter_name, name)) {
39
char *path;
40
41
path = g_malloc(path_len);
42
--
26
--
43
2.20.1
27
2.34.1
44
28
45
29
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Switch the cadence uart to multi-phase reset and add the
3
IEC binary prefixes ease code review: the unit is explicit.
4
reference clock input.
5
4
6
The input clock frequency is added to the migration structure.
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
The reference clock controls the baudrate generation. If it disabled,
7
Message-id: 20230109115316.2235-11-philmd@linaro.org
9
any input characters and events are ignored.
10
11
If this clock remains unconnected, the uart behaves as before
12
(it default to a 50MHz ref clock).
13
14
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
15
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-id: 20200406135251.157596-8-damien.hedde@greensocs.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
9
---
20
include/hw/char/cadence_uart.h | 1 +
10
hw/arm/omap_sx1.c | 33 +++++++++++++++++----------------
21
hw/char/cadence_uart.c | 73 +++++++++++++++++++++++++++++-----
11
1 file changed, 17 insertions(+), 16 deletions(-)
22
hw/char/trace-events | 3 ++
23
3 files changed, 67 insertions(+), 10 deletions(-)
24
12
25
diff --git a/include/hw/char/cadence_uart.h b/include/hw/char/cadence_uart.h
13
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
26
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/char/cadence_uart.h
15
--- a/hw/arm/omap_sx1.c
28
+++ b/include/hw/char/cadence_uart.h
16
+++ b/hw/arm/omap_sx1.c
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
30
CharBackend chr;
31
qemu_irq irq;
32
QEMUTimer *fifo_trigger_handle;
33
+ Clock *refclk;
34
} CadenceUARTState;
35
36
static inline DeviceState *cadence_uart_create(hwaddr addr,
37
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/char/cadence_uart.c
40
+++ b/hw/char/cadence_uart.c
41
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
42
#include "qemu/module.h"
18
* with this program; if not, see <http://www.gnu.org/licenses/>.
43
#include "hw/char/cadence_uart.h"
19
*/
44
#include "hw/irq.h"
20
#include "qemu/osdep.h"
45
+#include "hw/qdev-clock.h"
21
+#include "qemu/units.h"
46
+#include "trace.h"
22
#include "qapi/error.h"
47
23
#include "ui/console.h"
48
#ifdef CADENCE_UART_ERR_DEBUG
24
#include "hw/arm/omap.h"
49
#define DB_PRINT(...) do { \
25
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps static_ops = {
50
@@ -XXX,XX +XXX,XX @@
51
#define LOCAL_LOOPBACK (0x2 << UART_MR_CHMODE_SH)
52
#define REMOTE_LOOPBACK (0x3 << UART_MR_CHMODE_SH)
53
54
-#define UART_INPUT_CLK 50000000
55
+#define UART_DEFAULT_REF_CLK (50 * 1000 * 1000)
56
57
#define R_CR (0x00/4)
58
#define R_MR (0x04/4)
59
@@ -XXX,XX +XXX,XX @@ static void uart_send_breaks(CadenceUARTState *s)
60
static void uart_parameters_setup(CadenceUARTState *s)
61
{
62
QEMUSerialSetParams ssp;
63
- unsigned int baud_rate, packet_size;
64
+ unsigned int baud_rate, packet_size, input_clk;
65
+ input_clk = clock_get_hz(s->refclk);
66
67
- baud_rate = (s->r[R_MR] & UART_MR_CLKS) ?
68
- UART_INPUT_CLK / 8 : UART_INPUT_CLK;
69
+ baud_rate = (s->r[R_MR] & UART_MR_CLKS) ? input_clk / 8 : input_clk;
70
+ baud_rate /= (s->r[R_BRGR] * (s->r[R_BDIV] + 1));
71
+ trace_cadence_uart_baudrate(baud_rate);
72
+
73
+ ssp.speed = baud_rate;
74
75
- ssp.speed = baud_rate / (s->r[R_BRGR] * (s->r[R_BDIV] + 1));
76
packet_size = 1;
77
78
switch (s->r[R_MR] & UART_MR_PAR) {
79
@@ -XXX,XX +XXX,XX @@ static void uart_parameters_setup(CadenceUARTState *s)
80
}
81
82
packet_size += ssp.data_bits + ssp.stop_bits;
83
+ if (ssp.speed == 0) {
84
+ /*
85
+ * Avoid division-by-zero below.
86
+ * TODO: find something better
87
+ */
88
+ ssp.speed = 1;
89
+ }
90
s->char_tx_time = (NANOSECONDS_PER_SECOND / ssp.speed) * packet_size;
91
qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
92
}
93
@@ -XXX,XX +XXX,XX @@ static void uart_receive(void *opaque, const uint8_t *buf, int size)
94
CadenceUARTState *s = opaque;
95
uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE;
96
97
+ /* ignore characters when unclocked or in reset */
98
+ if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
99
+ return;
100
+ }
101
+
102
if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) {
103
uart_write_rx_fifo(opaque, buf, size);
104
}
105
@@ -XXX,XX +XXX,XX @@ static void uart_event(void *opaque, QEMUChrEvent event)
106
CadenceUARTState *s = opaque;
107
uint8_t buf = '\0';
108
109
+ /* ignore characters when unclocked or in reset */
110
+ if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
111
+ return;
112
+ }
113
+
114
if (event == CHR_EVENT_BREAK) {
115
uart_write_rx_fifo(opaque, &buf, 1);
116
}
117
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps uart_ops = {
118
.endianness = DEVICE_NATIVE_ENDIAN,
26
.endianness = DEVICE_NATIVE_ENDIAN,
119
};
27
};
120
28
121
-static void cadence_uart_reset(DeviceState *dev)
29
-#define sdram_size    0x02000000
122
+static void cadence_uart_reset_init(Object *obj, ResetType type)
30
-#define sector_size    (128 * 1024)
123
{
31
-#define flash0_size    (16 * 1024 * 1024)
124
- CadenceUARTState *s = CADENCE_UART(dev);
32
-#define flash1_size    ( 8 * 1024 * 1024)
125
+ CadenceUARTState *s = CADENCE_UART(obj);
33
-#define flash2_size    (32 * 1024 * 1024)
126
34
+#define SDRAM_SIZE (32 * MiB)
127
s->r[R_CR] = 0x00000128;
35
+#define SECTOR_SIZE (128 * KiB)
128
s->r[R_IMR] = 0;
36
+#define FLASH0_SIZE (16 * MiB)
129
@@ -XXX,XX +XXX,XX @@ static void cadence_uart_reset(DeviceState *dev)
37
+#define FLASH1_SIZE (8 * MiB)
130
s->r[R_BRGR] = 0x0000028B;
38
+#define FLASH2_SIZE (32 * MiB)
131
s->r[R_BDIV] = 0x0000000F;
39
132
s->r[R_TTRIG] = 0x00000020;
40
static struct arm_boot_info sx1_binfo = {
133
+}
41
.loader_start = OMAP_EMIFF_BASE,
134
+
42
- .ram_size = sdram_size,
135
+static void cadence_uart_reset_hold(Object *obj)
43
+ .ram_size = SDRAM_SIZE,
136
+{
44
.board_id = 0x265,
137
+ CadenceUARTState *s = CADENCE_UART(obj);
45
};
138
46
139
uart_rx_reset(s);
47
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
140
uart_tx_reset(s);
48
static uint32_t cs3val = 0x00001139;
141
@@ -XXX,XX +XXX,XX @@ static void cadence_uart_realize(DeviceState *dev, Error **errp)
49
DriveInfo *dinfo;
142
uart_event, NULL, s, NULL, true);
50
int fl_idx;
51
- uint32_t flash_size = flash0_size;
52
+ uint32_t flash_size = FLASH0_SIZE;
53
54
if (machine->ram_size != mc->default_ram_size) {
55
char *sz = size_to_str(mc->default_ram_size);
56
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
57
}
58
59
if (version == 2) {
60
- flash_size = flash2_size;
61
+ flash_size = FLASH2_SIZE;
62
}
63
64
memory_region_add_subregion(address_space, OMAP_EMIFF_BASE, machine->ram);
65
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
66
if (!pflash_cfi01_register(OMAP_CS0_BASE,
67
"omap_sx1.flash0-1", flash_size,
68
blk_by_legacy_dinfo(dinfo),
69
- sector_size, 4, 0, 0, 0, 0, 0)) {
70
+ SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
71
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
72
fl_idx);
73
}
74
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
75
(dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
76
MemoryRegion *flash_1 = g_new(MemoryRegion, 1);
77
memory_region_init_rom(flash_1, NULL, "omap_sx1.flash1-0",
78
- flash1_size, &error_fatal);
79
+ FLASH1_SIZE, &error_fatal);
80
memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1);
81
82
memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
83
- "sx1.cs1", OMAP_CS1_SIZE - flash1_size);
84
+ "sx1.cs1", OMAP_CS1_SIZE - FLASH1_SIZE);
85
memory_region_add_subregion(address_space,
86
- OMAP_CS1_BASE + flash1_size, &cs[1]);
87
+ OMAP_CS1_BASE + FLASH1_SIZE, &cs[1]);
88
89
if (!pflash_cfi01_register(OMAP_CS1_BASE,
90
- "omap_sx1.flash1-1", flash1_size,
91
+ "omap_sx1.flash1-1", FLASH1_SIZE,
92
blk_by_legacy_dinfo(dinfo),
93
- sector_size, 4, 0, 0, 0, 0, 0)) {
94
+ SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
95
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
96
fl_idx);
97
}
98
@@ -XXX,XX +XXX,XX @@ static void sx1_machine_v2_class_init(ObjectClass *oc, void *data)
99
mc->init = sx1_init_v2;
100
mc->ignore_memory_transaction_failures = true;
101
mc->default_cpu_type = ARM_CPU_TYPE_NAME("ti925t");
102
- mc->default_ram_size = sdram_size;
103
+ mc->default_ram_size = SDRAM_SIZE;
104
mc->default_ram_id = "omap1.dram";
143
}
105
}
144
106
145
+static void cadence_uart_refclk_update(void *opaque)
107
@@ -XXX,XX +XXX,XX @@ static void sx1_machine_v1_class_init(ObjectClass *oc, void *data)
146
+{
108
mc->init = sx1_init_v1;
147
+ CadenceUARTState *s = opaque;
109
mc->ignore_memory_transaction_failures = true;
148
+
110
mc->default_cpu_type = ARM_CPU_TYPE_NAME("ti925t");
149
+ /* recompute uart's speed on clock change */
111
- mc->default_ram_size = sdram_size;
150
+ uart_parameters_setup(s);
112
+ mc->default_ram_size = SDRAM_SIZE;
151
+}
113
mc->default_ram_id = "omap1.dram";
152
+
153
static void cadence_uart_init(Object *obj)
154
{
155
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
156
@@ -XXX,XX +XXX,XX @@ static void cadence_uart_init(Object *obj)
157
sysbus_init_mmio(sbd, &s->iomem);
158
sysbus_init_irq(sbd, &s->irq);
159
160
+ s->refclk = qdev_init_clock_in(DEVICE(obj), "refclk",
161
+ cadence_uart_refclk_update, s);
162
+ /* initialize the frequency in case the clock remains unconnected */
163
+ clock_set_hz(s->refclk, UART_DEFAULT_REF_CLK);
164
+
165
s->char_tx_time = (NANOSECONDS_PER_SECOND / 9600) * 10;
166
}
114
}
167
115
168
+static int cadence_uart_pre_load(void *opaque)
169
+{
170
+ CadenceUARTState *s = opaque;
171
+
172
+ /* the frequency will be overriden if the refclk field is present */
173
+ clock_set_hz(s->refclk, UART_DEFAULT_REF_CLK);
174
+ return 0;
175
+}
176
+
177
static int cadence_uart_post_load(void *opaque, int version_id)
178
{
179
CadenceUARTState *s = opaque;
180
@@ -XXX,XX +XXX,XX @@ static int cadence_uart_post_load(void *opaque, int version_id)
181
182
static const VMStateDescription vmstate_cadence_uart = {
183
.name = "cadence_uart",
184
- .version_id = 2,
185
+ .version_id = 3,
186
.minimum_version_id = 2,
187
+ .pre_load = cadence_uart_pre_load,
188
.post_load = cadence_uart_post_load,
189
.fields = (VMStateField[]) {
190
VMSTATE_UINT32_ARRAY(r, CadenceUARTState, CADENCE_UART_R_MAX),
191
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_cadence_uart = {
192
VMSTATE_UINT32(tx_count, CadenceUARTState),
193
VMSTATE_UINT32(rx_wpos, CadenceUARTState),
194
VMSTATE_TIMER_PTR(fifo_trigger_handle, CadenceUARTState),
195
+ VMSTATE_CLOCK_V(refclk, CadenceUARTState, 3),
196
VMSTATE_END_OF_LIST()
197
- }
198
+ },
199
};
200
201
static Property cadence_uart_properties[] = {
202
@@ -XXX,XX +XXX,XX @@ static Property cadence_uart_properties[] = {
203
static void cadence_uart_class_init(ObjectClass *klass, void *data)
204
{
205
DeviceClass *dc = DEVICE_CLASS(klass);
206
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
207
208
dc->realize = cadence_uart_realize;
209
dc->vmsd = &vmstate_cadence_uart;
210
- dc->reset = cadence_uart_reset;
211
+ rc->phases.enter = cadence_uart_reset_init;
212
+ rc->phases.hold = cadence_uart_reset_hold;
213
device_class_set_props(dc, cadence_uart_properties);
214
}
215
216
diff --git a/hw/char/trace-events b/hw/char/trace-events
217
index XXXXXXX..XXXXXXX 100644
218
--- a/hw/char/trace-events
219
+++ b/hw/char/trace-events
220
@@ -XXX,XX +XXX,XX @@ exynos_uart_wo_read(uint32_t channel, const char *name, uint32_t reg) "UART%d: T
221
exynos_uart_rxsize(uint32_t channel, uint32_t size) "UART%d: Rx FIFO size: %d"
222
exynos_uart_channel_error(uint32_t channel) "Wrong UART channel number: %d"
223
exynos_uart_rx_timeout(uint32_t channel, uint32_t stat, uint32_t intsp) "UART%d: Rx timeout stat=0x%x intsp=0x%x"
224
+
225
+# hw/char/cadence_uart.c
226
+cadence_uart_baudrate(unsigned baudrate) "baudrate %u"
227
--
116
--
228
2.20.1
117
2.34.1
229
118
230
119
diff view generated by jsdifflib
1
From: Jerome Forissier <jerome@forissier.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The /secure-chosen node is currently used only by create_uart(), but
3
IEC binary prefixes ease code review: the unit is explicit.
4
this will change. Therefore move the creation of this node to
5
create_fdt().
6
4
7
Signed-off-by: Jerome Forissier <jerome@forissier.org>
5
Add the FLASH_SECTOR_SIZE definition.
8
Message-id: 20200420121807.8204-2-jerome@forissier.org
6
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109115316.2235-12-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/arm/virt.c | 5 ++++-
12
hw/arm/z2.c | 6 ++++--
13
1 file changed, 4 insertions(+), 1 deletion(-)
13
1 file changed, 4 insertions(+), 2 deletions(-)
14
14
15
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/virt.c
17
--- a/hw/arm/z2.c
18
+++ b/hw/arm/virt.c
18
+++ b/hw/arm/z2.c
19
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
19
@@ -XXX,XX +XXX,XX @@
20
/* /chosen must exist for load_dtb to fill in necessary properties later */
20
*/
21
qemu_fdt_add_subnode(fdt, "/chosen");
21
22
22
#include "qemu/osdep.h"
23
+ if (vms->secure) {
23
+#include "qemu/units.h"
24
+ qemu_fdt_add_subnode(fdt, "/secure-chosen");
24
#include "hw/arm/pxa.h"
25
+ }
25
#include "hw/arm/boot.h"
26
#include "hw/i2c/i2c.h"
27
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aer915_info = {
28
.class_init = aer915_class_init,
29
};
30
31
+#define FLASH_SECTOR_SIZE (64 * KiB)
26
+
32
+
27
/* Clock node, for the benefit of the UART. The kernel device tree
33
static void z2_init(MachineState *machine)
28
* binding documentation claims the PL011 node clock properties are
34
{
29
* optional but in practice if you omit them the kernel refuses to
35
- uint32_t sector_len = 0x10000;
30
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, int uart,
36
PXA2xxState *mpu;
31
qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
37
DriveInfo *dinfo;
32
qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
38
void *z2_lcd;
33
39
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
34
- qemu_fdt_add_subnode(vms->fdt, "/secure-chosen");
40
dinfo = drive_get(IF_PFLASH, 0, 0);
35
qemu_fdt_setprop_string(vms->fdt, "/secure-chosen", "stdout-path",
41
if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
36
nodename);
42
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
43
- sector_len, 4, 0, 0, 0, 0, 0)) {
44
+ FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
45
error_report("Error registering flash memory");
46
exit(1);
37
}
47
}
38
--
48
--
39
2.20.1
49
2.34.1
40
50
41
51
diff view generated by jsdifflib
1
From: Jerome Forissier <jerome@forissier.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Generate random seeds to be used by the non-secure and/or secure OSes
3
Upon introduction in commit b8433303fb ("Set proper device-width
4
for ASLR. The seeds are 64-bit random values exported via the DT
4
for vexpress flash"), ve_pflash_cfi01_register() was calling
5
properties /chosen/kaslr-seed [1] and /secure-chosen/kaslr-seed, the
5
qdev_init_nofail() which can not fail. This call was later
6
latter being used by OP-TEE [2].
6
converted with a script to use &error_fatal, still unable to
7
fail. Remove the unreachable code.
7
8
8
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e5bc0c37c97e1
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
[2] https://github.com/OP-TEE/optee_os/commit/ef262691fe0e
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
11
Message-id: 20230109115316.2235-13-philmd@linaro.org
11
Signed-off-by: Jerome Forissier <jerome@forissier.org>
12
Message-id: 20200420121807.8204-3-jerome@forissier.org
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
hw/arm/virt.c | 15 +++++++++++++++
14
hw/arm/vexpress.c | 10 +---------
17
1 file changed, 15 insertions(+)
15
1 file changed, 1 insertion(+), 9 deletions(-)
18
16
19
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
17
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/virt.c
19
--- a/hw/arm/vexpress.c
22
+++ b/hw/arm/virt.c
20
+++ b/hw/arm/vexpress.c
23
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
24
#include "hw/acpi/generic_event_device.h"
22
dinfo = drive_get(IF_PFLASH, 0, 0);
25
#include "hw/virtio/virtio-iommu.h"
23
pflash0 = ve_pflash_cfi01_register(map[VE_NORFLASH0], "vexpress.flash0",
26
#include "hw/char/pl011.h"
24
dinfo);
27
+#include "qemu/guest-random.h"
25
- if (!pflash0) {
28
26
- error_report("vexpress: error registering flash 0");
29
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
27
- exit(1);
30
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
28
- }
31
@@ -XXX,XX +XXX,XX @@ static bool cpu_type_valid(const char *cpu)
29
32
return false;
30
if (map[VE_NORFLASHALIAS] != -1) {
33
}
31
/* Map flash 0 as an alias into low memory */
34
32
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
35
+static void create_kaslr_seed(VirtMachineState *vms, const char *node)
36
+{
37
+ Error *err = NULL;
38
+ uint64_t seed;
39
+
40
+ if (qemu_guest_getrandom(&seed, sizeof(seed), &err)) {
41
+ error_free(err);
42
+ return;
43
+ }
44
+ qemu_fdt_setprop_u64(vms->fdt, node, "kaslr-seed", seed);
45
+}
46
+
47
static void create_fdt(VirtMachineState *vms)
48
{
49
MachineState *ms = MACHINE(vms);
50
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
51
52
/* /chosen must exist for load_dtb to fill in necessary properties later */
53
qemu_fdt_add_subnode(fdt, "/chosen");
54
+ create_kaslr_seed(vms, "/chosen");
55
56
if (vms->secure) {
57
qemu_fdt_add_subnode(fdt, "/secure-chosen");
58
+ create_kaslr_seed(vms, "/secure-chosen");
59
}
33
}
60
34
61
/* Clock node, for the benefit of the UART. The kernel device tree
35
dinfo = drive_get(IF_PFLASH, 0, 1);
36
- if (!ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1",
37
- dinfo)) {
38
- error_report("vexpress: error registering flash 1");
39
- exit(1);
40
- }
41
+ ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1", dinfo);
42
43
sram_size = 0x2000000;
44
memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
62
--
45
--
63
2.20.1
46
2.34.1
64
47
65
48
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Fix descriptor loading from registers wrt host endianness.
3
Since its QOM'ification in commit 368a354f02 ("pflash_cfi0x:
4
QOMified") the pflash_cfi01_register() function does not fail.
4
5
5
Reported-by: Peter Maydell <peter.maydell@linaro.org>
6
This call was later converted with a script to use &error_fatal,
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
still unable to fail. Remove the unreachable code.
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
8
Message-id: 20200404122718.25111-3-edgar.iglesias@gmail.com
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20230109115316.2235-14-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
hw/dma/xlnx-zdma.c | 14 ++++++++++----
14
hw/arm/gumstix.c | 18 ++++++------------
12
1 file changed, 10 insertions(+), 4 deletions(-)
15
hw/arm/mainstone.c | 13 +++++--------
16
hw/arm/omap_sx1.c | 22 ++++++++--------------
17
hw/arm/versatilepb.c | 6 ++----
18
hw/arm/z2.c | 9 +++------
19
5 files changed, 24 insertions(+), 44 deletions(-)
13
20
14
diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c
21
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/dma/xlnx-zdma.c
23
--- a/hw/arm/gumstix.c
17
+++ b/hw/dma/xlnx-zdma.c
24
+++ b/hw/arm/gumstix.c
18
@@ -XXX,XX +XXX,XX @@ static void zdma_put_regaddr64(XlnxZDMA *s, unsigned int basereg, uint64_t addr)
25
@@ -XXX,XX +XXX,XX @@ static void connex_init(MachineState *machine)
19
s->regs[basereg + 1] = addr >> 32;
20
}
21
22
+static void zdma_load_descriptor_reg(XlnxZDMA *s, unsigned int reg,
23
+ XlnxZDMADescr *descr)
24
+{
25
+ descr->addr = zdma_get_regaddr64(s, reg);
26
+ descr->size = s->regs[reg + 2];
27
+ descr->attr = s->regs[reg + 3];
28
+}
29
+
30
static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr,
31
XlnxZDMADescr *descr)
32
{
33
@@ -XXX,XX +XXX,XX @@ static void zdma_load_src_descriptor(XlnxZDMA *s)
34
unsigned int ptype = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, POINT_TYPE);
35
36
if (ptype == PT_REG) {
37
- memcpy(&s->dsc_src, &s->regs[R_ZDMA_CH_SRC_DSCR_WORD0],
38
- sizeof(s->dsc_src));
39
+ zdma_load_descriptor_reg(s, R_ZDMA_CH_SRC_DSCR_WORD0, &s->dsc_src);
40
return;
41
}
26
}
42
27
43
@@ -XXX,XX +XXX,XX @@ static void zdma_load_dst_descriptor(XlnxZDMA *s)
28
/* Numonyx RC28F128J3F75 */
44
bool dst_type;
29
- if (!pflash_cfi01_register(0x00000000, "connext.rom", CONNEX_FLASH_SIZE,
45
30
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
46
if (ptype == PT_REG) {
31
- FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0)) {
47
- memcpy(&s->dsc_dst, &s->regs[R_ZDMA_CH_DST_DSCR_WORD0],
32
- error_report("Error registering flash memory");
48
- sizeof(s->dsc_dst));
33
- exit(1);
49
+ zdma_load_descriptor_reg(s, R_ZDMA_CH_DST_DSCR_WORD0, &s->dsc_dst);
34
- }
50
return;
35
+ pflash_cfi01_register(0x00000000, "connext.rom", CONNEX_FLASH_SIZE,
36
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
37
+ FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0);
38
39
/* Interrupt line of NIC is connected to GPIO line 36 */
40
smc91c111_init(&nd_table[0], 0x04000300,
41
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
51
}
42
}
52
43
44
/* Micron RC28F256P30TFA */
45
- if (!pflash_cfi01_register(0x00000000, "verdex.rom", VERDEX_FLASH_SIZE,
46
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
47
- FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0)) {
48
- error_report("Error registering flash memory");
49
- exit(1);
50
- }
51
+ pflash_cfi01_register(0x00000000, "verdex.rom", VERDEX_FLASH_SIZE,
52
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
53
+ FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0);
54
55
/* Interrupt line of NIC is connected to GPIO line 99 */
56
smc91c111_init(&nd_table[0], 0x04000300,
57
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/mainstone.c
60
+++ b/hw/arm/mainstone.c
61
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MachineState *machine,
62
/* There are two 32MiB flash devices on the board */
63
for (i = 0; i < 2; i ++) {
64
dinfo = drive_get(IF_PFLASH, 0, i);
65
- if (!pflash_cfi01_register(mainstone_flash_base[i],
66
- i ? "mainstone.flash1" : "mainstone.flash0",
67
- MAINSTONE_FLASH_SIZE,
68
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
69
- FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
70
- error_report("Error registering flash memory");
71
- exit(1);
72
- }
73
+ pflash_cfi01_register(mainstone_flash_base[i],
74
+ i ? "mainstone.flash1" : "mainstone.flash0",
75
+ MAINSTONE_FLASH_SIZE,
76
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
77
+ FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0);
78
}
79
80
mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,
81
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/arm/omap_sx1.c
84
+++ b/hw/arm/omap_sx1.c
85
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
86
87
fl_idx = 0;
88
if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
89
- if (!pflash_cfi01_register(OMAP_CS0_BASE,
90
- "omap_sx1.flash0-1", flash_size,
91
- blk_by_legacy_dinfo(dinfo),
92
- SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
93
- fprintf(stderr, "qemu: Error registering flash memory %d.\n",
94
- fl_idx);
95
- }
96
+ pflash_cfi01_register(OMAP_CS0_BASE,
97
+ "omap_sx1.flash0-1", flash_size,
98
+ blk_by_legacy_dinfo(dinfo),
99
+ SECTOR_SIZE, 4, 0, 0, 0, 0, 0);
100
fl_idx++;
101
}
102
103
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
104
memory_region_add_subregion(address_space,
105
OMAP_CS1_BASE + FLASH1_SIZE, &cs[1]);
106
107
- if (!pflash_cfi01_register(OMAP_CS1_BASE,
108
- "omap_sx1.flash1-1", FLASH1_SIZE,
109
- blk_by_legacy_dinfo(dinfo),
110
- SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
111
- fprintf(stderr, "qemu: Error registering flash memory %d.\n",
112
- fl_idx);
113
- }
114
+ pflash_cfi01_register(OMAP_CS1_BASE,
115
+ "omap_sx1.flash1-1", FLASH1_SIZE,
116
+ blk_by_legacy_dinfo(dinfo),
117
+ SECTOR_SIZE, 4, 0, 0, 0, 0, 0);
118
fl_idx++;
119
} else {
120
memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
121
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/hw/arm/versatilepb.c
124
+++ b/hw/arm/versatilepb.c
125
@@ -XXX,XX +XXX,XX @@ static void versatile_init(MachineState *machine, int board_id)
126
/* 0x34000000 NOR Flash */
127
128
dinfo = drive_get(IF_PFLASH, 0, 0);
129
- if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, "versatile.flash",
130
+ pflash_cfi01_register(VERSATILE_FLASH_ADDR, "versatile.flash",
131
VERSATILE_FLASH_SIZE,
132
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
133
VERSATILE_FLASH_SECT_SIZE,
134
- 4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {
135
- fprintf(stderr, "qemu: Error registering flash memory.\n");
136
- }
137
+ 4, 0x0089, 0x0018, 0x0000, 0x0, 0);
138
139
versatile_binfo.ram_size = machine->ram_size;
140
versatile_binfo.board_id = board_id;
141
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/hw/arm/z2.c
144
+++ b/hw/arm/z2.c
145
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
146
mpu = pxa270_init(z2_binfo.ram_size, machine->cpu_type);
147
148
dinfo = drive_get(IF_PFLASH, 0, 0);
149
- if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
150
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
151
- FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
152
- error_report("Error registering flash memory");
153
- exit(1);
154
- }
155
+ pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
156
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
157
+ FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0);
158
159
/* setup keypad */
160
pxa27x_register_keypad(mpu->kp, map, 0x100);
53
--
161
--
54
2.20.1
162
2.34.1
55
163
56
164
diff view generated by jsdifflib
1
From: Ramon Fried <rfried.dev@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The RX ring descriptors control field is used for setting
3
To avoid forward-declaring PXA2xxI2CState, declare
4
SOF and EOF (start of frame and end of frame).
4
PXA2XX_I2C before its use in pxa2xx_i2c_init() prototype.
5
The SOF and EOF weren't cleared from the previous descriptors,
6
causing inconsistencies in ring buffer.
7
Fix that by clearing the control field of every descriptors we're
8
processing.
9
5
10
Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Message-id: 20230109140306.23161-2-philmd@linaro.org
13
Message-id: 20200418085145.489726-1-rfried.dev@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
hw/net/cadence_gem.c | 7 +++++++
11
include/hw/arm/pxa.h | 6 +++---
17
1 file changed, 7 insertions(+)
12
1 file changed, 3 insertions(+), 3 deletions(-)
18
13
19
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
14
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/cadence_gem.c
16
--- a/include/hw/arm/pxa.h
22
+++ b/hw/net/cadence_gem.c
17
+++ b/include/hw/arm/pxa.h
23
@@ -XXX,XX +XXX,XX @@ static inline void rx_desc_set_sof(uint32_t *desc)
18
@@ -XXX,XX +XXX,XX @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp,
24
desc[1] |= DESC_1_RX_SOF;
19
const struct keymap *map, int size);
25
}
20
26
21
/* pxa2xx.c */
27
+static inline void rx_desc_clear_control(uint32_t *desc)
22
-typedef struct PXA2xxI2CState PXA2xxI2CState;
28
+{
23
+#define TYPE_PXA2XX_I2C "pxa2xx_i2c"
29
+ desc[1] = 0;
24
+OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxI2CState, PXA2XX_I2C)
30
+}
31
+
25
+
32
static inline void rx_desc_set_eof(uint32_t *desc)
26
PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
33
{
27
qemu_irq irq, uint32_t page_size);
34
desc[1] |= DESC_1_RX_EOF;
28
I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s);
35
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
29
36
rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
30
-#define TYPE_PXA2XX_I2C "pxa2xx_i2c"
37
bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
31
typedef struct PXA2xxI2SState PXA2xxI2SState;
38
32
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxI2CState, PXA2XX_I2C)
39
+ rx_desc_clear_control(s->rx_desc[q]);
33
40
+
34
#define TYPE_PXA2XX_FIR "pxa2xx-fir"
41
/* Update the descriptor. */
35
OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxFIrState, PXA2XX_FIR)
42
if (first_desc) {
43
rx_desc_set_sof(s->rx_desc[q]);
44
--
36
--
45
2.20.1
37
2.34.1
46
38
47
39
diff view generated by jsdifflib
1
From: Ramon Fried <rfried.dev@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Wraparound of TX descriptor cyclic buffer only updated
3
Add a local 'struct omap_gpif_s *' variable to improve readability.
4
the low 32 bits of the descriptor.
4
(This also eases next commit conversion).
5
Fix that by checking if we're working with 64bit descriptors.
6
5
7
Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200417171736.441607-1-rfried.dev@gmail.com
8
Message-id: 20230109140306.23161-3-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/net/cadence_gem.c | 9 ++++++++-
11
hw/gpio/omap_gpio.c | 3 ++-
13
1 file changed, 8 insertions(+), 1 deletion(-)
12
1 file changed, 2 insertions(+), 1 deletion(-)
14
13
15
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
14
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/net/cadence_gem.c
16
--- a/hw/gpio/omap_gpio.c
18
+++ b/hw/net/cadence_gem.c
17
+++ b/hw/gpio/omap_gpio.c
19
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
18
@@ -XXX,XX +XXX,XX @@ struct omap_gpif_s {
20
/* read next descriptor */
19
/* General-Purpose I/O of OMAP1 */
21
if (tx_desc_get_wrap(desc)) {
20
static void omap_gpio_set(void *opaque, int line, int level)
22
tx_desc_set_last(desc);
21
{
23
- packet_desc_addr = s->regs[GEM_TXQBASE];
22
- struct omap_gpio_s *s = &((struct omap_gpif_s *) opaque)->omap1;
24
+
23
+ struct omap_gpif_s *p = opaque;
25
+ if (s->regs[GEM_DMACFG] & GEM_DMACFG_ADDR_64B) {
24
+ struct omap_gpio_s *s = &p->omap1;
26
+ packet_desc_addr = s->regs[GEM_TBQPH];
25
uint16_t prev = s->inputs;
27
+ packet_desc_addr <<= 32;
26
28
+ } else {
27
if (level)
29
+ packet_desc_addr = 0;
30
+ }
31
+ packet_desc_addr |= s->regs[GEM_TXQBASE];
32
} else {
33
packet_desc_addr += 4 * gem_get_desc_len(s, false);
34
}
35
--
28
--
36
2.20.1
29
2.34.1
37
30
38
31
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add some clocks to zynq_slcr
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
+ the main input clock (ps_clk)
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
+ the reference clock outputs for each uart (uart0 & 1)
5
Message-id: 20230109140306.23161-4-philmd@linaro.org
6
7
This commit also transitional the slcr to multi-phase reset as it is
8
required to initialize the clocks correctly.
9
10
The clock frequencies are computed using the internal pll & uart configuration
11
registers and the input ps_clk frequency.
12
13
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
14
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
15
Acked-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20200406135251.157596-7-damien.hedde@greensocs.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
7
---
19
hw/misc/zynq_slcr.c | 172 ++++++++++++++++++++++++++++++++++++++++++--
8
hw/arm/omap1.c | 115 ++++++++++++++++++--------------------
20
1 file changed, 168 insertions(+), 4 deletions(-)
9
hw/arm/omap2.c | 40 ++++++-------
10
hw/arm/omap_sx1.c | 2 +-
11
hw/arm/palm.c | 2 +-
12
hw/char/omap_uart.c | 7 +--
13
hw/display/omap_dss.c | 15 +++--
14
hw/display/omap_lcdc.c | 9 ++-
15
hw/dma/omap_dma.c | 15 +++--
16
hw/gpio/omap_gpio.c | 15 +++--
17
hw/intc/omap_intc.c | 12 ++--
18
hw/misc/omap_gpmc.c | 12 ++--
19
hw/misc/omap_l4.c | 7 +--
20
hw/misc/omap_sdrc.c | 7 +--
21
hw/misc/omap_tap.c | 5 +-
22
hw/sd/omap_mmc.c | 9 ++-
23
hw/ssi/omap_spi.c | 7 +--
24
hw/timer/omap_gptimer.c | 22 ++++----
25
hw/timer/omap_synctimer.c | 4 +-
26
18 files changed, 142 insertions(+), 163 deletions(-)
21
27
22
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
28
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
23
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/misc/zynq_slcr.c
30
--- a/hw/arm/omap1.c
25
+++ b/hw/misc/zynq_slcr.c
31
+++ b/hw/arm/omap1.c
26
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ static void omap_timer_fire(void *opaque)
27
#include "qemu/log.h"
33
28
#include "qemu/module.h"
34
static void omap_timer_tick(void *opaque)
29
#include "hw/registerfields.h"
35
{
30
+#include "hw/qdev-clock.h"
36
- struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
31
37
+ struct omap_mpu_timer_s *timer = opaque;
32
#ifndef ZYNQ_SLCR_ERR_DEBUG
38
33
#define ZYNQ_SLCR_ERR_DEBUG 0
39
omap_timer_sync(timer);
34
@@ -XXX,XX +XXX,XX @@ REG32(LOCKSTA, 0x00c)
40
omap_timer_fire(timer);
35
REG32(ARM_PLL_CTRL, 0x100)
41
@@ -XXX,XX +XXX,XX @@ static void omap_timer_tick(void *opaque)
36
REG32(DDR_PLL_CTRL, 0x104)
42
37
REG32(IO_PLL_CTRL, 0x108)
43
static void omap_timer_clk_update(void *opaque, int line, int on)
38
+/* fields for [ARM|DDR|IO]_PLL_CTRL registers */
44
{
39
+ FIELD(xxx_PLL_CTRL, PLL_RESET, 0, 1)
45
- struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
40
+ FIELD(xxx_PLL_CTRL, PLL_PWRDWN, 1, 1)
46
+ struct omap_mpu_timer_s *timer = opaque;
41
+ FIELD(xxx_PLL_CTRL, PLL_BYPASS_QUAL, 3, 1)
47
42
+ FIELD(xxx_PLL_CTRL, PLL_BYPASS_FORCE, 4, 1)
48
omap_timer_sync(timer);
43
+ FIELD(xxx_PLL_CTRL, PLL_FPDIV, 12, 7)
49
timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
44
REG32(PLL_STATUS, 0x10c)
50
@@ -XXX,XX +XXX,XX @@ static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
45
REG32(ARM_PLL_CFG, 0x110)
51
static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
46
REG32(DDR_PLL_CFG, 0x114)
52
unsigned size)
47
@@ -XXX,XX +XXX,XX @@ REG32(SMC_CLK_CTRL, 0x148)
53
{
48
REG32(LQSPI_CLK_CTRL, 0x14c)
54
- struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
49
REG32(SDIO_CLK_CTRL, 0x150)
55
+ struct omap_mpu_timer_s *s = opaque;
50
REG32(UART_CLK_CTRL, 0x154)
56
51
+ FIELD(UART_CLK_CTRL, CLKACT0, 0, 1)
57
if (size != 4) {
52
+ FIELD(UART_CLK_CTRL, CLKACT1, 1, 1)
58
return omap_badwidth_read32(opaque, addr);
53
+ FIELD(UART_CLK_CTRL, SRCSEL, 4, 2)
59
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
54
+ FIELD(UART_CLK_CTRL, DIVISOR, 8, 6)
60
static void omap_mpu_timer_write(void *opaque, hwaddr addr,
55
REG32(SPI_CLK_CTRL, 0x158)
61
uint64_t value, unsigned size)
56
REG32(CAN_CLK_CTRL, 0x15c)
62
{
57
REG32(CAN_MIOCLK_CTRL, 0x160)
63
- struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
58
@@ -XXX,XX +XXX,XX @@ typedef struct ZynqSLCRState {
64
+ struct omap_mpu_timer_s *s = opaque;
59
MemoryRegion iomem;
65
60
66
if (size != 4) {
61
uint32_t regs[ZYNQ_SLCR_NUM_REGS];
67
omap_badwidth_write32(opaque, addr, value);
62
+
68
@@ -XXX,XX +XXX,XX @@ struct omap_watchdog_timer_s {
63
+ Clock *ps_clk;
69
static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
64
+ Clock *uart0_ref_clk;
70
unsigned size)
65
+ Clock *uart1_ref_clk;
71
{
66
} ZynqSLCRState;
72
- struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
67
73
+ struct omap_watchdog_timer_s *s = opaque;
68
-static void zynq_slcr_reset(DeviceState *d)
74
69
+/*
75
if (size != 2) {
70
+ * return the output frequency of ARM/DDR/IO pll
76
return omap_badwidth_read16(opaque, addr);
71
+ * using input frequency and PLL_CTRL register
77
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
72
+ */
78
static void omap_wd_timer_write(void *opaque, hwaddr addr,
73
+static uint64_t zynq_slcr_compute_pll(uint64_t input, uint32_t ctrl_reg)
79
uint64_t value, unsigned size)
74
{
80
{
75
- ZynqSLCRState *s = ZYNQ_SLCR(d);
81
- struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
76
+ uint32_t mult = ((ctrl_reg & R_xxx_PLL_CTRL_PLL_FPDIV_MASK) >>
82
+ struct omap_watchdog_timer_s *s = opaque;
77
+ R_xxx_PLL_CTRL_PLL_FPDIV_SHIFT);
83
78
+
84
if (size != 2) {
79
+ /* first, check if pll is bypassed */
85
omap_badwidth_write16(opaque, addr, value);
80
+ if (ctrl_reg & R_xxx_PLL_CTRL_PLL_BYPASS_FORCE_MASK) {
86
@@ -XXX,XX +XXX,XX @@ struct omap_32khz_timer_s {
81
+ return input;
87
static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
82
+ }
88
unsigned size)
83
+
89
{
84
+ /* is pll disabled ? */
90
- struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
85
+ if (ctrl_reg & (R_xxx_PLL_CTRL_PLL_RESET_MASK |
91
+ struct omap_32khz_timer_s *s = opaque;
86
+ R_xxx_PLL_CTRL_PLL_PWRDWN_MASK)) {
92
int offset = addr & OMAP_MPUI_REG_MASK;
87
+ return 0;
93
88
+ }
94
if (size != 4) {
89
+
95
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
90
+ /* frequency multiplier -> period division */
96
static void omap_os_timer_write(void *opaque, hwaddr addr,
91
+ return input / mult;
97
uint64_t value, unsigned size)
92
+}
98
{
93
+
99
- struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
94
+/*
100
+ struct omap_32khz_timer_s *s = opaque;
95
+ * return the output period of a clock given:
101
int offset = addr & OMAP_MPUI_REG_MASK;
96
+ * + the periods in an array corresponding to input mux selector
102
97
+ * + the register xxx_CLK_CTRL value
103
if (size != 4) {
98
+ * + enable bit index in ctrl register
104
@@ -XXX,XX +XXX,XX @@ static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
99
+ *
105
static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr,
100
+ * This function makes the assumption that the ctrl_reg value is organized as
106
unsigned size)
101
+ * follows:
107
{
102
+ * + bits[13:8] clock frequency divisor
108
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
103
+ * + bits[5:4] clock mux selector (index in array)
109
+ struct omap_mpu_state_s *s = opaque;
104
+ * + bits[index] clock enable
110
uint16_t ret;
105
+ */
111
106
+static uint64_t zynq_slcr_compute_clock(const uint64_t periods[],
112
if (size != 2) {
107
+ uint32_t ctrl_reg,
113
@@ -XXX,XX +XXX,XX @@ static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
108
+ unsigned index)
114
static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
109
+{
115
uint64_t value, unsigned size)
110
+ uint32_t srcsel = extract32(ctrl_reg, 4, 2); /* bits [5:4] */
116
{
111
+ uint32_t divisor = extract32(ctrl_reg, 8, 6); /* bits [13:8] */
117
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
112
+
118
+ struct omap_mpu_state_s *s = opaque;
113
+ /* first, check if clock is disabled */
119
int64_t now, ticks;
114
+ if (((ctrl_reg >> index) & 1u) == 0) {
120
int div, mult;
115
+ return 0;
121
static const int bypass_div[4] = { 1, 2, 4, 4 };
116
+ }
122
@@ -XXX,XX +XXX,XX @@ static void omap_ulpd_pm_init(MemoryRegion *system_memory,
117
+
123
static uint64_t omap_pin_cfg_read(void *opaque, hwaddr addr,
118
+ /*
124
unsigned size)
119
+ * according to the Zynq technical ref. manual UG585 v1.12.2 in
125
{
120
+ * Clocks chapter, section 25.10.1 page 705:
126
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
121
+ * "The 6-bit divider provides a divide range of 1 to 63"
127
+ struct omap_mpu_state_s *s = opaque;
122
+ * We follow here what is implemented in linux kernel and consider
128
123
+ * the 0 value as a bypass (no division).
129
if (size != 4) {
124
+ */
130
return omap_badwidth_read32(opaque, addr);
125
+ /* frequency divisor -> period multiplication */
131
@@ -XXX,XX +XXX,XX @@ static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
126
+ return periods[srcsel] * (divisor ? divisor : 1u);
132
static void omap_pin_cfg_write(void *opaque, hwaddr addr,
127
+}
133
uint64_t value, unsigned size)
128
+
134
{
129
+/*
135
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
130
+ * macro helper around zynq_slcr_compute_clock to avoid repeating
136
+ struct omap_mpu_state_s *s = opaque;
131
+ * the register name.
137
uint32_t diff;
132
+ */
138
133
+#define ZYNQ_COMPUTE_CLK(state, plls, reg, enable_field) \
139
if (size != 4) {
134
+ zynq_slcr_compute_clock((plls), (state)->regs[reg], \
140
@@ -XXX,XX +XXX,XX @@ static void omap_pin_cfg_init(MemoryRegion *system_memory,
135
+ reg ## _ ## enable_field ## _SHIFT)
141
static uint64_t omap_id_read(void *opaque, hwaddr addr,
136
+
142
unsigned size)
137
+/**
143
{
138
+ * Compute and set the ouputs clocks periods.
144
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
139
+ * But do not propagate them further. Connected clocks
145
+ struct omap_mpu_state_s *s = opaque;
140
+ * will not receive any updates (See zynq_slcr_compute_clocks())
146
141
+ */
147
if (size != 4) {
142
+static void zynq_slcr_compute_clocks(ZynqSLCRState *s)
148
return omap_badwidth_read32(opaque, addr);
143
+{
149
@@ -XXX,XX +XXX,XX @@ static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
144
+ uint64_t ps_clk = clock_get(s->ps_clk);
150
static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
145
+
151
unsigned size)
146
+ /* consider outputs clocks are disabled while in reset */
152
{
147
+ if (device_is_in_reset(DEVICE(s))) {
153
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
148
+ ps_clk = 0;
154
+ struct omap_mpu_state_s *s = opaque;
149
+ }
155
150
+
156
if (size != 4) {
151
+ uint64_t io_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_IO_PLL_CTRL]);
157
return omap_badwidth_read32(opaque, addr);
152
+ uint64_t arm_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_ARM_PLL_CTRL]);
158
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
153
+ uint64_t ddr_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_DDR_PLL_CTRL]);
159
static void omap_mpui_write(void *opaque, hwaddr addr,
154
+
160
uint64_t value, unsigned size)
155
+ uint64_t uart_mux[4] = {io_pll, io_pll, arm_pll, ddr_pll};
161
{
156
+
162
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
157
+ /* compute uartX reference clocks */
163
+ struct omap_mpu_state_s *s = opaque;
158
+ clock_set(s->uart0_ref_clk,
164
159
+ ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT0));
165
if (size != 4) {
160
+ clock_set(s->uart1_ref_clk,
166
omap_badwidth_write32(opaque, addr, value);
161
+ ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT1));
167
@@ -XXX,XX +XXX,XX @@ struct omap_tipb_bridge_s {
162
+}
168
static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
163
+
169
unsigned size)
164
+/**
170
{
165
+ * Propagate the outputs clocks.
171
- struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
166
+ * zynq_slcr_compute_clocks() should have been called before
172
+ struct omap_tipb_bridge_s *s = opaque;
167
+ * to configure them.
173
168
+ */
174
if (size < 2) {
169
+static void zynq_slcr_propagate_clocks(ZynqSLCRState *s)
175
return omap_badwidth_read16(opaque, addr);
170
+{
176
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
171
+ clock_propagate(s->uart0_ref_clk);
177
static void omap_tipb_bridge_write(void *opaque, hwaddr addr,
172
+ clock_propagate(s->uart1_ref_clk);
178
uint64_t value, unsigned size)
173
+}
179
{
174
+
180
- struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
175
+static void zynq_slcr_ps_clk_callback(void *opaque)
181
+ struct omap_tipb_bridge_s *s = opaque;
176
+{
182
177
+ ZynqSLCRState *s = (ZynqSLCRState *) opaque;
183
if (size < 2) {
178
+ zynq_slcr_compute_clocks(s);
184
omap_badwidth_write16(opaque, addr, value);
179
+ zynq_slcr_propagate_clocks(s);
185
@@ -XXX,XX +XXX,XX @@ static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
180
+}
186
static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
181
+
187
unsigned size)
182
+static void zynq_slcr_reset_init(Object *obj, ResetType type)
188
{
183
+{
189
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
184
+ ZynqSLCRState *s = ZYNQ_SLCR(obj);
190
+ struct omap_mpu_state_s *s = opaque;
185
int i;
191
uint32_t ret;
186
192
187
DB_PRINT("RESET\n");
193
if (size != 4) {
188
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_reset(DeviceState *d)
194
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
189
s->regs[R_DDRIOB + 12] = 0x00000021;
195
static void omap_tcmi_write(void *opaque, hwaddr addr,
190
}
196
uint64_t value, unsigned size)
191
197
{
192
+static void zynq_slcr_reset_hold(Object *obj)
198
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
193
+{
199
+ struct omap_mpu_state_s *s = opaque;
194
+ ZynqSLCRState *s = ZYNQ_SLCR(obj);
200
195
+
201
if (size != 4) {
196
+ /* will disable all output clocks */
202
omap_badwidth_write32(opaque, addr, value);
197
+ zynq_slcr_compute_clocks(s);
203
@@ -XXX,XX +XXX,XX @@ struct dpll_ctl_s {
198
+ zynq_slcr_propagate_clocks(s);
204
static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
199
+}
205
unsigned size)
200
+
206
{
201
+static void zynq_slcr_reset_exit(Object *obj)
207
- struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
202
+{
208
+ struct dpll_ctl_s *s = opaque;
203
+ ZynqSLCRState *s = ZYNQ_SLCR(obj);
209
204
+
210
if (size != 2) {
205
+ /* will compute output clocks according to ps_clk and registers */
211
return omap_badwidth_read16(opaque, addr);
206
+ zynq_slcr_compute_clocks(s);
212
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
207
+ zynq_slcr_propagate_clocks(s);
213
static void omap_dpll_write(void *opaque, hwaddr addr,
208
+}
214
uint64_t value, unsigned size)
209
215
{
210
static bool zynq_slcr_check_offset(hwaddr offset, bool rnw)
216
- struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
211
{
217
+ struct dpll_ctl_s *s = opaque;
212
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
218
uint16_t diff;
213
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
219
static const int bypass_div[4] = { 1, 2, 4, 4 };
214
}
220
int div, mult;
215
break;
221
@@ -XXX,XX +XXX,XX @@ static struct dpll_ctl_s *omap_dpll_init(MemoryRegion *memory,
216
+ case R_IO_PLL_CTRL:
222
static uint64_t omap_clkm_read(void *opaque, hwaddr addr,
217
+ case R_ARM_PLL_CTRL:
223
unsigned size)
218
+ case R_DDR_PLL_CTRL:
224
{
219
+ case R_UART_CLK_CTRL:
225
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
220
+ zynq_slcr_compute_clocks(s);
226
+ struct omap_mpu_state_s *s = opaque;
221
+ zynq_slcr_propagate_clocks(s);
227
222
+ break;
228
if (size != 2) {
229
return omap_badwidth_read16(opaque, addr);
230
@@ -XXX,XX +XXX,XX @@ static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
231
static void omap_clkm_write(void *opaque, hwaddr addr,
232
uint64_t value, unsigned size)
233
{
234
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
235
+ struct omap_mpu_state_s *s = opaque;
236
uint16_t diff;
237
omap_clk clk;
238
static const char *clkschemename[8] = {
239
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_clkm_ops = {
240
static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
241
unsigned size)
242
{
243
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
244
+ struct omap_mpu_state_s *s = opaque;
245
CPUState *cpu = CPU(s->cpu);
246
247
if (size != 2) {
248
@@ -XXX,XX +XXX,XX @@ static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
249
static void omap_clkdsp_write(void *opaque, hwaddr addr,
250
uint64_t value, unsigned size)
251
{
252
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
253
+ struct omap_mpu_state_s *s = opaque;
254
uint16_t diff;
255
256
if (size != 2) {
257
@@ -XXX,XX +XXX,XX @@ struct omap_mpuio_s {
258
259
static void omap_mpuio_set(void *opaque, int line, int level)
260
{
261
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
262
+ struct omap_mpuio_s *s = opaque;
263
uint16_t prev = s->inputs;
264
265
if (level)
266
@@ -XXX,XX +XXX,XX @@ static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
267
static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
268
unsigned size)
269
{
270
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
271
+ struct omap_mpuio_s *s = opaque;
272
int offset = addr & OMAP_MPUI_REG_MASK;
273
uint16_t ret;
274
275
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
276
static void omap_mpuio_write(void *opaque, hwaddr addr,
277
uint64_t value, unsigned size)
278
{
279
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
280
+ struct omap_mpuio_s *s = opaque;
281
int offset = addr & OMAP_MPUI_REG_MASK;
282
uint16_t diff;
283
int ln;
284
@@ -XXX,XX +XXX,XX @@ static void omap_mpuio_reset(struct omap_mpuio_s *s)
285
286
static void omap_mpuio_onoff(void *opaque, int line, int on)
287
{
288
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
289
+ struct omap_mpuio_s *s = opaque;
290
291
s->clk = on;
292
if (on)
293
@@ -XXX,XX +XXX,XX @@ static void omap_uwire_transfer_start(struct omap_uwire_s *s)
223
}
294
}
224
}
295
}
225
296
226
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps slcr_ops = {
297
-static uint64_t omap_uwire_read(void *opaque, hwaddr addr,
298
- unsigned size)
299
+static uint64_t omap_uwire_read(void *opaque, hwaddr addr, unsigned size)
300
{
301
- struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
302
+ struct omap_uwire_s *s = opaque;
303
int offset = addr & OMAP_MPUI_REG_MASK;
304
305
if (size != 2) {
306
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_uwire_read(void *opaque, hwaddr addr,
307
static void omap_uwire_write(void *opaque, hwaddr addr,
308
uint64_t value, unsigned size)
309
{
310
- struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
311
+ struct omap_uwire_s *s = opaque;
312
int offset = addr & OMAP_MPUI_REG_MASK;
313
314
if (size != 2) {
315
@@ -XXX,XX +XXX,XX @@ static void omap_pwl_update(struct omap_pwl_s *s)
316
}
317
}
318
319
-static uint64_t omap_pwl_read(void *opaque, hwaddr addr,
320
- unsigned size)
321
+static uint64_t omap_pwl_read(void *opaque, hwaddr addr, unsigned size)
322
{
323
- struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
324
+ struct omap_pwl_s *s = opaque;
325
int offset = addr & OMAP_MPUI_REG_MASK;
326
327
if (size != 1) {
328
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_pwl_read(void *opaque, hwaddr addr,
329
static void omap_pwl_write(void *opaque, hwaddr addr,
330
uint64_t value, unsigned size)
331
{
332
- struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
333
+ struct omap_pwl_s *s = opaque;
334
int offset = addr & OMAP_MPUI_REG_MASK;
335
336
if (size != 1) {
337
@@ -XXX,XX +XXX,XX @@ static void omap_pwl_reset(struct omap_pwl_s *s)
338
339
static void omap_pwl_clk_update(void *opaque, int line, int on)
340
{
341
- struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
342
+ struct omap_pwl_s *s = opaque;
343
344
s->clk = on;
345
omap_pwl_update(s);
346
@@ -XXX,XX +XXX,XX @@ struct omap_pwt_s {
347
omap_clk clk;
348
};
349
350
-static uint64_t omap_pwt_read(void *opaque, hwaddr addr,
351
- unsigned size)
352
+static uint64_t omap_pwt_read(void *opaque, hwaddr addr, unsigned size)
353
{
354
- struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
355
+ struct omap_pwt_s *s = opaque;
356
int offset = addr & OMAP_MPUI_REG_MASK;
357
358
if (size != 1) {
359
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_pwt_read(void *opaque, hwaddr addr,
360
static void omap_pwt_write(void *opaque, hwaddr addr,
361
uint64_t value, unsigned size)
362
{
363
- struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
364
+ struct omap_pwt_s *s = opaque;
365
int offset = addr & OMAP_MPUI_REG_MASK;
366
367
if (size != 1) {
368
@@ -XXX,XX +XXX,XX @@ static void omap_rtc_alarm_update(struct omap_rtc_s *s)
369
printf("%s: conversion failed\n", __func__);
370
}
371
372
-static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
373
- unsigned size)
374
+static uint64_t omap_rtc_read(void *opaque, hwaddr addr, unsigned size)
375
{
376
- struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
377
+ struct omap_rtc_s *s = opaque;
378
int offset = addr & OMAP_MPUI_REG_MASK;
379
uint8_t i;
380
381
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
382
static void omap_rtc_write(void *opaque, hwaddr addr,
383
uint64_t value, unsigned size)
384
{
385
- struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
386
+ struct omap_rtc_s *s = opaque;
387
int offset = addr & OMAP_MPUI_REG_MASK;
388
struct tm new_tm;
389
time_t ti[2];
390
@@ -XXX,XX +XXX,XX @@ static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
391
392
static void omap_mcbsp_source_tick(void *opaque)
393
{
394
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
395
+ struct omap_mcbsp_s *s = opaque;
396
static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
397
398
if (!s->rx_rate)
399
@@ -XXX,XX +XXX,XX @@ static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
400
401
static void omap_mcbsp_sink_tick(void *opaque)
402
{
403
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
404
+ struct omap_mcbsp_s *s = opaque;
405
static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
406
407
if (!s->tx_rate)
408
@@ -XXX,XX +XXX,XX @@ static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
409
static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
410
unsigned size)
411
{
412
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
413
+ struct omap_mcbsp_s *s = opaque;
414
int offset = addr & OMAP_MPUI_REG_MASK;
415
uint16_t ret;
416
417
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
418
static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
419
uint32_t value)
420
{
421
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
422
+ struct omap_mcbsp_s *s = opaque;
423
int offset = addr & OMAP_MPUI_REG_MASK;
424
425
switch (offset) {
426
@@ -XXX,XX +XXX,XX @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
427
static void omap_mcbsp_writew(void *opaque, hwaddr addr,
428
uint32_t value)
429
{
430
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
431
+ struct omap_mcbsp_s *s = opaque;
432
int offset = addr & OMAP_MPUI_REG_MASK;
433
434
if (offset == 0x04) {                /* DXR */
435
@@ -XXX,XX +XXX,XX @@ static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
436
437
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
438
{
439
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
440
+ struct omap_mcbsp_s *s = opaque;
441
442
if (s->rx_rate) {
443
s->rx_req = s->codec->in.len;
444
@@ -XXX,XX +XXX,XX @@ static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
445
446
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
447
{
448
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
449
+ struct omap_mcbsp_s *s = opaque;
450
451
if (s->tx_rate) {
452
s->tx_req = s->codec->out.size;
453
@@ -XXX,XX +XXX,XX @@ static void omap_lpg_reset(struct omap_lpg_s *s)
454
omap_lpg_update(s);
455
}
456
457
-static uint64_t omap_lpg_read(void *opaque, hwaddr addr,
458
- unsigned size)
459
+static uint64_t omap_lpg_read(void *opaque, hwaddr addr, unsigned size)
460
{
461
- struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
462
+ struct omap_lpg_s *s = opaque;
463
int offset = addr & OMAP_MPUI_REG_MASK;
464
465
if (size != 1) {
466
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_lpg_read(void *opaque, hwaddr addr,
467
static void omap_lpg_write(void *opaque, hwaddr addr,
468
uint64_t value, unsigned size)
469
{
470
- struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
471
+ struct omap_lpg_s *s = opaque;
472
int offset = addr & OMAP_MPUI_REG_MASK;
473
474
if (size != 1) {
475
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_lpg_ops = {
476
477
static void omap_lpg_clk_update(void *opaque, int line, int on)
478
{
479
- struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
480
+ struct omap_lpg_s *s = opaque;
481
482
s->clk = on;
483
omap_lpg_update(s);
484
@@ -XXX,XX +XXX,XX @@ static void omap_setup_mpui_io(MemoryRegion *system_memory,
485
/* General chip reset */
486
static void omap1_mpu_reset(void *opaque)
487
{
488
- struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
489
+ struct omap_mpu_state_s *mpu = opaque;
490
491
omap_dma_reset(mpu->dma);
492
omap_mpu_timer_reset(mpu->timer[0]);
493
@@ -XXX,XX +XXX,XX @@ static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
494
495
void omap_mpu_wakeup(void *opaque, int irq, int req)
496
{
497
- struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
498
+ struct omap_mpu_state_s *mpu = opaque;
499
CPUState *cpu = CPU(mpu->cpu);
500
501
if (cpu->halted) {
502
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
503
index XXXXXXX..XXXXXXX 100644
504
--- a/hw/arm/omap2.c
505
+++ b/hw/arm/omap2.c
506
@@ -XXX,XX +XXX,XX @@ static inline void omap_eac_out_empty(struct omap_eac_s *s)
507
508
static void omap_eac_in_cb(void *opaque, int avail_b)
509
{
510
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
511
+ struct omap_eac_s *s = opaque;
512
513
s->codec.rxavail = avail_b >> 2;
514
omap_eac_in_refill(s);
515
@@ -XXX,XX +XXX,XX @@ static void omap_eac_in_cb(void *opaque, int avail_b)
516
517
static void omap_eac_out_cb(void *opaque, int free_b)
518
{
519
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
520
+ struct omap_eac_s *s = opaque;
521
522
s->codec.txavail = free_b >> 2;
523
if (s->codec.txlen)
524
@@ -XXX,XX +XXX,XX @@ static void omap_eac_reset(struct omap_eac_s *s)
525
omap_eac_interrupt_update(s);
526
}
527
528
-static uint64_t omap_eac_read(void *opaque, hwaddr addr,
529
- unsigned size)
530
+static uint64_t omap_eac_read(void *opaque, hwaddr addr, unsigned size)
531
{
532
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
533
+ struct omap_eac_s *s = opaque;
534
uint32_t ret;
535
536
if (size != 2) {
537
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_eac_read(void *opaque, hwaddr addr,
538
static void omap_eac_write(void *opaque, hwaddr addr,
539
uint64_t value, unsigned size)
540
{
541
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
542
+ struct omap_eac_s *s = opaque;
543
544
if (size != 2) {
545
omap_badwidth_write16(opaque, addr, value);
546
@@ -XXX,XX +XXX,XX @@ static void omap_sti_reset(struct omap_sti_s *s)
547
static uint64_t omap_sti_read(void *opaque, hwaddr addr,
548
unsigned size)
549
{
550
- struct omap_sti_s *s = (struct omap_sti_s *) opaque;
551
+ struct omap_sti_s *s = opaque;
552
553
if (size != 4) {
554
return omap_badwidth_read32(opaque, addr);
555
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_sti_read(void *opaque, hwaddr addr,
556
static void omap_sti_write(void *opaque, hwaddr addr,
557
uint64_t value, unsigned size)
558
{
559
- struct omap_sti_s *s = (struct omap_sti_s *) opaque;
560
+ struct omap_sti_s *s = opaque;
561
562
if (size != 4) {
563
omap_badwidth_write32(opaque, addr, value);
564
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_sti_ops = {
227
.endianness = DEVICE_NATIVE_ENDIAN,
565
.endianness = DEVICE_NATIVE_ENDIAN,
228
};
566
};
229
567
230
+static const ClockPortInitArray zynq_slcr_clocks = {
568
-static uint64_t omap_sti_fifo_read(void *opaque, hwaddr addr,
231
+ QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback),
569
- unsigned size)
232
+ QDEV_CLOCK_OUT(ZynqSLCRState, uart0_ref_clk),
570
+static uint64_t omap_sti_fifo_read(void *opaque, hwaddr addr, unsigned size)
233
+ QDEV_CLOCK_OUT(ZynqSLCRState, uart1_ref_clk),
571
{
234
+ QDEV_CLOCK_END
572
OMAP_BAD_REG(addr);
235
+};
573
return 0;
236
+
574
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_sti_fifo_read(void *opaque, hwaddr addr,
237
static void zynq_slcr_init(Object *obj)
575
static void omap_sti_fifo_write(void *opaque, hwaddr addr,
238
{
576
uint64_t value, unsigned size)
239
ZynqSLCRState *s = ZYNQ_SLCR(obj);
577
{
240
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_init(Object *obj)
578
- struct omap_sti_s *s = (struct omap_sti_s *) opaque;
241
memory_region_init_io(&s->iomem, obj, &slcr_ops, s, "slcr",
579
+ struct omap_sti_s *s = opaque;
242
ZYNQ_SLCR_MMIO_SIZE);
580
int ch = addr >> 6;
243
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
581
uint8_t byte = value;
244
+
582
245
+ qdev_init_clocks(DEVICE(obj), zynq_slcr_clocks);
583
@@ -XXX,XX +XXX,XX @@ static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
246
}
584
static uint64_t omap_prcm_read(void *opaque, hwaddr addr,
247
585
unsigned size)
248
static const VMStateDescription vmstate_zynq_slcr = {
586
{
249
.name = "zynq_slcr",
587
- struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
250
- .version_id = 2,
588
+ struct omap_prcm_s *s = opaque;
251
+ .version_id = 3,
589
uint32_t ret;
252
.minimum_version_id = 2,
590
253
.fields = (VMStateField[]) {
591
if (size != 4) {
254
VMSTATE_UINT32_ARRAY(regs, ZynqSLCRState, ZYNQ_SLCR_NUM_REGS),
592
@@ -XXX,XX +XXX,XX @@ static void omap_prcm_dpll_update(struct omap_prcm_s *s)
255
+ VMSTATE_CLOCK_V(ps_clk, ZynqSLCRState, 3),
593
static void omap_prcm_write(void *opaque, hwaddr addr,
256
VMSTATE_END_OF_LIST()
594
uint64_t value, unsigned size)
595
{
596
- struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
597
+ struct omap_prcm_s *s = opaque;
598
599
if (size != 4) {
600
omap_badwidth_write32(opaque, addr, value);
601
@@ -XXX,XX +XXX,XX @@ struct omap_sysctl_s {
602
static uint32_t omap_sysctl_read8(void *opaque, hwaddr addr)
603
{
604
605
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
606
+ struct omap_sysctl_s *s = opaque;
607
int pad_offset, byte_offset;
608
int value;
609
610
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_sysctl_read8(void *opaque, hwaddr addr)
611
612
static uint32_t omap_sysctl_read(void *opaque, hwaddr addr)
613
{
614
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
615
+ struct omap_sysctl_s *s = opaque;
616
617
switch (addr) {
618
case 0x000:    /* CONTROL_REVISION */
619
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_sysctl_read(void *opaque, hwaddr addr)
620
return 0;
621
}
622
623
-static void omap_sysctl_write8(void *opaque, hwaddr addr,
624
- uint32_t value)
625
+static void omap_sysctl_write8(void *opaque, hwaddr addr, uint32_t value)
626
{
627
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
628
+ struct omap_sysctl_s *s = opaque;
629
int pad_offset, byte_offset;
630
int prev_value;
631
632
@@ -XXX,XX +XXX,XX @@ static void omap_sysctl_write8(void *opaque, hwaddr addr,
257
}
633
}
258
};
634
}
259
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_zynq_slcr = {
635
260
static void zynq_slcr_class_init(ObjectClass *klass, void *data)
636
-static void omap_sysctl_write(void *opaque, hwaddr addr,
261
{
637
- uint32_t value)
262
DeviceClass *dc = DEVICE_CLASS(klass);
638
+static void omap_sysctl_write(void *opaque, hwaddr addr, uint32_t value)
263
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
639
{
264
640
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
265
dc->vmsd = &vmstate_zynq_slcr;
641
+ struct omap_sysctl_s *s = opaque;
266
- dc->reset = zynq_slcr_reset;
642
267
+ rc->phases.enter = zynq_slcr_reset_init;
643
switch (addr) {
268
+ rc->phases.hold = zynq_slcr_reset_hold;
644
case 0x000:    /* CONTROL_REVISION */
269
+ rc->phases.exit = zynq_slcr_reset_exit;
645
@@ -XXX,XX +XXX,XX @@ static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
270
}
646
/* General chip reset */
271
647
static void omap2_mpu_reset(void *opaque)
272
static const TypeInfo zynq_slcr_info = {
648
{
649
- struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
650
+ struct omap_mpu_state_s *mpu = opaque;
651
652
omap_dma_reset(mpu->dma);
653
omap_prcm_reset(mpu->prcm);
654
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
655
index XXXXXXX..XXXXXXX 100644
656
--- a/hw/arm/omap_sx1.c
657
+++ b/hw/arm/omap_sx1.c
658
@@ -XXX,XX +XXX,XX @@
659
static uint64_t static_read(void *opaque, hwaddr offset,
660
unsigned size)
661
{
662
- uint32_t *val = (uint32_t *) opaque;
663
+ uint32_t *val = opaque;
664
uint32_t mask = (4 / size) - 1;
665
666
return *val >> ((offset & mask) << 3);
667
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
668
index XXXXXXX..XXXXXXX 100644
669
--- a/hw/arm/palm.c
670
+++ b/hw/arm/palm.c
671
@@ -XXX,XX +XXX,XX @@ static struct {
672
673
static void palmte_button_event(void *opaque, int keycode)
674
{
675
- struct omap_mpu_state_s *cpu = (struct omap_mpu_state_s *) opaque;
676
+ struct omap_mpu_state_s *cpu = opaque;
677
678
if (palmte_keymap[keycode & 0x7f].row != -1)
679
omap_mpuio_key(cpu->mpuio,
680
diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c
681
index XXXXXXX..XXXXXXX 100644
682
--- a/hw/char/omap_uart.c
683
+++ b/hw/char/omap_uart.c
684
@@ -XXX,XX +XXX,XX @@ struct omap_uart_s *omap_uart_init(hwaddr base,
685
return s;
686
}
687
688
-static uint64_t omap_uart_read(void *opaque, hwaddr addr,
689
- unsigned size)
690
+static uint64_t omap_uart_read(void *opaque, hwaddr addr, unsigned size)
691
{
692
- struct omap_uart_s *s = (struct omap_uart_s *) opaque;
693
+ struct omap_uart_s *s = opaque;
694
695
if (size == 4) {
696
return omap_badwidth_read8(opaque, addr);
697
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_uart_read(void *opaque, hwaddr addr,
698
static void omap_uart_write(void *opaque, hwaddr addr,
699
uint64_t value, unsigned size)
700
{
701
- struct omap_uart_s *s = (struct omap_uart_s *) opaque;
702
+ struct omap_uart_s *s = opaque;
703
704
if (size == 4) {
705
omap_badwidth_write8(opaque, addr, value);
706
diff --git a/hw/display/omap_dss.c b/hw/display/omap_dss.c
707
index XXXXXXX..XXXXXXX 100644
708
--- a/hw/display/omap_dss.c
709
+++ b/hw/display/omap_dss.c
710
@@ -XXX,XX +XXX,XX @@ void omap_dss_reset(struct omap_dss_s *s)
711
static uint64_t omap_diss_read(void *opaque, hwaddr addr,
712
unsigned size)
713
{
714
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
715
+ struct omap_dss_s *s = opaque;
716
717
if (size != 4) {
718
return omap_badwidth_read32(opaque, addr);
719
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_diss_read(void *opaque, hwaddr addr,
720
static void omap_diss_write(void *opaque, hwaddr addr,
721
uint64_t value, unsigned size)
722
{
723
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
724
+ struct omap_dss_s *s = opaque;
725
726
if (size != 4) {
727
omap_badwidth_write32(opaque, addr, value);
728
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_diss_ops = {
729
static uint64_t omap_disc_read(void *opaque, hwaddr addr,
730
unsigned size)
731
{
732
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
733
+ struct omap_dss_s *s = opaque;
734
735
if (size != 4) {
736
return omap_badwidth_read32(opaque, addr);
737
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_disc_read(void *opaque, hwaddr addr,
738
static void omap_disc_write(void *opaque, hwaddr addr,
739
uint64_t value, unsigned size)
740
{
741
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
742
+ struct omap_dss_s *s = opaque;
743
744
if (size != 4) {
745
omap_badwidth_write32(opaque, addr, value);
746
@@ -XXX,XX +XXX,XX @@ static void omap_rfbi_transfer_start(struct omap_dss_s *s)
747
omap_dispc_interrupt_update(s);
748
}
749
750
-static uint64_t omap_rfbi_read(void *opaque, hwaddr addr,
751
- unsigned size)
752
+static uint64_t omap_rfbi_read(void *opaque, hwaddr addr, unsigned size)
753
{
754
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
755
+ struct omap_dss_s *s = opaque;
756
757
if (size != 4) {
758
return omap_badwidth_read32(opaque, addr);
759
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_rfbi_read(void *opaque, hwaddr addr,
760
static void omap_rfbi_write(void *opaque, hwaddr addr,
761
uint64_t value, unsigned size)
762
{
763
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
764
+ struct omap_dss_s *s = opaque;
765
766
if (size != 4) {
767
omap_badwidth_write32(opaque, addr, value);
768
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
769
index XXXXXXX..XXXXXXX 100644
770
--- a/hw/display/omap_lcdc.c
771
+++ b/hw/display/omap_lcdc.c
772
@@ -XXX,XX +XXX,XX @@ static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
773
774
static void omap_update_display(void *opaque)
775
{
776
- struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
777
+ struct omap_lcd_panel_s *omap_lcd = opaque;
778
DisplaySurface *surface;
779
drawfn draw_line;
780
int size, height, first, last;
781
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_update(struct omap_lcd_panel_s *s) {
782
}
783
}
784
785
-static uint64_t omap_lcdc_read(void *opaque, hwaddr addr,
786
- unsigned size)
787
+static uint64_t omap_lcdc_read(void *opaque, hwaddr addr, unsigned size)
788
{
789
- struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *) opaque;
790
+ struct omap_lcd_panel_s *s = opaque;
791
792
switch (addr) {
793
case 0x00:    /* LCD_CONTROL */
794
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_lcdc_read(void *opaque, hwaddr addr,
795
static void omap_lcdc_write(void *opaque, hwaddr addr,
796
uint64_t value, unsigned size)
797
{
798
- struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *) opaque;
799
+ struct omap_lcd_panel_s *s = opaque;
800
801
switch (addr) {
802
case 0x00:    /* LCD_CONTROL */
803
diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
804
index XXXXXXX..XXXXXXX 100644
805
--- a/hw/dma/omap_dma.c
806
+++ b/hw/dma/omap_dma.c
807
@@ -XXX,XX +XXX,XX @@ static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
808
return 0;
809
}
810
811
-static uint64_t omap_dma_read(void *opaque, hwaddr addr,
812
- unsigned size)
813
+static uint64_t omap_dma_read(void *opaque, hwaddr addr, unsigned size)
814
{
815
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
816
+ struct omap_dma_s *s = opaque;
817
int reg, ch;
818
uint16_t ret;
819
820
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_dma_read(void *opaque, hwaddr addr,
821
static void omap_dma_write(void *opaque, hwaddr addr,
822
uint64_t value, unsigned size)
823
{
824
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
825
+ struct omap_dma_s *s = opaque;
826
int reg, ch;
827
828
if (size != 2) {
829
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_dma_ops = {
830
831
static void omap_dma_request(void *opaque, int drq, int req)
832
{
833
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
834
+ struct omap_dma_s *s = opaque;
835
/* The request pins are level triggered in QEMU. */
836
if (req) {
837
if (~s->dma->drqbmp & (1ULL << drq)) {
838
@@ -XXX,XX +XXX,XX @@ static void omap_dma_request(void *opaque, int drq, int req)
839
/* XXX: this won't be needed once soc_dma knows about clocks. */
840
static void omap_dma_clk_update(void *opaque, int line, int on)
841
{
842
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
843
+ struct omap_dma_s *s = opaque;
844
int i;
845
846
s->dma->freq = omap_clk_getrate(s->clk);
847
@@ -XXX,XX +XXX,XX @@ static void omap_dma_interrupts_4_update(struct omap_dma_s *s)
848
static uint64_t omap_dma4_read(void *opaque, hwaddr addr,
849
unsigned size)
850
{
851
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
852
+ struct omap_dma_s *s = opaque;
853
int irqn = 0, chnum;
854
struct omap_dma_channel_s *ch;
855
856
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_dma4_read(void *opaque, hwaddr addr,
857
static void omap_dma4_write(void *opaque, hwaddr addr,
858
uint64_t value, unsigned size)
859
{
860
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
861
+ struct omap_dma_s *s = opaque;
862
int chnum, irqn = 0;
863
struct omap_dma_channel_s *ch;
864
865
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
866
index XXXXXXX..XXXXXXX 100644
867
--- a/hw/gpio/omap_gpio.c
868
+++ b/hw/gpio/omap_gpio.c
869
@@ -XXX,XX +XXX,XX @@ static void omap_gpio_set(void *opaque, int line, int level)
870
static uint64_t omap_gpio_read(void *opaque, hwaddr addr,
871
unsigned size)
872
{
873
- struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
874
+ struct omap_gpio_s *s = opaque;
875
int offset = addr & OMAP_MPUI_REG_MASK;
876
877
if (size != 2) {
878
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_gpio_read(void *opaque, hwaddr addr,
879
static void omap_gpio_write(void *opaque, hwaddr addr,
880
uint64_t value, unsigned size)
881
{
882
- struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
883
+ struct omap_gpio_s *s = opaque;
884
int offset = addr & OMAP_MPUI_REG_MASK;
885
uint16_t diff;
886
int ln;
887
@@ -XXX,XX +XXX,XX @@ static void omap2_gpio_module_reset(struct omap2_gpio_s *s)
888
889
static uint32_t omap2_gpio_module_read(void *opaque, hwaddr addr)
890
{
891
- struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
892
+ struct omap2_gpio_s *s = opaque;
893
894
switch (addr) {
895
case 0x00:    /* GPIO_REVISION */
896
@@ -XXX,XX +XXX,XX @@ static uint32_t omap2_gpio_module_read(void *opaque, hwaddr addr)
897
static void omap2_gpio_module_write(void *opaque, hwaddr addr,
898
uint32_t value)
899
{
900
- struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
901
+ struct omap2_gpio_s *s = opaque;
902
uint32_t diff;
903
int ln;
904
905
@@ -XXX,XX +XXX,XX @@ static void omap2_gpif_reset(DeviceState *dev)
906
s->gpo = 0;
907
}
908
909
-static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr,
910
- unsigned size)
911
+static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr, unsigned size)
912
{
913
- struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
914
+ struct omap2_gpif_s *s = opaque;
915
916
switch (addr) {
917
case 0x00:    /* IPGENERICOCPSPL_REVISION */
918
@@ -XXX,XX +XXX,XX @@ static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr,
919
static void omap2_gpif_top_write(void *opaque, hwaddr addr,
920
uint64_t value, unsigned size)
921
{
922
- struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
923
+ struct omap2_gpif_s *s = opaque;
924
925
switch (addr) {
926
case 0x00:    /* IPGENERICOCPSPL_REVISION */
927
diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
928
index XXXXXXX..XXXXXXX 100644
929
--- a/hw/intc/omap_intc.c
930
+++ b/hw/intc/omap_intc.c
931
@@ -XXX,XX +XXX,XX @@ static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
932
933
static void omap_set_intr(void *opaque, int irq, int req)
934
{
935
- struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
936
+ struct omap_intr_handler_s *ih = opaque;
937
uint32_t rise;
938
939
struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
940
@@ -XXX,XX +XXX,XX @@ static void omap_set_intr(void *opaque, int irq, int req)
941
/* Simplified version with no edge detection */
942
static void omap_set_intr_noedge(void *opaque, int irq, int req)
943
{
944
- struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
945
+ struct omap_intr_handler_s *ih = opaque;
946
uint32_t rise;
947
948
struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
949
@@ -XXX,XX +XXX,XX @@ static void omap_set_intr_noedge(void *opaque, int irq, int req)
950
static uint64_t omap_inth_read(void *opaque, hwaddr addr,
951
unsigned size)
952
{
953
- struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
954
+ struct omap_intr_handler_s *s = opaque;
955
int i, offset = addr;
956
int bank_no = offset >> 8;
957
int line_no;
958
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_inth_read(void *opaque, hwaddr addr,
959
static void omap_inth_write(void *opaque, hwaddr addr,
960
uint64_t value, unsigned size)
961
{
962
- struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
963
+ struct omap_intr_handler_s *s = opaque;
964
int i, offset = addr;
965
int bank_no = offset >> 8;
966
struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
967
@@ -XXX,XX +XXX,XX @@ static const TypeInfo omap_intc_info = {
968
static uint64_t omap2_inth_read(void *opaque, hwaddr addr,
969
unsigned size)
970
{
971
- struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
972
+ struct omap_intr_handler_s *s = opaque;
973
int offset = addr;
974
int bank_no, line_no;
975
struct omap_intr_handler_bank_s *bank = NULL;
976
@@ -XXX,XX +XXX,XX @@ static uint64_t omap2_inth_read(void *opaque, hwaddr addr,
977
static void omap2_inth_write(void *opaque, hwaddr addr,
978
uint64_t value, unsigned size)
979
{
980
- struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
981
+ struct omap_intr_handler_s *s = opaque;
982
int offset = addr;
983
int bank_no, line_no;
984
struct omap_intr_handler_bank_s *bank = NULL;
985
diff --git a/hw/misc/omap_gpmc.c b/hw/misc/omap_gpmc.c
986
index XXXXXXX..XXXXXXX 100644
987
--- a/hw/misc/omap_gpmc.c
988
+++ b/hw/misc/omap_gpmc.c
989
@@ -XXX,XX +XXX,XX @@ static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value)
990
static uint64_t omap_nand_read(void *opaque, hwaddr addr,
991
unsigned size)
992
{
993
- struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
994
+ struct omap_gpmc_cs_file_s *f = opaque;
995
uint64_t v;
996
nand_setpins(f->dev, 0, 0, 0, 1, 0);
997
switch (omap_gpmc_devsize(f)) {
998
@@ -XXX,XX +XXX,XX @@ static void omap_nand_setio(DeviceState *dev, uint64_t value,
999
static void omap_nand_write(void *opaque, hwaddr addr,
1000
uint64_t value, unsigned size)
1001
{
1002
- struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
1003
+ struct omap_gpmc_cs_file_s *f = opaque;
1004
nand_setpins(f->dev, 0, 0, 0, 1, 0);
1005
omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
1006
}
1007
@@ -XXX,XX +XXX,XX @@ static void fill_prefetch_fifo(struct omap_gpmc_s *s)
1008
static uint64_t omap_gpmc_prefetch_read(void *opaque, hwaddr addr,
1009
unsigned size)
1010
{
1011
- struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
1012
+ struct omap_gpmc_s *s = opaque;
1013
uint32_t data;
1014
if (s->prefetch.config1 & 1) {
1015
/* The TRM doesn't define the behaviour if you read from the
1016
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_gpmc_prefetch_read(void *opaque, hwaddr addr,
1017
static void omap_gpmc_prefetch_write(void *opaque, hwaddr addr,
1018
uint64_t value, unsigned size)
1019
{
1020
- struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
1021
+ struct omap_gpmc_s *s = opaque;
1022
int cs = prefetch_cs(s->prefetch.config1);
1023
if ((s->prefetch.config1 & 1) == 0) {
1024
/* The TRM doesn't define the behaviour of writing to the
1025
@@ -XXX,XX +XXX,XX @@ static int gpmc_wordaccess_only(hwaddr addr)
1026
static uint64_t omap_gpmc_read(void *opaque, hwaddr addr,
1027
unsigned size)
1028
{
1029
- struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
1030
+ struct omap_gpmc_s *s = opaque;
1031
int cs;
1032
struct omap_gpmc_cs_file_s *f;
1033
1034
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_gpmc_read(void *opaque, hwaddr addr,
1035
static void omap_gpmc_write(void *opaque, hwaddr addr,
1036
uint64_t value, unsigned size)
1037
{
1038
- struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
1039
+ struct omap_gpmc_s *s = opaque;
1040
int cs;
1041
struct omap_gpmc_cs_file_s *f;
1042
1043
diff --git a/hw/misc/omap_l4.c b/hw/misc/omap_l4.c
1044
index XXXXXXX..XXXXXXX 100644
1045
--- a/hw/misc/omap_l4.c
1046
+++ b/hw/misc/omap_l4.c
1047
@@ -XXX,XX +XXX,XX @@ hwaddr omap_l4_region_size(struct omap_target_agent_s *ta,
1048
return ta->start[region].size;
1049
}
1050
1051
-static uint64_t omap_l4ta_read(void *opaque, hwaddr addr,
1052
- unsigned size)
1053
+static uint64_t omap_l4ta_read(void *opaque, hwaddr addr, unsigned size)
1054
{
1055
- struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
1056
+ struct omap_target_agent_s *s = opaque;
1057
1058
if (size != 2) {
1059
return omap_badwidth_read16(opaque, addr);
1060
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_l4ta_read(void *opaque, hwaddr addr,
1061
static void omap_l4ta_write(void *opaque, hwaddr addr,
1062
uint64_t value, unsigned size)
1063
{
1064
- struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
1065
+ struct omap_target_agent_s *s = opaque;
1066
1067
if (size != 4) {
1068
omap_badwidth_write32(opaque, addr, value);
1069
diff --git a/hw/misc/omap_sdrc.c b/hw/misc/omap_sdrc.c
1070
index XXXXXXX..XXXXXXX 100644
1071
--- a/hw/misc/omap_sdrc.c
1072
+++ b/hw/misc/omap_sdrc.c
1073
@@ -XXX,XX +XXX,XX @@ void omap_sdrc_reset(struct omap_sdrc_s *s)
1074
s->config = 0x10;
1075
}
1076
1077
-static uint64_t omap_sdrc_read(void *opaque, hwaddr addr,
1078
- unsigned size)
1079
+static uint64_t omap_sdrc_read(void *opaque, hwaddr addr, unsigned size)
1080
{
1081
- struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
1082
+ struct omap_sdrc_s *s = opaque;
1083
1084
if (size != 4) {
1085
return omap_badwidth_read32(opaque, addr);
1086
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_sdrc_read(void *opaque, hwaddr addr,
1087
static void omap_sdrc_write(void *opaque, hwaddr addr,
1088
uint64_t value, unsigned size)
1089
{
1090
- struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
1091
+ struct omap_sdrc_s *s = opaque;
1092
1093
if (size != 4) {
1094
omap_badwidth_write32(opaque, addr, value);
1095
diff --git a/hw/misc/omap_tap.c b/hw/misc/omap_tap.c
1096
index XXXXXXX..XXXXXXX 100644
1097
--- a/hw/misc/omap_tap.c
1098
+++ b/hw/misc/omap_tap.c
1099
@@ -XXX,XX +XXX,XX @@
1100
#include "hw/arm/omap.h"
1101
1102
/* TEST-Chip-level TAP */
1103
-static uint64_t omap_tap_read(void *opaque, hwaddr addr,
1104
- unsigned size)
1105
+static uint64_t omap_tap_read(void *opaque, hwaddr addr, unsigned size)
1106
{
1107
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1108
+ struct omap_mpu_state_s *s = opaque;
1109
1110
if (size != 4) {
1111
return omap_badwidth_read32(opaque, addr);
1112
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
1113
index XXXXXXX..XXXXXXX 100644
1114
--- a/hw/sd/omap_mmc.c
1115
+++ b/hw/sd/omap_mmc.c
1116
@@ -XXX,XX +XXX,XX @@ void omap_mmc_reset(struct omap_mmc_s *host)
1117
device_cold_reset(DEVICE(host->card));
1118
}
1119
1120
-static uint64_t omap_mmc_read(void *opaque, hwaddr offset,
1121
- unsigned size)
1122
+static uint64_t omap_mmc_read(void *opaque, hwaddr offset, unsigned size)
1123
{
1124
uint16_t i;
1125
- struct omap_mmc_s *s = (struct omap_mmc_s *) opaque;
1126
+ struct omap_mmc_s *s = opaque;
1127
1128
if (size != 2) {
1129
return omap_badwidth_read16(opaque, offset);
1130
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_write(void *opaque, hwaddr offset,
1131
uint64_t value, unsigned size)
1132
{
1133
int i;
1134
- struct omap_mmc_s *s = (struct omap_mmc_s *) opaque;
1135
+ struct omap_mmc_s *s = opaque;
1136
1137
if (size != 2) {
1138
omap_badwidth_write16(opaque, offset, value);
1139
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_mmc_ops = {
1140
1141
static void omap_mmc_cover_cb(void *opaque, int line, int level)
1142
{
1143
- struct omap_mmc_s *host = (struct omap_mmc_s *) opaque;
1144
+ struct omap_mmc_s *host = opaque;
1145
1146
if (!host->cdet_state && level) {
1147
host->status |= 0x0002;
1148
diff --git a/hw/ssi/omap_spi.c b/hw/ssi/omap_spi.c
1149
index XXXXXXX..XXXXXXX 100644
1150
--- a/hw/ssi/omap_spi.c
1151
+++ b/hw/ssi/omap_spi.c
1152
@@ -XXX,XX +XXX,XX @@ void omap_mcspi_reset(struct omap_mcspi_s *s)
1153
omap_mcspi_interrupt_update(s);
1154
}
1155
1156
-static uint64_t omap_mcspi_read(void *opaque, hwaddr addr,
1157
- unsigned size)
1158
+static uint64_t omap_mcspi_read(void *opaque, hwaddr addr, unsigned size)
1159
{
1160
- struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1161
+ struct omap_mcspi_s *s = opaque;
1162
int ch = 0;
1163
uint32_t ret;
1164
1165
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_mcspi_read(void *opaque, hwaddr addr,
1166
static void omap_mcspi_write(void *opaque, hwaddr addr,
1167
uint64_t value, unsigned size)
1168
{
1169
- struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1170
+ struct omap_mcspi_s *s = opaque;
1171
int ch = 0;
1172
1173
if (size != 4) {
1174
diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c
1175
index XXXXXXX..XXXXXXX 100644
1176
--- a/hw/timer/omap_gptimer.c
1177
+++ b/hw/timer/omap_gptimer.c
1178
@@ -XXX,XX +XXX,XX @@ static inline void omap_gp_timer_trigger(struct omap_gp_timer_s *timer)
1179
1180
static void omap_gp_timer_tick(void *opaque)
1181
{
1182
- struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
1183
+ struct omap_gp_timer_s *timer = opaque;
1184
1185
if (!timer->ar) {
1186
timer->st = 0;
1187
@@ -XXX,XX +XXX,XX @@ static void omap_gp_timer_tick(void *opaque)
1188
1189
static void omap_gp_timer_match(void *opaque)
1190
{
1191
- struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
1192
+ struct omap_gp_timer_s *timer = opaque;
1193
1194
if (timer->trigger == gpt_trigger_both)
1195
omap_gp_timer_trigger(timer);
1196
@@ -XXX,XX +XXX,XX @@ static void omap_gp_timer_match(void *opaque)
1197
1198
static void omap_gp_timer_input(void *opaque, int line, int on)
1199
{
1200
- struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
1201
+ struct omap_gp_timer_s *s = opaque;
1202
int trigger;
1203
1204
switch (s->capture) {
1205
@@ -XXX,XX +XXX,XX @@ static void omap_gp_timer_input(void *opaque, int line, int on)
1206
1207
static void omap_gp_timer_clk_update(void *opaque, int line, int on)
1208
{
1209
- struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
1210
+ struct omap_gp_timer_s *timer = opaque;
1211
1212
omap_gp_timer_sync(timer);
1213
timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1214
@@ -XXX,XX +XXX,XX @@ void omap_gp_timer_reset(struct omap_gp_timer_s *s)
1215
1216
static uint32_t omap_gp_timer_readw(void *opaque, hwaddr addr)
1217
{
1218
- struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
1219
+ struct omap_gp_timer_s *s = opaque;
1220
1221
switch (addr) {
1222
case 0x00:    /* TIDR */
1223
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_gp_timer_readw(void *opaque, hwaddr addr)
1224
1225
static uint32_t omap_gp_timer_readh(void *opaque, hwaddr addr)
1226
{
1227
- struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
1228
+ struct omap_gp_timer_s *s = opaque;
1229
uint32_t ret;
1230
1231
if (addr & 2)
1232
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_gp_timer_readh(void *opaque, hwaddr addr)
1233
}
1234
}
1235
1236
-static void omap_gp_timer_write(void *opaque, hwaddr addr,
1237
- uint32_t value)
1238
+static void omap_gp_timer_write(void *opaque, hwaddr addr, uint32_t value)
1239
{
1240
- struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
1241
+ struct omap_gp_timer_s *s = opaque;
1242
1243
switch (addr) {
1244
case 0x00:    /* TIDR */
1245
@@ -XXX,XX +XXX,XX @@ static void omap_gp_timer_write(void *opaque, hwaddr addr,
1246
}
1247
}
1248
1249
-static void omap_gp_timer_writeh(void *opaque, hwaddr addr,
1250
- uint32_t value)
1251
+static void omap_gp_timer_writeh(void *opaque, hwaddr addr, uint32_t value)
1252
{
1253
- struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
1254
+ struct omap_gp_timer_s *s = opaque;
1255
1256
if (addr & 2)
1257
omap_gp_timer_write(opaque, addr, (value << 16) | s->writeh);
1258
diff --git a/hw/timer/omap_synctimer.c b/hw/timer/omap_synctimer.c
1259
index XXXXXXX..XXXXXXX 100644
1260
--- a/hw/timer/omap_synctimer.c
1261
+++ b/hw/timer/omap_synctimer.c
1262
@@ -XXX,XX +XXX,XX @@ void omap_synctimer_reset(struct omap_synctimer_s *s)
1263
1264
static uint32_t omap_synctimer_readw(void *opaque, hwaddr addr)
1265
{
1266
- struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
1267
+ struct omap_synctimer_s *s = opaque;
1268
1269
switch (addr) {
1270
case 0x00:    /* 32KSYNCNT_REV */
1271
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_synctimer_readw(void *opaque, hwaddr addr)
1272
1273
static uint32_t omap_synctimer_readh(void *opaque, hwaddr addr)
1274
{
1275
- struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
1276
+ struct omap_synctimer_s *s = opaque;
1277
uint32_t ret;
1278
1279
if (addr & 2)
273
--
1280
--
274
2.20.1
1281
2.34.1
275
1282
276
1283
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
3
Following docs/devel/style.rst guidelines, rename omap_gpif_s ->
4
Omap1GpioState. This also remove a use of 'struct' in the
5
DECLARE_INSTANCE_CHECKER() macro call.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20230109140306.23161-5-philmd@linaro.org
6
Message-id: 20200423073358.27155-4-philmd@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
target/arm/cpu.c | 8 +++-----
12
include/hw/arm/omap.h | 6 +++---
10
target/arm/cpu64.c | 8 +++-----
13
hw/gpio/omap_gpio.c | 16 ++++++++--------
11
2 files changed, 6 insertions(+), 10 deletions(-)
14
2 files changed, 11 insertions(+), 11 deletions(-)
12
15
13
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.c
18
--- a/include/hw/arm/omap.h
16
+++ b/target/arm/cpu.c
19
+++ b/include/hw/arm/omap.h
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
20
@@ -XXX,XX +XXX,XX @@ void omap_i2c_set_fclk(OMAPI2CState *i2c, omap_clk clk);
18
{ .name = "any", .initfn = arm_max_initfn },
21
19
#endif
22
/* omap_gpio.c */
20
#endif
23
#define TYPE_OMAP1_GPIO "omap-gpio"
21
- { .name = NULL }
24
-DECLARE_INSTANCE_CHECKER(struct omap_gpif_s, OMAP1_GPIO,
25
+typedef struct Omap1GpioState Omap1GpioState;
26
+DECLARE_INSTANCE_CHECKER(Omap1GpioState, OMAP1_GPIO,
27
TYPE_OMAP1_GPIO)
28
29
#define TYPE_OMAP2_GPIO "omap2-gpio"
30
DECLARE_INSTANCE_CHECKER(struct omap2_gpif_s, OMAP2_GPIO,
31
TYPE_OMAP2_GPIO)
32
33
-typedef struct omap_gpif_s omap_gpif;
34
typedef struct omap2_gpif_s omap2_gpif;
35
36
/* TODO: clock framework (see above) */
37
-void omap_gpio_set_clk(omap_gpif *gpio, omap_clk clk);
38
+void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk);
39
40
void omap2_gpio_set_iclk(omap2_gpif *gpio, omap_clk clk);
41
void omap2_gpio_set_fclk(omap2_gpif *gpio, uint8_t i, omap_clk clk);
42
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/gpio/omap_gpio.c
45
+++ b/hw/gpio/omap_gpio.c
46
@@ -XXX,XX +XXX,XX @@ struct omap_gpio_s {
47
uint16_t pins;
22
};
48
};
23
49
24
static Property arm_cpu_properties[] = {
50
-struct omap_gpif_s {
25
@@ -XXX,XX +XXX,XX @@ static const TypeInfo idau_interface_type_info = {
51
+struct Omap1GpioState {
26
52
SysBusDevice parent_obj;
27
static void arm_cpu_register_types(void)
53
54
MemoryRegion iomem;
55
@@ -XXX,XX +XXX,XX @@ struct omap_gpif_s {
56
/* General-Purpose I/O of OMAP1 */
57
static void omap_gpio_set(void *opaque, int line, int level)
28
{
58
{
29
- const ARMCPUInfo *info = arm_cpus;
59
- struct omap_gpif_s *p = opaque;
30
+ size_t i;
60
+ Omap1GpioState *p = opaque;
31
61
struct omap_gpio_s *s = &p->omap1;
32
type_register_static(&arm_cpu_type_info);
62
uint16_t prev = s->inputs;
33
type_register_static(&idau_interface_type_info);
63
34
64
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap2_gpio_module_ops = {
35
- while (info->name) {
65
36
- arm_cpu_register(info);
66
static void omap_gpif_reset(DeviceState *dev)
37
- info++;
38
+ for (i = 0; i < ARRAY_SIZE(arm_cpus); ++i) {
39
+ arm_cpu_register(&arm_cpus[i]);
40
}
41
42
#ifdef CONFIG_KVM
43
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/cpu64.c
46
+++ b/target/arm/cpu64.c
47
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
48
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
49
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
50
{ .name = "max", .initfn = aarch64_max_initfn },
51
- { .name = NULL }
52
};
53
54
static bool aarch64_cpu_get_aarch64(Object *obj, Error **errp)
55
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aarch64_cpu_type_info = {
56
57
static void aarch64_cpu_register_types(void)
58
{
67
{
59
- const ARMCPUInfo *info = aarch64_cpus;
68
- struct omap_gpif_s *s = OMAP1_GPIO(dev);
60
+ size_t i;
69
+ Omap1GpioState *s = OMAP1_GPIO(dev);
61
70
62
type_register_static(&aarch64_cpu_type_info);
71
omap_gpio_reset(&s->omap1);
63
72
}
64
- while (info->name) {
73
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap2_gpif_top_ops = {
65
- aarch64_cpu_register(info);
74
static void omap_gpio_init(Object *obj)
66
- info++;
75
{
67
+ for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
76
DeviceState *dev = DEVICE(obj);
68
+ aarch64_cpu_register(&aarch64_cpus[i]);
77
- struct omap_gpif_s *s = OMAP1_GPIO(obj);
78
+ Omap1GpioState *s = OMAP1_GPIO(obj);
79
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
80
81
qdev_init_gpio_in(dev, omap_gpio_set, 16);
82
@@ -XXX,XX +XXX,XX @@ static void omap_gpio_init(Object *obj)
83
84
static void omap_gpio_realize(DeviceState *dev, Error **errp)
85
{
86
- struct omap_gpif_s *s = OMAP1_GPIO(dev);
87
+ Omap1GpioState *s = OMAP1_GPIO(dev);
88
89
if (!s->clk) {
90
error_setg(errp, "omap-gpio: clk not connected");
91
@@ -XXX,XX +XXX,XX @@ static void omap2_gpio_realize(DeviceState *dev, Error **errp)
69
}
92
}
70
}
93
}
71
94
95
-void omap_gpio_set_clk(omap_gpif *gpio, omap_clk clk)
96
+void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk)
97
{
98
gpio->clk = clk;
99
}
100
101
static Property omap_gpio_properties[] = {
102
- DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0),
103
+ DEFINE_PROP_INT32("mpu_model", Omap1GpioState, mpu_model, 0),
104
DEFINE_PROP_END_OF_LIST(),
105
};
106
107
@@ -XXX,XX +XXX,XX @@ static void omap_gpio_class_init(ObjectClass *klass, void *data)
108
static const TypeInfo omap_gpio_info = {
109
.name = TYPE_OMAP1_GPIO,
110
.parent = TYPE_SYS_BUS_DEVICE,
111
- .instance_size = sizeof(struct omap_gpif_s),
112
+ .instance_size = sizeof(Omap1GpioState),
113
.instance_init = omap_gpio_init,
114
.class_init = omap_gpio_class_init,
115
};
72
--
116
--
73
2.20.1
117
2.34.1
74
118
75
119
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add the connection between the slcr's output clocks and the uarts inputs.
3
Following docs/devel/style.rst guidelines, rename omap2_gpif_s ->
4
Omap2GpioState. This also remove a use of 'struct' in the
5
DECLARE_INSTANCE_CHECKER() macro call.
4
6
5
Also add the main board clock 'ps_clk', which is hard-coded to 33.33MHz
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
(the default frequency). This clock is used to feed the slcr's input
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
clock.
9
Message-id: 20230109140306.23161-6-philmd@linaro.org
8
9
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Message-id: 20200406135251.157596-9-damien.hedde@greensocs.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
hw/arm/xilinx_zynq.c | 57 +++++++++++++++++++++++++++++++++++++-------
12
include/hw/arm/omap.h | 9 ++++-----
16
1 file changed, 49 insertions(+), 8 deletions(-)
13
hw/gpio/omap_gpio.c | 20 ++++++++++----------
14
2 files changed, 14 insertions(+), 15 deletions(-)
17
15
18
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
16
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/xilinx_zynq.c
18
--- a/include/hw/arm/omap.h
21
+++ b/hw/arm/xilinx_zynq.c
19
+++ b/include/hw/arm/omap.h
22
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(Omap1GpioState, OMAP1_GPIO,
23
#include "hw/char/cadence_uart.h"
21
TYPE_OMAP1_GPIO)
24
#include "hw/net/cadence_gem.h"
22
25
#include "hw/cpu/a9mpcore.h"
23
#define TYPE_OMAP2_GPIO "omap2-gpio"
26
+#include "hw/qdev-clock.h"
24
-DECLARE_INSTANCE_CHECKER(struct omap2_gpif_s, OMAP2_GPIO,
27
+#include "sysemu/reset.h"
25
+typedef struct Omap2GpioState Omap2GpioState;
28
+
26
+DECLARE_INSTANCE_CHECKER(Omap2GpioState, OMAP2_GPIO,
29
+#define TYPE_ZYNQ_MACHINE MACHINE_TYPE_NAME("xilinx-zynq-a9")
27
TYPE_OMAP2_GPIO)
30
+#define ZYNQ_MACHINE(obj) \
28
31
+ OBJECT_CHECK(ZynqMachineState, (obj), TYPE_ZYNQ_MACHINE)
29
-typedef struct omap2_gpif_s omap2_gpif;
32
+
30
-
33
+/* board base frequency: 33.333333 MHz */
31
/* TODO: clock framework (see above) */
34
+#define PS_CLK_FREQUENCY (100 * 1000 * 1000 / 3)
32
void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk);
35
33
36
#define NUM_SPI_FLASHES 4
34
-void omap2_gpio_set_iclk(omap2_gpif *gpio, omap_clk clk);
37
#define NUM_QSPI_FLASHES 2
35
-void omap2_gpio_set_fclk(omap2_gpif *gpio, uint8_t i, omap_clk clk);
38
@@ -XXX,XX +XXX,XX @@ static const int dma_irqs[8] = {
36
+void omap2_gpio_set_iclk(Omap2GpioState *gpio, omap_clk clk);
39
0xe3401000 + ARMV7_IMM16(extract32((val), 16, 16)), /* movt r1 ... */ \
37
+void omap2_gpio_set_fclk(Omap2GpioState *gpio, uint8_t i, omap_clk clk);
40
0xe5801000 + (addr)
38
41
39
/* OMAP2 l4 Interconnect */
42
+typedef struct ZynqMachineState {
40
struct omap_l4_s;
43
+ MachineState parent;
41
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
44
+ Clock *ps_clk;
42
index XXXXXXX..XXXXXXX 100644
45
+} ZynqMachineState;
43
--- a/hw/gpio/omap_gpio.c
46
+
44
+++ b/hw/gpio/omap_gpio.c
47
static void zynq_write_board_setup(ARMCPU *cpu,
45
@@ -XXX,XX +XXX,XX @@ struct omap2_gpio_s {
48
const struct arm_boot_info *info)
46
uint8_t delay;
47
};
48
49
-struct omap2_gpif_s {
50
+struct Omap2GpioState {
51
SysBusDevice parent_obj;
52
53
MemoryRegion iomem;
54
@@ -XXX,XX +XXX,XX @@ static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
55
56
static void omap2_gpio_set(void *opaque, int line, int level)
49
{
57
{
50
@@ -XXX,XX +XXX,XX @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
58
- struct omap2_gpif_s *p = opaque;
51
59
+ Omap2GpioState *p = opaque;
52
static void zynq_init(MachineState *machine)
60
struct omap2_gpio_s *s = &p->modules[line >> 5];
61
62
line &= 31;
63
@@ -XXX,XX +XXX,XX @@ static void omap_gpif_reset(DeviceState *dev)
64
65
static void omap2_gpif_reset(DeviceState *dev)
53
{
66
{
54
+ ZynqMachineState *zynq_machine = ZYNQ_MACHINE(machine);
67
- struct omap2_gpif_s *s = OMAP2_GPIO(dev);
55
ARMCPU *cpu;
68
+ Omap2GpioState *s = OMAP2_GPIO(dev);
56
MemoryRegion *address_space_mem = get_system_memory();
69
int i;
57
MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
70
58
- DeviceState *dev;
71
for (i = 0; i < s->modulecount; i++) {
59
+ DeviceState *dev, *slcr;
72
@@ -XXX,XX +XXX,XX @@ static void omap2_gpif_reset(DeviceState *dev)
60
SysBusDevice *busdev;
73
61
qemu_irq pic[64];
74
static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr, unsigned size)
62
int n;
75
{
63
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
76
- struct omap2_gpif_s *s = opaque;
64
1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
77
+ Omap2GpioState *s = opaque;
65
0);
78
66
79
switch (addr) {
67
- dev = qdev_create(NULL, "xilinx,zynq_slcr");
80
case 0x00:    /* IPGENERICOCPSPL_REVISION */
68
- qdev_init_nofail(dev);
81
@@ -XXX,XX +XXX,XX @@ static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr, unsigned size)
69
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xF8000000);
82
static void omap2_gpif_top_write(void *opaque, hwaddr addr,
70
+ /* Create slcr, keep a pointer to connect clocks */
83
uint64_t value, unsigned size)
71
+ slcr = qdev_create(NULL, "xilinx,zynq_slcr");
84
{
72
+ qdev_init_nofail(slcr);
85
- struct omap2_gpif_s *s = opaque;
73
+ sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF8000000);
86
+ Omap2GpioState *s = opaque;
74
+
87
75
+ /* Create the main clock source, and feed slcr with it */
88
switch (addr) {
76
+ zynq_machine->ps_clk = CLOCK(object_new(TYPE_CLOCK));
89
case 0x00:    /* IPGENERICOCPSPL_REVISION */
77
+ object_property_add_child(OBJECT(zynq_machine), "ps_clk",
90
@@ -XXX,XX +XXX,XX @@ static void omap_gpio_realize(DeviceState *dev, Error **errp)
78
+ OBJECT(zynq_machine->ps_clk), &error_abort);
91
79
+ object_unref(OBJECT(zynq_machine->ps_clk));
92
static void omap2_gpio_realize(DeviceState *dev, Error **errp)
80
+ clock_set_hz(zynq_machine->ps_clk, PS_CLK_FREQUENCY);
93
{
81
+ qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
94
- struct omap2_gpif_s *s = OMAP2_GPIO(dev);
82
95
+ Omap2GpioState *s = OMAP2_GPIO(dev);
83
dev = qdev_create(NULL, TYPE_A9MPCORE_PRIV);
96
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
84
qdev_prop_set_uint32(dev, "num-cpu", 1);
97
int i;
85
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
98
86
sysbus_create_simple(TYPE_CHIPIDEA, 0xE0002000, pic[53 - IRQ_OFFSET]);
99
@@ -XXX,XX +XXX,XX @@ static const TypeInfo omap_gpio_info = {
87
sysbus_create_simple(TYPE_CHIPIDEA, 0xE0003000, pic[76 - IRQ_OFFSET]);
100
.class_init = omap_gpio_class_init,
88
101
};
89
- cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0));
102
90
- cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1));
103
-void omap2_gpio_set_iclk(omap2_gpif *gpio, omap_clk clk)
91
+ dev = cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0));
104
+void omap2_gpio_set_iclk(Omap2GpioState *gpio, omap_clk clk)
92
+ qdev_connect_clock_in(dev, "refclk",
105
{
93
+ qdev_get_clock_out(slcr, "uart0_ref_clk"));
106
gpio->iclk = clk;
94
+ dev = cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1));
95
+ qdev_connect_clock_in(dev, "refclk",
96
+ qdev_get_clock_out(slcr, "uart1_ref_clk"));
97
98
sysbus_create_varargs("cadence_ttc", 0xF8001000,
99
pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NULL);
100
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
101
arm_load_kernel(ARM_CPU(first_cpu), machine, &zynq_binfo);
102
}
107
}
103
108
104
-static void zynq_machine_init(MachineClass *mc)
109
-void omap2_gpio_set_fclk(omap2_gpif *gpio, uint8_t i, omap_clk clk)
105
+static void zynq_machine_class_init(ObjectClass *oc, void *data)
110
+void omap2_gpio_set_fclk(Omap2GpioState *gpio, uint8_t i, omap_clk clk)
106
{
111
{
107
+ MachineClass *mc = MACHINE_CLASS(oc);
112
assert(i <= 5);
108
mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
113
gpio->fclk[i] = clk;
109
mc->init = zynq_init;
110
mc->max_cpus = 1;
111
@@ -XXX,XX +XXX,XX @@ static void zynq_machine_init(MachineClass *mc)
112
mc->default_ram_id = "zynq.ext_ram";
113
}
114
}
114
115
115
-DEFINE_MACHINE("xilinx-zynq-a9", zynq_machine_init)
116
static Property omap2_gpio_properties[] = {
116
+static const TypeInfo zynq_machine_type = {
117
- DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0),
117
+ .name = TYPE_ZYNQ_MACHINE,
118
+ DEFINE_PROP_INT32("mpu_model", Omap2GpioState, mpu_model, 0),
118
+ .parent = TYPE_MACHINE,
119
DEFINE_PROP_END_OF_LIST(),
119
+ .class_init = zynq_machine_class_init,
120
};
120
+ .instance_size = sizeof(ZynqMachineState),
121
121
+};
122
@@ -XXX,XX +XXX,XX @@ static void omap2_gpio_class_init(ObjectClass *klass, void *data)
122
+
123
static const TypeInfo omap2_gpio_info = {
123
+static void zynq_machine_register_types(void)
124
.name = TYPE_OMAP2_GPIO,
124
+{
125
.parent = TYPE_SYS_BUS_DEVICE,
125
+ type_register_static(&zynq_machine_type);
126
- .instance_size = sizeof(struct omap2_gpif_s),
126
+}
127
+ .instance_size = sizeof(Omap2GpioState),
127
+
128
.class_init = omap2_gpio_class_init,
128
+type_init(zynq_machine_register_types)
129
};
130
129
--
131
--
130
2.20.1
132
2.34.1
131
133
132
134
diff view generated by jsdifflib
New patch
1
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
3
Following docs/devel/style.rst guidelines, rename
4
omap_intr_handler_s -> OMAPIntcState. This also remove a
5
use of 'struct' in the DECLARE_INSTANCE_CHECKER() macro call.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109140306.23161-7-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/omap.h | 9 ++++-----
13
hw/intc/omap_intc.c | 38 +++++++++++++++++++-------------------
14
2 files changed, 23 insertions(+), 24 deletions(-)
15
16
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/omap.h
19
+++ b/include/hw/arm/omap.h
20
@@ -XXX,XX +XXX,XX @@ void omap_clk_reparent(omap_clk clk, omap_clk parent);
21
22
/* omap_intc.c */
23
#define TYPE_OMAP_INTC "common-omap-intc"
24
-typedef struct omap_intr_handler_s omap_intr_handler;
25
-DECLARE_INSTANCE_CHECKER(omap_intr_handler, OMAP_INTC,
26
- TYPE_OMAP_INTC)
27
+typedef struct OMAPIntcState OMAPIntcState;
28
+DECLARE_INSTANCE_CHECKER(OMAPIntcState, OMAP_INTC, TYPE_OMAP_INTC)
29
30
31
/*
32
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(omap_intr_handler, OMAP_INTC,
33
* (ie the struct omap_mpu_state_s*) to do the clockname to pointer
34
* translation.)
35
*/
36
-void omap_intc_set_iclk(omap_intr_handler *intc, omap_clk clk);
37
-void omap_intc_set_fclk(omap_intr_handler *intc, omap_clk clk);
38
+void omap_intc_set_iclk(OMAPIntcState *intc, omap_clk clk);
39
+void omap_intc_set_fclk(OMAPIntcState *intc, omap_clk clk);
40
41
/* omap_i2c.c */
42
#define TYPE_OMAP_I2C "omap_i2c"
43
diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/omap_intc.c
46
+++ b/hw/intc/omap_intc.c
47
@@ -XXX,XX +XXX,XX @@ struct omap_intr_handler_bank_s {
48
unsigned char priority[32];
49
};
50
51
-struct omap_intr_handler_s {
52
+struct OMAPIntcState {
53
SysBusDevice parent_obj;
54
55
qemu_irq *pins;
56
@@ -XXX,XX +XXX,XX @@ struct omap_intr_handler_s {
57
struct omap_intr_handler_bank_s bank[3];
58
};
59
60
-static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
61
+static void omap_inth_sir_update(OMAPIntcState *s, int is_fiq)
62
{
63
int i, j, sir_intr, p_intr, p;
64
uint32_t level;
65
@@ -XXX,XX +XXX,XX @@ static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
66
s->sir_intr[is_fiq] = sir_intr;
67
}
68
69
-static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
70
+static inline void omap_inth_update(OMAPIntcState *s, int is_fiq)
71
{
72
int i;
73
uint32_t has_intr = 0;
74
@@ -XXX,XX +XXX,XX @@ static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
75
76
static void omap_set_intr(void *opaque, int irq, int req)
77
{
78
- struct omap_intr_handler_s *ih = opaque;
79
+ OMAPIntcState *ih = opaque;
80
uint32_t rise;
81
82
struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
83
@@ -XXX,XX +XXX,XX @@ static void omap_set_intr(void *opaque, int irq, int req)
84
/* Simplified version with no edge detection */
85
static void omap_set_intr_noedge(void *opaque, int irq, int req)
86
{
87
- struct omap_intr_handler_s *ih = opaque;
88
+ OMAPIntcState *ih = opaque;
89
uint32_t rise;
90
91
struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
92
@@ -XXX,XX +XXX,XX @@ static void omap_set_intr_noedge(void *opaque, int irq, int req)
93
static uint64_t omap_inth_read(void *opaque, hwaddr addr,
94
unsigned size)
95
{
96
- struct omap_intr_handler_s *s = opaque;
97
+ OMAPIntcState *s = opaque;
98
int i, offset = addr;
99
int bank_no = offset >> 8;
100
int line_no;
101
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_inth_read(void *opaque, hwaddr addr,
102
static void omap_inth_write(void *opaque, hwaddr addr,
103
uint64_t value, unsigned size)
104
{
105
- struct omap_intr_handler_s *s = opaque;
106
+ OMAPIntcState *s = opaque;
107
int i, offset = addr;
108
int bank_no = offset >> 8;
109
struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
110
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_inth_mem_ops = {
111
112
static void omap_inth_reset(DeviceState *dev)
113
{
114
- struct omap_intr_handler_s *s = OMAP_INTC(dev);
115
+ OMAPIntcState *s = OMAP_INTC(dev);
116
int i;
117
118
for (i = 0; i < s->nbanks; ++i){
119
@@ -XXX,XX +XXX,XX @@ static void omap_inth_reset(DeviceState *dev)
120
static void omap_intc_init(Object *obj)
121
{
122
DeviceState *dev = DEVICE(obj);
123
- struct omap_intr_handler_s *s = OMAP_INTC(obj);
124
+ OMAPIntcState *s = OMAP_INTC(obj);
125
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
126
127
s->nbanks = 1;
128
@@ -XXX,XX +XXX,XX @@ static void omap_intc_init(Object *obj)
129
130
static void omap_intc_realize(DeviceState *dev, Error **errp)
131
{
132
- struct omap_intr_handler_s *s = OMAP_INTC(dev);
133
+ OMAPIntcState *s = OMAP_INTC(dev);
134
135
if (!s->iclk) {
136
error_setg(errp, "omap-intc: clk not connected");
137
}
138
}
139
140
-void omap_intc_set_iclk(omap_intr_handler *intc, omap_clk clk)
141
+void omap_intc_set_iclk(OMAPIntcState *intc, omap_clk clk)
142
{
143
intc->iclk = clk;
144
}
145
146
-void omap_intc_set_fclk(omap_intr_handler *intc, omap_clk clk)
147
+void omap_intc_set_fclk(OMAPIntcState *intc, omap_clk clk)
148
{
149
intc->fclk = clk;
150
}
151
152
static Property omap_intc_properties[] = {
153
- DEFINE_PROP_UINT32("size", struct omap_intr_handler_s, size, 0x100),
154
+ DEFINE_PROP_UINT32("size", OMAPIntcState, size, 0x100),
155
DEFINE_PROP_END_OF_LIST(),
156
};
157
158
@@ -XXX,XX +XXX,XX @@ static const TypeInfo omap_intc_info = {
159
static uint64_t omap2_inth_read(void *opaque, hwaddr addr,
160
unsigned size)
161
{
162
- struct omap_intr_handler_s *s = opaque;
163
+ OMAPIntcState *s = opaque;
164
int offset = addr;
165
int bank_no, line_no;
166
struct omap_intr_handler_bank_s *bank = NULL;
167
@@ -XXX,XX +XXX,XX @@ static uint64_t omap2_inth_read(void *opaque, hwaddr addr,
168
static void omap2_inth_write(void *opaque, hwaddr addr,
169
uint64_t value, unsigned size)
170
{
171
- struct omap_intr_handler_s *s = opaque;
172
+ OMAPIntcState *s = opaque;
173
int offset = addr;
174
int bank_no, line_no;
175
struct omap_intr_handler_bank_s *bank = NULL;
176
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap2_inth_mem_ops = {
177
static void omap2_intc_init(Object *obj)
178
{
179
DeviceState *dev = DEVICE(obj);
180
- struct omap_intr_handler_s *s = OMAP_INTC(obj);
181
+ OMAPIntcState *s = OMAP_INTC(obj);
182
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
183
184
s->level_only = 1;
185
@@ -XXX,XX +XXX,XX @@ static void omap2_intc_init(Object *obj)
186
187
static void omap2_intc_realize(DeviceState *dev, Error **errp)
188
{
189
- struct omap_intr_handler_s *s = OMAP_INTC(dev);
190
+ OMAPIntcState *s = OMAP_INTC(dev);
191
192
if (!s->iclk) {
193
error_setg(errp, "omap2-intc: iclk not connected");
194
@@ -XXX,XX +XXX,XX @@ static void omap2_intc_realize(DeviceState *dev, Error **errp)
195
}
196
197
static Property omap2_intc_properties[] = {
198
- DEFINE_PROP_UINT8("revision", struct omap_intr_handler_s,
199
+ DEFINE_PROP_UINT8("revision", OMAPIntcState,
200
revision, 0x21),
201
DEFINE_PROP_END_OF_LIST(),
202
};
203
@@ -XXX,XX +XXX,XX @@ static const TypeInfo omap2_intc_info = {
204
static const TypeInfo omap_intc_type_info = {
205
.name = TYPE_OMAP_INTC,
206
.parent = TYPE_SYS_BUS_DEVICE,
207
- .instance_size = sizeof(omap_intr_handler),
208
+ .instance_size = sizeof(OMAPIntcState),
209
.abstract = true,
210
};
211
212
--
213
2.34.1
214
215
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This prints the clocks attached to a DeviceState when using
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
"info qtree" monitor command. For every clock, it displays the
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
direction, the name and if the clock is forwarded. For input clock,
5
Message-id: 20230109140306.23161-8-philmd@linaro.org
6
it displays also the frequency.
7
8
This is based on the original work of Frederic Konrad.
9
10
Here follows a sample of `info qtree` output on xilinx_zynq machine
11
after linux boot with only one uart clocked:
12
> bus: main-system-bus
13
> type System
14
> [...]
15
> dev: cadence_uart, id ""
16
> gpio-out "sysbus-irq" 1
17
> clock-in "refclk" freq_hz=0.000000e+00
18
> chardev = ""
19
> mmio 00000000e0001000/0000000000001000
20
> dev: cadence_uart, id ""
21
> gpio-out "sysbus-irq" 1
22
> clock-in "refclk" freq_hz=1.375661e+07
23
> chardev = "serial0"
24
> mmio 00000000e0000000/0000000000001000
25
> [...]
26
> dev: xilinx,zynq_slcr, id ""
27
> clock-out "uart1_ref_clk" freq_hz=0.000000e+00
28
> clock-out "uart0_ref_clk" freq_hz=1.375661e+07
29
> clock-in "ps_clk" freq_hz=3.333333e+07
30
> mmio 00000000f8000000/0000000000001000
31
32
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
33
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
34
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
35
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
36
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
37
Message-id: 20200406135251.157596-10-damien.hedde@greensocs.com
38
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
---
7
---
40
qdev-monitor.c | 9 +++++++++
8
hw/arm/stellaris.c | 6 +++---
41
1 file changed, 9 insertions(+)
9
1 file changed, 3 insertions(+), 3 deletions(-)
42
10
43
diff --git a/qdev-monitor.c b/qdev-monitor.c
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
44
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
45
--- a/qdev-monitor.c
13
--- a/hw/arm/stellaris.c
46
+++ b/qdev-monitor.c
14
+++ b/hw/arm/stellaris.c
47
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_update(stellaris_adc_state *s)
48
#include "migration/misc.h"
16
49
#include "migration/migration.h"
17
static void stellaris_adc_trigger(void *opaque, int irq, int level)
50
#include "qemu/cutils.h"
18
{
51
+#include "hw/clock.h"
19
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
52
20
+ stellaris_adc_state *s = opaque;
53
/*
21
int n;
54
* Aliases were a bad idea from the start. Let's keep them
22
55
@@ -XXX,XX +XXX,XX @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
23
for (n = 0; n < 4; n++) {
56
ObjectClass *class;
24
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_reset(stellaris_adc_state *s)
57
BusState *child;
25
static uint64_t stellaris_adc_read(void *opaque, hwaddr offset,
58
NamedGPIOList *ngl;
26
unsigned size)
59
+ NamedClockList *ncl;
27
{
60
28
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
61
qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
29
+ stellaris_adc_state *s = opaque;
62
dev->id ? dev->id : "");
30
63
@@ -XXX,XX +XXX,XX @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
31
/* TODO: Implement this. */
64
ngl->num_out);
32
if (offset >= 0x40 && offset < 0xc0) {
65
}
33
@@ -XXX,XX +XXX,XX @@ static uint64_t stellaris_adc_read(void *opaque, hwaddr offset,
66
}
34
static void stellaris_adc_write(void *opaque, hwaddr offset,
67
+ QLIST_FOREACH(ncl, &dev->clocks, node) {
35
uint64_t value, unsigned size)
68
+ qdev_printf("clock-%s%s \"%s\" freq_hz=%e\n",
36
{
69
+ ncl->output ? "out" : "in",
37
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
70
+ ncl->alias ? " (alias)" : "",
38
+ stellaris_adc_state *s = opaque;
71
+ ncl->name,
39
72
+ CLOCK_PERIOD_TO_HZ(1.0 * clock_get(ncl->clock)));
40
/* TODO: Implement this. */
73
+ }
41
if (offset >= 0x40 && offset < 0xc0) {
74
class = object_get_class(OBJECT(dev));
75
do {
76
qdev_print_props(mon, dev, DEVICE_CLASS(class)->props_, indent);
77
--
42
--
78
2.20.1
43
2.34.1
79
44
80
45
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
These instructions are often used in glibc's string routines.
3
Following docs/devel/style.rst guidelines, rename
4
They were the final uses of the 32-bit at a time neon helpers.
4
stellaris_adc_state -> StellarisADCState. This also remove a
5
use of 'struct' in the DECLARE_INSTANCE_CHECKER() macro call.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20200418162808.4680-1-richard.henderson@linaro.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20230109140306.23161-9-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/helper.h | 27 ++--
12
hw/arm/stellaris.c | 73 +++++++++++++++++++++++-----------------------
12
target/arm/translate.h | 5 +
13
1 file changed, 36 insertions(+), 37 deletions(-)
13
target/arm/neon_helper.c | 24 ----
14
target/arm/translate-a64.c | 64 +++-------
15
target/arm/translate.c | 256 +++++++++++++++++++++++++++++++------
16
target/arm/vec_helper.c | 25 ++++
17
6 files changed, 278 insertions(+), 123 deletions(-)
18
14
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
17
--- a/hw/arm/stellaris.c
22
+++ b/target/arm/helper.h
18
+++ b/hw/arm/stellaris.c
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_hsub_u16, i32, i32, i32)
19
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
24
DEF_HELPER_2(neon_hsub_s32, s32, s32, s32)
20
#define STELLARIS_ADC_FIFO_FULL 0x1000
25
DEF_HELPER_2(neon_hsub_u32, i32, i32, i32)
21
26
22
#define TYPE_STELLARIS_ADC "stellaris-adc"
27
-DEF_HELPER_2(neon_cgt_u8, i32, i32, i32)
23
-typedef struct StellarisADCState stellaris_adc_state;
28
-DEF_HELPER_2(neon_cgt_s8, i32, i32, i32)
24
-DECLARE_INSTANCE_CHECKER(stellaris_adc_state, STELLARIS_ADC,
29
-DEF_HELPER_2(neon_cgt_u16, i32, i32, i32)
25
- TYPE_STELLARIS_ADC)
30
-DEF_HELPER_2(neon_cgt_s16, i32, i32, i32)
26
+typedef struct StellarisADCState StellarisADCState;
31
-DEF_HELPER_2(neon_cgt_u32, i32, i32, i32)
27
+DECLARE_INSTANCE_CHECKER(StellarisADCState, STELLARIS_ADC, TYPE_STELLARIS_ADC)
32
-DEF_HELPER_2(neon_cgt_s32, i32, i32, i32)
28
33
-DEF_HELPER_2(neon_cge_u8, i32, i32, i32)
29
struct StellarisADCState {
34
-DEF_HELPER_2(neon_cge_s8, i32, i32, i32)
30
SysBusDevice parent_obj;
35
-DEF_HELPER_2(neon_cge_u16, i32, i32, i32)
31
@@ -XXX,XX +XXX,XX @@ struct StellarisADCState {
36
-DEF_HELPER_2(neon_cge_s16, i32, i32, i32)
32
qemu_irq irq[4];
37
-DEF_HELPER_2(neon_cge_u32, i32, i32, i32)
33
};
38
-DEF_HELPER_2(neon_cge_s32, i32, i32, i32)
34
39
-
35
-static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
40
DEF_HELPER_2(neon_pmin_u8, i32, i32, i32)
36
+static uint32_t stellaris_adc_fifo_read(StellarisADCState *s, int n)
41
DEF_HELPER_2(neon_pmin_s8, i32, i32, i32)
37
{
42
DEF_HELPER_2(neon_pmin_u16, i32, i32, i32)
38
int tail;
43
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
39
44
DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
40
@@ -XXX,XX +XXX,XX @@ static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
45
DEF_HELPER_2(neon_tst_u16, i32, i32, i32)
41
return s->fifo[n].data[tail];
46
DEF_HELPER_2(neon_tst_u32, i32, i32, i32)
47
-DEF_HELPER_2(neon_ceq_u8, i32, i32, i32)
48
-DEF_HELPER_2(neon_ceq_u16, i32, i32, i32)
49
-DEF_HELPER_2(neon_ceq_u32, i32, i32, i32)
50
51
DEF_HELPER_1(neon_clz_u8, i32, i32)
52
DEF_HELPER_1(neon_clz_u16, i32, i32)
53
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(frint64_s, TCG_CALL_NO_RWG, f32, f32, ptr)
54
DEF_HELPER_FLAGS_2(frint32_d, TCG_CALL_NO_RWG, f64, f64, ptr)
55
DEF_HELPER_FLAGS_2(frint64_d, TCG_CALL_NO_RWG, f64, f64, ptr)
56
57
+DEF_HELPER_FLAGS_3(gvec_ceq0_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
58
+DEF_HELPER_FLAGS_3(gvec_ceq0_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
59
+DEF_HELPER_FLAGS_3(gvec_clt0_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
60
+DEF_HELPER_FLAGS_3(gvec_clt0_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
61
+DEF_HELPER_FLAGS_3(gvec_cle0_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
62
+DEF_HELPER_FLAGS_3(gvec_cle0_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
63
+DEF_HELPER_FLAGS_3(gvec_cgt0_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
64
+DEF_HELPER_FLAGS_3(gvec_cgt0_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
65
+DEF_HELPER_FLAGS_3(gvec_cge0_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
66
+DEF_HELPER_FLAGS_3(gvec_cge0_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
67
+
68
DEF_HELPER_FLAGS_4(gvec_sshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
69
DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
70
DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
71
diff --git a/target/arm/translate.h b/target/arm/translate.h
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate.h
74
+++ b/target/arm/translate.h
75
@@ -XXX,XX +XXX,XX @@ static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
76
uint64_t vfp_expand_imm(int size, uint8_t imm8);
77
78
/* Vector operations shared between ARM and AArch64. */
79
+extern const GVecGen2 ceq0_op[4];
80
+extern const GVecGen2 clt0_op[4];
81
+extern const GVecGen2 cgt0_op[4];
82
+extern const GVecGen2 cle0_op[4];
83
+extern const GVecGen2 cge0_op[4];
84
extern const GVecGen3 mla_op[4];
85
extern const GVecGen3 mls_op[4];
86
extern const GVecGen3 cmtst_op[4];
87
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/neon_helper.c
90
+++ b/target/arm/neon_helper.c
91
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(neon_hsub_u32)(uint32_t src1, uint32_t src2)
92
return dest;
93
}
42
}
94
43
95
-#define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? ~0 : 0
44
-static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
96
-NEON_VOP(cgt_s8, neon_s8, 4)
45
+static void stellaris_adc_fifo_write(StellarisADCState *s, int n,
97
-NEON_VOP(cgt_u8, neon_u8, 4)
46
uint32_t value)
98
-NEON_VOP(cgt_s16, neon_s16, 2)
99
-NEON_VOP(cgt_u16, neon_u16, 2)
100
-NEON_VOP(cgt_s32, neon_s32, 1)
101
-NEON_VOP(cgt_u32, neon_u32, 1)
102
-#undef NEON_FN
103
-
104
-#define NEON_FN(dest, src1, src2) dest = (src1 >= src2) ? ~0 : 0
105
-NEON_VOP(cge_s8, neon_s8, 4)
106
-NEON_VOP(cge_u8, neon_u8, 4)
107
-NEON_VOP(cge_s16, neon_s16, 2)
108
-NEON_VOP(cge_u16, neon_u16, 2)
109
-NEON_VOP(cge_s32, neon_s32, 1)
110
-NEON_VOP(cge_u32, neon_u32, 1)
111
-#undef NEON_FN
112
-
113
#define NEON_FN(dest, src1, src2) dest = (src1 < src2) ? src1 : src2
114
NEON_POP(pmin_s8, neon_s8, 4)
115
NEON_POP(pmin_u8, neon_u8, 4)
116
@@ -XXX,XX +XXX,XX @@ NEON_VOP(tst_u16, neon_u16, 2)
117
NEON_VOP(tst_u32, neon_u32, 1)
118
#undef NEON_FN
119
120
-#define NEON_FN(dest, src1, src2) dest = (src1 == src2) ? -1 : 0
121
-NEON_VOP(ceq_u8, neon_u8, 4)
122
-NEON_VOP(ceq_u16, neon_u16, 2)
123
-NEON_VOP(ceq_u32, neon_u32, 1)
124
-#undef NEON_FN
125
-
126
/* Count Leading Sign/Zero Bits. */
127
static inline int do_clz8(uint8_t x)
128
{
47
{
129
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
48
int head;
130
index XXXXXXX..XXXXXXX 100644
49
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
131
--- a/target/arm/translate-a64.c
50
s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
132
+++ b/target/arm/translate-a64.c
133
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_fn4(DisasContext *s, bool is_q, int rd, int rn, int rm,
134
is_q ? 16 : 8, vec_full_reg_size(s));
135
}
51
}
136
52
137
+/* Expand a 2-operand AdvSIMD vector operation using an op descriptor. */
53
-static void stellaris_adc_update(stellaris_adc_state *s)
138
+static void gen_gvec_op2(DisasContext *s, bool is_q, int rd,
54
+static void stellaris_adc_update(StellarisADCState *s)
139
+ int rn, const GVecGen2 *gvec_op)
140
+{
141
+ tcg_gen_gvec_2(vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
142
+ is_q ? 16 : 8, vec_full_reg_size(s), gvec_op);
143
+}
144
+
145
/* Expand a 2-operand + immediate AdvSIMD vector operation using
146
* an op descriptor.
147
*/
148
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
149
return;
150
}
151
break;
152
+ case 0x8: /* CMGT, CMGE */
153
+ gen_gvec_op2(s, is_q, rd, rn, u ? &cge0_op[size] : &cgt0_op[size]);
154
+ return;
155
+ case 0x9: /* CMEQ, CMLE */
156
+ gen_gvec_op2(s, is_q, rd, rn, u ? &cle0_op[size] : &ceq0_op[size]);
157
+ return;
158
+ case 0xa: /* CMLT */
159
+ gen_gvec_op2(s, is_q, rd, rn, &clt0_op[size]);
160
+ return;
161
case 0xb:
162
if (u) { /* ABS, NEG */
163
gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_neg, size);
164
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
165
for (pass = 0; pass < (is_q ? 4 : 2); pass++) {
166
TCGv_i32 tcg_op = tcg_temp_new_i32();
167
TCGv_i32 tcg_res = tcg_temp_new_i32();
168
- TCGCond cond;
169
170
read_vec_element_i32(s, tcg_op, rn, pass, MO_32);
171
172
if (size == 2) {
173
/* Special cases for 32 bit elements */
174
switch (opcode) {
175
- case 0xa: /* CMLT */
176
- /* 32 bit integer comparison against zero, result is
177
- * test ? (2^32 - 1) : 0. We implement via setcond(test)
178
- * and inverting.
179
- */
180
- cond = TCG_COND_LT;
181
- do_cmop:
182
- tcg_gen_setcondi_i32(cond, tcg_res, tcg_op, 0);
183
- tcg_gen_neg_i32(tcg_res, tcg_res);
184
- break;
185
- case 0x8: /* CMGT, CMGE */
186
- cond = u ? TCG_COND_GE : TCG_COND_GT;
187
- goto do_cmop;
188
- case 0x9: /* CMEQ, CMLE */
189
- cond = u ? TCG_COND_LE : TCG_COND_EQ;
190
- goto do_cmop;
191
case 0x4: /* CLS */
192
if (u) {
193
tcg_gen_clzi_i32(tcg_res, tcg_op, 32);
194
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
195
genfn(tcg_res, cpu_env, tcg_op);
196
break;
197
}
198
- case 0x8: /* CMGT, CMGE */
199
- case 0x9: /* CMEQ, CMLE */
200
- case 0xa: /* CMLT */
201
- {
202
- static NeonGenTwoOpFn * const fns[3][2] = {
203
- { gen_helper_neon_cgt_s8, gen_helper_neon_cgt_s16 },
204
- { gen_helper_neon_cge_s8, gen_helper_neon_cge_s16 },
205
- { gen_helper_neon_ceq_u8, gen_helper_neon_ceq_u16 },
206
- };
207
- NeonGenTwoOpFn *genfn;
208
- int comp;
209
- bool reverse;
210
- TCGv_i32 tcg_zero = tcg_const_i32(0);
211
-
212
- /* comp = index into [CMGT, CMGE, CMEQ, CMLE, CMLT] */
213
- comp = (opcode - 0x8) * 2 + u;
214
- /* ...but LE, LT are implemented as reverse GE, GT */
215
- reverse = (comp > 2);
216
- if (reverse) {
217
- comp = 4 - comp;
218
- }
219
- genfn = fns[comp][size];
220
- if (reverse) {
221
- genfn(tcg_res, tcg_zero, tcg_op);
222
- } else {
223
- genfn(tcg_res, tcg_op, tcg_zero);
224
- }
225
- tcg_temp_free_i32(tcg_zero);
226
- break;
227
- }
228
case 0x4: /* CLS, CLZ */
229
if (u) {
230
if (size == 0) {
231
diff --git a/target/arm/translate.c b/target/arm/translate.c
232
index XXXXXXX..XXXXXXX 100644
233
--- a/target/arm/translate.c
234
+++ b/target/arm/translate.c
235
@@ -XXX,XX +XXX,XX @@ static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
236
return 1;
237
}
238
239
+static void gen_ceq0_i32(TCGv_i32 d, TCGv_i32 a)
240
+{
241
+ tcg_gen_setcondi_i32(TCG_COND_EQ, d, a, 0);
242
+ tcg_gen_neg_i32(d, d);
243
+}
244
+
245
+static void gen_ceq0_i64(TCGv_i64 d, TCGv_i64 a)
246
+{
247
+ tcg_gen_setcondi_i64(TCG_COND_EQ, d, a, 0);
248
+ tcg_gen_neg_i64(d, d);
249
+}
250
+
251
+static void gen_ceq0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
252
+{
253
+ TCGv_vec zero = tcg_const_zeros_vec_matching(d);
254
+ tcg_gen_cmp_vec(TCG_COND_EQ, vece, d, a, zero);
255
+ tcg_temp_free_vec(zero);
256
+}
257
+
258
+static const TCGOpcode vecop_list_cmp[] = {
259
+ INDEX_op_cmp_vec, 0
260
+};
261
+
262
+const GVecGen2 ceq0_op[4] = {
263
+ { .fno = gen_helper_gvec_ceq0_b,
264
+ .fniv = gen_ceq0_vec,
265
+ .opt_opc = vecop_list_cmp,
266
+ .vece = MO_8 },
267
+ { .fno = gen_helper_gvec_ceq0_h,
268
+ .fniv = gen_ceq0_vec,
269
+ .opt_opc = vecop_list_cmp,
270
+ .vece = MO_16 },
271
+ { .fni4 = gen_ceq0_i32,
272
+ .fniv = gen_ceq0_vec,
273
+ .opt_opc = vecop_list_cmp,
274
+ .vece = MO_32 },
275
+ { .fni8 = gen_ceq0_i64,
276
+ .fniv = gen_ceq0_vec,
277
+ .opt_opc = vecop_list_cmp,
278
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
279
+ .vece = MO_64 },
280
+};
281
+
282
+static void gen_cle0_i32(TCGv_i32 d, TCGv_i32 a)
283
+{
284
+ tcg_gen_setcondi_i32(TCG_COND_LE, d, a, 0);
285
+ tcg_gen_neg_i32(d, d);
286
+}
287
+
288
+static void gen_cle0_i64(TCGv_i64 d, TCGv_i64 a)
289
+{
290
+ tcg_gen_setcondi_i64(TCG_COND_LE, d, a, 0);
291
+ tcg_gen_neg_i64(d, d);
292
+}
293
+
294
+static void gen_cle0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
295
+{
296
+ TCGv_vec zero = tcg_const_zeros_vec_matching(d);
297
+ tcg_gen_cmp_vec(TCG_COND_LE, vece, d, a, zero);
298
+ tcg_temp_free_vec(zero);
299
+}
300
+
301
+const GVecGen2 cle0_op[4] = {
302
+ { .fno = gen_helper_gvec_cle0_b,
303
+ .fniv = gen_cle0_vec,
304
+ .opt_opc = vecop_list_cmp,
305
+ .vece = MO_8 },
306
+ { .fno = gen_helper_gvec_cle0_h,
307
+ .fniv = gen_cle0_vec,
308
+ .opt_opc = vecop_list_cmp,
309
+ .vece = MO_16 },
310
+ { .fni4 = gen_cle0_i32,
311
+ .fniv = gen_cle0_vec,
312
+ .opt_opc = vecop_list_cmp,
313
+ .vece = MO_32 },
314
+ { .fni8 = gen_cle0_i64,
315
+ .fniv = gen_cle0_vec,
316
+ .opt_opc = vecop_list_cmp,
317
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
318
+ .vece = MO_64 },
319
+};
320
+
321
+static void gen_cge0_i32(TCGv_i32 d, TCGv_i32 a)
322
+{
323
+ tcg_gen_setcondi_i32(TCG_COND_GE, d, a, 0);
324
+ tcg_gen_neg_i32(d, d);
325
+}
326
+
327
+static void gen_cge0_i64(TCGv_i64 d, TCGv_i64 a)
328
+{
329
+ tcg_gen_setcondi_i64(TCG_COND_GE, d, a, 0);
330
+ tcg_gen_neg_i64(d, d);
331
+}
332
+
333
+static void gen_cge0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
334
+{
335
+ TCGv_vec zero = tcg_const_zeros_vec_matching(d);
336
+ tcg_gen_cmp_vec(TCG_COND_GE, vece, d, a, zero);
337
+ tcg_temp_free_vec(zero);
338
+}
339
+
340
+const GVecGen2 cge0_op[4] = {
341
+ { .fno = gen_helper_gvec_cge0_b,
342
+ .fniv = gen_cge0_vec,
343
+ .opt_opc = vecop_list_cmp,
344
+ .vece = MO_8 },
345
+ { .fno = gen_helper_gvec_cge0_h,
346
+ .fniv = gen_cge0_vec,
347
+ .opt_opc = vecop_list_cmp,
348
+ .vece = MO_16 },
349
+ { .fni4 = gen_cge0_i32,
350
+ .fniv = gen_cge0_vec,
351
+ .opt_opc = vecop_list_cmp,
352
+ .vece = MO_32 },
353
+ { .fni8 = gen_cge0_i64,
354
+ .fniv = gen_cge0_vec,
355
+ .opt_opc = vecop_list_cmp,
356
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
357
+ .vece = MO_64 },
358
+};
359
+
360
+static void gen_clt0_i32(TCGv_i32 d, TCGv_i32 a)
361
+{
362
+ tcg_gen_setcondi_i32(TCG_COND_LT, d, a, 0);
363
+ tcg_gen_neg_i32(d, d);
364
+}
365
+
366
+static void gen_clt0_i64(TCGv_i64 d, TCGv_i64 a)
367
+{
368
+ tcg_gen_setcondi_i64(TCG_COND_LT, d, a, 0);
369
+ tcg_gen_neg_i64(d, d);
370
+}
371
+
372
+static void gen_clt0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
373
+{
374
+ TCGv_vec zero = tcg_const_zeros_vec_matching(d);
375
+ tcg_gen_cmp_vec(TCG_COND_LT, vece, d, a, zero);
376
+ tcg_temp_free_vec(zero);
377
+}
378
+
379
+const GVecGen2 clt0_op[4] = {
380
+ { .fno = gen_helper_gvec_clt0_b,
381
+ .fniv = gen_clt0_vec,
382
+ .opt_opc = vecop_list_cmp,
383
+ .vece = MO_8 },
384
+ { .fno = gen_helper_gvec_clt0_h,
385
+ .fniv = gen_clt0_vec,
386
+ .opt_opc = vecop_list_cmp,
387
+ .vece = MO_16 },
388
+ { .fni4 = gen_clt0_i32,
389
+ .fniv = gen_clt0_vec,
390
+ .opt_opc = vecop_list_cmp,
391
+ .vece = MO_32 },
392
+ { .fni8 = gen_clt0_i64,
393
+ .fniv = gen_clt0_vec,
394
+ .opt_opc = vecop_list_cmp,
395
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
396
+ .vece = MO_64 },
397
+};
398
+
399
+static void gen_cgt0_i32(TCGv_i32 d, TCGv_i32 a)
400
+{
401
+ tcg_gen_setcondi_i32(TCG_COND_GT, d, a, 0);
402
+ tcg_gen_neg_i32(d, d);
403
+}
404
+
405
+static void gen_cgt0_i64(TCGv_i64 d, TCGv_i64 a)
406
+{
407
+ tcg_gen_setcondi_i64(TCG_COND_GT, d, a, 0);
408
+ tcg_gen_neg_i64(d, d);
409
+}
410
+
411
+static void gen_cgt0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
412
+{
413
+ TCGv_vec zero = tcg_const_zeros_vec_matching(d);
414
+ tcg_gen_cmp_vec(TCG_COND_GT, vece, d, a, zero);
415
+ tcg_temp_free_vec(zero);
416
+}
417
+
418
+const GVecGen2 cgt0_op[4] = {
419
+ { .fno = gen_helper_gvec_cgt0_b,
420
+ .fniv = gen_cgt0_vec,
421
+ .opt_opc = vecop_list_cmp,
422
+ .vece = MO_8 },
423
+ { .fno = gen_helper_gvec_cgt0_h,
424
+ .fniv = gen_cgt0_vec,
425
+ .opt_opc = vecop_list_cmp,
426
+ .vece = MO_16 },
427
+ { .fni4 = gen_cgt0_i32,
428
+ .fniv = gen_cgt0_vec,
429
+ .opt_opc = vecop_list_cmp,
430
+ .vece = MO_32 },
431
+ { .fni8 = gen_cgt0_i64,
432
+ .fniv = gen_cgt0_vec,
433
+ .opt_opc = vecop_list_cmp,
434
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
435
+ .vece = MO_64 },
436
+};
437
+
438
static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
439
{
55
{
440
tcg_gen_vec_sar8i_i64(a, a, shift);
56
int level;
441
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
57
int n;
442
tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
58
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_update(stellaris_adc_state *s)
443
break;
59
444
60
static void stellaris_adc_trigger(void *opaque, int irq, int level)
445
+ case NEON_2RM_VCEQ0:
61
{
446
+ tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
62
- stellaris_adc_state *s = opaque;
447
+ vec_size, &ceq0_op[size]);
63
+ StellarisADCState *s = opaque;
448
+ break;
64
int n;
449
+ case NEON_2RM_VCGT0:
65
450
+ tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
66
for (n = 0; n < 4; n++) {
451
+ vec_size, &cgt0_op[size]);
67
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
452
+ break;
453
+ case NEON_2RM_VCLE0:
454
+ tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
455
+ vec_size, &cle0_op[size]);
456
+ break;
457
+ case NEON_2RM_VCGE0:
458
+ tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
459
+ vec_size, &cge0_op[size]);
460
+ break;
461
+ case NEON_2RM_VCLT0:
462
+ tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
463
+ vec_size, &clt0_op[size]);
464
+ break;
465
+
466
default:
467
elementwise:
468
for (pass = 0; pass < (q ? 4 : 2); pass++) {
469
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
470
default: abort();
471
}
472
break;
473
- case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
474
- tmp2 = tcg_const_i32(0);
475
- switch(size) {
476
- case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
477
- case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
478
- case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
479
- default: abort();
480
- }
481
- tcg_temp_free_i32(tmp2);
482
- if (op == NEON_2RM_VCLE0) {
483
- tcg_gen_not_i32(tmp, tmp);
484
- }
485
- break;
486
- case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
487
- tmp2 = tcg_const_i32(0);
488
- switch(size) {
489
- case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
490
- case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
491
- case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
492
- default: abort();
493
- }
494
- tcg_temp_free_i32(tmp2);
495
- if (op == NEON_2RM_VCLT0) {
496
- tcg_gen_not_i32(tmp, tmp);
497
- }
498
- break;
499
- case NEON_2RM_VCEQ0:
500
- tmp2 = tcg_const_i32(0);
501
- switch(size) {
502
- case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
503
- case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
504
- case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
505
- default: abort();
506
- }
507
- tcg_temp_free_i32(tmp2);
508
- break;
509
case NEON_2RM_VCGT0_F:
510
{
511
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
512
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
513
index XXXXXXX..XXXXXXX 100644
514
--- a/target/arm/vec_helper.c
515
+++ b/target/arm/vec_helper.c
516
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_pmull_h)(void *vd, void *vn, void *vm, uint32_t desc)
517
}
68
}
518
}
69
}
519
#endif
70
520
+
71
-static void stellaris_adc_reset(stellaris_adc_state *s)
521
+#define DO_CMP0(NAME, TYPE, OP) \
72
+static void stellaris_adc_reset(StellarisADCState *s)
522
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
73
{
523
+{ \
74
int n;
524
+ intptr_t i, opr_sz = simd_oprsz(desc); \
75
525
+ for (i = 0; i < opr_sz; i += sizeof(TYPE)) { \
76
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_reset(stellaris_adc_state *s)
526
+ TYPE nn = *(TYPE *)(vn + i); \
77
static uint64_t stellaris_adc_read(void *opaque, hwaddr offset,
527
+ *(TYPE *)(vd + i) = -(nn OP 0); \
78
unsigned size)
528
+ } \
79
{
529
+ clear_tail(vd, opr_sz, simd_maxsz(desc)); \
80
- stellaris_adc_state *s = opaque;
530
+}
81
+ StellarisADCState *s = opaque;
531
+
82
532
+DO_CMP0(gvec_ceq0_b, int8_t, ==)
83
/* TODO: Implement this. */
533
+DO_CMP0(gvec_clt0_b, int8_t, <)
84
if (offset >= 0x40 && offset < 0xc0) {
534
+DO_CMP0(gvec_cle0_b, int8_t, <=)
85
@@ -XXX,XX +XXX,XX @@ static uint64_t stellaris_adc_read(void *opaque, hwaddr offset,
535
+DO_CMP0(gvec_cgt0_b, int8_t, >)
86
static void stellaris_adc_write(void *opaque, hwaddr offset,
536
+DO_CMP0(gvec_cge0_b, int8_t, >=)
87
uint64_t value, unsigned size)
537
+
88
{
538
+DO_CMP0(gvec_ceq0_h, int16_t, ==)
89
- stellaris_adc_state *s = opaque;
539
+DO_CMP0(gvec_clt0_h, int16_t, <)
90
+ StellarisADCState *s = opaque;
540
+DO_CMP0(gvec_cle0_h, int16_t, <=)
91
541
+DO_CMP0(gvec_cgt0_h, int16_t, >)
92
/* TODO: Implement this. */
542
+DO_CMP0(gvec_cge0_h, int16_t, >=)
93
if (offset >= 0x40 && offset < 0xc0) {
543
+
94
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_adc = {
544
+#undef DO_CMP0
95
.version_id = 1,
96
.minimum_version_id = 1,
97
.fields = (VMStateField[]) {
98
- VMSTATE_UINT32(actss, stellaris_adc_state),
99
- VMSTATE_UINT32(ris, stellaris_adc_state),
100
- VMSTATE_UINT32(im, stellaris_adc_state),
101
- VMSTATE_UINT32(emux, stellaris_adc_state),
102
- VMSTATE_UINT32(ostat, stellaris_adc_state),
103
- VMSTATE_UINT32(ustat, stellaris_adc_state),
104
- VMSTATE_UINT32(sspri, stellaris_adc_state),
105
- VMSTATE_UINT32(sac, stellaris_adc_state),
106
- VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
107
- VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
108
- VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
109
- VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
110
- VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
111
- VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
112
- VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
113
- VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
114
- VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
115
- VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
116
- VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
117
- VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
118
- VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
119
- VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
120
- VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
121
- VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
122
- VMSTATE_UINT32(noise, stellaris_adc_state),
123
+ VMSTATE_UINT32(actss, StellarisADCState),
124
+ VMSTATE_UINT32(ris, StellarisADCState),
125
+ VMSTATE_UINT32(im, StellarisADCState),
126
+ VMSTATE_UINT32(emux, StellarisADCState),
127
+ VMSTATE_UINT32(ostat, StellarisADCState),
128
+ VMSTATE_UINT32(ustat, StellarisADCState),
129
+ VMSTATE_UINT32(sspri, StellarisADCState),
130
+ VMSTATE_UINT32(sac, StellarisADCState),
131
+ VMSTATE_UINT32(fifo[0].state, StellarisADCState),
132
+ VMSTATE_UINT32_ARRAY(fifo[0].data, StellarisADCState, 16),
133
+ VMSTATE_UINT32(ssmux[0], StellarisADCState),
134
+ VMSTATE_UINT32(ssctl[0], StellarisADCState),
135
+ VMSTATE_UINT32(fifo[1].state, StellarisADCState),
136
+ VMSTATE_UINT32_ARRAY(fifo[1].data, StellarisADCState, 16),
137
+ VMSTATE_UINT32(ssmux[1], StellarisADCState),
138
+ VMSTATE_UINT32(ssctl[1], StellarisADCState),
139
+ VMSTATE_UINT32(fifo[2].state, StellarisADCState),
140
+ VMSTATE_UINT32_ARRAY(fifo[2].data, StellarisADCState, 16),
141
+ VMSTATE_UINT32(ssmux[2], StellarisADCState),
142
+ VMSTATE_UINT32(ssctl[2], StellarisADCState),
143
+ VMSTATE_UINT32(fifo[3].state, StellarisADCState),
144
+ VMSTATE_UINT32_ARRAY(fifo[3].data, StellarisADCState, 16),
145
+ VMSTATE_UINT32(ssmux[3], StellarisADCState),
146
+ VMSTATE_UINT32(ssctl[3], StellarisADCState),
147
+ VMSTATE_UINT32(noise, StellarisADCState),
148
VMSTATE_END_OF_LIST()
149
}
150
};
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_adc = {
152
static void stellaris_adc_init(Object *obj)
153
{
154
DeviceState *dev = DEVICE(obj);
155
- stellaris_adc_state *s = STELLARIS_ADC(obj);
156
+ StellarisADCState *s = STELLARIS_ADC(obj);
157
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
158
int n;
159
160
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_class_init(ObjectClass *klass, void *data)
161
static const TypeInfo stellaris_adc_info = {
162
.name = TYPE_STELLARIS_ADC,
163
.parent = TYPE_SYS_BUS_DEVICE,
164
- .instance_size = sizeof(stellaris_adc_state),
165
+ .instance_size = sizeof(StellarisADCState),
166
.instance_init = stellaris_adc_init,
167
.class_init = stellaris_adc_class_init,
168
};
545
--
169
--
546
2.20.1
170
2.34.1
547
171
548
172
diff view generated by jsdifflib
1
From: Subbaraya Sundeep <sundeep.lkml@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
In addition to simple serial test this patch uses ping
3
The typedef and definitions are generated by the OBJECT_DECLARE_TYPE
4
to test the ethernet block modelled in SmartFusion2 SoC.
4
macro in "hw/arm/bcm2836.h":
5
5
6
Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
6
20 #define TYPE_BCM283X "bcm283x"
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
21 OBJECT_DECLARE_TYPE(BCM283XState, BCM283XClass, BCM283X)
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
9
Message-id: 1587048891-30493-4-git-send-email-sundeep.lkml@gmail.com
9
The script ran in commit a489d1951c ("Use OBJECT_DECLARE_TYPE when
10
possible") missed them because they are declared in a different
11
file unit. Remove them.
12
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20230109140306.23161-10-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
tests/acceptance/boot_linux_console.py | 15 ++++++++++-----
18
hw/arm/bcm2836.c | 9 ++-------
13
1 file changed, 10 insertions(+), 5 deletions(-)
19
1 file changed, 2 insertions(+), 7 deletions(-)
14
20
15
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
21
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/acceptance/boot_linux_console.py
23
--- a/hw/arm/bcm2836.c
18
+++ b/tests/acceptance/boot_linux_console.py
24
+++ b/hw/arm/bcm2836.c
19
@@ -XXX,XX +XXX,XX @@ class BootLinuxConsole(Test):
25
@@ -XXX,XX +XXX,XX @@
20
"""
26
#include "hw/arm/raspi_platform.h"
21
uboot_url = ('https://raw.githubusercontent.com/'
27
#include "hw/sysbus.h"
22
'Subbaraya-Sundeep/qemu-test-binaries/'
28
23
- 'fa030bd77a014a0b8e360d3b7011df89283a2f0b/u-boot')
29
-typedef struct BCM283XClass {
24
- uboot_hash = 'abba5d9c24cdd2d49cdc2a8aa92976cf20737eff'
30
+struct BCM283XClass {
25
+ 'fe371d32e50ca682391e1e70ab98c2942aeffb01/u-boot')
31
/*< private >*/
26
+ uboot_hash = 'cbb8cbab970f594bf6523b9855be209c08374ae2'
32
DeviceClass parent_class;
27
uboot_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash)
33
/*< public >*/
28
spi_url = ('https://raw.githubusercontent.com/'
34
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XClass {
29
'Subbaraya-Sundeep/qemu-test-binaries/'
35
hwaddr peri_base; /* Peripheral base address seen by the CPU */
30
- 'fa030bd77a014a0b8e360d3b7011df89283a2f0b/spi.bin')
36
hwaddr ctrl_base; /* Interrupt controller and mailboxes etc. */
31
- spi_hash = '85f698329d38de63aea6e884a86fbde70890a78a'
37
int clusterid;
32
+ 'fe371d32e50ca682391e1e70ab98c2942aeffb01/spi.bin')
38
-} BCM283XClass;
33
+ spi_hash = '65523a1835949b6f4553be96dec1b6a38fb05501'
39
-
34
spi_path = self.fetch_asset(spi_url, asset_hash=spi_hash)
40
-#define BCM283X_CLASS(klass) \
35
41
- OBJECT_CLASS_CHECK(BCM283XClass, (klass), TYPE_BCM283X)
36
self.vm.set_console()
42
-#define BCM283X_GET_CLASS(obj) \
37
@@ -XXX,XX +XXX,XX @@ class BootLinuxConsole(Test):
43
- OBJECT_GET_CLASS(BCM283XClass, (obj), TYPE_BCM283X)
38
'-drive', 'file=' + spi_path + ',if=mtd,format=raw',
44
+};
39
'-no-reboot')
45
40
self.vm.launch()
46
static Property bcm2836_enabled_cores_property =
41
- self.wait_for_console_pattern('init started: BusyBox')
47
DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus, 0);
42
+ self.wait_for_console_pattern('Enter \'help\' for a list')
43
+
44
+ exec_command_and_wait_for_pattern(self, 'ifconfig eth0 10.0.2.15',
45
+ 'eth0: link becomes ready')
46
+ exec_command_and_wait_for_pattern(self, 'ping -c 3 10.0.2.2',
47
+ '3 packets transmitted, 3 packets received, 0% packet loss')
48
49
def do_test_arm_raspi2(self, uart_id):
50
"""
51
--
48
--
52
2.20.1
49
2.34.1
53
50
54
51
diff view generated by jsdifflib
New patch
1
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
3
NPCM7XX models have been commited after the conversion from
4
commit 8063396bf3 ("Use OBJECT_DECLARE_SIMPLE_TYPE when possible").
5
Manually convert them.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109140306.23161-11-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/adc/npcm7xx_adc.h | 7 +++----
13
include/hw/arm/npcm7xx.h | 18 ++++++------------
14
include/hw/i2c/npcm7xx_smbus.h | 7 +++----
15
include/hw/misc/npcm7xx_clk.h | 2 +-
16
include/hw/misc/npcm7xx_gcr.h | 6 +++---
17
include/hw/misc/npcm7xx_mft.h | 7 +++----
18
include/hw/misc/npcm7xx_pwm.h | 3 +--
19
include/hw/misc/npcm7xx_rng.h | 6 +++---
20
include/hw/net/npcm7xx_emc.h | 5 +----
21
include/hw/sd/npcm7xx_sdhci.h | 4 ++--
22
10 files changed, 26 insertions(+), 39 deletions(-)
23
24
diff --git a/include/hw/adc/npcm7xx_adc.h b/include/hw/adc/npcm7xx_adc.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/adc/npcm7xx_adc.h
27
+++ b/include/hw/adc/npcm7xx_adc.h
28
@@ -XXX,XX +XXX,XX @@
29
* @iref: The internal reference voltage, initialized at launch time.
30
* @rv: The calibrated output values of 0.5V and 1.5V for the ADC.
31
*/
32
-typedef struct {
33
+struct NPCM7xxADCState {
34
SysBusDevice parent;
35
36
MemoryRegion iomem;
37
@@ -XXX,XX +XXX,XX @@ typedef struct {
38
uint32_t iref;
39
40
uint16_t calibration_r_values[NPCM7XX_ADC_NUM_CALIB];
41
-} NPCM7xxADCState;
42
+};
43
44
#define TYPE_NPCM7XX_ADC "npcm7xx-adc"
45
-#define NPCM7XX_ADC(obj) \
46
- OBJECT_CHECK(NPCM7xxADCState, (obj), TYPE_NPCM7XX_ADC)
47
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxADCState, NPCM7XX_ADC)
48
49
#endif /* NPCM7XX_ADC_H */
50
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/hw/arm/npcm7xx.h
53
+++ b/include/hw/arm/npcm7xx.h
54
@@ -XXX,XX +XXX,XX @@
55
56
#define NPCM7XX_NR_PWM_MODULES 2
57
58
-typedef struct NPCM7xxMachine {
59
+struct NPCM7xxMachine {
60
MachineState parent;
61
/*
62
* PWM fan splitter. each splitter connects to one PWM output and
63
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxMachine {
64
*/
65
SplitIRQ fan_splitter[NPCM7XX_NR_PWM_MODULES *
66
NPCM7XX_PWM_PER_MODULE];
67
-} NPCM7xxMachine;
68
+};
69
70
#define TYPE_NPCM7XX_MACHINE MACHINE_TYPE_NAME("npcm7xx")
71
-#define NPCM7XX_MACHINE(obj) \
72
- OBJECT_CHECK(NPCM7xxMachine, (obj), TYPE_NPCM7XX_MACHINE)
73
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxMachine, NPCM7XX_MACHINE)
74
75
typedef struct NPCM7xxMachineClass {
76
MachineClass parent;
77
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxMachineClass {
78
#define NPCM7XX_MACHINE_GET_CLASS(obj) \
79
OBJECT_GET_CLASS(NPCM7xxMachineClass, (obj), TYPE_NPCM7XX_MACHINE)
80
81
-typedef struct NPCM7xxState {
82
+struct NPCM7xxState {
83
DeviceState parent;
84
85
ARMCPU cpu[NPCM7XX_MAX_NUM_CPUS];
86
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
87
NPCM7xxFIUState fiu[2];
88
NPCM7xxEMCState emc[2];
89
NPCM7xxSDHCIState mmc;
90
-} NPCM7xxState;
91
+};
92
93
#define TYPE_NPCM7XX "npcm7xx"
94
-#define NPCM7XX(obj) OBJECT_CHECK(NPCM7xxState, (obj), TYPE_NPCM7XX)
95
+OBJECT_DECLARE_TYPE(NPCM7xxState, NPCM7xxClass, NPCM7XX)
96
97
#define TYPE_NPCM730 "npcm730"
98
#define TYPE_NPCM750 "npcm750"
99
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxClass {
100
uint32_t num_cpus;
101
} NPCM7xxClass;
102
103
-#define NPCM7XX_CLASS(klass) \
104
- OBJECT_CLASS_CHECK(NPCM7xxClass, (klass), TYPE_NPCM7XX)
105
-#define NPCM7XX_GET_CLASS(obj) \
106
- OBJECT_GET_CLASS(NPCM7xxClass, (obj), TYPE_NPCM7XX)
107
-
108
/**
109
* npcm7xx_load_kernel - Loads memory with everything needed to boot
110
* @machine - The machine containing the SoC to be booted.
111
diff --git a/include/hw/i2c/npcm7xx_smbus.h b/include/hw/i2c/npcm7xx_smbus.h
112
index XXXXXXX..XXXXXXX 100644
113
--- a/include/hw/i2c/npcm7xx_smbus.h
114
+++ b/include/hw/i2c/npcm7xx_smbus.h
115
@@ -XXX,XX +XXX,XX @@ typedef enum NPCM7xxSMBusStatus {
116
* @rx_cur: The current position of rx_fifo.
117
* @status: The current status of the SMBus.
118
*/
119
-typedef struct NPCM7xxSMBusState {
120
+struct NPCM7xxSMBusState {
121
SysBusDevice parent;
122
123
MemoryRegion iomem;
124
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxSMBusState {
125
uint8_t rx_cur;
126
127
NPCM7xxSMBusStatus status;
128
-} NPCM7xxSMBusState;
129
+};
130
131
#define TYPE_NPCM7XX_SMBUS "npcm7xx-smbus"
132
-#define NPCM7XX_SMBUS(obj) OBJECT_CHECK(NPCM7xxSMBusState, (obj), \
133
- TYPE_NPCM7XX_SMBUS)
134
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxSMBusState, NPCM7XX_SMBUS)
135
136
#endif /* NPCM7XX_SMBUS_H */
137
diff --git a/include/hw/misc/npcm7xx_clk.h b/include/hw/misc/npcm7xx_clk.h
138
index XXXXXXX..XXXXXXX 100644
139
--- a/include/hw/misc/npcm7xx_clk.h
140
+++ b/include/hw/misc/npcm7xx_clk.h
141
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxCLKState {
142
};
143
144
#define TYPE_NPCM7XX_CLK "npcm7xx-clk"
145
-#define NPCM7XX_CLK(obj) OBJECT_CHECK(NPCM7xxCLKState, (obj), TYPE_NPCM7XX_CLK)
146
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxCLKState, NPCM7XX_CLK)
147
148
#endif /* NPCM7XX_CLK_H */
149
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
150
index XXXXXXX..XXXXXXX 100644
151
--- a/include/hw/misc/npcm7xx_gcr.h
152
+++ b/include/hw/misc/npcm7xx_gcr.h
153
@@ -XXX,XX +XXX,XX @@
154
*/
155
#define NPCM7XX_GCR_NR_REGS (0x148 / sizeof(uint32_t))
156
157
-typedef struct NPCM7xxGCRState {
158
+struct NPCM7xxGCRState {
159
SysBusDevice parent;
160
161
MemoryRegion iomem;
162
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxGCRState {
163
uint32_t reset_pwron;
164
uint32_t reset_mdlr;
165
uint32_t reset_intcr3;
166
-} NPCM7xxGCRState;
167
+};
168
169
#define TYPE_NPCM7XX_GCR "npcm7xx-gcr"
170
-#define NPCM7XX_GCR(obj) OBJECT_CHECK(NPCM7xxGCRState, (obj), TYPE_NPCM7XX_GCR)
171
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxGCRState, NPCM7XX_GCR)
172
173
#endif /* NPCM7XX_GCR_H */
174
diff --git a/include/hw/misc/npcm7xx_mft.h b/include/hw/misc/npcm7xx_mft.h
175
index XXXXXXX..XXXXXXX 100644
176
--- a/include/hw/misc/npcm7xx_mft.h
177
+++ b/include/hw/misc/npcm7xx_mft.h
178
@@ -XXX,XX +XXX,XX @@
179
* @max_rpm: The maximum rpm for fans. Order: A0, B0, A1, B1.
180
* @duty: The duty cycles for fans, relative to NPCM7XX_PWM_MAX_DUTY.
181
*/
182
-typedef struct NPCM7xxMFTState {
183
+struct NPCM7xxMFTState {
184
SysBusDevice parent;
185
186
MemoryRegion iomem;
187
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxMFTState {
188
189
uint32_t max_rpm[NPCM7XX_MFT_FANIN_COUNT];
190
uint32_t duty[NPCM7XX_MFT_FANIN_COUNT];
191
-} NPCM7xxMFTState;
192
+};
193
194
#define TYPE_NPCM7XX_MFT "npcm7xx-mft"
195
-#define NPCM7XX_MFT(obj) \
196
- OBJECT_CHECK(NPCM7xxMFTState, (obj), TYPE_NPCM7XX_MFT)
197
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxMFTState, NPCM7XX_MFT)
198
199
#endif /* NPCM7XX_MFT_H */
200
diff --git a/include/hw/misc/npcm7xx_pwm.h b/include/hw/misc/npcm7xx_pwm.h
201
index XXXXXXX..XXXXXXX 100644
202
--- a/include/hw/misc/npcm7xx_pwm.h
203
+++ b/include/hw/misc/npcm7xx_pwm.h
204
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxPWMState {
205
};
206
207
#define TYPE_NPCM7XX_PWM "npcm7xx-pwm"
208
-#define NPCM7XX_PWM(obj) \
209
- OBJECT_CHECK(NPCM7xxPWMState, (obj), TYPE_NPCM7XX_PWM)
210
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxPWMState, NPCM7XX_PWM)
211
212
#endif /* NPCM7XX_PWM_H */
213
diff --git a/include/hw/misc/npcm7xx_rng.h b/include/hw/misc/npcm7xx_rng.h
214
index XXXXXXX..XXXXXXX 100644
215
--- a/include/hw/misc/npcm7xx_rng.h
216
+++ b/include/hw/misc/npcm7xx_rng.h
217
@@ -XXX,XX +XXX,XX @@
218
219
#include "hw/sysbus.h"
220
221
-typedef struct NPCM7xxRNGState {
222
+struct NPCM7xxRNGState {
223
SysBusDevice parent;
224
225
MemoryRegion iomem;
226
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxRNGState {
227
uint8_t rngcs;
228
uint8_t rngd;
229
uint8_t rngmode;
230
-} NPCM7xxRNGState;
231
+};
232
233
#define TYPE_NPCM7XX_RNG "npcm7xx-rng"
234
-#define NPCM7XX_RNG(obj) OBJECT_CHECK(NPCM7xxRNGState, (obj), TYPE_NPCM7XX_RNG)
235
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxRNGState, NPCM7XX_RNG)
236
237
#endif /* NPCM7XX_RNG_H */
238
diff --git a/include/hw/net/npcm7xx_emc.h b/include/hw/net/npcm7xx_emc.h
239
index XXXXXXX..XXXXXXX 100644
240
--- a/include/hw/net/npcm7xx_emc.h
241
+++ b/include/hw/net/npcm7xx_emc.h
242
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxEMCState {
243
bool rx_active;
244
};
245
246
-typedef struct NPCM7xxEMCState NPCM7xxEMCState;
247
-
248
#define TYPE_NPCM7XX_EMC "npcm7xx-emc"
249
-#define NPCM7XX_EMC(obj) \
250
- OBJECT_CHECK(NPCM7xxEMCState, (obj), TYPE_NPCM7XX_EMC)
251
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxEMCState, NPCM7XX_EMC)
252
253
#endif /* NPCM7XX_EMC_H */
254
diff --git a/include/hw/sd/npcm7xx_sdhci.h b/include/hw/sd/npcm7xx_sdhci.h
255
index XXXXXXX..XXXXXXX 100644
256
--- a/include/hw/sd/npcm7xx_sdhci.h
257
+++ b/include/hw/sd/npcm7xx_sdhci.h
258
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxRegs {
259
uint32_t boottoctrl;
260
} NPCM7xxRegisters;
261
262
-typedef struct NPCM7xxSDHCIState {
263
+struct NPCM7xxSDHCIState {
264
SysBusDevice parent;
265
266
MemoryRegion container;
267
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxSDHCIState {
268
NPCM7xxRegisters regs;
269
270
SDHCIState sdhci;
271
-} NPCM7xxSDHCIState;
272
+};
273
274
#endif /* NPCM7XX_SDHCI_H */
275
--
276
2.34.1
277
278
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Introduce a function and macro helpers to setup several clocks
3
The structure is named SECUREECState. Rename the type accordingly.
4
in a device from a static array description.
5
4
6
An element of the array describes the clock (name and direction) as
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
well as the related callback and an optional offset to store the
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
created object pointer in the device state structure.
7
Message-id: 20230109140306.23161-12-philmd@linaro.org
9
10
The array must be terminated by a special element QDEV_CLOCK_END.
11
12
This is based on the original work of Frederic Konrad.
13
14
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
18
Message-id: 20200406135251.157596-5-damien.hedde@greensocs.com
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
9
---
21
include/hw/qdev-clock.h | 55 +++++++++++++++++++++++++++++++++++++++++
10
hw/misc/sbsa_ec.c | 13 +++++++------
22
hw/core/qdev-clock.c | 17 +++++++++++++
11
1 file changed, 7 insertions(+), 6 deletions(-)
23
2 files changed, 72 insertions(+)
24
12
25
diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h
13
diff --git a/hw/misc/sbsa_ec.c b/hw/misc/sbsa_ec.c
26
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/qdev-clock.h
15
--- a/hw/misc/sbsa_ec.c
28
+++ b/include/hw/qdev-clock.h
16
+++ b/hw/misc/sbsa_ec.c
29
@@ -XXX,XX +XXX,XX @@ Clock *qdev_alias_clock(DeviceState *dev, const char *name,
17
@@ -XXX,XX +XXX,XX @@
30
*/
18
#include "hw/sysbus.h"
31
void qdev_finalize_clocklist(DeviceState *dev);
19
#include "sysemu/runstate.h"
32
20
33
+/**
21
-typedef struct {
34
+ * ClockPortInitElem:
22
+typedef struct SECUREECState {
35
+ * @name: name of the clock (can't be NULL)
23
SysBusDevice parent_obj;
36
+ * @output: indicates whether the clock is input or output
24
MemoryRegion iomem;
37
+ * @callback: for inputs, optional callback to be called on clock's update
25
} SECUREECState;
38
+ * with device as opaque
26
39
+ * @offset: optional offset to store the ClockIn or ClockOut pointer in device
27
-#define TYPE_SBSA_EC "sbsa-ec"
40
+ * state structure (0 means unused)
28
-#define SECURE_EC(obj) OBJECT_CHECK(SECUREECState, (obj), TYPE_SBSA_EC)
41
+ */
29
+#define TYPE_SBSA_SECURE_EC "sbsa-ec"
42
+struct ClockPortInitElem {
30
+#define SBSA_SECURE_EC(obj) \
43
+ const char *name;
31
+ OBJECT_CHECK(SECUREECState, (obj), TYPE_SBSA_SECURE_EC)
44
+ bool is_output;
32
45
+ ClockCallback *callback;
33
enum sbsa_ec_powerstates {
46
+ size_t offset;
34
SBSA_EC_CMD_POWEROFF = 0x01,
47
+};
35
@@ -XXX,XX +XXX,XX @@ static uint64_t sbsa_ec_read(void *opaque, hwaddr offset, unsigned size)
48
+
49
+#define clock_offset_value(devstate, field) \
50
+ (offsetof(devstate, field) + \
51
+ type_check(Clock *, typeof_field(devstate, field)))
52
+
53
+#define QDEV_CLOCK(out_not_in, devstate, field, cb) { \
54
+ .name = (stringify(field)), \
55
+ .is_output = out_not_in, \
56
+ .callback = cb, \
57
+ .offset = clock_offset_value(devstate, field), \
58
+}
59
+
60
+/**
61
+ * QDEV_CLOCK_(IN|OUT):
62
+ * @devstate: structure type. @dev argument of qdev_init_clocks below must be
63
+ * a pointer to that same type.
64
+ * @field: a field in @_devstate (must be Clock*)
65
+ * @callback: (for input only) callback (or NULL) to be called with the device
66
+ * state as argument
67
+ *
68
+ * The name of the clock will be derived from @field
69
+ */
70
+#define QDEV_CLOCK_IN(devstate, field, callback) \
71
+ QDEV_CLOCK(false, devstate, field, callback)
72
+
73
+#define QDEV_CLOCK_OUT(devstate, field) \
74
+ QDEV_CLOCK(true, devstate, field, NULL)
75
+
76
+#define QDEV_CLOCK_END { .name = NULL }
77
+
78
+typedef struct ClockPortInitElem ClockPortInitArray[];
79
+
80
+/**
81
+ * qdev_init_clocks:
82
+ * @dev: the device to add clocks to
83
+ * @clocks: a QDEV_CLOCK_END-terminated array which contains the
84
+ * clocks information.
85
+ */
86
+void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks);
87
+
88
#endif /* QDEV_CLOCK_H */
89
diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/hw/core/qdev-clock.c
92
+++ b/hw/core/qdev-clock.c
93
@@ -XXX,XX +XXX,XX @@ Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
94
return ncl->clock;
95
}
36
}
96
37
97
+void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks)
38
static void sbsa_ec_write(void *opaque, hwaddr offset,
98
+{
39
- uint64_t value, unsigned size)
99
+ const struct ClockPortInitElem *elem;
40
+ uint64_t value, unsigned size)
100
+
101
+ for (elem = &clocks[0]; elem->name != NULL; elem++) {
102
+ Clock **clkp;
103
+ /* offset cannot be inside the DeviceState part */
104
+ assert(elem->offset > sizeof(DeviceState));
105
+ clkp = (Clock **)(((void *) dev) + elem->offset);
106
+ if (elem->is_output) {
107
+ *clkp = qdev_init_clock_out(dev, elem->name);
108
+ } else {
109
+ *clkp = qdev_init_clock_in(dev, elem->name, elem->callback, dev);
110
+ }
111
+ }
112
+}
113
+
114
static NamedClockList *qdev_get_clocklist(DeviceState *dev, const char *name)
115
{
41
{
116
NamedClockList *ncl;
42
if (offset == 0) { /* PSCI machine power command register */
43
switch (value) {
44
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps sbsa_ec_ops = {
45
46
static void sbsa_ec_init(Object *obj)
47
{
48
- SECUREECState *s = SECURE_EC(obj);
49
+ SECUREECState *s = SBSA_SECURE_EC(obj);
50
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
51
52
memory_region_init_io(&s->iomem, obj, &sbsa_ec_ops, s, "sbsa-ec",
53
@@ -XXX,XX +XXX,XX @@ static void sbsa_ec_class_init(ObjectClass *klass, void *data)
54
}
55
56
static const TypeInfo sbsa_ec_info = {
57
- .name = TYPE_SBSA_EC,
58
+ .name = TYPE_SBSA_SECURE_EC,
59
.parent = TYPE_SYS_BUS_DEVICE,
60
.instance_size = sizeof(SECUREECState),
61
.instance_init = sbsa_ec_init,
117
--
62
--
118
2.20.1
63
2.34.1
119
64
120
65
diff view generated by jsdifflib
1
From: Keqian Zhu <zhukeqian1@huawei.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The KVM_VGIC_ATTR macro expect the second parameter as gicr_typer,
3
This model was merged few days before the QOM cleanup from
4
of which high 32bit is constructed by mp_affinity. For most case,
4
commit 8063396bf3 ("Use OBJECT_DECLARE_SIMPLE_TYPE when possible")
5
the high 32bit of mp_affinity is zero, so it will always access the
5
was pulled and merged. Manually adapt.
6
ICC_CTLR_EL1 of CPU0.
7
6
8
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20200413091552.62748-2-zhukeqian1@huawei.com
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20230109140306.23161-13-philmd@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
hw/intc/arm_gicv3_kvm.c | 4 +---
12
hw/misc/sbsa_ec.c | 3 +--
14
1 file changed, 1 insertion(+), 3 deletions(-)
13
1 file changed, 1 insertion(+), 2 deletions(-)
15
14
16
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
15
diff --git a/hw/misc/sbsa_ec.c b/hw/misc/sbsa_ec.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/arm_gicv3_kvm.c
17
--- a/hw/misc/sbsa_ec.c
19
+++ b/hw/intc/arm_gicv3_kvm.c
18
+++ b/hw/misc/sbsa_ec.c
20
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_get(GICv3State *s)
19
@@ -XXX,XX +XXX,XX @@ typedef struct SECUREECState {
21
20
} SECUREECState;
22
static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
21
23
{
22
#define TYPE_SBSA_SECURE_EC "sbsa-ec"
24
- ARMCPU *cpu;
23
-#define SBSA_SECURE_EC(obj) \
25
GICv3State *s;
24
- OBJECT_CHECK(SECUREECState, (obj), TYPE_SBSA_SECURE_EC)
26
GICv3CPUState *c;
25
+OBJECT_DECLARE_SIMPLE_TYPE(SECUREECState, SBSA_SECURE_EC)
27
26
28
c = (GICv3CPUState *)env->gicv3state;
27
enum sbsa_ec_powerstates {
29
s = c->gic;
28
SBSA_EC_CMD_POWEROFF = 0x01,
30
- cpu = ARM_CPU(c->cpu);
31
32
c->icc_pmr_el1 = 0;
33
c->icc_bpr[GICV3_G0] = GIC_MIN_BPR;
34
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
35
36
/* Initialize to actual HW supported configuration */
37
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
38
- KVM_VGIC_ATTR(ICC_CTLR_EL1, cpu->mp_affinity),
39
+ KVM_VGIC_ATTR(ICC_CTLR_EL1, c->gicr_typer),
40
&c->icc_ctlr_el1[GICV3_NS], false, &error_abort);
41
42
c->icc_ctlr_el1[GICV3_S] = c->icc_ctlr_el1[GICV3_NS];
43
--
29
--
44
2.20.1
30
2.34.1
45
31
46
32
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Make cpu_register() (renamed to arm_cpu_register()) available
3
This remove a use of 'struct' in the DECLARE_INSTANCE_CHECKER()
4
from internals.h so we can register CPUs also from other files
4
macro call, to avoid after a QOM refactor:
5
in the future.
6
5
7
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
hw/intc/xilinx_intc.c:45:1: error: declaration of anonymous struct must be a definition
7
DECLARE_INSTANCE_CHECKER(struct xlx_pic, XILINX_INTC,
8
^
9
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Reviewed-by: Edgar E. Iglesias <edgar@zeroasic.com>
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20230109140306.23161-14-philmd@linaro.org
11
Message-id: 20200423073358.27155-3-philmd@redhat.com
12
Message-ID: <20190921150420.30743-2-thuth@redhat.com>
13
[PMD: Only take cpu_register() from Thomas's patch]
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
15
---
17
target/arm/cpu-qom.h | 9 ++++++++-
16
hw/intc/xilinx_intc.c | 28 +++++++++++++---------------
18
target/arm/cpu.c | 10 ++--------
17
1 file changed, 13 insertions(+), 15 deletions(-)
19
target/arm/cpu64.c | 8 +-------
20
3 files changed, 11 insertions(+), 16 deletions(-)
21
18
22
diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h
19
diff --git a/hw/intc/xilinx_intc.c b/hw/intc/xilinx_intc.c
23
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu-qom.h
21
--- a/hw/intc/xilinx_intc.c
25
+++ b/target/arm/cpu-qom.h
22
+++ b/hw/intc/xilinx_intc.c
26
@@ -XXX,XX +XXX,XX @@ struct arm_boot_info;
23
@@ -XXX,XX +XXX,XX @@
27
24
#define R_MAX 8
28
#define TYPE_ARM_MAX_CPU "max-" TYPE_ARM_CPU
25
29
26
#define TYPE_XILINX_INTC "xlnx.xps-intc"
30
-typedef struct ARMCPUInfo ARMCPUInfo;
27
-DECLARE_INSTANCE_CHECKER(struct xlx_pic, XILINX_INTC,
31
+typedef struct ARMCPUInfo {
28
- TYPE_XILINX_INTC)
32
+ const char *name;
29
+typedef struct XpsIntc XpsIntc;
33
+ void (*initfn)(Object *obj);
30
+DECLARE_INSTANCE_CHECKER(XpsIntc, XILINX_INTC, TYPE_XILINX_INTC)
34
+ void (*class_init)(ObjectClass *oc, void *data);
31
35
+} ARMCPUInfo;
32
-struct xlx_pic
36
+
33
+struct XpsIntc
37
+void arm_cpu_register(const ARMCPUInfo *info);
34
{
38
+void aarch64_cpu_register(const ARMCPUInfo *info);
35
SysBusDevice parent_obj;
39
36
40
/**
37
@@ -XXX,XX +XXX,XX @@ struct xlx_pic
41
* ARMCPUClass:
38
uint32_t irq_pin_state;
42
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
39
};
43
index XXXXXXX..XXXXXXX 100644
40
44
--- a/target/arm/cpu.c
41
-static void update_irq(struct xlx_pic *p)
45
+++ b/target/arm/cpu.c
42
+static void update_irq(XpsIntc *p)
46
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
43
{
47
44
uint32_t i;
48
#endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */
45
49
46
@@ -XXX,XX +XXX,XX @@ static void update_irq(struct xlx_pic *p)
50
-struct ARMCPUInfo {
47
qemu_set_irq(p->parent_irq, (p->regs[R_MER] & 1) && p->regs[R_IPR]);
51
- const char *name;
52
- void (*initfn)(Object *obj);
53
- void (*class_init)(ObjectClass *oc, void *data);
54
-};
55
-
56
static const ARMCPUInfo arm_cpus[] = {
57
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
58
{ .name = "arm926", .initfn = arm926_initfn },
59
@@ -XXX,XX +XXX,XX @@ static void cpu_register_class_init(ObjectClass *oc, void *data)
60
acc->info = data;
61
}
48
}
62
49
63
-static void cpu_register(const ARMCPUInfo *info)
50
-static uint64_t
64
+void arm_cpu_register(const ARMCPUInfo *info)
51
-pic_read(void *opaque, hwaddr addr, unsigned int size)
52
+static uint64_t pic_read(void *opaque, hwaddr addr, unsigned int size)
65
{
53
{
66
TypeInfo type_info = {
54
- struct xlx_pic *p = opaque;
67
.parent = TYPE_ARM_CPU,
55
+ XpsIntc *p = opaque;
68
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
56
uint32_t r = 0;
69
type_register_static(&idau_interface_type_info);
57
70
58
addr >>= 2;
71
while (info->name) {
59
@@ -XXX,XX +XXX,XX @@ pic_read(void *opaque, hwaddr addr, unsigned int size)
72
- cpu_register(info);
60
return r;
73
+ arm_cpu_register(info);
74
info++;
75
}
76
77
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/cpu64.c
80
+++ b/target/arm/cpu64.c
81
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
82
cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
83
}
61
}
84
62
85
-struct ARMCPUInfo {
63
-static void
86
- const char *name;
64
-pic_write(void *opaque, hwaddr addr,
87
- void (*initfn)(Object *obj);
65
- uint64_t val64, unsigned int size)
88
- void (*class_init)(ObjectClass *oc, void *data);
66
+static void pic_write(void *opaque, hwaddr addr,
89
-};
67
+ uint64_t val64, unsigned int size)
90
-
68
{
91
static const ARMCPUInfo aarch64_cpus[] = {
69
- struct xlx_pic *p = opaque;
92
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
70
+ XpsIntc *p = opaque;
93
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
71
uint32_t value = val64;
94
@@ -XXX,XX +XXX,XX @@ static void cpu_register_class_init(ObjectClass *oc, void *data)
72
95
acc->info = data;
73
addr >>= 2;
74
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps pic_ops = {
75
76
static void irq_handler(void *opaque, int irq, int level)
77
{
78
- struct xlx_pic *p = opaque;
79
+ XpsIntc *p = opaque;
80
81
/* edge triggered interrupt */
82
if (p->c_kind_of_intr & (1 << irq) && p->regs[R_MER] & 2) {
83
@@ -XXX,XX +XXX,XX @@ static void irq_handler(void *opaque, int irq, int level)
84
85
static void xilinx_intc_init(Object *obj)
86
{
87
- struct xlx_pic *p = XILINX_INTC(obj);
88
+ XpsIntc *p = XILINX_INTC(obj);
89
90
qdev_init_gpio_in(DEVICE(obj), irq_handler, 32);
91
sysbus_init_irq(SYS_BUS_DEVICE(obj), &p->parent_irq);
92
@@ -XXX,XX +XXX,XX @@ static void xilinx_intc_init(Object *obj)
96
}
93
}
97
94
98
-static void aarch64_cpu_register(const ARMCPUInfo *info)
95
static Property xilinx_intc_properties[] = {
99
+void aarch64_cpu_register(const ARMCPUInfo *info)
96
- DEFINE_PROP_UINT32("kind-of-intr", struct xlx_pic, c_kind_of_intr, 0),
100
{
97
+ DEFINE_PROP_UINT32("kind-of-intr", XpsIntc, c_kind_of_intr, 0),
101
TypeInfo type_info = {
98
DEFINE_PROP_END_OF_LIST(),
102
.parent = TYPE_AARCH64_CPU,
99
};
100
101
@@ -XXX,XX +XXX,XX @@ static void xilinx_intc_class_init(ObjectClass *klass, void *data)
102
static const TypeInfo xilinx_intc_info = {
103
.name = TYPE_XILINX_INTC,
104
.parent = TYPE_SYS_BUS_DEVICE,
105
- .instance_size = sizeof(struct xlx_pic),
106
+ .instance_size = sizeof(XpsIntc),
107
.instance_init = xilinx_intc_init,
108
.class_init = xilinx_intc_class_init,
109
};
103
--
110
--
104
2.20.1
111
2.34.1
105
112
106
113
diff view generated by jsdifflib
1
From: Cameron Esfahani <dirty@apple.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
NRF51_GPIO_REG_CNF_END doesn't actually refer to the start of the last
3
This remove a use of 'struct' in the DECLARE_INSTANCE_CHECKER()
4
valid CNF register: it's referring to the last byte of the last valid
4
macro call, to avoid after a QOM refactor:
5
CNF register.
6
5
7
This hasn't been a problem up to now, as current implementation in
6
hw/timer/xilinx_timer.c:65:1: error: declaration of anonymous struct must be a definition
8
memory.c turns an unaligned 4-byte read from 0x77f to a single byte read
7
DECLARE_INSTANCE_CHECKER(struct timerblock, XILINX_TIMER,
9
and the qtest only looks at the least-significant byte of the register.
8
^
10
9
11
But when running with patches which fix unaligned accesses in memory.c,
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
the qtest breaks.
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
12
Reviewed-by: Edgar E. Iglesias <edgar@zeroasic.com>
14
Considering NRF51 doesn't support unaligned accesses, the simplest fix
13
Message-id: 20230109140306.23161-15-philmd@linaro.org
15
is to actually set NRF51_GPIO_REG_CNF_END to the start of the last valid
16
CNF register: 0x77c.
17
18
Now, qtests work with or without the unaligned access patches.
19
20
Reviewed-by: Cédric Le Goater <clg@kaod.org>
21
Tested-by: Cédric Le Goater <clg@kaod.org>
22
Reviewed-by: Joel Stanley <joel@jms.id.au>
23
Signed-off-by: Cameron Esfahani <dirty@apple.com>
24
Message-id: 51b427f06838622da783d38ba56e3630d6d85c60.1586925392.git.dirty@apple.com
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
15
---
28
include/hw/gpio/nrf51_gpio.h | 2 +-
16
hw/timer/xilinx_timer.c | 27 +++++++++++++--------------
29
1 file changed, 1 insertion(+), 1 deletion(-)
17
1 file changed, 13 insertions(+), 14 deletions(-)
30
18
31
diff --git a/include/hw/gpio/nrf51_gpio.h b/include/hw/gpio/nrf51_gpio.h
19
diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c
32
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/gpio/nrf51_gpio.h
21
--- a/hw/timer/xilinx_timer.c
34
+++ b/include/hw/gpio/nrf51_gpio.h
22
+++ b/hw/timer/xilinx_timer.c
35
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ struct xlx_timer
36
#define NRF51_GPIO_REG_DIRSET 0x518
24
};
37
#define NRF51_GPIO_REG_DIRCLR 0x51C
25
38
#define NRF51_GPIO_REG_CNF_START 0x700
26
#define TYPE_XILINX_TIMER "xlnx.xps-timer"
39
-#define NRF51_GPIO_REG_CNF_END 0x77F
27
-DECLARE_INSTANCE_CHECKER(struct timerblock, XILINX_TIMER,
40
+#define NRF51_GPIO_REG_CNF_END 0x77C
28
- TYPE_XILINX_TIMER)
41
29
+typedef struct XpsTimerState XpsTimerState;
42
#define NRF51_GPIO_PULLDOWN 1
30
+DECLARE_INSTANCE_CHECKER(XpsTimerState, XILINX_TIMER, TYPE_XILINX_TIMER)
43
#define NRF51_GPIO_PULLUP 3
31
32
-struct timerblock
33
+struct XpsTimerState
34
{
35
SysBusDevice parent_obj;
36
37
@@ -XXX,XX +XXX,XX @@ struct timerblock
38
struct xlx_timer *timers;
39
};
40
41
-static inline unsigned int num_timers(struct timerblock *t)
42
+static inline unsigned int num_timers(XpsTimerState *t)
43
{
44
return 2 - t->one_timer_only;
45
}
46
@@ -XXX,XX +XXX,XX @@ static inline unsigned int timer_from_addr(hwaddr addr)
47
return addr >> 2;
48
}
49
50
-static void timer_update_irq(struct timerblock *t)
51
+static void timer_update_irq(XpsTimerState *t)
52
{
53
unsigned int i, irq = 0;
54
uint32_t csr;
55
@@ -XXX,XX +XXX,XX @@ static void timer_update_irq(struct timerblock *t)
56
static uint64_t
57
timer_read(void *opaque, hwaddr addr, unsigned int size)
58
{
59
- struct timerblock *t = opaque;
60
+ XpsTimerState *t = opaque;
61
struct xlx_timer *xt;
62
uint32_t r = 0;
63
unsigned int timer;
64
@@ -XXX,XX +XXX,XX @@ static void
65
timer_write(void *opaque, hwaddr addr,
66
uint64_t val64, unsigned int size)
67
{
68
- struct timerblock *t = opaque;
69
+ XpsTimerState *t = opaque;
70
struct xlx_timer *xt;
71
unsigned int timer;
72
uint32_t value = val64;
73
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps timer_ops = {
74
static void timer_hit(void *opaque)
75
{
76
struct xlx_timer *xt = opaque;
77
- struct timerblock *t = xt->parent;
78
+ XpsTimerState *t = xt->parent;
79
D(fprintf(stderr, "%s %d\n", __func__, xt->nr));
80
xt->regs[R_TCSR] |= TCSR_TINT;
81
82
@@ -XXX,XX +XXX,XX @@ static void timer_hit(void *opaque)
83
84
static void xilinx_timer_realize(DeviceState *dev, Error **errp)
85
{
86
- struct timerblock *t = XILINX_TIMER(dev);
87
+ XpsTimerState *t = XILINX_TIMER(dev);
88
unsigned int i;
89
90
/* Init all the ptimers. */
91
@@ -XXX,XX +XXX,XX @@ static void xilinx_timer_realize(DeviceState *dev, Error **errp)
92
93
static void xilinx_timer_init(Object *obj)
94
{
95
- struct timerblock *t = XILINX_TIMER(obj);
96
+ XpsTimerState *t = XILINX_TIMER(obj);
97
98
/* All timers share a single irq line. */
99
sysbus_init_irq(SYS_BUS_DEVICE(obj), &t->irq);
100
}
101
102
static Property xilinx_timer_properties[] = {
103
- DEFINE_PROP_UINT32("clock-frequency", struct timerblock, freq_hz,
104
- 62 * 1000000),
105
- DEFINE_PROP_UINT8("one-timer-only", struct timerblock, one_timer_only, 0),
106
+ DEFINE_PROP_UINT32("clock-frequency", XpsTimerState, freq_hz, 62 * 1000000),
107
+ DEFINE_PROP_UINT8("one-timer-only", XpsTimerState, one_timer_only, 0),
108
DEFINE_PROP_END_OF_LIST(),
109
};
110
111
@@ -XXX,XX +XXX,XX @@ static void xilinx_timer_class_init(ObjectClass *klass, void *data)
112
static const TypeInfo xilinx_timer_info = {
113
.name = TYPE_XILINX_TIMER,
114
.parent = TYPE_SYS_BUS_DEVICE,
115
- .instance_size = sizeof(struct timerblock),
116
+ .instance_size = sizeof(XpsTimerState),
117
.instance_init = xilinx_timer_init,
118
.class_init = xilinx_timer_class_init,
119
};
44
--
120
--
45
2.20.1
121
2.34.1
46
122
47
123
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
2
2
3
Under KVM these registers are written by the hardware.
3
ARM trusted firmware, when built with FEAT_HCX support, sets SCR_EL3.HXEn bit
4
Restrict the writefn handlers to TCG to avoid when building
4
to allow EL2 to modify HCRX_EL2 register without trapping it in EL3. Qemu
5
without TCG:
5
uses a valid mask to clear unsupported SCR_EL3 bits when emulating SCR_EL3
6
write, and that mask doesn't include SCR_EL3.HXEn bit even if FEAT_HCX is
7
enabled and exposed to the guest. As a result EL3 writes of that bit are
8
ignored.
6
9
7
LINK aarch64-softmmu/qemu-system-aarch64
10
Cc: qemu-stable@nongnu.org
8
target/arm/helper.o: In function `do_ats_write':
11
Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
9
target/arm/helper.c:3524: undefined reference to `raise_exception'
12
Message-id: 20230105221251.17896-4-eiakovlev@linux.microsoft.com
10
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Message-id: 20200423073358.27155-2-philmd@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
15
---
17
target/arm/helper.c | 17 +++++++++++++++++
16
target/arm/helper.c | 3 +++
18
1 file changed, 17 insertions(+)
17
1 file changed, 3 insertions(+)
19
18
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
21
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
22
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
23
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
25
return CP_ACCESS_OK;
24
if (cpu_isar_feature(aa64_sme, cpu)) {
26
}
25
valid_mask |= SCR_ENTP2;
27
26
}
28
+#ifdef CONFIG_TCG
27
+ if (cpu_isar_feature(aa64_hcx, cpu)) {
29
static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
28
+ valid_mask |= SCR_HXEN;
30
MMUAccessType access_type, ARMMMUIdx mmu_idx)
29
+ }
31
{
30
} else {
32
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
31
valid_mask &= ~(SCR_RW | SCR_ST);
33
}
32
if (cpu_isar_feature(aa32_ras, cpu)) {
34
return par64;
35
}
36
+#endif /* CONFIG_TCG */
37
38
static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
39
{
40
+#ifdef CONFIG_TCG
41
MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
42
uint64_t par64;
43
ARMMMUIdx mmu_idx;
44
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
45
par64 = do_ats_write(env, value, access_type, mmu_idx);
46
47
A32_BANKED_CURRENT_REG_SET(env, par, par64);
48
+#else
49
+ /* Handled by hardware accelerator. */
50
+ g_assert_not_reached();
51
+#endif /* CONFIG_TCG */
52
}
53
54
static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
55
uint64_t value)
56
{
57
+#ifdef CONFIG_TCG
58
MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
59
uint64_t par64;
60
61
par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2);
62
63
A32_BANKED_CURRENT_REG_SET(env, par, par64);
64
+#else
65
+ /* Handled by hardware accelerator. */
66
+ g_assert_not_reached();
67
+#endif /* CONFIG_TCG */
68
}
69
70
static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
71
@@ -XXX,XX +XXX,XX @@ static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
72
static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
73
uint64_t value)
74
{
75
+#ifdef CONFIG_TCG
76
MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
77
ARMMMUIdx mmu_idx;
78
int secure = arm_is_secure_below_el3(env);
79
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
80
}
81
82
env->cp15.par_el[1] = do_ats_write(env, value, access_type, mmu_idx);
83
+#else
84
+ /* Handled by hardware accelerator. */
85
+ g_assert_not_reached();
86
+#endif /* CONFIG_TCG */
87
}
88
#endif
89
90
--
33
--
91
2.20.1
34
2.34.1
92
93
diff view generated by jsdifflib