1
Arm patch queue -- these are all bug fix patches but we might
1
A grab-bag of minor stuff for the end of the year. My to-review
2
as well put them in to rc0...
2
queue is not empty, but it it at least in single figures...
3
3
4
thanks
5
-- PMM
4
-- PMM
6
5
7
The following changes since commit 2c8cfc0b52b5a4d123c26c0b5fdf941be24805be:
6
The following changes since commit 5bfbd8170ce7acb98a1834ff49ed7340b0837144:
8
7
9
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2018-03-19 11:44:26 +0000)
8
Merge remote-tracking branch 'remotes/vivier2/tags/trivial-branch-for-6.0-pull-request' into staging (2020-12-14 20:32:38 +0000)
10
9
11
are available in the Git repository at:
10
are available in the Git repository at:
12
11
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180319
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201215
14
13
15
for you to fetch changes up to ff72cb6b46b95bb530787add5277c211af3d31c6:
14
for you to fetch changes up to 23af268566069183285bebbdf95b1b37cb7c0942:
16
15
17
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs (2018-03-19 18:23:24 +0000)
16
hw/block/m25p80: Fix Numonyx fast read dummy cycle count (2020-12-15 13:39:30 +0000)
18
17
19
----------------------------------------------------------------
18
----------------------------------------------------------------
20
target-arm queue:
19
target-arm queue:
21
* fsl-imx6: Fix incorrect Ethernet interrupt defines
20
* gdbstub: Correct misparsing of vCont C/S requests
22
* dump: Update correct kdump phys_base field for AArch64
21
* openrisc: Move pic_cpu code into CPU object proper
23
* char: i.MX: Add support for "TX complete" interrupt
22
* nios2: Move IIC code into CPU object proper
24
* bcm2836/raspi: Fix various bugs resulting in panics trying
23
* Improve reporting of ROM overlap errors
25
to boot a Debian Linux kernel on raspi3
24
* xlnx-versal: Add USB support
25
* hw/misc/zynq_slcr: Avoid #DIV/0! error
26
* Numonyx: Fix dummy cycles and check for SPI mode on cmds
26
27
27
----------------------------------------------------------------
28
----------------------------------------------------------------
28
Andrey Smirnov (2):
29
Joe Komlodi (4):
29
char: i.MX: Simplify imx_update()
30
hw/block/m25p80: Make Numonyx config field names more accurate
30
char: i.MX: Add support for "TX complete" interrupt
31
hw/block/m25p80: Fix when VCFG XIP bit is set for Numonyx
32
hw/block/m25p80: Check SPI mode before running some Numonyx commands
33
hw/block/m25p80: Fix Numonyx fast read dummy cycle count
31
34
32
Guenter Roeck (1):
35
Peter Maydell (11):
33
fsl-imx6: Swap Ethernet interrupt defines
36
gdbstub: Correct misparsing of vCont C/S requests
37
hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to multiple CPUs
38
hw/openrisc/openrisc_sim: Abstract out "get IRQ x of CPU y"
39
target/openrisc: Move pic_cpu code into CPU object proper
40
target/nios2: Move IIC code into CPU object proper
41
target/nios2: Move nios2_check_interrupts() into target/nios2
42
target/nios2: Use deposit32() to update ipending register
43
hw/core/loader.c: Track last-seen ROM in rom_check_and_register_reset()
44
hw/core/loader.c: Improve reporting of ROM overlap errors
45
elf_ops.h: Don't truncate name of the ROM blobs we create
46
elf_ops.h: Be more verbose with ROM blob names
34
47
35
Peter Maydell (9):
48
Philippe Mathieu-Daudé (1):
36
hw/arm/raspi: Don't do board-setup or secure-boot for raspi3
49
hw/misc/zynq_slcr: Avoid #DIV/0! error
37
hw/arm/boot: assert that secure_boot and secure_board_setup are false for AArch64
38
hw/arm/boot: If booting a kernel in EL2, set SCR_EL3.HCE
39
hw/arm/bcm2386: Fix parent type of bcm2386
40
hw/arm/bcm2836: Rename bcm2836 type/struct to bcm283x
41
hw/arm/bcm2836: Create proper bcm2837 device
42
hw/arm/bcm2836: Use correct affinity values for BCM2837
43
hw/arm/bcm2836: Hardcode correct CPU type
44
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs
45
50
46
Wei Huang (1):
51
Sai Pavan Boddu (2):
47
dump: Update correct kdump phys_base field for AArch64
52
usb: Add versal-usb2-ctrl-regs module
53
usb: xlnx-usb-subsystem: Add xilinx usb subsystem
48
54
49
include/hw/arm/bcm2836.h | 31 +++++++++++++---
55
Vikram Garhwal (2):
50
include/hw/arm/fsl-imx6.h | 4 +-
56
usb: Add DWC3 model
51
include/hw/char/imx_serial.h | 3 ++
57
arm: xlnx-versal: Connect usb to virt-versal
52
dump.c | 14 +++++--
53
hw/arm/bcm2836.c | 87 +++++++++++++++++++++++++++++++-------------
54
hw/arm/boot.c | 12 ++++++
55
hw/arm/raspi.c | 77 +++++++++++++++++++++++++++++++--------
56
hw/char/imx_serial.c | 44 ++++++++++++++++------
57
hw/net/imx_fec.c | 28 +++++++++++++-
58
9 files changed, 237 insertions(+), 63 deletions(-)
59
58
59
include/hw/arm/xlnx-versal.h | 9 +
60
include/hw/elf_ops.h | 5 +-
61
include/hw/usb/hcd-dwc3.h | 55 +++
62
include/hw/usb/xlnx-usb-subsystem.h | 45 ++
63
include/hw/usb/xlnx-versal-usb2-ctrl-regs.h | 45 ++
64
target/nios2/cpu.h | 3 -
65
target/openrisc/cpu.h | 1 -
66
gdbstub.c | 2 +-
67
hw/arm/xlnx-versal-virt.c | 55 +++
68
hw/arm/xlnx-versal.c | 26 ++
69
hw/block/m25p80.c | 158 +++++--
70
hw/core/loader.c | 67 ++-
71
hw/intc/nios2_iic.c | 95 ----
72
hw/misc/zynq_slcr.c | 5 +
73
hw/nios2/10m50_devboard.c | 13 +-
74
hw/nios2/cpu_pic.c | 67 ---
75
hw/openrisc/openrisc_sim.c | 46 +-
76
hw/openrisc/pic_cpu.c | 61 ---
77
hw/usb/hcd-dwc3.c | 689 ++++++++++++++++++++++++++++
78
hw/usb/xlnx-usb-subsystem.c | 94 ++++
79
hw/usb/xlnx-versal-usb2-ctrl-regs.c | 229 +++++++++
80
softmmu/vl.c | 1 -
81
target/nios2/cpu.c | 29 ++
82
target/nios2/op_helper.c | 9 +
83
target/openrisc/cpu.c | 32 ++
84
MAINTAINERS | 1 -
85
hw/intc/meson.build | 1 -
86
hw/nios2/meson.build | 2 +-
87
hw/openrisc/Kconfig | 1 +
88
hw/openrisc/meson.build | 2 +-
89
hw/usb/Kconfig | 10 +
90
hw/usb/meson.build | 3 +
91
32 files changed, 1557 insertions(+), 304 deletions(-)
92
create mode 100644 include/hw/usb/hcd-dwc3.h
93
create mode 100644 include/hw/usb/xlnx-usb-subsystem.h
94
create mode 100644 include/hw/usb/xlnx-versal-usb2-ctrl-regs.h
95
delete mode 100644 hw/intc/nios2_iic.c
96
delete mode 100644 hw/nios2/cpu_pic.c
97
delete mode 100644 hw/openrisc/pic_cpu.c
98
create mode 100644 hw/usb/hcd-dwc3.c
99
create mode 100644 hw/usb/xlnx-usb-subsystem.c
100
create mode 100644 hw/usb/xlnx-versal-usb2-ctrl-regs.c
101
diff view generated by jsdifflib
New patch
1
In the vCont packet, two of the command actions (C and S) take an
2
argument specifying the signal to be sent to the process/thread, which is
3
sent as an ASCII string of two hex digits which immediately follow the
4
'C' or 'S' character.
1
5
6
Our code for parsing this packet accidentally skipped the first of the
7
two bytes of the signal value, because it started parsing the hex string
8
at 'p + 1' when the preceding code had already moved past the 'C' or
9
'S' with "cur_action = *p++".
10
11
This meant that we would only do the right thing for signals below
12
10, and would misinterpret the rest. For instance, when the debugger
13
wants to send the process a SIGPROF (27 on x86-64) we mangle this into
14
a SIGSEGV (11).
15
16
Remove the accidental double increment.
17
18
Fixes: https://bugs.launchpad.net/qemu/+bug/1773743
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
22
Message-id: 20201121210342.10089-1-peter.maydell@linaro.org
23
---
24
gdbstub.c | 2 +-
25
1 file changed, 1 insertion(+), 1 deletion(-)
26
27
diff --git a/gdbstub.c b/gdbstub.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/gdbstub.c
30
+++ b/gdbstub.c
31
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_vcont(const char *p)
32
cur_action = *p++;
33
if (cur_action == 'C' || cur_action == 'S') {
34
cur_action = qemu_tolower(cur_action);
35
- res = qemu_strtoul(p + 1, &p, 16, &tmp);
36
+ res = qemu_strtoul(p, &p, 16, &tmp);
37
if (res) {
38
goto out;
39
}
40
--
41
2.20.1
42
43
diff view generated by jsdifflib
New patch
1
openrisc_sim_net_init() attempts to connect the IRQ line from the
2
ethernet device to both CPUs in an SMP configuration by simply caling
3
sysbus_connect_irq() for it twice. This doesn't work, because the
4
second connection simply overrides the first.
1
5
6
Fix this by creating a TYPE_SPLIT_IRQ to split the IRQ in the SMP
7
case.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Stafford Horne <shorne@gmail.com>
11
Message-id: 20201127225127.14770-2-peter.maydell@linaro.org
12
---
13
hw/openrisc/openrisc_sim.c | 13 +++++++++++--
14
hw/openrisc/Kconfig | 1 +
15
2 files changed, 12 insertions(+), 2 deletions(-)
16
17
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/openrisc/openrisc_sim.c
20
+++ b/hw/openrisc/openrisc_sim.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/sysbus.h"
23
#include "sysemu/qtest.h"
24
#include "sysemu/reset.h"
25
+#include "hw/core/split-irq.h"
26
27
#define KERNEL_LOAD_ADDR 0x100
28
29
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
30
31
s = SYS_BUS_DEVICE(dev);
32
sysbus_realize_and_unref(s, &error_fatal);
33
- for (i = 0; i < num_cpus; i++) {
34
- sysbus_connect_irq(s, 0, cpu_irqs[i][irq_pin]);
35
+ if (num_cpus > 1) {
36
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
37
+ qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
38
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
39
+ for (i = 0; i < num_cpus; i++) {
40
+ qdev_connect_gpio_out(splitter, i, cpu_irqs[i][irq_pin]);
41
+ }
42
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(splitter, 0));
43
+ } else {
44
+ sysbus_connect_irq(s, 0, cpu_irqs[0][irq_pin]);
45
}
46
sysbus_mmio_map(s, 0, base);
47
sysbus_mmio_map(s, 1, descriptors);
48
diff --git a/hw/openrisc/Kconfig b/hw/openrisc/Kconfig
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/openrisc/Kconfig
51
+++ b/hw/openrisc/Kconfig
52
@@ -XXX,XX +XXX,XX @@ config OR1K_SIM
53
select SERIAL
54
select OPENCORES_ETH
55
select OMPIC
56
+ select SPLIT_IRQ
57
--
58
2.20.1
59
60
diff view generated by jsdifflib
New patch
1
We're about to refactor the OpenRISC pic_cpu code in a way that means
2
that just grabbing the whole qemu_irq[] array of inbound IRQs for a
3
CPU won't be possible any more. Abstract out a function for "return
4
the qemu_irq for IRQ x input of CPU y" so we can more easily replace
5
the implementation.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Stafford Horne <shorne@gmail.com>
9
Message-id: 20201127225127.14770-3-peter.maydell@linaro.org
10
---
11
hw/openrisc/openrisc_sim.c | 38 +++++++++++++++++++++-----------------
12
1 file changed, 21 insertions(+), 17 deletions(-)
13
14
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/openrisc/openrisc_sim.c
17
+++ b/hw/openrisc/openrisc_sim.c
18
@@ -XXX,XX +XXX,XX @@ static void main_cpu_reset(void *opaque)
19
cpu_set_pc(cs, boot_info.bootstrap_pc);
20
}
21
22
+static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
23
+{
24
+ return cpus[cpunum]->env.irq[irq_pin];
25
+}
26
+
27
static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
28
- int num_cpus, qemu_irq **cpu_irqs,
29
+ int num_cpus, OpenRISCCPU *cpus[],
30
int irq_pin, NICInfo *nd)
31
{
32
DeviceState *dev;
33
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
34
qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
35
qdev_realize_and_unref(splitter, NULL, &error_fatal);
36
for (i = 0; i < num_cpus; i++) {
37
- qdev_connect_gpio_out(splitter, i, cpu_irqs[i][irq_pin]);
38
+ qdev_connect_gpio_out(splitter, i, get_cpu_irq(cpus, i, irq_pin));
39
}
40
sysbus_connect_irq(s, 0, qdev_get_gpio_in(splitter, 0));
41
} else {
42
- sysbus_connect_irq(s, 0, cpu_irqs[0][irq_pin]);
43
+ sysbus_connect_irq(s, 0, get_cpu_irq(cpus, 0, irq_pin));
44
}
45
sysbus_mmio_map(s, 0, base);
46
sysbus_mmio_map(s, 1, descriptors);
47
}
48
49
static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
50
- qemu_irq **cpu_irqs, int irq_pin)
51
+ OpenRISCCPU *cpus[], int irq_pin)
52
{
53
DeviceState *dev;
54
SysBusDevice *s;
55
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
56
s = SYS_BUS_DEVICE(dev);
57
sysbus_realize_and_unref(s, &error_fatal);
58
for (i = 0; i < num_cpus; i++) {
59
- sysbus_connect_irq(s, i, cpu_irqs[i][irq_pin]);
60
+ sysbus_connect_irq(s, i, get_cpu_irq(cpus, i, irq_pin));
61
}
62
sysbus_mmio_map(s, 0, base);
63
}
64
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_init(MachineState *machine)
65
{
66
ram_addr_t ram_size = machine->ram_size;
67
const char *kernel_filename = machine->kernel_filename;
68
- OpenRISCCPU *cpu = NULL;
69
+ OpenRISCCPU *cpus[2] = {};
70
MemoryRegion *ram;
71
- qemu_irq *cpu_irqs[2];
72
qemu_irq serial_irq;
73
int n;
74
unsigned int smp_cpus = machine->smp.cpus;
75
76
assert(smp_cpus >= 1 && smp_cpus <= 2);
77
for (n = 0; n < smp_cpus; n++) {
78
- cpu = OPENRISC_CPU(cpu_create(machine->cpu_type));
79
- if (cpu == NULL) {
80
+ cpus[n] = OPENRISC_CPU(cpu_create(machine->cpu_type));
81
+ if (cpus[n] == NULL) {
82
fprintf(stderr, "Unable to find CPU definition!\n");
83
exit(1);
84
}
85
- cpu_openrisc_pic_init(cpu);
86
- cpu_irqs[n] = (qemu_irq *) cpu->env.irq;
87
+ cpu_openrisc_pic_init(cpus[n]);
88
89
- cpu_openrisc_clock_init(cpu);
90
+ cpu_openrisc_clock_init(cpus[n]);
91
92
- qemu_register_reset(main_cpu_reset, cpu);
93
+ qemu_register_reset(main_cpu_reset, cpus[n]);
94
}
95
96
ram = g_malloc(sizeof(*ram));
97
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_init(MachineState *machine)
98
99
if (nd_table[0].used) {
100
openrisc_sim_net_init(0x92000000, 0x92000400, smp_cpus,
101
- cpu_irqs, 4, nd_table);
102
+ cpus, 4, nd_table);
103
}
104
105
if (smp_cpus > 1) {
106
- openrisc_sim_ompic_init(0x98000000, smp_cpus, cpu_irqs, 1);
107
+ openrisc_sim_ompic_init(0x98000000, smp_cpus, cpus, 1);
108
109
- serial_irq = qemu_irq_split(cpu_irqs[0][2], cpu_irqs[1][2]);
110
+ serial_irq = qemu_irq_split(get_cpu_irq(cpus, 0, 2),
111
+ get_cpu_irq(cpus, 1, 2));
112
} else {
113
- serial_irq = cpu_irqs[0][2];
114
+ serial_irq = get_cpu_irq(cpus, 0, 2);
115
}
116
117
serial_mm_init(get_system_memory(), 0x90000000, 0, serial_irq,
118
--
119
2.20.1
120
121
diff view generated by jsdifflib
1
Now we have separate types for BCM2386 and BCM2387, we might as well
1
The openrisc code uses an old style of interrupt handling, where a
2
just hard-code the CPU type they use rather than having it passed
2
separate standalone set of qemu_irqs invoke a function
3
through as an object property. This then lets us put the initialization
3
openrisc_pic_cpu_handler() which signals the interrupt to the CPU
4
of the CPU object in init rather than realize.
4
proper by directly calling cpu_interrupt() and cpu_reset_interrupt().
5
Because CPU objects now inherit (indirectly) from TYPE_DEVICE, they
6
can have GPIO input lines themselves, and the neater modern way to
7
implement this is to simply have the CPU object itself provide the
8
input IRQ lines.
5
9
6
Note that this change means that it's no longer possible on
10
Create GPIO inputs to the OpenRISC CPU object, and make the only user
7
the command line to use -cpu to ask for a different kind of
11
of cpu_openrisc_pic_init() wire up directly to those instead.
8
CPU than the SoC supports. This was never a supported thing to
9
do anyway; we were just not sanity-checking the command line.
10
12
11
This does require us to only build the bcm2837 object on
13
This allows us to delete the hw/openrisc/pic_cpu.c file entirely.
12
TARGET_AARCH64 configs, since otherwise it won't instantiate
13
due to the missing cortex-a53 device and "make check" will fail.
14
14
15
This fixes a trivial memory leak reported by Coverity of the IRQs
16
allocated in cpu_openrisc_pic_init().
17
18
Fixes: Coverity CID 1421934
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
20
Reviewed-by: Stafford Horne <shorne@gmail.com>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20201127225127.14770-4-peter.maydell@linaro.org
18
Message-id: 20180313153458.26822-9-peter.maydell@linaro.org
19
---
22
---
20
hw/arm/bcm2836.c | 24 +++++++++++++++---------
23
target/openrisc/cpu.h | 1 -
21
hw/arm/raspi.c | 2 --
24
hw/openrisc/openrisc_sim.c | 3 +-
22
2 files changed, 15 insertions(+), 11 deletions(-)
25
hw/openrisc/pic_cpu.c | 61 --------------------------------------
26
target/openrisc/cpu.c | 32 ++++++++++++++++++++
27
hw/openrisc/meson.build | 2 +-
28
5 files changed, 34 insertions(+), 65 deletions(-)
29
delete mode 100644 hw/openrisc/pic_cpu.c
23
30
24
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
31
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
25
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/bcm2836.c
33
--- a/target/openrisc/cpu.h
27
+++ b/hw/arm/bcm2836.c
34
+++ b/target/openrisc/cpu.h
35
@@ -XXX,XX +XXX,XX @@ typedef struct CPUOpenRISCState {
36
uint32_t picmr; /* Interrupt mask register */
37
uint32_t picsr; /* Interrupt contrl register*/
38
#endif
39
- void *irq[32]; /* Interrupt irq input */
40
} CPUOpenRISCState;
41
42
/**
43
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/openrisc/openrisc_sim.c
46
+++ b/hw/openrisc/openrisc_sim.c
47
@@ -XXX,XX +XXX,XX @@ static void main_cpu_reset(void *opaque)
48
49
static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
50
{
51
- return cpus[cpunum]->env.irq[irq_pin];
52
+ return qdev_get_gpio_in_named(DEVICE(cpus[cpunum]), "IRQ", irq_pin);
53
}
54
55
static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
56
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_init(MachineState *machine)
57
fprintf(stderr, "Unable to find CPU definition!\n");
58
exit(1);
59
}
60
- cpu_openrisc_pic_init(cpus[n]);
61
62
cpu_openrisc_clock_init(cpus[n]);
63
64
diff --git a/hw/openrisc/pic_cpu.c b/hw/openrisc/pic_cpu.c
65
deleted file mode 100644
66
index XXXXXXX..XXXXXXX
67
--- a/hw/openrisc/pic_cpu.c
68
+++ /dev/null
28
@@ -XXX,XX +XXX,XX @@
69
@@ -XXX,XX +XXX,XX @@
29
70
-/*
30
struct BCM283XInfo {
71
- * OpenRISC Programmable Interrupt Controller support.
31
const char *name;
72
- *
32
+ const char *cpu_type;
73
- * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
33
int clusterid;
74
- * Feng Gao <gf91597@gmail.com>
34
};
75
- *
35
76
- * This library is free software; you can redistribute it and/or
36
static const BCM283XInfo bcm283x_socs[] = {
77
- * modify it under the terms of the GNU Lesser General Public
37
{
78
- * License as published by the Free Software Foundation; either
38
.name = TYPE_BCM2836,
79
- * version 2.1 of the License, or (at your option) any later version.
39
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"),
80
- *
40
.clusterid = 0xf,
81
- * This library is distributed in the hope that it will be useful,
41
},
82
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
42
+#ifdef TARGET_AARCH64
83
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
43
{
84
- * Lesser General Public License for more details.
44
.name = TYPE_BCM2837,
85
- *
45
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
86
- * You should have received a copy of the GNU Lesser General Public
46
.clusterid = 0x0,
87
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
47
},
88
- */
48
+#endif
89
-
49
};
90
-#include "qemu/osdep.h"
50
91
-#include "hw/irq.h"
51
static void bcm2836_init(Object *obj)
92
-#include "cpu.h"
52
{
93
-
53
BCM283XState *s = BCM283X(obj);
94
-/* OpenRISC pic handler */
54
+ BCM283XClass *bc = BCM283X_GET_CLASS(obj);
95
-static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)
55
+ const BCM283XInfo *info = bc->info;
96
-{
56
+ int n;
97
- OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;
57
+
98
- CPUState *cs = CPU(cpu);
58
+ for (n = 0; n < BCM283X_NCPUS; n++) {
99
- uint32_t irq_bit;
59
+ object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
100
-
60
+ info->cpu_type);
101
- if (irq > 31 || irq < 0) {
61
+ object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
102
- return;
62
+ &error_abort);
63
+ }
64
65
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
66
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
67
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
68
69
/* common peripherals from bcm2835 */
70
71
- obj = OBJECT(dev);
72
- for (n = 0; n < BCM283X_NCPUS; n++) {
73
- object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
74
- s->cpu_type);
75
- object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
76
- &error_abort);
77
- }
103
- }
78
-
104
-
79
obj = object_property_get_link(OBJECT(dev), "ram", &err);
105
- irq_bit = 1U << irq;
80
if (obj == NULL) {
106
-
81
error_setg(errp, "%s: required ram link not found: %s",
107
- if (level) {
82
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
108
- cpu->env.picsr |= irq_bit;
109
- } else {
110
- cpu->env.picsr &= ~irq_bit;
111
- }
112
-
113
- if (cpu->env.picsr & cpu->env.picmr) {
114
- cpu_interrupt(cs, CPU_INTERRUPT_HARD);
115
- } else {
116
- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
117
- cpu->env.picsr = 0;
118
- }
119
-}
120
-
121
-void cpu_openrisc_pic_init(OpenRISCCPU *cpu)
122
-{
123
- int i;
124
- qemu_irq *qi;
125
- qi = qemu_allocate_irqs(openrisc_pic_cpu_handler, cpu, NR_IRQS);
126
-
127
- for (i = 0; i < NR_IRQS; i++) {
128
- cpu->env.irq[i] = qi[i];
129
- }
130
-}
131
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/openrisc/cpu.c
134
+++ b/target/openrisc/cpu.c
135
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset(DeviceState *dev)
136
#endif
83
}
137
}
84
138
85
static Property bcm2836_props[] = {
139
+#ifndef CONFIG_USER_ONLY
86
- DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
140
+static void openrisc_cpu_set_irq(void *opaque, int irq, int level)
87
DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
141
+{
88
BCM283X_NCPUS),
142
+ OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;
89
DEFINE_PROP_END_OF_LIST()
143
+ CPUState *cs = CPU(cpu);
90
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
144
+ uint32_t irq_bit;
145
+
146
+ if (irq > 31 || irq < 0) {
147
+ return;
148
+ }
149
+
150
+ irq_bit = 1U << irq;
151
+
152
+ if (level) {
153
+ cpu->env.picsr |= irq_bit;
154
+ } else {
155
+ cpu->env.picsr &= ~irq_bit;
156
+ }
157
+
158
+ if (cpu->env.picsr & cpu->env.picmr) {
159
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
160
+ } else {
161
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
162
+ cpu->env.picsr = 0;
163
+ }
164
+}
165
+#endif
166
+
167
static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp)
168
{
169
CPUState *cs = CPU(dev);
170
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_initfn(Object *obj)
171
OpenRISCCPU *cpu = OPENRISC_CPU(obj);
172
173
cpu_set_cpustate_pointers(cpu);
174
+
175
+#ifndef CONFIG_USER_ONLY
176
+ qdev_init_gpio_in_named(DEVICE(cpu), openrisc_cpu_set_irq, "IRQ", NR_IRQS);
177
+#endif
178
}
179
180
/* CPU models */
181
diff --git a/hw/openrisc/meson.build b/hw/openrisc/meson.build
91
index XXXXXXX..XXXXXXX 100644
182
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/arm/raspi.c
183
--- a/hw/openrisc/meson.build
93
+++ b/hw/arm/raspi.c
184
+++ b/hw/openrisc/meson.build
94
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
185
@@ -XXX,XX +XXX,XX @@
95
/* Setup the SOC */
186
openrisc_ss = ss.source_set()
96
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
187
-openrisc_ss.add(files('pic_cpu.c', 'cputimer.c'))
97
&error_abort);
188
+openrisc_ss.add(files('cputimer.c'))
98
- object_property_set_str(OBJECT(&s->soc), machine->cpu_type, "cpu-type",
189
openrisc_ss.add(when: 'CONFIG_OR1K_SIM', if_true: files('openrisc_sim.c'))
99
- &error_abort);
190
100
object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
191
hw_arch += {'openrisc': openrisc_ss}
101
&error_abort);
102
int board_rev = version == 3 ? 0xa02082 : 0xa21041;
103
--
192
--
104
2.16.2
193
2.20.1
105
194
106
195
diff view generated by jsdifflib
New patch
1
1
The Nios2 architecture supports two different interrupt controller
2
options:
3
4
* The IIC (Internal Interrupt Controller) is part of the CPU itself;
5
it has 32 IRQ input lines and no NMI support. Interrupt status is
6
queried and controlled via the CPU's ipending and istatus
7
registers.
8
9
* The EIC (External Interrupt Controller) interface allows the CPU
10
to connect to an external interrupt controller. The interface
11
allows the interrupt controller to present a packet of information
12
containing:
13
- handler address
14
- interrupt level
15
- register set
16
- NMI mode
17
18
QEMU does not model an EIC currently. We do model the IIC, but its
19
implementation is split across code in hw/nios2/cpu_pic.c and
20
hw/intc/nios2_iic.c. The code in those two files has no state of its
21
own -- the IIC state is in the Nios2CPU state struct.
22
23
Because CPU objects now inherit (indirectly) from TYPE_DEVICE, they
24
can have GPIO input lines themselves, so we can implement the IIC
25
directly in the CPU object the same way that real hardware does.
26
27
Create named "IRQ" GPIO inputs to the Nios2 CPU object, and make the
28
only user of the IIC wire up directly to those instead.
29
30
Note that the old code had an "NMI" concept which was entirely unused
31
and also as far as I can see not architecturally correct, since only
32
the EIC has a concept of an NMI.
33
34
This fixes a Coverity-reported trivial memory leak of the IRQ array
35
allocated in nios2_cpu_pic_init().
36
37
Fixes: Coverity CID 1421916
38
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
40
Message-id: 20201129174022.26530-2-peter.maydell@linaro.org
41
Reviewed-by: Wentong Wu <wentong.wu@intel.com>
42
Tested-by: Wentong Wu <wentong.wu@intel.com>
43
---
44
target/nios2/cpu.h | 1 -
45
hw/intc/nios2_iic.c | 95 ---------------------------------------
46
hw/nios2/10m50_devboard.c | 13 +-----
47
hw/nios2/cpu_pic.c | 31 -------------
48
target/nios2/cpu.c | 30 +++++++++++++
49
MAINTAINERS | 1 -
50
hw/intc/meson.build | 1 -
51
7 files changed, 32 insertions(+), 140 deletions(-)
52
delete mode 100644 hw/intc/nios2_iic.c
53
54
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/nios2/cpu.h
57
+++ b/target/nios2/cpu.h
58
@@ -XXX,XX +XXX,XX @@ void nios2_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
59
MMUAccessType access_type,
60
int mmu_idx, uintptr_t retaddr);
61
62
-qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu);
63
void nios2_check_interrupts(CPUNios2State *env);
64
65
void do_nios2_semihosting(CPUNios2State *env);
66
diff --git a/hw/intc/nios2_iic.c b/hw/intc/nios2_iic.c
67
deleted file mode 100644
68
index XXXXXXX..XXXXXXX
69
--- a/hw/intc/nios2_iic.c
70
+++ /dev/null
71
@@ -XXX,XX +XXX,XX @@
72
-/*
73
- * QEMU Altera Internal Interrupt Controller.
74
- *
75
- * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
76
- *
77
- * This library is free software; you can redistribute it and/or
78
- * modify it under the terms of the GNU Lesser General Public
79
- * License as published by the Free Software Foundation; either
80
- * version 2.1 of the License, or (at your option) any later version.
81
- *
82
- * This library is distributed in the hope that it will be useful,
83
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
84
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
85
- * Lesser General Public License for more details.
86
- *
87
- * You should have received a copy of the GNU Lesser General Public
88
- * License along with this library; if not, see
89
- * <http://www.gnu.org/licenses/lgpl-2.1.html>
90
- */
91
-
92
-#include "qemu/osdep.h"
93
-#include "qemu/module.h"
94
-#include "qapi/error.h"
95
-
96
-#include "hw/irq.h"
97
-#include "hw/sysbus.h"
98
-#include "cpu.h"
99
-#include "qom/object.h"
100
-
101
-#define TYPE_ALTERA_IIC "altera,iic"
102
-OBJECT_DECLARE_SIMPLE_TYPE(AlteraIIC, ALTERA_IIC)
103
-
104
-struct AlteraIIC {
105
- SysBusDevice parent_obj;
106
- void *cpu;
107
- qemu_irq parent_irq;
108
-};
109
-
110
-static void update_irq(AlteraIIC *pv)
111
-{
112
- CPUNios2State *env = &((Nios2CPU *)(pv->cpu))->env;
113
-
114
- qemu_set_irq(pv->parent_irq,
115
- env->regs[CR_IPENDING] & env->regs[CR_IENABLE]);
116
-}
117
-
118
-static void irq_handler(void *opaque, int irq, int level)
119
-{
120
- AlteraIIC *pv = opaque;
121
- CPUNios2State *env = &((Nios2CPU *)(pv->cpu))->env;
122
-
123
- env->regs[CR_IPENDING] &= ~(1 << irq);
124
- env->regs[CR_IPENDING] |= !!level << irq;
125
-
126
- update_irq(pv);
127
-}
128
-
129
-static void altera_iic_init(Object *obj)
130
-{
131
- AlteraIIC *pv = ALTERA_IIC(obj);
132
-
133
- qdev_init_gpio_in(DEVICE(pv), irq_handler, 32);
134
- sysbus_init_irq(SYS_BUS_DEVICE(obj), &pv->parent_irq);
135
-}
136
-
137
-static void altera_iic_realize(DeviceState *dev, Error **errp)
138
-{
139
- struct AlteraIIC *pv = ALTERA_IIC(dev);
140
-
141
- pv->cpu = object_property_get_link(OBJECT(dev), "cpu", &error_abort);
142
-}
143
-
144
-static void altera_iic_class_init(ObjectClass *klass, void *data)
145
-{
146
- DeviceClass *dc = DEVICE_CLASS(klass);
147
-
148
- /* Reason: needs to be wired up, e.g. by nios2_10m50_ghrd_init() */
149
- dc->user_creatable = false;
150
- dc->realize = altera_iic_realize;
151
-}
152
-
153
-static TypeInfo altera_iic_info = {
154
- .name = TYPE_ALTERA_IIC,
155
- .parent = TYPE_SYS_BUS_DEVICE,
156
- .instance_size = sizeof(AlteraIIC),
157
- .instance_init = altera_iic_init,
158
- .class_init = altera_iic_class_init,
159
-};
160
-
161
-static void altera_iic_register(void)
162
-{
163
- type_register_static(&altera_iic_info);
164
-}
165
-
166
-type_init(altera_iic_register)
167
diff --git a/hw/nios2/10m50_devboard.c b/hw/nios2/10m50_devboard.c
168
index XXXXXXX..XXXXXXX 100644
169
--- a/hw/nios2/10m50_devboard.c
170
+++ b/hw/nios2/10m50_devboard.c
171
@@ -XXX,XX +XXX,XX @@ static void nios2_10m50_ghrd_init(MachineState *machine)
172
ram_addr_t tcm_size = 0x1000; /* 1 kiB, but QEMU limit is 4 kiB */
173
ram_addr_t ram_base = 0x08000000;
174
ram_addr_t ram_size = 0x08000000;
175
- qemu_irq *cpu_irq, irq[32];
176
+ qemu_irq irq[32];
177
int i;
178
179
/* Physical TCM (tb_ram_1k) with alias at 0xc0000000 */
180
@@ -XXX,XX +XXX,XX @@ static void nios2_10m50_ghrd_init(MachineState *machine)
181
182
/* Create CPU -- FIXME */
183
cpu = NIOS2_CPU(cpu_create(TYPE_NIOS2_CPU));
184
-
185
- /* Register: CPU interrupt controller (PIC) */
186
- cpu_irq = nios2_cpu_pic_init(cpu);
187
-
188
- /* Register: Internal Interrupt Controller (IIC) */
189
- dev = qdev_new("altera,iic");
190
- object_property_add_const_link(OBJECT(dev), "cpu", OBJECT(cpu));
191
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
192
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]);
193
for (i = 0; i < 32; i++) {
194
- irq[i] = qdev_get_gpio_in(dev, i);
195
+ irq[i] = qdev_get_gpio_in_named(DEVICE(cpu), "IRQ", i);
196
}
197
198
/* Register: Altera 16550 UART */
199
diff --git a/hw/nios2/cpu_pic.c b/hw/nios2/cpu_pic.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/hw/nios2/cpu_pic.c
202
+++ b/hw/nios2/cpu_pic.c
203
@@ -XXX,XX +XXX,XX @@
204
205
#include "boot.h"
206
207
-static void nios2_pic_cpu_handler(void *opaque, int irq, int level)
208
-{
209
- Nios2CPU *cpu = opaque;
210
- CPUNios2State *env = &cpu->env;
211
- CPUState *cs = CPU(cpu);
212
- int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD;
213
-
214
- if (type == CPU_INTERRUPT_HARD) {
215
- env->irq_pending = level;
216
-
217
- if (level && (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
218
- env->irq_pending = 0;
219
- cpu_interrupt(cs, type);
220
- } else if (!level) {
221
- env->irq_pending = 0;
222
- cpu_reset_interrupt(cs, type);
223
- }
224
- } else {
225
- if (level) {
226
- cpu_interrupt(cs, type);
227
- } else {
228
- cpu_reset_interrupt(cs, type);
229
- }
230
- }
231
-}
232
-
233
void nios2_check_interrupts(CPUNios2State *env)
234
{
235
if (env->irq_pending &&
236
@@ -XXX,XX +XXX,XX @@ void nios2_check_interrupts(CPUNios2State *env)
237
cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HARD);
238
}
239
}
240
-
241
-qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu)
242
-{
243
- return qemu_allocate_irqs(nios2_pic_cpu_handler, cpu, 2);
244
-}
245
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
246
index XXXXXXX..XXXXXXX 100644
247
--- a/target/nios2/cpu.c
248
+++ b/target/nios2/cpu.c
249
@@ -XXX,XX +XXX,XX @@ static void nios2_cpu_reset(DeviceState *dev)
250
#endif
251
}
252
253
+#ifndef CONFIG_USER_ONLY
254
+static void nios2_cpu_set_irq(void *opaque, int irq, int level)
255
+{
256
+ Nios2CPU *cpu = opaque;
257
+ CPUNios2State *env = &cpu->env;
258
+ CPUState *cs = CPU(cpu);
259
+
260
+ env->regs[CR_IPENDING] &= ~(1 << irq);
261
+ env->regs[CR_IPENDING] |= !!level << irq;
262
+
263
+ env->irq_pending = env->regs[CR_IPENDING] & env->regs[CR_IENABLE];
264
+
265
+ if (env->irq_pending && (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
266
+ env->irq_pending = 0;
267
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
268
+ } else if (!env->irq_pending) {
269
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
270
+ }
271
+}
272
+#endif
273
+
274
static void nios2_cpu_initfn(Object *obj)
275
{
276
Nios2CPU *cpu = NIOS2_CPU(obj);
277
@@ -XXX,XX +XXX,XX @@ static void nios2_cpu_initfn(Object *obj)
278
279
#if !defined(CONFIG_USER_ONLY)
280
mmu_init(&cpu->env);
281
+
282
+ /*
283
+ * These interrupt lines model the IIC (internal interrupt
284
+ * controller). QEMU does not currently support the EIC
285
+ * (external interrupt controller) -- if we did it would be
286
+ * a separate device in hw/intc with a custom interface to
287
+ * the CPU, and boards using it would not wire up these IRQ lines.
288
+ */
289
+ qdev_init_gpio_in_named(DEVICE(cpu), nios2_cpu_set_irq, "IRQ", 32);
290
#endif
291
}
292
293
diff --git a/MAINTAINERS b/MAINTAINERS
294
index XXXXXXX..XXXXXXX 100644
295
--- a/MAINTAINERS
296
+++ b/MAINTAINERS
297
@@ -XXX,XX +XXX,XX @@ M: Marek Vasut <marex@denx.de>
298
S: Maintained
299
F: target/nios2/
300
F: hw/nios2/
301
-F: hw/intc/nios2_iic.c
302
F: disas/nios2.c
303
F: default-configs/nios2-softmmu.mak
304
305
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
306
index XXXXXXX..XXXXXXX 100644
307
--- a/hw/intc/meson.build
308
+++ b/hw/intc/meson.build
309
@@ -XXX,XX +XXX,XX @@ specific_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_plic.c'))
310
specific_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
311
specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: files('loongson_liointc.c'))
312
specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gic.c'))
313
-specific_ss.add(when: 'CONFIG_NIOS2', if_true: files('nios2_iic.c'))
314
specific_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_intc.c'))
315
specific_ss.add(when: 'CONFIG_OMPIC', if_true: files('ompic.c'))
316
specific_ss.add(when: 'CONFIG_OPENPIC_KVM', if_true: files('openpic_kvm.c'))
317
--
318
2.20.1
319
320
diff view generated by jsdifflib
1
The raspi3 has AArch64 CPUs, which means that our smpboot
1
The function nios2_check_interrupts)() looks only at CPU-internal
2
code for keeping the secondary CPUs in a pen needs to have
2
state; it belongs in target/nios2, not hw/nios2. Move it into the
3
a version for A64 as well as A32. Without this, the
3
same file as its only caller, so it can just be local to that file.
4
secondary CPUs go into an infinite loop of taking undefined
4
5
instruction exceptions.
5
This removes the only remaining code from cpu_pic.c, so we can delete
6
that file entirely.
6
7
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20180313153458.26822-10-peter.maydell@linaro.org
10
Message-id: 20201129174022.26530-3-peter.maydell@linaro.org
11
Reviewed-by: Wentong Wu <wentong.wu@intel.com>
12
Tested-by: Wentong Wu <wentong.wu@intel.com>
10
---
13
---
11
hw/arm/raspi.c | 41 ++++++++++++++++++++++++++++++++++++++++-
14
target/nios2/cpu.h | 2 --
12
1 file changed, 40 insertions(+), 1 deletion(-)
15
hw/nios2/cpu_pic.c | 36 ------------------------------------
16
target/nios2/op_helper.c | 9 +++++++++
17
hw/nios2/meson.build | 2 +-
18
4 files changed, 10 insertions(+), 39 deletions(-)
19
delete mode 100644 hw/nios2/cpu_pic.c
13
20
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
21
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/raspi.c
23
--- a/target/nios2/cpu.h
17
+++ b/hw/arm/raspi.c
24
+++ b/target/nios2/cpu.h
25
@@ -XXX,XX +XXX,XX @@ void nios2_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
26
MMUAccessType access_type,
27
int mmu_idx, uintptr_t retaddr);
28
29
-void nios2_check_interrupts(CPUNios2State *env);
30
-
31
void do_nios2_semihosting(CPUNios2State *env);
32
33
#define CPU_RESOLVING_TYPE TYPE_NIOS2_CPU
34
diff --git a/hw/nios2/cpu_pic.c b/hw/nios2/cpu_pic.c
35
deleted file mode 100644
36
index XXXXXXX..XXXXXXX
37
--- a/hw/nios2/cpu_pic.c
38
+++ /dev/null
18
@@ -XXX,XX +XXX,XX @@
39
@@ -XXX,XX +XXX,XX @@
19
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
40
-/*
20
#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
41
- * Altera Nios2 CPU PIC
21
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
42
- *
22
+#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
43
- * Copyright (c) 2016 Marek Vasut <marek.vasut@gmail.com>
23
44
- *
24
/* Table of Linux board IDs for different Pi versions */
45
- * This library is free software; you can redistribute it and/or
25
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
46
- * modify it under the terms of the GNU Lesser General Public
26
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
47
- * License as published by the Free Software Foundation; either
27
info->smp_loader_start);
48
- * version 2.1 of the License, or (at your option) any later version.
49
- *
50
- * This library is distributed in the hope that it will be useful,
51
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
52
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
53
- * Lesser General Public License for more details.
54
- *
55
- * You should have received a copy of the GNU Lesser General Public
56
- * License along with this library; if not, see
57
- * <http://www.gnu.org/licenses/lgpl-2.1.html>
58
- */
59
-
60
-#include "qemu/osdep.h"
61
-#include "cpu.h"
62
-#include "hw/irq.h"
63
-
64
-#include "qemu/config-file.h"
65
-
66
-#include "boot.h"
67
-
68
-void nios2_check_interrupts(CPUNios2State *env)
69
-{
70
- if (env->irq_pending &&
71
- (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
72
- env->irq_pending = 0;
73
- cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HARD);
74
- }
75
-}
76
diff --git a/target/nios2/op_helper.c b/target/nios2/op_helper.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/nios2/op_helper.c
79
+++ b/target/nios2/op_helper.c
80
@@ -XXX,XX +XXX,XX @@ void helper_mmu_write(CPUNios2State *env, uint32_t rn, uint32_t v)
81
mmu_write(env, rn, v);
28
}
82
}
29
83
30
+static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
84
+static void nios2_check_interrupts(CPUNios2State *env)
31
+{
85
+{
32
+ /* Unlike the AArch32 version we don't need to call the board setup hook.
86
+ if (env->irq_pending &&
33
+ * The mechanism for doing the spin-table is also entirely different.
87
+ (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
34
+ * We must have four 64-bit fields at absolute addresses
88
+ env->irq_pending = 0;
35
+ * 0xd8, 0xe0, 0xe8, 0xf0 in RAM, which are the flag variables for
89
+ cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HARD);
36
+ * our CPUs, and which we must ensure are zero initialized before
90
+ }
37
+ * the primary CPU goes into the kernel. We put these variables inside
38
+ * a rom blob, so that the reset for ROM contents zeroes them for us.
39
+ */
40
+ static const uint32_t smpboot[] = {
41
+ 0xd2801b05, /* mov x5, 0xd8 */
42
+ 0xd53800a6, /* mrs x6, mpidr_el1 */
43
+ 0x924004c6, /* and x6, x6, #0x3 */
44
+ 0xd503205f, /* spin: wfe */
45
+ 0xf86678a4, /* ldr x4, [x5,x6,lsl #3] */
46
+ 0xb4ffffc4, /* cbz x4, spin */
47
+ 0xd2800000, /* mov x0, #0x0 */
48
+ 0xd2800001, /* mov x1, #0x0 */
49
+ 0xd2800002, /* mov x2, #0x0 */
50
+ 0xd2800003, /* mov x3, #0x0 */
51
+ 0xd61f0080, /* br x4 */
52
+ };
53
+
54
+ static const uint64_t spintables[] = {
55
+ 0, 0, 0, 0
56
+ };
57
+
58
+ rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
59
+ info->smp_loader_start);
60
+ rom_add_blob_fixed("raspi_spintables", spintables, sizeof(spintables),
61
+ SPINTABLE_ADDR);
62
+}
91
+}
63
+
92
+
64
static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
93
void helper_check_interrupts(CPUNios2State *env)
65
{
94
{
66
arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
95
qemu_mutex_lock_iothread();
67
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
96
diff --git a/hw/nios2/meson.build b/hw/nios2/meson.build
68
/* Pi2 and Pi3 requires SMP setup */
97
index XXXXXXX..XXXXXXX 100644
69
if (version >= 2) {
98
--- a/hw/nios2/meson.build
70
binfo.smp_loader_start = SMPBOOT_ADDR;
99
+++ b/hw/nios2/meson.build
71
- binfo.write_secondary_boot = write_smpboot;
100
@@ -XXX,XX +XXX,XX @@
72
+ if (version == 2) {
101
nios2_ss = ss.source_set()
73
+ binfo.write_secondary_boot = write_smpboot;
102
-nios2_ss.add(files('boot.c', 'cpu_pic.c'))
74
+ } else {
103
+nios2_ss.add(files('boot.c'))
75
+ binfo.write_secondary_boot = write_smpboot64;
104
nios2_ss.add(when: 'CONFIG_NIOS2_10M50', if_true: files('10m50_devboard.c'))
76
+ }
105
nios2_ss.add(when: 'CONFIG_NIOS2_GENERIC_NOMMU', if_true: files('generic_nommu.c'))
77
binfo.secondary_cpu_reset_hook = reset_secondary;
78
}
79
106
80
--
107
--
81
2.16.2
108
2.20.1
82
109
83
110
diff view generated by jsdifflib
1
Add some assertions that if we're about to boot an AArch64 kernel,
1
In nios2_cpu_set_irq(), use deposit32() rather than raw shift-and-mask
2
the board code has not mistakenly set either secure_boot or
2
operations to set the appropriate bit in the ipending register.
3
secure_board_setup. It doesn't make sense to set secure_boot,
4
because all AArch64 kernels must be booted in non-secure mode.
5
6
It might in theory make sense to set secure_board_setup, but
7
we don't currently support that, because only the AArch32
8
bootloader[] code calls this hook; bootloader_aarch64[] does not.
9
Since we don't have a current need for this functionality, just
10
assert that we don't try to use it. If it's needed we'll add
11
it later.
12
3
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20180313153458.26822-3-peter.maydell@linaro.org
6
Message-id: 20201129174022.26530-4-peter.maydell@linaro.org
16
---
7
---
17
hw/arm/boot.c | 7 +++++++
8
target/nios2/cpu.c | 3 +--
18
1 file changed, 7 insertions(+)
9
1 file changed, 1 insertion(+), 2 deletions(-)
19
10
20
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
11
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
21
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/boot.c
13
--- a/target/nios2/cpu.c
23
+++ b/hw/arm/boot.c
14
+++ b/target/nios2/cpu.c
24
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
15
@@ -XXX,XX +XXX,XX @@ static void nios2_cpu_set_irq(void *opaque, int irq, int level)
25
} else {
16
CPUNios2State *env = &cpu->env;
26
env->pstate = PSTATE_MODE_EL1h;
17
CPUState *cs = CPU(cpu);
27
}
18
28
+ /* AArch64 kernels never boot in secure mode */
19
- env->regs[CR_IPENDING] &= ~(1 << irq);
29
+ assert(!info->secure_boot);
20
- env->regs[CR_IPENDING] |= !!level << irq;
30
+ /* This hook is only supported for AArch32 currently:
21
+ env->regs[CR_IPENDING] = deposit32(env->regs[CR_IPENDING], irq, 1, !!level);
31
+ * bootloader_aarch64[] will not call the hook, and
22
32
+ * the code above has already dropped us into EL2 or EL1.
23
env->irq_pending = env->regs[CR_IPENDING] & env->regs[CR_IENABLE];
33
+ */
24
34
+ assert(!info->secure_board_setup);
35
}
36
37
/* Set to non-secure if not a secure boot */
38
--
25
--
39
2.16.2
26
2.20.1
40
27
41
28
diff view generated by jsdifflib
New patch
1
In rom_check_and_register_reset() we detect overlaps by looking at
2
whether the ROM blob we're currently examining is in the same address
3
space and starts before the previous ROM blob ends. (This works
4
because the ROM list is kept sorted in order by AddressSpace and then
5
by address.)
1
6
7
Instead of keeping the AddressSpace and last address of the previous ROM
8
blob in local variables, just keep a pointer to it.
9
10
This will allow us to print more useful information when we do detect
11
an overlap.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20201129203923.10622-2-peter.maydell@linaro.org
16
---
17
hw/core/loader.c | 23 +++++++++++++++--------
18
1 file changed, 15 insertions(+), 8 deletions(-)
19
20
diff --git a/hw/core/loader.c b/hw/core/loader.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/core/loader.c
23
+++ b/hw/core/loader.c
24
@@ -XXX,XX +XXX,XX @@ static void rom_reset(void *unused)
25
}
26
}
27
28
+/* Return true if two consecutive ROMs in the ROM list overlap */
29
+static bool roms_overlap(Rom *last_rom, Rom *this_rom)
30
+{
31
+ if (!last_rom) {
32
+ return false;
33
+ }
34
+ return last_rom->as == this_rom->as &&
35
+ last_rom->addr + last_rom->romsize > this_rom->addr;
36
+}
37
+
38
int rom_check_and_register_reset(void)
39
{
40
- hwaddr addr = 0;
41
MemoryRegionSection section;
42
- Rom *rom;
43
- AddressSpace *as = NULL;
44
+ Rom *rom, *last_rom = NULL;
45
46
QTAILQ_FOREACH(rom, &roms, next) {
47
if (rom->fw_file) {
48
continue;
49
}
50
if (!rom->mr) {
51
- if ((addr > rom->addr) && (as == rom->as)) {
52
+ if (roms_overlap(last_rom, rom)) {
53
fprintf(stderr, "rom: requested regions overlap "
54
"(rom %s. free=0x" TARGET_FMT_plx
55
", addr=0x" TARGET_FMT_plx ")\n",
56
- rom->name, addr, rom->addr);
57
+ rom->name, last_rom->addr + last_rom->romsize,
58
+ rom->addr);
59
return -1;
60
}
61
- addr = rom->addr;
62
- addr += rom->romsize;
63
- as = rom->as;
64
+ last_rom = rom;
65
}
66
section = memory_region_find(rom->mr ? rom->mr : get_system_memory(),
67
rom->addr, 1);
68
--
69
2.20.1
70
71
diff view generated by jsdifflib
1
The BCM2837 sets the Aff1 field of the MPIDR affinity values for the
1
In rom_check_and_register_reset() we report to the user if there is
2
CPUs to 0, whereas the BCM2836 uses 0xf. Set this correctly, as it
2
a "ROM region overlap". This has a couple of problems:
3
is required for Linux to boot.
3
* the reported information is not very easy to intepret
4
* the function just prints the overlap to stderr (and relies on
5
its single callsite in vl.c to do an error_report() and exit)
6
* only the first overlap encountered is diagnosed
7
8
Make this function use error_report() and error_printf() and
9
report a more user-friendly report with all the overlaps
10
diagnosed.
11
12
Sample old output:
13
14
rom: requested regions overlap (rom dtb. free=0x0000000000008000, addr=0x0000000000000000)
15
qemu-system-aarch64: rom check and register reset failed
16
17
Sample new output:
18
19
qemu-system-aarch64: Some ROM regions are overlapping
20
These ROM regions might have been loaded by direct user request or by default.
21
They could be BIOS/firmware images, a guest kernel, initrd or some other file loaded into guest memory.
22
Check whether you intended to load all this guest code, and whether it has been built to load to the correct addresses.
23
24
The following two regions overlap (in the cpu-memory-0 address space):
25
phdr #0: /home/petmay01/linaro/qemu-misc-tests/ldmia-fault.axf (addresses 0x0000000000000000 - 0x0000000000008000)
26
dtb (addresses 0x0000000000000000 - 0x0000000000100000)
27
28
The following two regions overlap (in the cpu-memory-0 address space):
29
phdr #1: /home/petmay01/linaro/qemu-misc-tests/bad-psci-call.axf (addresses 0x0000000040000000 - 0x0000000040000010)
30
phdr #0: /home/petmay01/linaro/qemu-misc-tests/bp-test.elf (addresses 0x0000000040000000 - 0x0000000040000020)
4
31
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
34
Message-id: 20201129203923.10622-3-peter.maydell@linaro.org
8
Message-id: 20180313153458.26822-8-peter.maydell@linaro.org
9
---
35
---
10
hw/arm/bcm2836.c | 11 +++++++----
36
hw/core/loader.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
11
1 file changed, 7 insertions(+), 4 deletions(-)
37
softmmu/vl.c | 1 -
38
2 files changed, 42 insertions(+), 7 deletions(-)
12
39
13
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
40
diff --git a/hw/core/loader.c b/hw/core/loader.c
14
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/bcm2836.c
42
--- a/hw/core/loader.c
16
+++ b/hw/arm/bcm2836.c
43
+++ b/hw/core/loader.c
17
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@ static bool roms_overlap(Rom *last_rom, Rom *this_rom)
18
45
last_rom->addr + last_rom->romsize > this_rom->addr;
19
struct BCM283XInfo {
46
}
20
const char *name;
47
21
+ int clusterid;
48
+static const char *rom_as_name(Rom *rom)
22
};
49
+{
23
50
+ const char *name = rom->as ? rom->as->name : NULL;
24
static const BCM283XInfo bcm283x_socs[] = {
51
+ return name ?: "anonymous";
25
{
52
+}
26
.name = TYPE_BCM2836,
53
+
27
+ .clusterid = 0xf,
54
+static void rom_print_overlap_error_header(void)
28
},
55
+{
29
{
56
+ error_report("Some ROM regions are overlapping");
30
.name = TYPE_BCM2837,
57
+ error_printf(
31
+ .clusterid = 0x0,
58
+ "These ROM regions might have been loaded by "
32
},
59
+ "direct user request or by default.\n"
33
};
60
+ "They could be BIOS/firmware images, a guest kernel, "
34
61
+ "initrd or some other file loaded into guest memory.\n"
35
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
62
+ "Check whether you intended to load all this guest code, and "
36
static void bcm2836_realize(DeviceState *dev, Error **errp)
63
+ "whether it has been built to load to the correct addresses.\n");
64
+}
65
+
66
+static void rom_print_one_overlap_error(Rom *last_rom, Rom *rom)
67
+{
68
+ error_printf(
69
+ "\nThe following two regions overlap (in the %s address space):\n",
70
+ rom_as_name(rom));
71
+ error_printf(
72
+ " %s (addresses 0x" TARGET_FMT_plx " - 0x" TARGET_FMT_plx ")\n",
73
+ last_rom->name, last_rom->addr, last_rom->addr + last_rom->romsize);
74
+ error_printf(
75
+ " %s (addresses 0x" TARGET_FMT_plx " - 0x" TARGET_FMT_plx ")\n",
76
+ rom->name, rom->addr, rom->addr + rom->romsize);
77
+}
78
+
79
int rom_check_and_register_reset(void)
37
{
80
{
38
BCM283XState *s = BCM283X(dev);
81
MemoryRegionSection section;
39
+ BCM283XClass *bc = BCM283X_GET_CLASS(dev);
82
Rom *rom, *last_rom = NULL;
40
+ const BCM283XInfo *info = bc->info;
83
+ bool found_overlap = false;
41
Object *obj;
84
42
Error *err = NULL;
85
QTAILQ_FOREACH(rom, &roms, next) {
43
int n;
86
if (rom->fw_file) {
44
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
87
@@ -XXX,XX +XXX,XX @@ int rom_check_and_register_reset(void)
45
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
88
}
46
89
if (!rom->mr) {
47
for (n = 0; n < BCM283X_NCPUS; n++) {
90
if (roms_overlap(last_rom, rom)) {
48
- /* Mirror bcm2836, which has clusterid set to 0xf
91
- fprintf(stderr, "rom: requested regions overlap "
49
- * TODO: this should be converted to a property of ARM_CPU
92
- "(rom %s. free=0x" TARGET_FMT_plx
50
- */
93
- ", addr=0x" TARGET_FMT_plx ")\n",
51
- s->cpus[n].mp_affinity = 0xF00 | n;
94
- rom->name, last_rom->addr + last_rom->romsize,
52
+ /* TODO: this should be converted to a property of ARM_CPU */
95
- rom->addr);
53
+ s->cpus[n].mp_affinity = (info->clusterid << 8) | n;
96
- return -1;
54
97
+ if (!found_overlap) {
55
/* set periphbase/CBAR value for CPU-local registers */
98
+ found_overlap = true;
56
object_property_set_int(OBJECT(&s->cpus[n]),
99
+ rom_print_overlap_error_header();
100
+ }
101
+ rom_print_one_overlap_error(last_rom, rom);
102
+ /* Keep going through the list so we report all overlaps */
103
}
104
last_rom = rom;
105
}
106
@@ -XXX,XX +XXX,XX @@ int rom_check_and_register_reset(void)
107
rom->isrom = int128_nz(section.size) && memory_region_is_rom(section.mr);
108
memory_region_unref(section.mr);
109
}
110
+ if (found_overlap) {
111
+ return -1;
112
+ }
113
+
114
qemu_register_reset(rom_reset, NULL);
115
roms_loaded = 1;
116
return 0;
117
diff --git a/softmmu/vl.c b/softmmu/vl.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/softmmu/vl.c
120
+++ b/softmmu/vl.c
121
@@ -XXX,XX +XXX,XX @@ static void qemu_machine_creation_done(void)
122
qemu_run_machine_init_done_notifiers();
123
124
if (rom_check_and_register_reset() != 0) {
125
- error_report("rom check and register reset failed");
126
exit(1);
127
}
128
57
--
129
--
58
2.16.2
130
2.20.1
59
131
60
132
diff view generated by jsdifflib
1
Our BCM2836 type is really a generic one that can be any of
1
Currently the load_elf code assembles the ROM blob name into a
2
the bcm283x family. Rename it accordingly. We change only
2
local 128 byte fixed-size array. Use g_strdup_printf() instead so
3
the names which are visible via the header file to the
3
that we don't truncate the pathname if it happens to be long.
4
rest of the QEMU code, leaving private function names
4
(This matters mostly for monitor 'info roms' output and for the
5
in bcm2836.c as they are.
5
error messages if ROM blobs overlap.)
6
7
This is a preliminary to making bcm283x be an abstract
8
parent class to specific types for the bcm2836 and bcm2837.
9
6
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20201129203923.10622-4-peter.maydell@linaro.org
13
Message-id: 20180313153458.26822-6-peter.maydell@linaro.org
14
---
10
---
15
include/hw/arm/bcm2836.h | 12 ++++++------
11
include/hw/elf_ops.h | 4 ++--
16
hw/arm/bcm2836.c | 17 +++++++++--------
12
1 file changed, 2 insertions(+), 2 deletions(-)
17
hw/arm/raspi.c | 16 ++++++++--------
18
3 files changed, 23 insertions(+), 22 deletions(-)
19
13
20
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
14
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/bcm2836.h
16
--- a/include/hw/elf_ops.h
23
+++ b/include/hw/arm/bcm2836.h
17
+++ b/include/hw/elf_ops.h
24
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static int glue(load_elf, SZ)(const char *name, int fd,
25
#include "hw/arm/bcm2835_peripherals.h"
19
uint64_t addr, low = (uint64_t)-1, high = 0;
26
#include "hw/intc/bcm2836_control.h"
20
GMappedFile *mapped_file = NULL;
27
21
uint8_t *data = NULL;
28
-#define TYPE_BCM2836 "bcm2836"
22
- char label[128];
29
-#define BCM2836(obj) OBJECT_CHECK(BCM2836State, (obj), TYPE_BCM2836)
23
int ret = ELF_LOAD_FAILED;
30
+#define TYPE_BCM283X "bcm283x"
24
31
+#define BCM283X(obj) OBJECT_CHECK(BCM283XState, (obj), TYPE_BCM283X)
25
if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
32
26
@@ -XXX,XX +XXX,XX @@ static int glue(load_elf, SZ)(const char *name, int fd,
33
-#define BCM2836_NCPUS 4
27
*/
34
+#define BCM283X_NCPUS 4
28
if (mem_size != 0) {
35
29
if (load_rom) {
36
-typedef struct BCM2836State {
30
- snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
37
+typedef struct BCM283XState {
31
+ g_autofree char *label =
38
/*< private >*/
32
+ g_strdup_printf("phdr #%d: %s", i, name);
39
DeviceState parent_obj;
33
40
/*< public >*/
34
/*
41
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
35
* rom_add_elf_program() takes its own reference to
42
char *cpu_type;
43
uint32_t enabled_cpus;
44
45
- ARMCPU cpus[BCM2836_NCPUS];
46
+ ARMCPU cpus[BCM283X_NCPUS];
47
BCM2836ControlState control;
48
BCM2835PeripheralState peripherals;
49
-} BCM2836State;
50
+} BCM283XState;
51
52
#endif /* BCM2836_H */
53
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/bcm2836.c
56
+++ b/hw/arm/bcm2836.c
57
@@ -XXX,XX +XXX,XX @@
58
59
static void bcm2836_init(Object *obj)
60
{
61
- BCM2836State *s = BCM2836(obj);
62
+ BCM283XState *s = BCM283X(obj);
63
64
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
65
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
66
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
67
68
static void bcm2836_realize(DeviceState *dev, Error **errp)
69
{
70
- BCM2836State *s = BCM2836(dev);
71
+ BCM283XState *s = BCM283X(dev);
72
Object *obj;
73
Error *err = NULL;
74
int n;
75
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
76
/* common peripherals from bcm2835 */
77
78
obj = OBJECT(dev);
79
- for (n = 0; n < BCM2836_NCPUS; n++) {
80
+ for (n = 0; n < BCM283X_NCPUS; n++) {
81
object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
82
s->cpu_type);
83
object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
84
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
85
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
86
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
87
88
- for (n = 0; n < BCM2836_NCPUS; n++) {
89
+ for (n = 0; n < BCM283X_NCPUS; n++) {
90
/* Mirror bcm2836, which has clusterid set to 0xf
91
* TODO: this should be converted to a property of ARM_CPU
92
*/
93
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
94
}
95
96
static Property bcm2836_props[] = {
97
- DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
98
- DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
99
+ DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
100
+ DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
101
+ BCM283X_NCPUS),
102
DEFINE_PROP_END_OF_LIST()
103
};
104
105
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
106
}
107
108
static const TypeInfo bcm2836_type_info = {
109
- .name = TYPE_BCM2836,
110
+ .name = TYPE_BCM283X,
111
.parent = TYPE_DEVICE,
112
- .instance_size = sizeof(BCM2836State),
113
+ .instance_size = sizeof(BCM283XState),
114
.instance_init = bcm2836_init,
115
.class_init = bcm2836_class_init,
116
};
117
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/hw/arm/raspi.c
120
+++ b/hw/arm/raspi.c
121
@@ -XXX,XX +XXX,XX @@
122
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
123
124
typedef struct RasPiState {
125
- BCM2836State soc;
126
+ BCM283XState soc;
127
MemoryRegion ram;
128
} RasPiState;
129
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2836);
135
+ object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
136
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
137
&error_abort);
138
139
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
143
- mc->max_cpus = BCM2836_NCPUS;
144
- mc->min_cpus = BCM2836_NCPUS;
145
- mc->default_cpus = BCM2836_NCPUS;
146
+ mc->max_cpus = BCM283X_NCPUS;
147
+ mc->min_cpus = BCM283X_NCPUS;
148
+ mc->default_cpus = BCM283X_NCPUS;
149
mc->default_ram_size = 1024 * 1024 * 1024;
150
mc->ignore_memory_transaction_failures = true;
151
};
152
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_init(MachineClass *mc)
153
mc->no_floppy = 1;
154
mc->no_cdrom = 1;
155
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
156
- mc->max_cpus = BCM2836_NCPUS;
157
- mc->min_cpus = BCM2836_NCPUS;
158
- mc->default_cpus = BCM2836_NCPUS;
159
+ mc->max_cpus = BCM283X_NCPUS;
160
+ mc->min_cpus = BCM283X_NCPUS;
161
+ mc->default_cpus = BCM283X_NCPUS;
162
mc->default_ram_size = 1024 * 1024 * 1024;
163
}
164
DEFINE_MACHINE("raspi3", raspi3_machine_init)
165
--
36
--
166
2.16.2
37
2.20.1
167
38
168
39
diff view generated by jsdifflib
1
For the rpi1 and 2 we want to boot the Linux kernel via some
1
Instead of making the ROM blob name something like:
2
custom setup code that makes sure that the SMC instruction
2
phdr #0: /home/petmay01/linaro/qemu-misc-tests/ldmia-fault.axf
3
acts as a no-op, because it's used for cache maintenance.
3
make it a little more self-explanatory for people who don't know
4
The rpi3 boots AArch64 kernels, which don't need SMC for
4
ELF format details:
5
cache maintenance and always expect to be booted non-secure.
5
/home/petmay01/linaro/qemu-misc-tests/ldmia-fault.axf ELF program header segment 0
6
Don't fill in the aarch32-specific parts of the binfo struct.
7
6
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20201129203923.10622-5-peter.maydell@linaro.org
11
Message-id: 20180313153458.26822-2-peter.maydell@linaro.org
12
---
10
---
13
hw/arm/raspi.c | 17 +++++++++++++----
11
include/hw/elf_ops.h | 3 ++-
14
1 file changed, 13 insertions(+), 4 deletions(-)
12
1 file changed, 2 insertions(+), 1 deletion(-)
15
13
16
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
14
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/raspi.c
16
--- a/include/hw/elf_ops.h
19
+++ b/hw/arm/raspi.c
17
+++ b/include/hw/elf_ops.h
20
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
18
@@ -XXX,XX +XXX,XX @@ static int glue(load_elf, SZ)(const char *name, int fd,
21
binfo.board_id = raspi_boardid[version];
19
if (mem_size != 0) {
22
binfo.ram_size = ram_size;
20
if (load_rom) {
23
binfo.nb_cpus = smp_cpus;
21
g_autofree char *label =
24
- binfo.board_setup_addr = BOARDSETUP_ADDR;
22
- g_strdup_printf("phdr #%d: %s", i, name);
25
- binfo.write_board_setup = write_board_setup;
23
+ g_strdup_printf("%s ELF program header segment %d",
26
- binfo.secure_board_setup = true;
24
+ name, i);
27
- binfo.secure_boot = true;
25
28
+
26
/*
29
+ if (version <= 2) {
27
* rom_add_elf_program() takes its own reference to
30
+ /* The rpi1 and 2 require some custom setup code to run in Secure
31
+ * mode before booting a kernel (to set up the SMC vectors so
32
+ * that we get a no-op SMC; this is used by Linux to call the
33
+ * firmware for some cache maintenance operations.
34
+ * The rpi3 doesn't need this.
35
+ */
36
+ binfo.board_setup_addr = BOARDSETUP_ADDR;
37
+ binfo.write_board_setup = write_board_setup;
38
+ binfo.secure_board_setup = true;
39
+ binfo.secure_boot = true;
40
+ }
41
42
/* Pi2 and Pi3 requires SMP setup */
43
if (version >= 2) {
44
--
28
--
45
2.16.2
29
2.20.1
46
30
47
31
diff view generated by jsdifflib
New patch
1
1
From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
2
3
This module emulates control registers of versal usb2 controller, this is added
4
just to make guest happy. In general this module would control the phy-reset
5
signal from usb controller, data coherency of the transactions, signals
6
the host system errors received from controller.
7
8
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
9
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1607023357-5096-2-git-send-email-sai.pavan.boddu@xilinx.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/hw/usb/xlnx-versal-usb2-ctrl-regs.h | 45 ++++
16
hw/usb/xlnx-versal-usb2-ctrl-regs.c | 229 ++++++++++++++++++++
17
hw/usb/meson.build | 1 +
18
3 files changed, 275 insertions(+)
19
create mode 100644 include/hw/usb/xlnx-versal-usb2-ctrl-regs.h
20
create mode 100644 hw/usb/xlnx-versal-usb2-ctrl-regs.c
21
22
diff --git a/include/hw/usb/xlnx-versal-usb2-ctrl-regs.h b/include/hw/usb/xlnx-versal-usb2-ctrl-regs.h
23
new file mode 100644
24
index XXXXXXX..XXXXXXX
25
--- /dev/null
26
+++ b/include/hw/usb/xlnx-versal-usb2-ctrl-regs.h
27
@@ -XXX,XX +XXX,XX @@
28
+/*
29
+ * QEMU model of the VersalUsb2CtrlRegs Register control/Status block for
30
+ * USB2.0 controller
31
+ *
32
+ * Copyright (c) 2020 Xilinx Inc. Vikram Garhwal <fnu.vikram@xilinx.com>
33
+ *
34
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
35
+ * of this software and associated documentation files (the "Software"), to deal
36
+ * in the Software without restriction, including without limitation the rights
37
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38
+ * copies of the Software, and to permit persons to whom the Software is
39
+ * furnished to do so, subject to the following conditions:
40
+ *
41
+ * The above copyright notice and this permission notice shall be included in
42
+ * all copies or substantial portions of the Software.
43
+ *
44
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
47
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
50
+ * THE SOFTWARE.
51
+ */
52
+
53
+#ifndef _XLNX_USB2_REGS_H_
54
+#define _XLNX_USB2_REGS_H_
55
+
56
+#define TYPE_XILINX_VERSAL_USB2_CTRL_REGS "xlnx.versal-usb2-ctrl-regs"
57
+
58
+#define XILINX_VERSAL_USB2_CTRL_REGS(obj) \
59
+ OBJECT_CHECK(VersalUsb2CtrlRegs, (obj), TYPE_XILINX_VERSAL_USB2_CTRL_REGS)
60
+
61
+#define USB2_REGS_R_MAX ((0x78 / 4) + 1)
62
+
63
+typedef struct VersalUsb2CtrlRegs {
64
+ SysBusDevice parent_obj;
65
+ MemoryRegion iomem;
66
+ qemu_irq irq_ir;
67
+
68
+ uint32_t regs[USB2_REGS_R_MAX];
69
+ RegisterInfo regs_info[USB2_REGS_R_MAX];
70
+} VersalUsb2CtrlRegs;
71
+
72
+#endif
73
diff --git a/hw/usb/xlnx-versal-usb2-ctrl-regs.c b/hw/usb/xlnx-versal-usb2-ctrl-regs.c
74
new file mode 100644
75
index XXXXXXX..XXXXXXX
76
--- /dev/null
77
+++ b/hw/usb/xlnx-versal-usb2-ctrl-regs.c
78
@@ -XXX,XX +XXX,XX @@
79
+/*
80
+ * QEMU model of the VersalUsb2CtrlRegs Register control/Status block for
81
+ * USB2.0 controller
82
+ *
83
+ * This module should control phy_reset, permanent device plugs, frame length
84
+ * time adjust & setting of coherency paths. None of which are emulated in
85
+ * present model.
86
+ *
87
+ * Copyright (c) 2020 Xilinx Inc. Vikram Garhwal <fnu.vikram@xilinx.com>
88
+ *
89
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
90
+ * of this software and associated documentation files (the "Software"), to deal
91
+ * in the Software without restriction, including without limitation the rights
92
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
93
+ * copies of the Software, and to permit persons to whom the Software is
94
+ * furnished to do so, subject to the following conditions:
95
+ *
96
+ * The above copyright notice and this permission notice shall be included in
97
+ * all copies or substantial portions of the Software.
98
+ *
99
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
100
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
101
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
102
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
103
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
104
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
105
+ * THE SOFTWARE.
106
+ */
107
+
108
+#include "qemu/osdep.h"
109
+#include "hw/sysbus.h"
110
+#include "hw/irq.h"
111
+#include "hw/register.h"
112
+#include "qemu/bitops.h"
113
+#include "qemu/log.h"
114
+#include "qom/object.h"
115
+#include "migration/vmstate.h"
116
+#include "hw/usb/xlnx-versal-usb2-ctrl-regs.h"
117
+
118
+#ifndef XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG
119
+#define XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG 0
120
+#endif
121
+
122
+REG32(BUS_FILTER, 0x30)
123
+ FIELD(BUS_FILTER, BYPASS, 0, 4)
124
+REG32(PORT, 0x34)
125
+ FIELD(PORT, HOST_SMI_BAR_WR, 4, 1)
126
+ FIELD(PORT, HOST_SMI_PCI_CMD_REG_WR, 3, 1)
127
+ FIELD(PORT, HOST_MSI_ENABLE, 2, 1)
128
+ FIELD(PORT, PWR_CTRL_PRSNT, 1, 1)
129
+ FIELD(PORT, HUB_PERM_ATTACH, 0, 1)
130
+REG32(JITTER_ADJUST, 0x38)
131
+ FIELD(JITTER_ADJUST, FLADJ, 0, 6)
132
+REG32(BIGENDIAN, 0x40)
133
+ FIELD(BIGENDIAN, ENDIAN_GS, 0, 1)
134
+REG32(COHERENCY, 0x44)
135
+ FIELD(COHERENCY, USB_COHERENCY, 0, 1)
136
+REG32(XHC_BME, 0x48)
137
+ FIELD(XHC_BME, XHC_BME, 0, 1)
138
+REG32(REG_CTRL, 0x60)
139
+ FIELD(REG_CTRL, SLVERR_ENABLE, 0, 1)
140
+REG32(IR_STATUS, 0x64)
141
+ FIELD(IR_STATUS, HOST_SYS_ERR, 1, 1)
142
+ FIELD(IR_STATUS, ADDR_DEC_ERR, 0, 1)
143
+REG32(IR_MASK, 0x68)
144
+ FIELD(IR_MASK, HOST_SYS_ERR, 1, 1)
145
+ FIELD(IR_MASK, ADDR_DEC_ERR, 0, 1)
146
+REG32(IR_ENABLE, 0x6c)
147
+ FIELD(IR_ENABLE, HOST_SYS_ERR, 1, 1)
148
+ FIELD(IR_ENABLE, ADDR_DEC_ERR, 0, 1)
149
+REG32(IR_DISABLE, 0x70)
150
+ FIELD(IR_DISABLE, HOST_SYS_ERR, 1, 1)
151
+ FIELD(IR_DISABLE, ADDR_DEC_ERR, 0, 1)
152
+REG32(USB3, 0x78)
153
+
154
+static void ir_update_irq(VersalUsb2CtrlRegs *s)
155
+{
156
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
157
+ qemu_set_irq(s->irq_ir, pending);
158
+}
159
+
160
+static void ir_status_postw(RegisterInfo *reg, uint64_t val64)
161
+{
162
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque);
163
+ /*
164
+ * TODO: This should also clear USBSTS.HSE field in USB XHCI register.
165
+ * May be combine both the modules.
166
+ */
167
+ ir_update_irq(s);
168
+}
169
+
170
+static uint64_t ir_enable_prew(RegisterInfo *reg, uint64_t val64)
171
+{
172
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque);
173
+ uint32_t val = val64;
174
+
175
+ s->regs[R_IR_MASK] &= ~val;
176
+ ir_update_irq(s);
177
+ return 0;
178
+}
179
+
180
+static uint64_t ir_disable_prew(RegisterInfo *reg, uint64_t val64)
181
+{
182
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque);
183
+ uint32_t val = val64;
184
+
185
+ s->regs[R_IR_MASK] |= val;
186
+ ir_update_irq(s);
187
+ return 0;
188
+}
189
+
190
+static const RegisterAccessInfo usb2_ctrl_regs_regs_info[] = {
191
+ { .name = "BUS_FILTER", .addr = A_BUS_FILTER,
192
+ .rsvd = 0xfffffff0,
193
+ },{ .name = "PORT", .addr = A_PORT,
194
+ .rsvd = 0xffffffe0,
195
+ },{ .name = "JITTER_ADJUST", .addr = A_JITTER_ADJUST,
196
+ .reset = 0x20,
197
+ .rsvd = 0xffffffc0,
198
+ },{ .name = "BIGENDIAN", .addr = A_BIGENDIAN,
199
+ .rsvd = 0xfffffffe,
200
+ },{ .name = "COHERENCY", .addr = A_COHERENCY,
201
+ .rsvd = 0xfffffffe,
202
+ },{ .name = "XHC_BME", .addr = A_XHC_BME,
203
+ .reset = 0x1,
204
+ .rsvd = 0xfffffffe,
205
+ },{ .name = "REG_CTRL", .addr = A_REG_CTRL,
206
+ .rsvd = 0xfffffffe,
207
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
208
+ .rsvd = 0xfffffffc,
209
+ .w1c = 0x3,
210
+ .post_write = ir_status_postw,
211
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
212
+ .reset = 0x3,
213
+ .rsvd = 0xfffffffc,
214
+ .ro = 0x3,
215
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
216
+ .rsvd = 0xfffffffc,
217
+ .pre_write = ir_enable_prew,
218
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
219
+ .rsvd = 0xfffffffc,
220
+ .pre_write = ir_disable_prew,
221
+ },{ .name = "USB3", .addr = A_USB3,
222
+ }
223
+};
224
+
225
+static void usb2_ctrl_regs_reset_init(Object *obj, ResetType type)
226
+{
227
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(obj);
228
+ unsigned int i;
229
+
230
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
231
+ register_reset(&s->regs_info[i]);
232
+ }
233
+}
234
+
235
+static void usb2_ctrl_regs_reset_hold(Object *obj)
236
+{
237
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(obj);
238
+
239
+ ir_update_irq(s);
240
+}
241
+
242
+static const MemoryRegionOps usb2_ctrl_regs_ops = {
243
+ .read = register_read_memory,
244
+ .write = register_write_memory,
245
+ .endianness = DEVICE_LITTLE_ENDIAN,
246
+ .valid = {
247
+ .min_access_size = 4,
248
+ .max_access_size = 4,
249
+ },
250
+};
251
+
252
+static void usb2_ctrl_regs_init(Object *obj)
253
+{
254
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(obj);
255
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
256
+ RegisterInfoArray *reg_array;
257
+
258
+ memory_region_init(&s->iomem, obj, TYPE_XILINX_VERSAL_USB2_CTRL_REGS,
259
+ USB2_REGS_R_MAX * 4);
260
+ reg_array =
261
+ register_init_block32(DEVICE(obj), usb2_ctrl_regs_regs_info,
262
+ ARRAY_SIZE(usb2_ctrl_regs_regs_info),
263
+ s->regs_info, s->regs,
264
+ &usb2_ctrl_regs_ops,
265
+ XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG,
266
+ USB2_REGS_R_MAX * 4);
267
+ memory_region_add_subregion(&s->iomem,
268
+ 0x0,
269
+ &reg_array->mem);
270
+ sysbus_init_mmio(sbd, &s->iomem);
271
+ sysbus_init_irq(sbd, &s->irq_ir);
272
+}
273
+
274
+static const VMStateDescription vmstate_usb2_ctrl_regs = {
275
+ .name = TYPE_XILINX_VERSAL_USB2_CTRL_REGS,
276
+ .version_id = 1,
277
+ .minimum_version_id = 1,
278
+ .fields = (VMStateField[]) {
279
+ VMSTATE_UINT32_ARRAY(regs, VersalUsb2CtrlRegs, USB2_REGS_R_MAX),
280
+ VMSTATE_END_OF_LIST(),
281
+ }
282
+};
283
+
284
+static void usb2_ctrl_regs_class_init(ObjectClass *klass, void *data)
285
+{
286
+ DeviceClass *dc = DEVICE_CLASS(klass);
287
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
288
+
289
+ rc->phases.enter = usb2_ctrl_regs_reset_init;
290
+ rc->phases.hold = usb2_ctrl_regs_reset_hold;
291
+ dc->vmsd = &vmstate_usb2_ctrl_regs;
292
+}
293
+
294
+static const TypeInfo usb2_ctrl_regs_info = {
295
+ .name = TYPE_XILINX_VERSAL_USB2_CTRL_REGS,
296
+ .parent = TYPE_SYS_BUS_DEVICE,
297
+ .instance_size = sizeof(VersalUsb2CtrlRegs),
298
+ .class_init = usb2_ctrl_regs_class_init,
299
+ .instance_init = usb2_ctrl_regs_init,
300
+};
301
+
302
+static void usb2_ctrl_regs_register_types(void)
303
+{
304
+ type_register_static(&usb2_ctrl_regs_info);
305
+}
306
+
307
+type_init(usb2_ctrl_regs_register_types)
308
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
309
index XXXXXXX..XXXXXXX 100644
310
--- a/hw/usb/meson.build
311
+++ b/hw/usb/meson.build
312
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_USB_DWC2', if_true: files('hcd-dwc2.c'))
313
softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c'))
314
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c'))
315
softmmu_ss.add(when: 'CONFIG_IMX_USBPHY', if_true: files('imx-usb-phy.c'))
316
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-usb2-ctrl-regs.c'))
317
318
# emulated usb devices
319
softmmu_ss.add(when: 'CONFIG_USB', if_true: files('dev-hub.c'))
320
--
321
2.20.1
322
323
diff view generated by jsdifflib
1
The bcm2837 is pretty similar to the bcm2836, but it does have
1
From: Vikram Garhwal <fnu.vikram@xilinx.com>
2
some differences. Notably, the MPIDR affinity aff1 values it
3
sets for the CPUs are 0x0, rather than the 0xf that the bcm2836
4
uses, and if this is wrong Linux will not boot.
5
2
6
Rather than trying to have one device with properties that
3
This patch adds skeleton model of dwc3 usb controller attached to
7
configure it differently for the two cases, create two
4
xhci-sysbus device. It defines global register space of DWC3 controller,
8
separate QOM devices for the two SoCs. We use the same approach
5
global registers control the AXI/AHB interfaces properties, external FIFO
9
as hw/arm/aspeed_soc.c and share code and have a data table
6
support and event count support. All of which are unimplemented at
10
that might differ per-SoC. For the moment the two types don't
7
present,we are only supporting core reset and read of ID register.
11
actually have different behaviour.
12
8
9
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
10
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Message-id: 1607023357-5096-3-git-send-email-sai.pavan.boddu@xilinx.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20180313153458.26822-7-peter.maydell@linaro.org
16
---
14
---
17
include/hw/arm/bcm2836.h | 19 +++++++++++++++++++
15
include/hw/usb/hcd-dwc3.h | 55 +++
18
hw/arm/bcm2836.c | 37 ++++++++++++++++++++++++++++++++-----
16
hw/usb/hcd-dwc3.c | 689 ++++++++++++++++++++++++++++++++++++++
19
hw/arm/raspi.c | 3 ++-
17
hw/usb/Kconfig | 5 +
20
3 files changed, 53 insertions(+), 6 deletions(-)
18
hw/usb/meson.build | 1 +
19
4 files changed, 750 insertions(+)
20
create mode 100644 include/hw/usb/hcd-dwc3.h
21
create mode 100644 hw/usb/hcd-dwc3.c
21
22
22
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
23
diff --git a/include/hw/usb/hcd-dwc3.h b/include/hw/usb/hcd-dwc3.h
23
index XXXXXXX..XXXXXXX 100644
24
new file mode 100644
24
--- a/include/hw/arm/bcm2836.h
25
index XXXXXXX..XXXXXXX
25
+++ b/include/hw/arm/bcm2836.h
26
--- /dev/null
27
+++ b/include/hw/usb/hcd-dwc3.h
26
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
27
29
+/*
28
#define BCM283X_NCPUS 4
30
+ * QEMU model of the USB DWC3 host controller emulation.
29
31
+ *
30
+/* These type names are for specific SoCs; other than instantiating
32
+ * Copyright (c) 2020 Xilinx Inc.
31
+ * them, code using these devices should always handle them via the
33
+ *
32
+ * BCM283x base class, so they have no BCM2836(obj) etc macros.
34
+ * Written by Vikram Garhwal<fnu.vikram@xilinx.com>
35
+ *
36
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
37
+ * of this software and associated documentation files (the "Software"), to deal
38
+ * in the Software without restriction, including without limitation the rights
39
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
40
+ * copies of the Software, and to permit persons to whom the Software is
41
+ * furnished to do so, subject to the following conditions:
42
+ *
43
+ * The above copyright notice and this permission notice shall be included in
44
+ * all copies or substantial portions of the Software.
45
+ *
46
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
49
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
51
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
52
+ * THE SOFTWARE.
33
+ */
53
+ */
34
+#define TYPE_BCM2836 "bcm2836"
54
+#ifndef HCD_DWC3_H
35
+#define TYPE_BCM2837 "bcm2837"
55
+#define HCD_DWC3_H
36
+
56
+
37
typedef struct BCM283XState {
57
+#include "hw/usb/hcd-xhci.h"
38
/*< private >*/
58
+#include "hw/usb/hcd-xhci-sysbus.h"
39
DeviceState parent_obj;
59
+
40
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XState {
60
+#define TYPE_USB_DWC3 "usb_dwc3"
41
BCM2835PeripheralState peripherals;
61
+
42
} BCM283XState;
62
+#define USB_DWC3(obj) \
43
63
+ OBJECT_CHECK(USBDWC3, (obj), TYPE_USB_DWC3)
44
+typedef struct BCM283XInfo BCM283XInfo;
64
+
45
+
65
+#define USB_DWC3_R_MAX ((0x530 / 4) + 1)
46
+typedef struct BCM283XClass {
66
+#define DWC3_SIZE 0x10000
47
+ DeviceClass parent_class;
67
+
48
+ const BCM283XInfo *info;
68
+typedef struct USBDWC3 {
49
+} BCM283XClass;
69
+ SysBusDevice parent_obj;
50
+
70
+ MemoryRegion iomem;
51
+#define BCM283X_CLASS(klass) \
71
+ XHCISysbusState sysbus_xhci;
52
+ OBJECT_CLASS_CHECK(BCM283XClass, (klass), TYPE_BCM283X)
72
+
53
+#define BCM283X_GET_CLASS(obj) \
73
+ uint32_t regs[USB_DWC3_R_MAX];
54
+ OBJECT_GET_CLASS(BCM283XClass, (obj), TYPE_BCM283X)
74
+ RegisterInfo regs_info[USB_DWC3_R_MAX];
55
+
75
+
56
#endif /* BCM2836_H */
76
+ struct {
57
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
77
+ uint8_t mode;
58
index XXXXXXX..XXXXXXX 100644
78
+ uint32_t dwc_usb3_user;
59
--- a/hw/arm/bcm2836.c
79
+ } cfg;
60
+++ b/hw/arm/bcm2836.c
80
+
81
+} USBDWC3;
82
+
83
+#endif
84
diff --git a/hw/usb/hcd-dwc3.c b/hw/usb/hcd-dwc3.c
85
new file mode 100644
86
index XXXXXXX..XXXXXXX
87
--- /dev/null
88
+++ b/hw/usb/hcd-dwc3.c
61
@@ -XXX,XX +XXX,XX @@
89
@@ -XXX,XX +XXX,XX @@
62
/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
90
+/*
63
#define BCM2836_CONTROL_BASE 0x40000000
91
+ * QEMU model of the USB DWC3 host controller emulation.
64
92
+ *
65
+struct BCM283XInfo {
93
+ * This model defines global register space of DWC3 controller. Global
66
+ const char *name;
94
+ * registers control the AXI/AHB interfaces properties, external FIFO support
95
+ * and event count support. All of which are unimplemented at present. We are
96
+ * only supporting core reset and read of ID register.
97
+ *
98
+ * Copyright (c) 2020 Xilinx Inc. Vikram Garhwal<fnu.vikram@xilinx.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
+
119
+#include "qemu/osdep.h"
120
+#include "hw/sysbus.h"
121
+#include "hw/register.h"
122
+#include "qemu/bitops.h"
123
+#include "qemu/log.h"
124
+#include "qom/object.h"
125
+#include "migration/vmstate.h"
126
+#include "hw/qdev-properties.h"
127
+#include "hw/usb/hcd-dwc3.h"
128
+#include "qapi/error.h"
129
+
130
+#ifndef USB_DWC3_ERR_DEBUG
131
+#define USB_DWC3_ERR_DEBUG 0
132
+#endif
133
+
134
+#define HOST_MODE 1
135
+#define FIFO_LEN 0x1000
136
+
137
+REG32(GSBUSCFG0, 0x00)
138
+ FIELD(GSBUSCFG0, DATRDREQINFO, 28, 4)
139
+ FIELD(GSBUSCFG0, DESRDREQINFO, 24, 4)
140
+ FIELD(GSBUSCFG0, DATWRREQINFO, 20, 4)
141
+ FIELD(GSBUSCFG0, DESWRREQINFO, 16, 4)
142
+ FIELD(GSBUSCFG0, RESERVED_15_12, 12, 4)
143
+ FIELD(GSBUSCFG0, DATBIGEND, 11, 1)
144
+ FIELD(GSBUSCFG0, DESBIGEND, 10, 1)
145
+ FIELD(GSBUSCFG0, RESERVED_9_8, 8, 2)
146
+ FIELD(GSBUSCFG0, INCR256BRSTENA, 7, 1)
147
+ FIELD(GSBUSCFG0, INCR128BRSTENA, 6, 1)
148
+ FIELD(GSBUSCFG0, INCR64BRSTENA, 5, 1)
149
+ FIELD(GSBUSCFG0, INCR32BRSTENA, 4, 1)
150
+ FIELD(GSBUSCFG0, INCR16BRSTENA, 3, 1)
151
+ FIELD(GSBUSCFG0, INCR8BRSTENA, 2, 1)
152
+ FIELD(GSBUSCFG0, INCR4BRSTENA, 1, 1)
153
+ FIELD(GSBUSCFG0, INCRBRSTENA, 0, 1)
154
+REG32(GSBUSCFG1, 0x04)
155
+ FIELD(GSBUSCFG1, RESERVED_31_13, 13, 19)
156
+ FIELD(GSBUSCFG1, EN1KPAGE, 12, 1)
157
+ FIELD(GSBUSCFG1, PIPETRANSLIMIT, 8, 4)
158
+ FIELD(GSBUSCFG1, RESERVED_7_0, 0, 8)
159
+REG32(GTXTHRCFG, 0x08)
160
+ FIELD(GTXTHRCFG, RESERVED_31, 31, 1)
161
+ FIELD(GTXTHRCFG, RESERVED_30, 30, 1)
162
+ FIELD(GTXTHRCFG, USBTXPKTCNTSEL, 29, 1)
163
+ FIELD(GTXTHRCFG, RESERVED_28, 28, 1)
164
+ FIELD(GTXTHRCFG, USBTXPKTCNT, 24, 4)
165
+ FIELD(GTXTHRCFG, USBMAXTXBURSTSIZE, 16, 8)
166
+ FIELD(GTXTHRCFG, RESERVED_15, 15, 1)
167
+ FIELD(GTXTHRCFG, RESERVED_14, 14, 1)
168
+ FIELD(GTXTHRCFG, RESERVED_13_11, 11, 3)
169
+ FIELD(GTXTHRCFG, RESERVED_10_0, 0, 11)
170
+REG32(GRXTHRCFG, 0x0c)
171
+ FIELD(GRXTHRCFG, RESERVED_31_30, 30, 2)
172
+ FIELD(GRXTHRCFG, USBRXPKTCNTSEL, 29, 1)
173
+ FIELD(GRXTHRCFG, RESERVED_28, 28, 1)
174
+ FIELD(GRXTHRCFG, USBRXPKTCNT, 24, 4)
175
+ FIELD(GRXTHRCFG, USBMAXRXBURSTSIZE, 19, 5)
176
+ FIELD(GRXTHRCFG, RESERVED_18_16, 16, 3)
177
+ FIELD(GRXTHRCFG, RESERVED_15, 15, 1)
178
+ FIELD(GRXTHRCFG, RESERVED_14_13, 13, 2)
179
+ FIELD(GRXTHRCFG, RESVISOCOUTSPC, 0, 13)
180
+REG32(GCTL, 0x10)
181
+ FIELD(GCTL, PWRDNSCALE, 19, 13)
182
+ FIELD(GCTL, MASTERFILTBYPASS, 18, 1)
183
+ FIELD(GCTL, BYPSSETADDR, 17, 1)
184
+ FIELD(GCTL, U2RSTECN, 16, 1)
185
+ FIELD(GCTL, FRMSCLDWN, 14, 2)
186
+ FIELD(GCTL, PRTCAPDIR, 12, 2)
187
+ FIELD(GCTL, CORESOFTRESET, 11, 1)
188
+ FIELD(GCTL, U1U2TIMERSCALE, 9, 1)
189
+ FIELD(GCTL, DEBUGATTACH, 8, 1)
190
+ FIELD(GCTL, RAMCLKSEL, 6, 2)
191
+ FIELD(GCTL, SCALEDOWN, 4, 2)
192
+ FIELD(GCTL, DISSCRAMBLE, 3, 1)
193
+ FIELD(GCTL, U2EXIT_LFPS, 2, 1)
194
+ FIELD(GCTL, GBLHIBERNATIONEN, 1, 1)
195
+ FIELD(GCTL, DSBLCLKGTNG, 0, 1)
196
+REG32(GPMSTS, 0x14)
197
+REG32(GSTS, 0x18)
198
+ FIELD(GSTS, CBELT, 20, 12)
199
+ FIELD(GSTS, RESERVED_19_12, 12, 8)
200
+ FIELD(GSTS, SSIC_IP, 11, 1)
201
+ FIELD(GSTS, OTG_IP, 10, 1)
202
+ FIELD(GSTS, BC_IP, 9, 1)
203
+ FIELD(GSTS, ADP_IP, 8, 1)
204
+ FIELD(GSTS, HOST_IP, 7, 1)
205
+ FIELD(GSTS, DEVICE_IP, 6, 1)
206
+ FIELD(GSTS, CSRTIMEOUT, 5, 1)
207
+ FIELD(GSTS, BUSERRADDRVLD, 4, 1)
208
+ FIELD(GSTS, RESERVED_3_2, 2, 2)
209
+ FIELD(GSTS, CURMOD, 0, 2)
210
+REG32(GUCTL1, 0x1c)
211
+ FIELD(GUCTL1, RESUME_OPMODE_HS_HOST, 10, 1)
212
+REG32(GSNPSID, 0x20)
213
+REG32(GGPIO, 0x24)
214
+ FIELD(GGPIO, GPO, 16, 16)
215
+ FIELD(GGPIO, GPI, 0, 16)
216
+REG32(GUID, 0x28)
217
+REG32(GUCTL, 0x2c)
218
+ FIELD(GUCTL, REFCLKPER, 22, 10)
219
+ FIELD(GUCTL, NOEXTRDL, 21, 1)
220
+ FIELD(GUCTL, RESERVED_20_18, 18, 3)
221
+ FIELD(GUCTL, SPRSCTRLTRANSEN, 17, 1)
222
+ FIELD(GUCTL, RESBWHSEPS, 16, 1)
223
+ FIELD(GUCTL, RESERVED_15, 15, 1)
224
+ FIELD(GUCTL, USBHSTINAUTORETRYEN, 14, 1)
225
+ FIELD(GUCTL, ENOVERLAPCHK, 13, 1)
226
+ FIELD(GUCTL, EXTCAPSUPPTEN, 12, 1)
227
+ FIELD(GUCTL, INSRTEXTRFSBODI, 11, 1)
228
+ FIELD(GUCTL, DTCT, 9, 2)
229
+ FIELD(GUCTL, DTFT, 0, 9)
230
+REG32(GBUSERRADDRLO, 0x30)
231
+REG32(GBUSERRADDRHI, 0x34)
232
+REG32(GHWPARAMS0, 0x40)
233
+ FIELD(GHWPARAMS0, GHWPARAMS0_31_24, 24, 8)
234
+ FIELD(GHWPARAMS0, GHWPARAMS0_23_16, 16, 8)
235
+ FIELD(GHWPARAMS0, GHWPARAMS0_15_8, 8, 8)
236
+ FIELD(GHWPARAMS0, GHWPARAMS0_7_6, 6, 2)
237
+ FIELD(GHWPARAMS0, GHWPARAMS0_5_3, 3, 3)
238
+ FIELD(GHWPARAMS0, GHWPARAMS0_2_0, 0, 3)
239
+REG32(GHWPARAMS1, 0x44)
240
+ FIELD(GHWPARAMS1, GHWPARAMS1_31, 31, 1)
241
+ FIELD(GHWPARAMS1, GHWPARAMS1_30, 30, 1)
242
+ FIELD(GHWPARAMS1, GHWPARAMS1_29, 29, 1)
243
+ FIELD(GHWPARAMS1, GHWPARAMS1_28, 28, 1)
244
+ FIELD(GHWPARAMS1, GHWPARAMS1_27, 27, 1)
245
+ FIELD(GHWPARAMS1, GHWPARAMS1_26, 26, 1)
246
+ FIELD(GHWPARAMS1, GHWPARAMS1_25_24, 24, 2)
247
+ FIELD(GHWPARAMS1, GHWPARAMS1_23, 23, 1)
248
+ FIELD(GHWPARAMS1, GHWPARAMS1_22_21, 21, 2)
249
+ FIELD(GHWPARAMS1, GHWPARAMS1_20_15, 15, 6)
250
+ FIELD(GHWPARAMS1, GHWPARAMS1_14_12, 12, 3)
251
+ FIELD(GHWPARAMS1, GHWPARAMS1_11_9, 9, 3)
252
+ FIELD(GHWPARAMS1, GHWPARAMS1_8_6, 6, 3)
253
+ FIELD(GHWPARAMS1, GHWPARAMS1_5_3, 3, 3)
254
+ FIELD(GHWPARAMS1, GHWPARAMS1_2_0, 0, 3)
255
+REG32(GHWPARAMS2, 0x48)
256
+REG32(GHWPARAMS3, 0x4c)
257
+ FIELD(GHWPARAMS3, GHWPARAMS3_31, 31, 1)
258
+ FIELD(GHWPARAMS3, GHWPARAMS3_30_23, 23, 8)
259
+ FIELD(GHWPARAMS3, GHWPARAMS3_22_18, 18, 5)
260
+ FIELD(GHWPARAMS3, GHWPARAMS3_17_12, 12, 6)
261
+ FIELD(GHWPARAMS3, GHWPARAMS3_11, 11, 1)
262
+ FIELD(GHWPARAMS3, GHWPARAMS3_10, 10, 1)
263
+ FIELD(GHWPARAMS3, GHWPARAMS3_9_8, 8, 2)
264
+ FIELD(GHWPARAMS3, GHWPARAMS3_7_6, 6, 2)
265
+ FIELD(GHWPARAMS3, GHWPARAMS3_5_4, 4, 2)
266
+ FIELD(GHWPARAMS3, GHWPARAMS3_3_2, 2, 2)
267
+ FIELD(GHWPARAMS3, GHWPARAMS3_1_0, 0, 2)
268
+REG32(GHWPARAMS4, 0x50)
269
+ FIELD(GHWPARAMS4, GHWPARAMS4_31_28, 28, 4)
270
+ FIELD(GHWPARAMS4, GHWPARAMS4_27_24, 24, 4)
271
+ FIELD(GHWPARAMS4, GHWPARAMS4_23, 23, 1)
272
+ FIELD(GHWPARAMS4, GHWPARAMS4_22, 22, 1)
273
+ FIELD(GHWPARAMS4, GHWPARAMS4_21, 21, 1)
274
+ FIELD(GHWPARAMS4, GHWPARAMS4_20_17, 17, 4)
275
+ FIELD(GHWPARAMS4, GHWPARAMS4_16_13, 13, 4)
276
+ FIELD(GHWPARAMS4, GHWPARAMS4_12, 12, 1)
277
+ FIELD(GHWPARAMS4, GHWPARAMS4_11, 11, 1)
278
+ FIELD(GHWPARAMS4, GHWPARAMS4_10_9, 9, 2)
279
+ FIELD(GHWPARAMS4, GHWPARAMS4_8_7, 7, 2)
280
+ FIELD(GHWPARAMS4, GHWPARAMS4_6, 6, 1)
281
+ FIELD(GHWPARAMS4, GHWPARAMS4_5_0, 0, 6)
282
+REG32(GHWPARAMS5, 0x54)
283
+ FIELD(GHWPARAMS5, GHWPARAMS5_31_28, 28, 4)
284
+ FIELD(GHWPARAMS5, GHWPARAMS5_27_22, 22, 6)
285
+ FIELD(GHWPARAMS5, GHWPARAMS5_21_16, 16, 6)
286
+ FIELD(GHWPARAMS5, GHWPARAMS5_15_10, 10, 6)
287
+ FIELD(GHWPARAMS5, GHWPARAMS5_9_4, 4, 6)
288
+ FIELD(GHWPARAMS5, GHWPARAMS5_3_0, 0, 4)
289
+REG32(GHWPARAMS6, 0x58)
290
+ FIELD(GHWPARAMS6, GHWPARAMS6_31_16, 16, 16)
291
+ FIELD(GHWPARAMS6, BUSFLTRSSUPPORT, 15, 1)
292
+ FIELD(GHWPARAMS6, BCSUPPORT, 14, 1)
293
+ FIELD(GHWPARAMS6, OTG_SS_SUPPORT, 13, 1)
294
+ FIELD(GHWPARAMS6, ADPSUPPORT, 12, 1)
295
+ FIELD(GHWPARAMS6, HNPSUPPORT, 11, 1)
296
+ FIELD(GHWPARAMS6, SRPSUPPORT, 10, 1)
297
+ FIELD(GHWPARAMS6, GHWPARAMS6_9_8, 8, 2)
298
+ FIELD(GHWPARAMS6, GHWPARAMS6_7, 7, 1)
299
+ FIELD(GHWPARAMS6, GHWPARAMS6_6, 6, 1)
300
+ FIELD(GHWPARAMS6, GHWPARAMS6_5_0, 0, 6)
301
+REG32(GHWPARAMS7, 0x5c)
302
+ FIELD(GHWPARAMS7, GHWPARAMS7_31_16, 16, 16)
303
+ FIELD(GHWPARAMS7, GHWPARAMS7_15_0, 0, 16)
304
+REG32(GDBGFIFOSPACE, 0x60)
305
+ FIELD(GDBGFIFOSPACE, SPACE_AVAILABLE, 16, 16)
306
+ FIELD(GDBGFIFOSPACE, RESERVED_15_9, 9, 7)
307
+ FIELD(GDBGFIFOSPACE, FIFO_QUEUE_SELECT, 0, 9)
308
+REG32(GUCTL2, 0x9c)
309
+ FIELD(GUCTL2, RESERVED_31_26, 26, 6)
310
+ FIELD(GUCTL2, EN_HP_PM_TIMER, 19, 7)
311
+ FIELD(GUCTL2, NOLOWPWRDUR, 15, 4)
312
+ FIELD(GUCTL2, RST_ACTBITLATER, 14, 1)
313
+ FIELD(GUCTL2, RESERVED_13, 13, 1)
314
+ FIELD(GUCTL2, DISABLECFC, 11, 1)
315
+REG32(GUSB2PHYCFG, 0x100)
316
+ FIELD(GUSB2PHYCFG, U2_FREECLK_EXISTS, 30, 1)
317
+ FIELD(GUSB2PHYCFG, ULPI_LPM_WITH_OPMODE_CHK, 29, 1)
318
+ FIELD(GUSB2PHYCFG, RESERVED_25, 25, 1)
319
+ FIELD(GUSB2PHYCFG, LSTRD, 22, 3)
320
+ FIELD(GUSB2PHYCFG, LSIPD, 19, 3)
321
+ FIELD(GUSB2PHYCFG, ULPIEXTVBUSINDIACTOR, 18, 1)
322
+ FIELD(GUSB2PHYCFG, ULPIEXTVBUSDRV, 17, 1)
323
+ FIELD(GUSB2PHYCFG, RESERVED_16, 16, 1)
324
+ FIELD(GUSB2PHYCFG, ULPIAUTORES, 15, 1)
325
+ FIELD(GUSB2PHYCFG, RESERVED_14, 14, 1)
326
+ FIELD(GUSB2PHYCFG, USBTRDTIM, 10, 4)
327
+ FIELD(GUSB2PHYCFG, XCVRDLY, 9, 1)
328
+ FIELD(GUSB2PHYCFG, ENBLSLPM, 8, 1)
329
+ FIELD(GUSB2PHYCFG, PHYSEL, 7, 1)
330
+ FIELD(GUSB2PHYCFG, SUSPENDUSB20, 6, 1)
331
+ FIELD(GUSB2PHYCFG, FSINTF, 5, 1)
332
+ FIELD(GUSB2PHYCFG, ULPI_UTMI_SEL, 4, 1)
333
+ FIELD(GUSB2PHYCFG, PHYIF, 3, 1)
334
+ FIELD(GUSB2PHYCFG, TOUTCAL, 0, 3)
335
+REG32(GUSB2I2CCTL, 0x140)
336
+REG32(GUSB2PHYACC_ULPI, 0x180)
337
+ FIELD(GUSB2PHYACC_ULPI, RESERVED_31_27, 27, 5)
338
+ FIELD(GUSB2PHYACC_ULPI, DISUIPIDRVR, 26, 1)
339
+ FIELD(GUSB2PHYACC_ULPI, NEWREGREQ, 25, 1)
340
+ FIELD(GUSB2PHYACC_ULPI, VSTSDONE, 24, 1)
341
+ FIELD(GUSB2PHYACC_ULPI, VSTSBSY, 23, 1)
342
+ FIELD(GUSB2PHYACC_ULPI, REGWR, 22, 1)
343
+ FIELD(GUSB2PHYACC_ULPI, REGADDR, 16, 6)
344
+ FIELD(GUSB2PHYACC_ULPI, EXTREGADDR, 8, 8)
345
+ FIELD(GUSB2PHYACC_ULPI, REGDATA, 0, 8)
346
+REG32(GTXFIFOSIZ0, 0x200)
347
+ FIELD(GTXFIFOSIZ0, TXFSTADDR_N, 16, 16)
348
+ FIELD(GTXFIFOSIZ0, TXFDEP_N, 0, 16)
349
+REG32(GTXFIFOSIZ1, 0x204)
350
+ FIELD(GTXFIFOSIZ1, TXFSTADDR_N, 16, 16)
351
+ FIELD(GTXFIFOSIZ1, TXFDEP_N, 0, 16)
352
+REG32(GTXFIFOSIZ2, 0x208)
353
+ FIELD(GTXFIFOSIZ2, TXFSTADDR_N, 16, 16)
354
+ FIELD(GTXFIFOSIZ2, TXFDEP_N, 0, 16)
355
+REG32(GTXFIFOSIZ3, 0x20c)
356
+ FIELD(GTXFIFOSIZ3, TXFSTADDR_N, 16, 16)
357
+ FIELD(GTXFIFOSIZ3, TXFDEP_N, 0, 16)
358
+REG32(GTXFIFOSIZ4, 0x210)
359
+ FIELD(GTXFIFOSIZ4, TXFSTADDR_N, 16, 16)
360
+ FIELD(GTXFIFOSIZ4, TXFDEP_N, 0, 16)
361
+REG32(GTXFIFOSIZ5, 0x214)
362
+ FIELD(GTXFIFOSIZ5, TXFSTADDR_N, 16, 16)
363
+ FIELD(GTXFIFOSIZ5, TXFDEP_N, 0, 16)
364
+REG32(GRXFIFOSIZ0, 0x280)
365
+ FIELD(GRXFIFOSIZ0, RXFSTADDR_N, 16, 16)
366
+ FIELD(GRXFIFOSIZ0, RXFDEP_N, 0, 16)
367
+REG32(GRXFIFOSIZ1, 0x284)
368
+ FIELD(GRXFIFOSIZ1, RXFSTADDR_N, 16, 16)
369
+ FIELD(GRXFIFOSIZ1, RXFDEP_N, 0, 16)
370
+REG32(GRXFIFOSIZ2, 0x288)
371
+ FIELD(GRXFIFOSIZ2, RXFSTADDR_N, 16, 16)
372
+ FIELD(GRXFIFOSIZ2, RXFDEP_N, 0, 16)
373
+REG32(GEVNTADRLO_0, 0x300)
374
+REG32(GEVNTADRHI_0, 0x304)
375
+REG32(GEVNTSIZ_0, 0x308)
376
+ FIELD(GEVNTSIZ_0, EVNTINTRPTMASK, 31, 1)
377
+ FIELD(GEVNTSIZ_0, RESERVED_30_16, 16, 15)
378
+ FIELD(GEVNTSIZ_0, EVENTSIZ, 0, 16)
379
+REG32(GEVNTCOUNT_0, 0x30c)
380
+ FIELD(GEVNTCOUNT_0, EVNT_HANDLER_BUSY, 31, 1)
381
+ FIELD(GEVNTCOUNT_0, RESERVED_30_16, 16, 15)
382
+ FIELD(GEVNTCOUNT_0, EVNTCOUNT, 0, 16)
383
+REG32(GEVNTADRLO_1, 0x310)
384
+REG32(GEVNTADRHI_1, 0x314)
385
+REG32(GEVNTSIZ_1, 0x318)
386
+ FIELD(GEVNTSIZ_1, EVNTINTRPTMASK, 31, 1)
387
+ FIELD(GEVNTSIZ_1, RESERVED_30_16, 16, 15)
388
+ FIELD(GEVNTSIZ_1, EVENTSIZ, 0, 16)
389
+REG32(GEVNTCOUNT_1, 0x31c)
390
+ FIELD(GEVNTCOUNT_1, EVNT_HANDLER_BUSY, 31, 1)
391
+ FIELD(GEVNTCOUNT_1, RESERVED_30_16, 16, 15)
392
+ FIELD(GEVNTCOUNT_1, EVNTCOUNT, 0, 16)
393
+REG32(GEVNTADRLO_2, 0x320)
394
+REG32(GEVNTADRHI_2, 0x324)
395
+REG32(GEVNTSIZ_2, 0x328)
396
+ FIELD(GEVNTSIZ_2, EVNTINTRPTMASK, 31, 1)
397
+ FIELD(GEVNTSIZ_2, RESERVED_30_16, 16, 15)
398
+ FIELD(GEVNTSIZ_2, EVENTSIZ, 0, 16)
399
+REG32(GEVNTCOUNT_2, 0x32c)
400
+ FIELD(GEVNTCOUNT_2, EVNT_HANDLER_BUSY, 31, 1)
401
+ FIELD(GEVNTCOUNT_2, RESERVED_30_16, 16, 15)
402
+ FIELD(GEVNTCOUNT_2, EVNTCOUNT, 0, 16)
403
+REG32(GEVNTADRLO_3, 0x330)
404
+REG32(GEVNTADRHI_3, 0x334)
405
+REG32(GEVNTSIZ_3, 0x338)
406
+ FIELD(GEVNTSIZ_3, EVNTINTRPTMASK, 31, 1)
407
+ FIELD(GEVNTSIZ_3, RESERVED_30_16, 16, 15)
408
+ FIELD(GEVNTSIZ_3, EVENTSIZ, 0, 16)
409
+REG32(GEVNTCOUNT_3, 0x33c)
410
+ FIELD(GEVNTCOUNT_3, EVNT_HANDLER_BUSY, 31, 1)
411
+ FIELD(GEVNTCOUNT_3, RESERVED_30_16, 16, 15)
412
+ FIELD(GEVNTCOUNT_3, EVNTCOUNT, 0, 16)
413
+REG32(GHWPARAMS8, 0x500)
414
+REG32(GTXFIFOPRIDEV, 0x510)
415
+ FIELD(GTXFIFOPRIDEV, RESERVED_31_N, 6, 26)
416
+ FIELD(GTXFIFOPRIDEV, GTXFIFOPRIDEV, 0, 6)
417
+REG32(GTXFIFOPRIHST, 0x518)
418
+ FIELD(GTXFIFOPRIHST, RESERVED_31_16, 3, 29)
419
+ FIELD(GTXFIFOPRIHST, GTXFIFOPRIHST, 0, 3)
420
+REG32(GRXFIFOPRIHST, 0x51c)
421
+ FIELD(GRXFIFOPRIHST, RESERVED_31_16, 3, 29)
422
+ FIELD(GRXFIFOPRIHST, GRXFIFOPRIHST, 0, 3)
423
+REG32(GDMAHLRATIO, 0x524)
424
+ FIELD(GDMAHLRATIO, RESERVED_31_13, 13, 19)
425
+ FIELD(GDMAHLRATIO, HSTRXFIFO, 8, 5)
426
+ FIELD(GDMAHLRATIO, RESERVED_7_5, 5, 3)
427
+ FIELD(GDMAHLRATIO, HSTTXFIFO, 0, 5)
428
+REG32(GFLADJ, 0x530)
429
+ FIELD(GFLADJ, GFLADJ_REFCLK_240MHZDECR_PLS1, 31, 1)
430
+ FIELD(GFLADJ, GFLADJ_REFCLK_240MHZ_DECR, 24, 7)
431
+ FIELD(GFLADJ, GFLADJ_REFCLK_LPM_SEL, 23, 1)
432
+ FIELD(GFLADJ, RESERVED_22, 22, 1)
433
+ FIELD(GFLADJ, GFLADJ_REFCLK_FLADJ, 8, 14)
434
+ FIELD(GFLADJ, GFLADJ_30MHZ_SDBND_SEL, 7, 1)
435
+ FIELD(GFLADJ, GFLADJ_30MHZ, 0, 6)
436
+
437
+#define DWC3_GLOBAL_OFFSET 0xC100
438
+static void reset_csr(USBDWC3 * s)
439
+{
440
+ int i = 0;
441
+ /*
442
+ * We reset all CSR regs except GCTL, GUCTL, GSTS, GSNPSID, GGPIO, GUID,
443
+ * GUSB2PHYCFGn registers and GUSB3PIPECTLn registers. We will skip PHY
444
+ * register as we don't implement them.
445
+ */
446
+ for (i = 0; i < USB_DWC3_R_MAX; i++) {
447
+ switch (i) {
448
+ case R_GCTL:
449
+ break;
450
+ case R_GSTS:
451
+ break;
452
+ case R_GSNPSID:
453
+ break;
454
+ case R_GGPIO:
455
+ break;
456
+ case R_GUID:
457
+ break;
458
+ case R_GUCTL:
459
+ break;
460
+ case R_GHWPARAMS0...R_GHWPARAMS7:
461
+ break;
462
+ case R_GHWPARAMS8:
463
+ break;
464
+ default:
465
+ register_reset(&s->regs_info[i]);
466
+ break;
467
+ }
468
+ }
469
+
470
+ xhci_sysbus_reset(DEVICE(&s->sysbus_xhci));
471
+}
472
+
473
+static void usb_dwc3_gctl_postw(RegisterInfo *reg, uint64_t val64)
474
+{
475
+ USBDWC3 *s = USB_DWC3(reg->opaque);
476
+
477
+ if (ARRAY_FIELD_EX32(s->regs, GCTL, CORESOFTRESET)) {
478
+ reset_csr(s);
479
+ }
480
+}
481
+
482
+static void usb_dwc3_guid_postw(RegisterInfo *reg, uint64_t val64)
483
+{
484
+ USBDWC3 *s = USB_DWC3(reg->opaque);
485
+
486
+ s->regs[R_GUID] = s->cfg.dwc_usb3_user;
487
+}
488
+
489
+static const RegisterAccessInfo usb_dwc3_regs_info[] = {
490
+ { .name = "GSBUSCFG0", .addr = A_GSBUSCFG0,
491
+ .ro = 0xf300,
492
+ .unimp = 0xffffffff,
493
+ },{ .name = "GSBUSCFG1", .addr = A_GSBUSCFG1,
494
+ .reset = 0x300,
495
+ .ro = 0xffffe0ff,
496
+ .unimp = 0xffffffff,
497
+ },{ .name = "GTXTHRCFG", .addr = A_GTXTHRCFG,
498
+ .ro = 0xd000ffff,
499
+ .unimp = 0xffffffff,
500
+ },{ .name = "GRXTHRCFG", .addr = A_GRXTHRCFG,
501
+ .ro = 0xd007e000,
502
+ .unimp = 0xffffffff,
503
+ },{ .name = "GCTL", .addr = A_GCTL,
504
+ .reset = 0x30c13004, .post_write = usb_dwc3_gctl_postw,
505
+ },{ .name = "GPMSTS", .addr = A_GPMSTS,
506
+ .ro = 0xfffffff,
507
+ .unimp = 0xffffffff,
508
+ },{ .name = "GSTS", .addr = A_GSTS,
509
+ .reset = 0x7e800000,
510
+ .ro = 0xffffffcf,
511
+ .w1c = 0x30,
512
+ .unimp = 0xffffffff,
513
+ },{ .name = "GUCTL1", .addr = A_GUCTL1,
514
+ .reset = 0x198a,
515
+ .ro = 0x7800,
516
+ .unimp = 0xffffffff,
517
+ },{ .name = "GSNPSID", .addr = A_GSNPSID,
518
+ .reset = 0x5533330a,
519
+ .ro = 0xffffffff,
520
+ },{ .name = "GGPIO", .addr = A_GGPIO,
521
+ .ro = 0xffff,
522
+ .unimp = 0xffffffff,
523
+ },{ .name = "GUID", .addr = A_GUID,
524
+ .reset = 0x12345678, .post_write = usb_dwc3_guid_postw,
525
+ },{ .name = "GUCTL", .addr = A_GUCTL,
526
+ .reset = 0x0c808010,
527
+ .ro = 0x1c8000,
528
+ .unimp = 0xffffffff,
529
+ },{ .name = "GBUSERRADDRLO", .addr = A_GBUSERRADDRLO,
530
+ .ro = 0xffffffff,
531
+ },{ .name = "GBUSERRADDRHI", .addr = A_GBUSERRADDRHI,
532
+ .ro = 0xffffffff,
533
+ },{ .name = "GHWPARAMS0", .addr = A_GHWPARAMS0,
534
+ .ro = 0xffffffff,
535
+ },{ .name = "GHWPARAMS1", .addr = A_GHWPARAMS1,
536
+ .ro = 0xffffffff,
537
+ },{ .name = "GHWPARAMS2", .addr = A_GHWPARAMS2,
538
+ .ro = 0xffffffff,
539
+ },{ .name = "GHWPARAMS3", .addr = A_GHWPARAMS3,
540
+ .ro = 0xffffffff,
541
+ },{ .name = "GHWPARAMS4", .addr = A_GHWPARAMS4,
542
+ .ro = 0xffffffff,
543
+ },{ .name = "GHWPARAMS5", .addr = A_GHWPARAMS5,
544
+ .ro = 0xffffffff,
545
+ },{ .name = "GHWPARAMS6", .addr = A_GHWPARAMS6,
546
+ .ro = 0xffffffff,
547
+ },{ .name = "GHWPARAMS7", .addr = A_GHWPARAMS7,
548
+ .ro = 0xffffffff,
549
+ },{ .name = "GDBGFIFOSPACE", .addr = A_GDBGFIFOSPACE,
550
+ .reset = 0xa0000,
551
+ .ro = 0xfffffe00,
552
+ .unimp = 0xffffffff,
553
+ },{ .name = "GUCTL2", .addr = A_GUCTL2,
554
+ .reset = 0x40d,
555
+ .ro = 0x2000,
556
+ .unimp = 0xffffffff,
557
+ },{ .name = "GUSB2PHYCFG", .addr = A_GUSB2PHYCFG,
558
+ .reset = 0x40102410,
559
+ .ro = 0x1e014030,
560
+ .unimp = 0xffffffff,
561
+ },{ .name = "GUSB2I2CCTL", .addr = A_GUSB2I2CCTL,
562
+ .ro = 0xffffffff,
563
+ .unimp = 0xffffffff,
564
+ },{ .name = "GUSB2PHYACC_ULPI", .addr = A_GUSB2PHYACC_ULPI,
565
+ .ro = 0xfd000000,
566
+ .unimp = 0xffffffff,
567
+ },{ .name = "GTXFIFOSIZ0", .addr = A_GTXFIFOSIZ0,
568
+ .reset = 0x2c7000a,
569
+ .unimp = 0xffffffff,
570
+ },{ .name = "GTXFIFOSIZ1", .addr = A_GTXFIFOSIZ1,
571
+ .reset = 0x2d10103,
572
+ .unimp = 0xffffffff,
573
+ },{ .name = "GTXFIFOSIZ2", .addr = A_GTXFIFOSIZ2,
574
+ .reset = 0x3d40103,
575
+ .unimp = 0xffffffff,
576
+ },{ .name = "GTXFIFOSIZ3", .addr = A_GTXFIFOSIZ3,
577
+ .reset = 0x4d70083,
578
+ .unimp = 0xffffffff,
579
+ },{ .name = "GTXFIFOSIZ4", .addr = A_GTXFIFOSIZ4,
580
+ .reset = 0x55a0083,
581
+ .unimp = 0xffffffff,
582
+ },{ .name = "GTXFIFOSIZ5", .addr = A_GTXFIFOSIZ5,
583
+ .reset = 0x5dd0083,
584
+ .unimp = 0xffffffff,
585
+ },{ .name = "GRXFIFOSIZ0", .addr = A_GRXFIFOSIZ0,
586
+ .reset = 0x1c20105,
587
+ .unimp = 0xffffffff,
588
+ },{ .name = "GRXFIFOSIZ1", .addr = A_GRXFIFOSIZ1,
589
+ .reset = 0x2c70000,
590
+ .unimp = 0xffffffff,
591
+ },{ .name = "GRXFIFOSIZ2", .addr = A_GRXFIFOSIZ2,
592
+ .reset = 0x2c70000,
593
+ .unimp = 0xffffffff,
594
+ },{ .name = "GEVNTADRLO_0", .addr = A_GEVNTADRLO_0,
595
+ .unimp = 0xffffffff,
596
+ },{ .name = "GEVNTADRHI_0", .addr = A_GEVNTADRHI_0,
597
+ .unimp = 0xffffffff,
598
+ },{ .name = "GEVNTSIZ_0", .addr = A_GEVNTSIZ_0,
599
+ .ro = 0x7fff0000,
600
+ .unimp = 0xffffffff,
601
+ },{ .name = "GEVNTCOUNT_0", .addr = A_GEVNTCOUNT_0,
602
+ .ro = 0x7fff0000,
603
+ .unimp = 0xffffffff,
604
+ },{ .name = "GEVNTADRLO_1", .addr = A_GEVNTADRLO_1,
605
+ .unimp = 0xffffffff,
606
+ },{ .name = "GEVNTADRHI_1", .addr = A_GEVNTADRHI_1,
607
+ .unimp = 0xffffffff,
608
+ },{ .name = "GEVNTSIZ_1", .addr = A_GEVNTSIZ_1,
609
+ .ro = 0x7fff0000,
610
+ .unimp = 0xffffffff,
611
+ },{ .name = "GEVNTCOUNT_1", .addr = A_GEVNTCOUNT_1,
612
+ .ro = 0x7fff0000,
613
+ .unimp = 0xffffffff,
614
+ },{ .name = "GEVNTADRLO_2", .addr = A_GEVNTADRLO_2,
615
+ .unimp = 0xffffffff,
616
+ },{ .name = "GEVNTADRHI_2", .addr = A_GEVNTADRHI_2,
617
+ .unimp = 0xffffffff,
618
+ },{ .name = "GEVNTSIZ_2", .addr = A_GEVNTSIZ_2,
619
+ .ro = 0x7fff0000,
620
+ .unimp = 0xffffffff,
621
+ },{ .name = "GEVNTCOUNT_2", .addr = A_GEVNTCOUNT_2,
622
+ .ro = 0x7fff0000,
623
+ .unimp = 0xffffffff,
624
+ },{ .name = "GEVNTADRLO_3", .addr = A_GEVNTADRLO_3,
625
+ .unimp = 0xffffffff,
626
+ },{ .name = "GEVNTADRHI_3", .addr = A_GEVNTADRHI_3,
627
+ .unimp = 0xffffffff,
628
+ },{ .name = "GEVNTSIZ_3", .addr = A_GEVNTSIZ_3,
629
+ .ro = 0x7fff0000,
630
+ .unimp = 0xffffffff,
631
+ },{ .name = "GEVNTCOUNT_3", .addr = A_GEVNTCOUNT_3,
632
+ .ro = 0x7fff0000,
633
+ .unimp = 0xffffffff,
634
+ },{ .name = "GHWPARAMS8", .addr = A_GHWPARAMS8,
635
+ .ro = 0xffffffff,
636
+ },{ .name = "GTXFIFOPRIDEV", .addr = A_GTXFIFOPRIDEV,
637
+ .ro = 0xffffffc0,
638
+ .unimp = 0xffffffff,
639
+ },{ .name = "GTXFIFOPRIHST", .addr = A_GTXFIFOPRIHST,
640
+ .ro = 0xfffffff8,
641
+ .unimp = 0xffffffff,
642
+ },{ .name = "GRXFIFOPRIHST", .addr = A_GRXFIFOPRIHST,
643
+ .ro = 0xfffffff8,
644
+ .unimp = 0xffffffff,
645
+ },{ .name = "GDMAHLRATIO", .addr = A_GDMAHLRATIO,
646
+ .ro = 0xffffe0e0,
647
+ .unimp = 0xffffffff,
648
+ },{ .name = "GFLADJ", .addr = A_GFLADJ,
649
+ .reset = 0xc83f020,
650
+ .rsvd = 0x40,
651
+ .ro = 0x400040,
652
+ .unimp = 0xffffffff,
653
+ }
67
+};
654
+};
68
+
655
+
69
+static const BCM283XInfo bcm283x_socs[] = {
656
+static void usb_dwc3_reset(DeviceState *dev)
70
+ {
657
+{
71
+ .name = TYPE_BCM2836,
658
+ USBDWC3 *s = USB_DWC3(dev);
72
+ },
659
+ unsigned int i;
73
+ {
660
+
74
+ .name = TYPE_BCM2837,
661
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
662
+ switch (i) {
663
+ case R_GHWPARAMS0...R_GHWPARAMS7:
664
+ break;
665
+ case R_GHWPARAMS8:
666
+ break;
667
+ default:
668
+ register_reset(&s->regs_info[i]);
669
+ };
670
+ }
671
+
672
+ xhci_sysbus_reset(DEVICE(&s->sysbus_xhci));
673
+}
674
+
675
+static const MemoryRegionOps usb_dwc3_ops = {
676
+ .read = register_read_memory,
677
+ .write = register_write_memory,
678
+ .endianness = DEVICE_LITTLE_ENDIAN,
679
+ .valid = {
680
+ .min_access_size = 4,
681
+ .max_access_size = 4,
75
+ },
682
+ },
76
+};
683
+};
77
+
684
+
78
static void bcm2836_init(Object *obj)
685
+static void usb_dwc3_realize(DeviceState *dev, Error **errp)
79
{
686
+{
80
BCM283XState *s = BCM283X(obj);
687
+ USBDWC3 *s = USB_DWC3(dev);
81
@@ -XXX,XX +XXX,XX @@ static Property bcm2836_props[] = {
688
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
82
DEFINE_PROP_END_OF_LIST()
689
+ Error *err = NULL;
83
};
690
+
84
691
+ sysbus_realize(SYS_BUS_DEVICE(&s->sysbus_xhci), &err);
85
-static void bcm2836_class_init(ObjectClass *oc, void *data)
692
+ if (err) {
86
+static void bcm283x_class_init(ObjectClass *oc, void *data)
693
+ error_propagate(errp, err);
87
{
694
+ return;
88
DeviceClass *dc = DEVICE_CLASS(oc);
89
+ BCM283XClass *bc = BCM283X_CLASS(oc);
90
91
- dc->props = bcm2836_props;
92
+ bc->info = data;
93
dc->realize = bcm2836_realize;
94
+ dc->props = bcm2836_props;
95
}
96
97
-static const TypeInfo bcm2836_type_info = {
98
+static const TypeInfo bcm283x_type_info = {
99
.name = TYPE_BCM283X,
100
.parent = TYPE_DEVICE,
101
.instance_size = sizeof(BCM283XState),
102
.instance_init = bcm2836_init,
103
- .class_init = bcm2836_class_init,
104
+ .class_size = sizeof(BCM283XClass),
105
+ .abstract = true,
106
};
107
108
static void bcm2836_register_types(void)
109
{
110
- type_register_static(&bcm2836_type_info);
111
+ int i;
112
+
113
+ type_register_static(&bcm283x_type_info);
114
+ for (i = 0; i < ARRAY_SIZE(bcm283x_socs); i++) {
115
+ TypeInfo ti = {
116
+ .name = bcm283x_socs[i].name,
117
+ .parent = TYPE_BCM283X,
118
+ .class_init = bcm283x_class_init,
119
+ .class_data = (void *) &bcm283x_socs[i],
120
+ };
121
+ type_register(&ti);
122
+ }
695
+ }
123
}
696
+
124
697
+ memory_region_add_subregion(&s->iomem, 0,
125
type_init(bcm2836_register_types)
698
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sysbus_xhci), 0));
126
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
699
+ sysbus_init_mmio(sbd, &s->iomem);
700
+
701
+ /*
702
+ * Device Configuration
703
+ */
704
+ s->regs[R_GHWPARAMS0] = 0x40204048 | s->cfg.mode;
705
+ s->regs[R_GHWPARAMS1] = 0x222493b;
706
+ s->regs[R_GHWPARAMS2] = 0x12345678;
707
+ s->regs[R_GHWPARAMS3] = 0x618c088;
708
+ s->regs[R_GHWPARAMS4] = 0x47822004;
709
+ s->regs[R_GHWPARAMS5] = 0x4202088;
710
+ s->regs[R_GHWPARAMS6] = 0x7850c20;
711
+ s->regs[R_GHWPARAMS7] = 0x0;
712
+ s->regs[R_GHWPARAMS8] = 0x478;
713
+}
714
+
715
+static void usb_dwc3_init(Object *obj)
716
+{
717
+ USBDWC3 *s = USB_DWC3(obj);
718
+ RegisterInfoArray *reg_array;
719
+
720
+ memory_region_init(&s->iomem, obj, TYPE_USB_DWC3, DWC3_SIZE);
721
+ reg_array =
722
+ register_init_block32(DEVICE(obj), usb_dwc3_regs_info,
723
+ ARRAY_SIZE(usb_dwc3_regs_info),
724
+ s->regs_info, s->regs,
725
+ &usb_dwc3_ops,
726
+ USB_DWC3_ERR_DEBUG,
727
+ USB_DWC3_R_MAX * 4);
728
+ memory_region_add_subregion(&s->iomem,
729
+ DWC3_GLOBAL_OFFSET,
730
+ &reg_array->mem);
731
+ object_initialize_child(obj, "dwc3-xhci", &s->sysbus_xhci,
732
+ TYPE_XHCI_SYSBUS);
733
+ qdev_alias_all_properties(DEVICE(&s->sysbus_xhci), obj);
734
+
735
+ s->cfg.mode = HOST_MODE;
736
+}
737
+
738
+static const VMStateDescription vmstate_usb_dwc3 = {
739
+ .name = "usb-dwc3",
740
+ .version_id = 1,
741
+ .fields = (VMStateField[]) {
742
+ VMSTATE_UINT32_ARRAY(regs, USBDWC3, USB_DWC3_R_MAX),
743
+ VMSTATE_UINT8(cfg.mode, USBDWC3),
744
+ VMSTATE_UINT32(cfg.dwc_usb3_user, USBDWC3),
745
+ VMSTATE_END_OF_LIST()
746
+ }
747
+};
748
+
749
+static Property usb_dwc3_properties[] = {
750
+ DEFINE_PROP_UINT32("DWC_USB3_USERID", USBDWC3, cfg.dwc_usb3_user,
751
+ 0x12345678),
752
+ DEFINE_PROP_END_OF_LIST(),
753
+};
754
+
755
+static void usb_dwc3_class_init(ObjectClass *klass, void *data)
756
+{
757
+ DeviceClass *dc = DEVICE_CLASS(klass);
758
+
759
+ dc->reset = usb_dwc3_reset;
760
+ dc->realize = usb_dwc3_realize;
761
+ dc->vmsd = &vmstate_usb_dwc3;
762
+ device_class_set_props(dc, usb_dwc3_properties);
763
+}
764
+
765
+static const TypeInfo usb_dwc3_info = {
766
+ .name = TYPE_USB_DWC3,
767
+ .parent = TYPE_SYS_BUS_DEVICE,
768
+ .instance_size = sizeof(USBDWC3),
769
+ .class_init = usb_dwc3_class_init,
770
+ .instance_init = usb_dwc3_init,
771
+};
772
+
773
+static void usb_dwc3_register_types(void)
774
+{
775
+ type_register_static(&usb_dwc3_info);
776
+}
777
+
778
+type_init(usb_dwc3_register_types)
779
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
127
index XXXXXXX..XXXXXXX 100644
780
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/arm/raspi.c
781
--- a/hw/usb/Kconfig
129
+++ b/hw/arm/raspi.c
782
+++ b/hw/usb/Kconfig
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
783
@@ -XXX,XX +XXX,XX @@ config IMX_USBPHY
131
BusState *bus;
784
bool
132
DeviceState *carddev;
785
default y
133
786
depends on USB
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
787
+
135
+ object_initialize(&s->soc, sizeof(s->soc),
788
+config USB_DWC3
136
+ version == 3 ? TYPE_BCM2837 : TYPE_BCM2836);
789
+ bool
137
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
790
+ select USB_XHCI_SYSBUS
138
&error_abort);
791
+ select REGISTER
139
792
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
793
index XXXXXXX..XXXXXXX 100644
794
--- a/hw/usb/meson.build
795
+++ b/hw/usb/meson.build
796
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_USB_XHCI_SYSBUS', if_true: files('hcd-xhci-sysbus.c
797
softmmu_ss.add(when: 'CONFIG_USB_XHCI_NEC', if_true: files('hcd-xhci-nec.c'))
798
softmmu_ss.add(when: 'CONFIG_USB_MUSB', if_true: files('hcd-musb.c'))
799
softmmu_ss.add(when: 'CONFIG_USB_DWC2', if_true: files('hcd-dwc2.c'))
800
+softmmu_ss.add(when: 'CONFIG_USB_DWC3', if_true: files('hcd-dwc3.c'))
801
802
softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c'))
803
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c'))
140
--
804
--
141
2.16.2
805
2.20.1
142
806
143
807
diff view generated by jsdifflib
New patch
1
1
From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
2
3
This model is a top level integration wrapper for hcd-dwc3 and
4
versal-usb2-ctrl-regs modules, this is used by xilinx versal soc's and
5
future xilinx usb subsystems would also be part of it.
6
7
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 1607023357-5096-4-git-send-email-sai.pavan.boddu@xilinx.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/usb/xlnx-usb-subsystem.h | 45 ++++++++++++++
14
hw/usb/xlnx-usb-subsystem.c | 94 +++++++++++++++++++++++++++++
15
hw/usb/Kconfig | 5 ++
16
hw/usb/meson.build | 1 +
17
4 files changed, 145 insertions(+)
18
create mode 100644 include/hw/usb/xlnx-usb-subsystem.h
19
create mode 100644 hw/usb/xlnx-usb-subsystem.c
20
21
diff --git a/include/hw/usb/xlnx-usb-subsystem.h b/include/hw/usb/xlnx-usb-subsystem.h
22
new file mode 100644
23
index XXXXXXX..XXXXXXX
24
--- /dev/null
25
+++ b/include/hw/usb/xlnx-usb-subsystem.h
26
@@ -XXX,XX +XXX,XX @@
27
+/*
28
+ * QEMU model of the Xilinx usb subsystem
29
+ *
30
+ * Copyright (c) 2020 Xilinx Inc. Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
31
+ *
32
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
33
+ * of this software and associated documentation files (the "Software"), to deal
34
+ * in the Software without restriction, including without limitation the rights
35
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
+ * copies of the Software, and to permit persons to whom the Software is
37
+ * furnished to do so, subject to the following conditions:
38
+ *
39
+ * The above copyright notice and this permission notice shall be included in
40
+ * all copies or substantial portions of the Software.
41
+ *
42
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
45
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
48
+ * THE SOFTWARE.
49
+ */
50
+
51
+#ifndef _XLNX_VERSAL_USB_SUBSYSTEM_H_
52
+#define _XLNX_VERSAL_USB_SUBSYSTEM_H_
53
+
54
+#include "hw/usb/xlnx-versal-usb2-ctrl-regs.h"
55
+#include "hw/usb/hcd-dwc3.h"
56
+
57
+#define TYPE_XILINX_VERSAL_USB2 "xlnx.versal-usb2"
58
+
59
+#define VERSAL_USB2(obj) \
60
+ OBJECT_CHECK(VersalUsb2, (obj), TYPE_XILINX_VERSAL_USB2)
61
+
62
+typedef struct VersalUsb2 {
63
+ SysBusDevice parent_obj;
64
+ MemoryRegion dwc3_mr;
65
+ MemoryRegion usb2Ctrl_mr;
66
+
67
+ VersalUsb2CtrlRegs usb2Ctrl;
68
+ USBDWC3 dwc3;
69
+} VersalUsb2;
70
+
71
+#endif
72
diff --git a/hw/usb/xlnx-usb-subsystem.c b/hw/usb/xlnx-usb-subsystem.c
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/hw/usb/xlnx-usb-subsystem.c
77
@@ -XXX,XX +XXX,XX @@
78
+/*
79
+ * QEMU model of the Xilinx usb subsystem
80
+ *
81
+ * Copyright (c) 2020 Xilinx Inc. Sai Pavan Boddu <sai.pava.boddu@xilinx.com>
82
+ *
83
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
84
+ * of this software and associated documentation files (the "Software"), to deal
85
+ * in the Software without restriction, including without limitation the rights
86
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
87
+ * copies of the Software, and to permit persons to whom the Software is
88
+ * furnished to do so, subject to the following conditions:
89
+ *
90
+ * The above copyright notice and this permission notice shall be included in
91
+ * all copies or substantial portions of the Software.
92
+ *
93
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
94
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
95
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
96
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
97
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
98
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
99
+ * THE SOFTWARE.
100
+ */
101
+
102
+#include "qemu/osdep.h"
103
+#include "hw/sysbus.h"
104
+#include "hw/irq.h"
105
+#include "hw/register.h"
106
+#include "qemu/bitops.h"
107
+#include "qemu/log.h"
108
+#include "qom/object.h"
109
+#include "qapi/error.h"
110
+#include "hw/qdev-properties.h"
111
+#include "hw/usb/xlnx-usb-subsystem.h"
112
+
113
+static void versal_usb2_realize(DeviceState *dev, Error **errp)
114
+{
115
+ VersalUsb2 *s = VERSAL_USB2(dev);
116
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
117
+ Error *err = NULL;
118
+
119
+ sysbus_realize(SYS_BUS_DEVICE(&s->dwc3), &err);
120
+ if (err) {
121
+ error_propagate(errp, err);
122
+ return;
123
+ }
124
+ sysbus_realize(SYS_BUS_DEVICE(&s->usb2Ctrl), &err);
125
+ if (err) {
126
+ error_propagate(errp, err);
127
+ return;
128
+ }
129
+ sysbus_init_mmio(sbd, &s->dwc3_mr);
130
+ sysbus_init_mmio(sbd, &s->usb2Ctrl_mr);
131
+ qdev_pass_gpios(DEVICE(&s->dwc3.sysbus_xhci), dev, SYSBUS_DEVICE_GPIO_IRQ);
132
+}
133
+
134
+static void versal_usb2_init(Object *obj)
135
+{
136
+ VersalUsb2 *s = VERSAL_USB2(obj);
137
+
138
+ object_initialize_child(obj, "versal.dwc3", &s->dwc3,
139
+ TYPE_USB_DWC3);
140
+ object_initialize_child(obj, "versal.usb2-ctrl", &s->usb2Ctrl,
141
+ TYPE_XILINX_VERSAL_USB2_CTRL_REGS);
142
+ memory_region_init_alias(&s->dwc3_mr, obj, "versal.dwc3_alias",
143
+ &s->dwc3.iomem, 0, DWC3_SIZE);
144
+ memory_region_init_alias(&s->usb2Ctrl_mr, obj, "versal.usb2Ctrl_alias",
145
+ &s->usb2Ctrl.iomem, 0, USB2_REGS_R_MAX * 4);
146
+ qdev_alias_all_properties(DEVICE(&s->dwc3), obj);
147
+ qdev_alias_all_properties(DEVICE(&s->dwc3.sysbus_xhci), obj);
148
+ object_property_add_alias(obj, "dma", OBJECT(&s->dwc3.sysbus_xhci), "dma");
149
+}
150
+
151
+static void versal_usb2_class_init(ObjectClass *klass, void *data)
152
+{
153
+ DeviceClass *dc = DEVICE_CLASS(klass);
154
+
155
+ dc->realize = versal_usb2_realize;
156
+}
157
+
158
+static const TypeInfo versal_usb2_info = {
159
+ .name = TYPE_XILINX_VERSAL_USB2,
160
+ .parent = TYPE_SYS_BUS_DEVICE,
161
+ .instance_size = sizeof(VersalUsb2),
162
+ .class_init = versal_usb2_class_init,
163
+ .instance_init = versal_usb2_init,
164
+};
165
+
166
+static void versal_usb_types(void)
167
+{
168
+ type_register_static(&versal_usb2_info);
169
+}
170
+
171
+type_init(versal_usb_types)
172
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
173
index XXXXXXX..XXXXXXX 100644
174
--- a/hw/usb/Kconfig
175
+++ b/hw/usb/Kconfig
176
@@ -XXX,XX +XXX,XX @@ config USB_DWC3
177
bool
178
select USB_XHCI_SYSBUS
179
select REGISTER
180
+
181
+config XLNX_USB_SUBSYS
182
+ bool
183
+ default y if XLNX_VERSAL
184
+ select USB_DWC3
185
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
186
index XXXXXXX..XXXXXXX 100644
187
--- a/hw/usb/meson.build
188
+++ b/hw/usb/meson.build
189
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c'))
190
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c'))
191
softmmu_ss.add(when: 'CONFIG_IMX_USBPHY', if_true: files('imx-usb-phy.c'))
192
specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-usb2-ctrl-regs.c'))
193
+specific_ss.add(when: 'CONFIG_XLNX_USB_SUBSYS', if_true: files('xlnx-usb-subsystem.c'))
194
195
# emulated usb devices
196
softmmu_ss.add(when: 'CONFIG_USB', if_true: files('dev-hub.c'))
197
--
198
2.20.1
199
200
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Vikram Garhwal <fnu.vikram@xilinx.com>
2
2
3
Code of imx_update() is slightly confusing since the "flags" variable
3
Connect VersalUsb2 subsystem to xlnx-versal SOC, its placed
4
doesn't really corespond to anything in real hardware and server as a
4
in iou of lpd domain and configure it as dual port host controller.
5
kitchensink accumulating events normally reported via USR1 and USR2
5
Add the respective guest dts nodes for "xlnx-versal-virt" machine.
6
registers.
7
6
8
Change the code to explicitly evaluate state of interrupts reported
7
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
9
via USR1 and USR2 against corresponding masking bits and use the to
8
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
10
detemine if IRQ line should be asserted or not.
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
10
Message-id: 1607023357-5096-5-git-send-email-sai.pavan.boddu@xilinx.com
12
NOTE: Check for UTS1_TXEMPTY being set has been dropped for two
13
reasons:
14
15
1. Emulation code implements a single character FIFO, so this flag
16
will always be set since characters are trasmitted as a part of
17
the code emulating "push" into the FIFO
18
19
2. imx_update() is really just a function doing ORing and maksing
20
of reported events, so checking for UTS1_TXEMPTY should happen,
21
if it's ever really needed should probably happen outside of
22
it.
23
24
Cc: qemu-devel@nongnu.org
25
Cc: qemu-arm@nongnu.org
26
Cc: Bill Paul <wpaul@windriver.com>
27
Cc: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
29
Message-id: 20180315191141.6789-1-andrew.smirnov@gmail.com
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
12
---
33
hw/char/imx_serial.c | 24 ++++++++++++++++--------
13
include/hw/arm/xlnx-versal.h | 9 ++++++
34
1 file changed, 16 insertions(+), 8 deletions(-)
14
hw/arm/xlnx-versal-virt.c | 55 ++++++++++++++++++++++++++++++++++++
15
hw/arm/xlnx-versal.c | 26 +++++++++++++++++
16
3 files changed, 90 insertions(+)
35
17
36
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
37
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/char/imx_serial.c
20
--- a/include/hw/arm/xlnx-versal.h
39
+++ b/hw/char/imx_serial.c
21
+++ b/include/hw/arm/xlnx-versal.h
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
22
@@ -XXX,XX +XXX,XX @@
41
23
#include "hw/net/cadence_gem.h"
42
static void imx_update(IMXSerialState *s)
24
#include "hw/rtc/xlnx-zynqmp-rtc.h"
25
#include "qom/object.h"
26
+#include "hw/usb/xlnx-usb-subsystem.h"
27
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
29
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
30
@@ -XXX,XX +XXX,XX @@ struct Versal {
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
33
XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
34
+ VersalUsb2 usb;
35
} iou;
36
} lpd;
37
38
@@ -XXX,XX +XXX,XX @@ struct Versal {
39
40
#define VERSAL_UART0_IRQ_0 18
41
#define VERSAL_UART1_IRQ_0 19
42
+#define VERSAL_USB0_IRQ_0 22
43
#define VERSAL_GEM0_IRQ_0 56
44
#define VERSAL_GEM0_WAKE_IRQ_0 57
45
#define VERSAL_GEM1_IRQ_0 58
46
@@ -XXX,XX +XXX,XX @@ struct Versal {
47
#define MM_OCM 0xfffc0000U
48
#define MM_OCM_SIZE 0x40000
49
50
+#define MM_USB2_CTRL_REGS 0xFF9D0000
51
+#define MM_USB2_CTRL_REGS_SIZE 0x10000
52
+
53
+#define MM_USB_0 0xFE200000
54
+#define MM_USB_0_SIZE 0x10000
55
+
56
#define MM_TOP_DDR 0x0
57
#define MM_TOP_DDR_SIZE 0x80000000U
58
#define MM_TOP_DDR_2 0x800000000ULL
59
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/xlnx-versal-virt.c
62
+++ b/hw/arm/xlnx-versal-virt.c
63
@@ -XXX,XX +XXX,XX @@ struct VersalVirt {
64
uint32_t ethernet_phy[2];
65
uint32_t clk_125Mhz;
66
uint32_t clk_25Mhz;
67
+ uint32_t usb;
68
+ uint32_t dwc;
69
} phandle;
70
struct arm_boot_info binfo;
71
72
@@ -XXX,XX +XXX,XX @@ static void fdt_create(VersalVirt *s)
73
s->phandle.clk_25Mhz = qemu_fdt_alloc_phandle(s->fdt);
74
s->phandle.clk_125Mhz = qemu_fdt_alloc_phandle(s->fdt);
75
76
+ s->phandle.usb = qemu_fdt_alloc_phandle(s->fdt);
77
+ s->phandle.dwc = qemu_fdt_alloc_phandle(s->fdt);
78
/* Create /chosen node for load_dtb. */
79
qemu_fdt_add_subnode(s->fdt, "/chosen");
80
81
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(VersalVirt *s)
82
compat, sizeof(compat));
83
}
84
85
+static void fdt_add_usb_xhci_nodes(VersalVirt *s)
86
+{
87
+ const char clocknames[] = "bus_clk\0ref_clk";
88
+ const char irq_name[] = "dwc_usb3";
89
+ const char compatVersalDWC3[] = "xlnx,versal-dwc3";
90
+ const char compatDWC3[] = "snps,dwc3";
91
+ char *name = g_strdup_printf("/usb@%" PRIx32, MM_USB2_CTRL_REGS);
92
+
93
+ qemu_fdt_add_subnode(s->fdt, name);
94
+ qemu_fdt_setprop(s->fdt, name, "compatible",
95
+ compatVersalDWC3, sizeof(compatVersalDWC3));
96
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
97
+ 2, MM_USB2_CTRL_REGS,
98
+ 2, MM_USB2_CTRL_REGS_SIZE);
99
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
100
+ clocknames, sizeof(clocknames));
101
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
102
+ s->phandle.clk_25Mhz, s->phandle.clk_125Mhz);
103
+ qemu_fdt_setprop(s->fdt, name, "ranges", NULL, 0);
104
+ qemu_fdt_setprop_cell(s->fdt, name, "#address-cells", 2);
105
+ qemu_fdt_setprop_cell(s->fdt, name, "#size-cells", 2);
106
+ qemu_fdt_setprop_cell(s->fdt, name, "phandle", s->phandle.usb);
107
+ g_free(name);
108
+
109
+ name = g_strdup_printf("/usb@%" PRIx32 "/dwc3@%" PRIx32,
110
+ MM_USB2_CTRL_REGS, MM_USB_0);
111
+ qemu_fdt_add_subnode(s->fdt, name);
112
+ qemu_fdt_setprop(s->fdt, name, "compatible",
113
+ compatDWC3, sizeof(compatDWC3));
114
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
115
+ 2, MM_USB_0, 2, MM_USB_0_SIZE);
116
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
117
+ irq_name, sizeof(irq_name));
118
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
119
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_USB0_IRQ_0,
120
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
121
+ qemu_fdt_setprop_cell(s->fdt, name,
122
+ "snps,quirk-frame-length-adjustment", 0x20);
123
+ qemu_fdt_setprop_cells(s->fdt, name, "#stream-id-cells", 1);
124
+ qemu_fdt_setprop_string(s->fdt, name, "dr_mode", "host");
125
+ qemu_fdt_setprop_string(s->fdt, name, "phy-names", "usb3-phy");
126
+ qemu_fdt_setprop(s->fdt, name, "snps,dis_u2_susphy_quirk", NULL, 0);
127
+ qemu_fdt_setprop(s->fdt, name, "snps,dis_u3_susphy_quirk", NULL, 0);
128
+ qemu_fdt_setprop(s->fdt, name, "snps,refclk_fladj", NULL, 0);
129
+ qemu_fdt_setprop(s->fdt, name, "snps,mask_phy_reset", NULL, 0);
130
+ qemu_fdt_setprop_cell(s->fdt, name, "phandle", s->phandle.dwc);
131
+ qemu_fdt_setprop_string(s->fdt, name, "maximum-speed", "high-speed");
132
+ g_free(name);
133
+}
134
+
135
static void fdt_add_uart_nodes(VersalVirt *s)
43
{
136
{
44
- uint32_t flags;
137
uint64_t addrs[] = { MM_UART1, MM_UART0 };
45
+ uint32_t usr1;
138
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
46
+ uint32_t usr2;
139
fdt_add_gic_nodes(s);
47
+ uint32_t mask;
140
fdt_add_timer_nodes(s);
48
141
fdt_add_zdma_nodes(s);
49
- flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
142
+ fdt_add_usb_xhci_nodes(s);
50
- if (s->ucr1 & UCR1_TXMPTYEN) {
143
fdt_add_sd_nodes(s);
51
- flags |= (s->uts1 & UTS1_TXEMPTY);
144
fdt_add_rtc_node(s);
52
- } else {
145
fdt_add_cpu_nodes(s, psci_conduit);
53
- flags &= ~USR1_TRDY;
146
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
54
- }
147
index XXXXXXX..XXXXXXX 100644
55
+ /*
148
--- a/hw/arm/xlnx-versal.c
56
+ * Lucky for us TRDY and RRDY has the same offset in both USR1 and
149
+++ b/hw/arm/xlnx-versal.c
57
+ * UCR1, so we can get away with something as simple as the
150
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
58
+ * following:
151
}
59
+ */
60
+ usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
61
+ /*
62
+ * Bits that we want in USR2 are not as conveniently laid out,
63
+ * unfortunately.
64
+ */
65
+ mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
66
+ usr2 = s->usr2 & mask;
67
68
- qemu_set_irq(s->irq, !!flags);
69
+ qemu_set_irq(s->irq, usr1 || usr2);
70
}
152
}
71
153
72
static void imx_serial_reset(IMXSerialState *s)
154
+static void versal_create_usbs(Versal *s, qemu_irq *pic)
155
+{
156
+ DeviceState *dev;
157
+ MemoryRegion *mr;
158
+
159
+ object_initialize_child(OBJECT(s), "usb2", &s->lpd.iou.usb,
160
+ TYPE_XILINX_VERSAL_USB2);
161
+ dev = DEVICE(&s->lpd.iou.usb);
162
+
163
+ object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps),
164
+ &error_abort);
165
+ qdev_prop_set_uint32(dev, "intrs", 1);
166
+ qdev_prop_set_uint32(dev, "slots", 2);
167
+
168
+ sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
169
+
170
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
171
+ memory_region_add_subregion(&s->mr_ps, MM_USB_0, mr);
172
+
173
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_USB0_IRQ_0]);
174
+
175
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
176
+ memory_region_add_subregion(&s->mr_ps, MM_USB2_CTRL_REGS, mr);
177
+}
178
+
179
static void versal_create_gems(Versal *s, qemu_irq *pic)
180
{
181
int i;
182
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
183
versal_create_apu_cpus(s);
184
versal_create_apu_gic(s, pic);
185
versal_create_uarts(s, pic);
186
+ versal_create_usbs(s, pic);
187
versal_create_gems(s, pic);
188
versal_create_admas(s, pic);
189
versal_create_sds(s, pic);
73
--
190
--
74
2.16.2
191
2.20.1
75
192
76
193
diff view generated by jsdifflib
1
If we're directly booting a Linux kernel and the CPU supports both
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
EL3 and EL2, we start the kernel in EL2, as it expects. We must also
3
set the SCR_EL3.HCE bit in this situation, so that the HVC
4
instruction is enabled rather than UNDEFing. Otherwise at least some
5
kernels will panic when trying to initialize KVM in the guest.
6
2
3
Malicious user can set the feedback divisor for the PLLs
4
to zero, triggering a floating-point exception (SIGFPE).
5
6
As the datasheet [*] is not clear how hardware behaves
7
when these bits are zeroes, use the maximum divisor
8
possible (128) to avoid the software FPE.
9
10
[*] Zynq-7000 TRM, UG585 (v1.12.2)
11
B.28 System Level Control Registers (slcr)
12
-> "Register (slcr) ARM_PLL_CTRL"
13
25.10.4 PLLs
14
-> "Software-Controlled PLL Update"
15
16
Fixes: 38867cb7ec9 ("hw/misc/zynq_slcr: add clock generation for uarts")
17
Reported-by: Gaoning Pan <pgn@zju.edu.cn>
18
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
21
Reviewed-by: Damien Hedde <damien.hedde@greensocs.com>
22
Message-id: 20201210141610.884600-1-f4bug@amsat.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20180313153458.26822-4-peter.maydell@linaro.org
9
---
24
---
10
hw/arm/boot.c | 5 +++++
25
hw/misc/zynq_slcr.c | 5 +++++
11
1 file changed, 5 insertions(+)
26
1 file changed, 5 insertions(+)
12
27
13
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
28
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
14
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/boot.c
30
--- a/hw/misc/zynq_slcr.c
16
+++ b/hw/arm/boot.c
31
+++ b/hw/misc/zynq_slcr.c
17
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
32
@@ -XXX,XX +XXX,XX @@ static uint64_t zynq_slcr_compute_pll(uint64_t input, uint32_t ctrl_reg)
18
assert(!info->secure_board_setup);
33
return 0;
19
}
34
}
20
35
21
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
36
+ /* Consider zero feedback as maximum divide ratio possible */
22
+ /* If we have EL2 then Linux expects the HVC insn to work */
37
+ if (!mult) {
23
+ env->cp15.scr_el3 |= SCR_HCE;
38
+ mult = 1 << R_xxx_PLL_CTRL_PLL_FPDIV_LENGTH;
24
+ }
39
+ }
25
+
40
+
26
/* Set to non-secure if not a secure boot */
41
/* frequency multiplier -> period division */
27
if (!info->secure_boot &&
42
return input / mult;
28
(cs != first_cpu || !info->secure_board_setup)) {
43
}
29
--
44
--
30
2.16.2
45
2.20.1
31
46
32
47
diff view generated by jsdifflib
1
From: Wei Huang <wei@redhat.com>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
For guest kernel that supports KASLR, the load address can change every
3
The previous naming of the configuration registers made it sound like that if
4
time when guest VM runs. To find the physical base address correctly,
4
the bits were set the settings would be enabled, while the opposite is true.
5
current QEMU dump searches VMCOREINFO for the string "NUMBER(phys_base)=".
6
However this string pattern is only available on x86_64. AArch64 uses a
7
different field, called "NUMBER(PHYS_OFFSET)=". This patch makes sure
8
QEMU dump uses the correct string on AArch64.
9
5
10
Signed-off-by: Wei Huang <wei@redhat.com>
6
Signed-off-by: Joe Komlodi <komlodi@xilinx.com>
11
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
12
Message-id: 1520615003-20869-1-git-send-email-wei@redhat.com
8
Message-id: 1605568264-26376-2-git-send-email-komlodi@xilinx.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
dump.c | 14 +++++++++++---
11
hw/block/m25p80.c | 12 ++++++------
16
1 file changed, 11 insertions(+), 3 deletions(-)
12
1 file changed, 6 insertions(+), 6 deletions(-)
17
13
18
diff --git a/dump.c b/dump.c
14
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/dump.c
16
--- a/hw/block/m25p80.c
21
+++ b/dump.c
17
+++ b/hw/block/m25p80.c
22
@@ -XXX,XX +XXX,XX @@ static void vmcoreinfo_update_phys_base(DumpState *s)
18
@@ -XXX,XX +XXX,XX @@ typedef struct FlashPartInfo {
23
19
#define VCFG_WRAP_SEQUENTIAL 0x2
24
lines = g_strsplit((char *)vmci, "\n", -1);
20
#define NVCFG_XIP_MODE_DISABLED (7 << 9)
25
for (i = 0; lines[i]; i++) {
21
#define NVCFG_XIP_MODE_MASK (7 << 9)
26
- if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
22
-#define VCFG_XIP_MODE_ENABLED (1 << 3)
27
- if (qemu_strtou64(lines[i] + 18, NULL, 16,
23
+#define VCFG_XIP_MODE_DISABLED (1 << 3)
28
+ const char *prefix = NULL;
24
#define CFG_DUMMY_CLK_LEN 4
29
+
25
#define NVCFG_DUMMY_CLK_POS 12
30
+ if (s->dump_info.d_machine == EM_X86_64) {
26
#define VCFG_DUMMY_CLK_POS 4
31
+ prefix = "NUMBER(phys_base)=";
27
@@ -XXX,XX +XXX,XX @@ typedef struct FlashPartInfo {
32
+ } else if (s->dump_info.d_machine == EM_AARCH64) {
28
#define EVCFG_VPP_ACCELERATOR (1 << 3)
33
+ prefix = "NUMBER(PHYS_OFFSET)=";
29
#define EVCFG_RESET_HOLD_ENABLED (1 << 4)
34
+ }
30
#define NVCFG_DUAL_IO_MASK (1 << 2)
35
+
31
-#define EVCFG_DUAL_IO_ENABLED (1 << 6)
36
+ if (prefix && g_str_has_prefix(lines[i], prefix)) {
32
+#define EVCFG_DUAL_IO_DISABLED (1 << 6)
37
+ if (qemu_strtou64(lines[i] + strlen(prefix), NULL, 16,
33
#define NVCFG_QUAD_IO_MASK (1 << 3)
38
&phys_base) < 0) {
34
-#define EVCFG_QUAD_IO_ENABLED (1 << 7)
39
- warn_report("Failed to read NUMBER(phys_base)=");
35
+#define EVCFG_QUAD_IO_DISABLED (1 << 7)
40
+ warn_report("Failed to read %s", prefix);
36
#define NVCFG_4BYTE_ADDR_MASK (1 << 0)
41
} else {
37
#define NVCFG_LOWER_SEGMENT_MASK (1 << 1)
42
s->dump_info.phys_base = phys_base;
38
43
}
39
@@ -XXX,XX +XXX,XX @@ static void reset_memory(Flash *s)
40
s->volatile_cfg |= VCFG_WRAP_SEQUENTIAL;
41
if ((s->nonvolatile_cfg & NVCFG_XIP_MODE_MASK)
42
!= NVCFG_XIP_MODE_DISABLED) {
43
- s->volatile_cfg |= VCFG_XIP_MODE_ENABLED;
44
+ s->volatile_cfg |= VCFG_XIP_MODE_DISABLED;
45
}
46
s->volatile_cfg |= deposit32(s->volatile_cfg,
47
VCFG_DUMMY_CLK_POS,
48
@@ -XXX,XX +XXX,XX @@ static void reset_memory(Flash *s)
49
s->enh_volatile_cfg |= EVCFG_VPP_ACCELERATOR;
50
s->enh_volatile_cfg |= EVCFG_RESET_HOLD_ENABLED;
51
if (s->nonvolatile_cfg & NVCFG_DUAL_IO_MASK) {
52
- s->enh_volatile_cfg |= EVCFG_DUAL_IO_ENABLED;
53
+ s->enh_volatile_cfg |= EVCFG_DUAL_IO_DISABLED;
54
}
55
if (s->nonvolatile_cfg & NVCFG_QUAD_IO_MASK) {
56
- s->enh_volatile_cfg |= EVCFG_QUAD_IO_ENABLED;
57
+ s->enh_volatile_cfg |= EVCFG_QUAD_IO_DISABLED;
58
}
59
if (!(s->nonvolatile_cfg & NVCFG_4BYTE_ADDR_MASK)) {
60
s->four_bytes_address_mode = true;
44
--
61
--
45
2.16.2
62
2.20.1
46
63
47
64
diff view generated by jsdifflib
1
The TypeInfo and state struct for bcm2386 disagree about what the
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
parent class is -- the TypeInfo says it's TYPE_SYS_BUS_DEVICE,
3
but the BCM2386State struct only defines the parent_obj field
4
as DeviceState. This would have caused problems if anything
5
actually tried to treat the object as a TYPE_SYS_BUS_DEVICE.
6
Fix the TypeInfo to use TYPE_DEVICE as the parent, since we don't
7
need any of the additional functionality TYPE_SYS_BUS_DEVICE
8
provides.
9
2
3
VCFG XIP is set (disabled) when the NVCFG XIP bits are all set (disabled).
4
5
Signed-off-by: Joe Komlodi <komlodi@xilinx.com>
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
7
Message-id: 1605568264-26376-3-git-send-email-komlodi@xilinx.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180313153458.26822-5-peter.maydell@linaro.org
14
---
9
---
15
hw/arm/bcm2836.c | 2 +-
10
hw/block/m25p80.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
17
12
18
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
13
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/bcm2836.c
15
--- a/hw/block/m25p80.c
21
+++ b/hw/arm/bcm2836.c
16
+++ b/hw/block/m25p80.c
22
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
17
@@ -XXX,XX +XXX,XX @@ static void reset_memory(Flash *s)
23
18
s->volatile_cfg |= VCFG_DUMMY;
24
static const TypeInfo bcm2836_type_info = {
19
s->volatile_cfg |= VCFG_WRAP_SEQUENTIAL;
25
.name = TYPE_BCM2836,
20
if ((s->nonvolatile_cfg & NVCFG_XIP_MODE_MASK)
26
- .parent = TYPE_SYS_BUS_DEVICE,
21
- != NVCFG_XIP_MODE_DISABLED) {
27
+ .parent = TYPE_DEVICE,
22
+ == NVCFG_XIP_MODE_DISABLED) {
28
.instance_size = sizeof(BCM2836State),
23
s->volatile_cfg |= VCFG_XIP_MODE_DISABLED;
29
.instance_init = bcm2836_init,
24
}
30
.class_init = bcm2836_class_init,
25
s->volatile_cfg |= deposit32(s->volatile_cfg,
31
--
26
--
32
2.16.2
27
2.20.1
33
28
34
29
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
Add support for "TX complete"/TXDC interrupt generate by real HW since
3
Some Numonyx flash commands cannot be executed in DIO and QIO mode, such as
4
it is needed to support guests other than Linux.
4
trying to do DPP or DOR when in QIO mode.
5
5
6
Based on the patch by Bill Paul as found here:
6
Signed-off-by: Joe Komlodi <komlodi@xilinx.com>
7
https://bugs.launchpad.net/qemu/+bug/1753314
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
8
8
Message-id: 1605568264-26376-4-git-send-email-komlodi@xilinx.com
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: Bill Paul <wpaul@windriver.com>
12
Cc: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Bill Paul <wpaul@windriver.com>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Message-id: 20180315191141.6789-2-andrew.smirnov@gmail.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
include/hw/char/imx_serial.h | 3 +++
11
hw/block/m25p80.c | 114 ++++++++++++++++++++++++++++++++++++++--------
20
hw/char/imx_serial.c | 20 +++++++++++++++++---
12
1 file changed, 95 insertions(+), 19 deletions(-)
21
2 files changed, 20 insertions(+), 3 deletions(-)
22
13
23
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
14
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/char/imx_serial.h
16
--- a/hw/block/m25p80.c
26
+++ b/include/hw/char/imx_serial.h
17
+++ b/hw/block/m25p80.c
27
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ typedef enum {
28
#define UCR2_RXEN (1<<1) /* Receiver enable */
19
MAN_GENERIC,
29
#define UCR2_SRST (1<<0) /* Reset complete */
20
} Manufacturer;
30
21
31
+#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
22
+typedef enum {
23
+ MODE_STD = 0,
24
+ MODE_DIO = 1,
25
+ MODE_QIO = 2
26
+} SPIMode;
32
+
27
+
33
#define UTS1_TXEMPTY (1<<6)
28
#define M25P80_INTERNAL_DATA_BUFFER_SZ 16
34
#define UTS1_RXEMPTY (1<<5)
29
35
#define UTS1_TXFULL (1<<4)
30
struct Flash {
36
@@ -XXX,XX +XXX,XX @@ typedef struct IMXSerialState {
31
@@ -XXX,XX +XXX,XX @@ static void reset_memory(Flash *s)
37
uint32_t ubmr;
32
trace_m25p80_reset_done(s);
38
uint32_t ubrc;
33
}
39
uint32_t ucr3;
34
40
+ uint32_t ucr4;
35
+static uint8_t numonyx_mode(Flash *s)
41
36
+{
42
qemu_irq irq;
37
+ if (!(s->enh_volatile_cfg & EVCFG_QUAD_IO_DISABLED)) {
43
CharBackend chr;
38
+ return MODE_QIO;
44
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
39
+ } else if (!(s->enh_volatile_cfg & EVCFG_DUAL_IO_DISABLED)) {
45
index XXXXXXX..XXXXXXX 100644
40
+ return MODE_DIO;
46
--- a/hw/char/imx_serial.c
41
+ } else {
47
+++ b/hw/char/imx_serial.c
42
+ return MODE_STD;
48
@@ -XXX,XX +XXX,XX @@
43
+ }
49
44
+}
50
static const VMStateDescription vmstate_imx_serial = {
51
.name = TYPE_IMX_SERIAL,
52
- .version_id = 1,
53
- .minimum_version_id = 1,
54
+ .version_id = 2,
55
+ .minimum_version_id = 2,
56
.fields = (VMStateField[]) {
57
VMSTATE_INT32(readbuff, IMXSerialState),
58
VMSTATE_UINT32(usr1, IMXSerialState),
59
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
60
VMSTATE_UINT32(ubmr, IMXSerialState),
61
VMSTATE_UINT32(ubrc, IMXSerialState),
62
VMSTATE_UINT32(ucr3, IMXSerialState),
63
+ VMSTATE_UINT32(ucr4, IMXSerialState),
64
VMSTATE_END_OF_LIST()
65
},
66
};
67
@@ -XXX,XX +XXX,XX @@ static void imx_update(IMXSerialState *s)
68
* unfortunately.
69
*/
70
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
71
+ /*
72
+ * TCEN and TXDC are both bit 3
73
+ */
74
+ mask |= s->ucr4 & UCR4_TCEN;
75
+
45
+
76
usr2 = s->usr2 & mask;
46
static void decode_fast_read_cmd(Flash *s)
77
47
{
78
qemu_set_irq(s->irq, usr1 || usr2);
48
s->needed_bytes = get_addr_length(s);
79
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
49
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
80
return s->ucr3;
50
case ERASE4_32K:
81
51
case ERASE_SECTOR:
82
case 0x23: /* UCR4 */
52
case ERASE4_SECTOR:
83
+ return s->ucr4;
53
- case READ:
84
+
54
- case READ4:
85
case 0x29: /* BRM Incremental */
55
- case DPP:
86
return 0x0; /* TODO */
56
- case QPP:
87
57
- case QPP_4:
88
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
58
case PP:
89
* qemu_chr_fe_write and background I/O callbacks */
59
case PP4:
90
qemu_chr_fe_write_all(&s->chr, &ch, 1);
60
- case PP4_4:
91
s->usr1 &= ~USR1_TRDY;
61
case DIE_ERASE:
92
+ s->usr2 &= ~USR2_TXDC;
62
case RDID_90:
93
imx_update(s);
63
case RDID_AB:
94
s->usr1 |= USR1_TRDY;
64
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
95
+ s->usr2 |= USR2_TXDC;
65
s->len = 0;
96
imx_update(s);
66
s->state = STATE_COLLECTING_DATA;
97
}
98
break;
67
break;
99
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
68
+ case READ:
100
s->ucr3 = value & 0xffff;
69
+ case READ4:
70
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) == MODE_STD) {
71
+ s->needed_bytes = get_addr_length(s);
72
+ s->pos = 0;
73
+ s->len = 0;
74
+ s->state = STATE_COLLECTING_DATA;
75
+ } else {
76
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
77
+ "DIO or QIO mode\n", s->cmd_in_progress);
78
+ }
79
+ break;
80
+ case DPP:
81
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_QIO) {
82
+ s->needed_bytes = get_addr_length(s);
83
+ s->pos = 0;
84
+ s->len = 0;
85
+ s->state = STATE_COLLECTING_DATA;
86
+ } else {
87
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
88
+ "QIO mode\n", s->cmd_in_progress);
89
+ }
90
+ break;
91
+ case QPP:
92
+ case QPP_4:
93
+ case PP4_4:
94
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_DIO) {
95
+ s->needed_bytes = get_addr_length(s);
96
+ s->pos = 0;
97
+ s->len = 0;
98
+ s->state = STATE_COLLECTING_DATA;
99
+ } else {
100
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
101
+ "DIO mode\n", s->cmd_in_progress);
102
+ }
103
+ break;
104
105
case FAST_READ:
106
case FAST_READ4:
107
+ decode_fast_read_cmd(s);
108
+ break;
109
case DOR:
110
case DOR4:
111
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_QIO) {
112
+ decode_fast_read_cmd(s);
113
+ } else {
114
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
115
+ "QIO mode\n", s->cmd_in_progress);
116
+ }
117
+ break;
118
case QOR:
119
case QOR4:
120
- decode_fast_read_cmd(s);
121
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_DIO) {
122
+ decode_fast_read_cmd(s);
123
+ } else {
124
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
125
+ "DIO mode\n", s->cmd_in_progress);
126
+ }
101
break;
127
break;
102
128
103
- case 0x2d: /* UTS1 */
129
case DIOR:
104
case 0x23: /* UCR4 */
130
case DIOR4:
105
+ s->ucr4 = value & 0xffff;
131
- decode_dio_read_cmd(s);
106
+ imx_update(s);
132
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_QIO) {
107
+ break;
133
+ decode_dio_read_cmd(s);
108
+
134
+ } else {
109
+ case 0x2d: /* UTS1 */
135
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
110
qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
136
+ "QIO mode\n", s->cmd_in_progress);
111
HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
137
+ }
112
/* TODO */
138
break;
139
140
case QIOR:
141
case QIOR4:
142
- decode_qio_read_cmd(s);
143
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_DIO) {
144
+ decode_qio_read_cmd(s);
145
+ } else {
146
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
147
+ "DIO mode\n", s->cmd_in_progress);
148
+ }
149
break;
150
151
case WRSR:
152
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
153
break;
154
155
case JEDEC_READ:
156
- trace_m25p80_populated_jedec(s);
157
- for (i = 0; i < s->pi->id_len; i++) {
158
- s->data[i] = s->pi->id[i];
159
- }
160
- for (; i < SPI_NOR_MAX_ID_LEN; i++) {
161
- s->data[i] = 0;
162
- }
163
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) == MODE_STD) {
164
+ trace_m25p80_populated_jedec(s);
165
+ for (i = 0; i < s->pi->id_len; i++) {
166
+ s->data[i] = s->pi->id[i];
167
+ }
168
+ for (; i < SPI_NOR_MAX_ID_LEN; i++) {
169
+ s->data[i] = 0;
170
+ }
171
172
- s->len = SPI_NOR_MAX_ID_LEN;
173
- s->pos = 0;
174
- s->state = STATE_READING_DATA;
175
+ s->len = SPI_NOR_MAX_ID_LEN;
176
+ s->pos = 0;
177
+ s->state = STATE_READING_DATA;
178
+ } else {
179
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute JEDEC read "
180
+ "in DIO or QIO mode\n");
181
+ }
182
break;
183
184
case RDCR:
113
--
185
--
114
2.16.2
186
2.20.1
115
187
116
188
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
The sabrelite machine model used by qemu-system-arm is based on the
3
Numonyx chips determine the number of cycles to wait based on bits 7:4
4
Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
4
in the volatile configuration register.
5
controller which is supported in QEMU using the imx_fec.c module
6
(actually called imx.enet for this model.)
7
5
8
The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for the
6
However, if these bits are 0x0 or 0xF, the number of dummy cycles to
9
imx.enet device like this:
7
wait is 10 for QIOR and QIOR4 commands or when in QIO mode, and otherwise 8 for
8
the currently supported fast read commands. [1]
10
9
11
#define FSL_IMX6_ENET_MAC_1588_IRQ 118
10
[1]
12
#define FSL_IMX6_ENET_MAC_IRQ 119
11
https://www.micron.com/-/media/client/global/documents/products/data-sheet/nor-flash/serial-nor/mt25q/die-rev-b/mt25q_qlkt_u_02g_cbb_0.pdf?rev=9b167fbf2b3645efba6385949a72e453
13
12
14
According to https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf,
13
Signed-off-by: Joe Komlodi <komlodi@xilinx.com>
15
page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary,
14
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
16
interrupts are as follows.
15
Message-id: 1605568264-26376-5-git-send-email-komlodi@xilinx.com
17
18
150 ENET MAC 0 IRQ
19
151 ENET MAC 0 1588 Timer interrupt
20
21
where
22
23
150 - 32 == 118
24
151 - 32 == 119
25
26
In other words, the vector definitions in the fsl-imx6.h file are reversed.
27
28
Fixing the interrupts alone causes problems with older Linux kernels:
29
The Ethernet interface will fail to probe with Linux v4.9 and earlier.
30
Linux v4.1 and earlier will crash due to a bug in Ethernet driver probe
31
error handling. This is a Linux kernel problem, not a qemu problem:
32
the Linux kernel only worked by accident since it requested both interrupts.
33
34
For backward compatibility, generate the Ethernet interrupt on both interrupt
35
lines. This was shown to work from all Linux kernel releases starting with
36
v3.16.
37
38
Link: https://bugs.launchpad.net/qemu/+bug/1753309
39
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
40
Message-id: 1520723090-22130-1-git-send-email-linux@roeck-us.net
41
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
---
17
---
44
include/hw/arm/fsl-imx6.h | 4 ++--
18
hw/block/m25p80.c | 30 +++++++++++++++++++++++++++---
45
hw/net/imx_fec.c | 28 +++++++++++++++++++++++++++-
19
1 file changed, 27 insertions(+), 3 deletions(-)
46
2 files changed, 29 insertions(+), 3 deletions(-)
47
20
48
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
21
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
49
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/arm/fsl-imx6.h
23
--- a/hw/block/m25p80.c
51
+++ b/include/hw/arm/fsl-imx6.h
24
+++ b/hw/block/m25p80.c
52
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
25
@@ -XXX,XX +XXX,XX @@ static uint8_t numonyx_mode(Flash *s)
53
#define FSL_IMX6_HDMI_MASTER_IRQ 115
26
}
54
#define FSL_IMX6_HDMI_CEC_IRQ 116
27
}
55
#define FSL_IMX6_MLB150_LOW_IRQ 117
28
56
-#define FSL_IMX6_ENET_MAC_1588_IRQ 118
29
+static uint8_t numonyx_extract_cfg_num_dummies(Flash *s)
57
-#define FSL_IMX6_ENET_MAC_IRQ 119
30
+{
58
+#define FSL_IMX6_ENET_MAC_IRQ 118
31
+ uint8_t num_dummies;
59
+#define FSL_IMX6_ENET_MAC_1588_IRQ 119
32
+ uint8_t mode;
60
#define FSL_IMX6_PCIE1_IRQ 120
33
+ assert(get_man(s) == MAN_NUMONYX);
61
#define FSL_IMX6_PCIE2_IRQ 121
34
+
62
#define FSL_IMX6_PCIE3_IRQ 122
35
+ mode = numonyx_mode(s);
63
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
36
+ num_dummies = extract32(s->volatile_cfg, 4, 4);
64
index XXXXXXX..XXXXXXX 100644
37
+
65
--- a/hw/net/imx_fec.c
38
+ if (num_dummies == 0x0 || num_dummies == 0xf) {
66
+++ b/hw/net/imx_fec.c
39
+ switch (s->cmd_in_progress) {
67
@@ -XXX,XX +XXX,XX @@ static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
40
+ case QIOR:
68
41
+ case QIOR4:
69
static void imx_eth_update(IMXFECState *s)
42
+ num_dummies = 10;
43
+ break;
44
+ default:
45
+ num_dummies = (mode == MODE_QIO) ? 10 : 8;
46
+ break;
47
+ }
48
+ }
49
+
50
+ return num_dummies;
51
+}
52
+
53
static void decode_fast_read_cmd(Flash *s)
70
{
54
{
71
- if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
55
s->needed_bytes = get_addr_length(s);
72
+ /*
56
@@ -XXX,XX +XXX,XX @@ static void decode_fast_read_cmd(Flash *s)
73
+ * Previous versions of qemu had the ENET_INT_MAC and ENET_INT_TS_TIMER
57
s->needed_bytes += 8;
74
+ * interrupts swapped. This worked with older versions of Linux (4.14
58
break;
75
+ * and older) since Linux associated both interrupt lines with Ethernet
59
case MAN_NUMONYX:
76
+ * MAC interrupts. Specifically,
60
- s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
77
+ * - Linux 4.15 and later have separate interrupt handlers for the MAC and
61
+ s->needed_bytes += numonyx_extract_cfg_num_dummies(s);
78
+ * timer interrupts. Those versions of Linux fail with versions of QEMU
62
break;
79
+ * with swapped interrupt assignments.
63
case MAN_MACRONIX:
80
+ * - In linux 4.14, both interrupt lines were registered with the Ethernet
64
if (extract32(s->volatile_cfg, 6, 2) == 1) {
81
+ * MAC interrupt handler. As a result, all versions of qemu happen to
65
@@ -XXX,XX +XXX,XX @@ static void decode_dio_read_cmd(Flash *s)
82
+ * work, though that is accidental.
66
);
83
+ * - In Linux 4.9 and older, the timer interrupt was registered directly
67
break;
84
+ * with the Ethernet MAC interrupt handler. The MAC interrupt was
68
case MAN_NUMONYX:
85
+ * redirected to a GPIO interrupt to work around erratum ERR006687.
69
- s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
86
+ * This was implemented using the SOC's IOMUX block. In qemu, this GPIO
70
+ s->needed_bytes += numonyx_extract_cfg_num_dummies(s);
87
+ * interrupt never fired since IOMUX is currently not supported in qemu.
71
break;
88
+ * Linux instead received MAC interrupts on the timer interrupt.
72
case MAN_MACRONIX:
89
+ * As a result, qemu versions with the swapped interrupt assignment work,
73
switch (extract32(s->volatile_cfg, 6, 2)) {
90
+ * albeit accidentally, but qemu versions with the correct interrupt
74
@@ -XXX,XX +XXX,XX @@ static void decode_qio_read_cmd(Flash *s)
91
+ * assignment fail.
75
);
92
+ *
76
break;
93
+ * To ensure that all versions of Linux work, generate ENET_INT_MAC
77
case MAN_NUMONYX:
94
+ * interrrupts on both interrupt lines. This should be changed if and when
78
- s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
95
+ * qemu supports IOMUX.
79
+ s->needed_bytes += numonyx_extract_cfg_num_dummies(s);
96
+ */
80
break;
97
+ if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] &
81
case MAN_MACRONIX:
98
+ (ENET_INT_MAC | ENET_INT_TS_TIMER)) {
82
switch (extract32(s->volatile_cfg, 6, 2)) {
99
qemu_set_irq(s->irq[1], 1);
100
} else {
101
qemu_set_irq(s->irq[1], 0);
102
--
83
--
103
2.16.2
84
2.20.1
104
85
105
86
diff view generated by jsdifflib