1
The following changes since commit 621745c4f349ac09b72706c46febee983abca916:
1
The following changes since commit 527dede083d3e3e5a13ee996776926e0a0c4e258:
2
2
3
Merge tag 'trivial-branch-for-7.1-pull-request' of https://gitlab.com/laurent_vivier/qemu into staging (2022-06-30 04:49:40 +0530)
3
Merge tag 'pull-request-2025-03-19' of https://gitlab.com/thuth/qemu into staging (2025-03-20 08:41:25 -0400)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/legoater/qemu/ tags/pull-aspeed-20220630
7
https://github.com/legoater/qemu/ tags/pull-aspeed-20250323
8
8
9
for you to fetch changes up to 55c57023b740c29151d42600af9ac43ba00e56cc:
9
for you to fetch changes up to 78877b2e06464f49f777e086845e094ea7bc82ef:
10
10
11
hw/misc/aspeed: Add PECI controller (2022-06-30 09:21:14 +0200)
11
hw/misc/aspeed_hace: Fix buffer overflow in has_padding function (2025-03-23 18:42:16 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
aspeed queue:
14
aspeed queue:
15
15
16
* m25p80 improvements (Iris)
16
* Fix AST2700 SoC model
17
* Code cleanup in preparation of multi SoC machine (Peter)
18
* New MAX31785 model (Mahesh)
19
* New Qualcomm machines (Jae and Graeme)
20
* Core I2C slave mode (Klaus)
21
* Aspeed I2C slave mode for old and new register interface (Peter and Klaus)
22
* New Aspeed PECI model (Peter)
23
* Various small fixes
24
17
25
----------------------------------------------------------------
18
----------------------------------------------------------------
26
Cédric Le Goater (4):
19
Jamin Lin (1):
27
aspeed: Set the dram container at the SoC level
20
hw/misc/aspeed_hace: Fix buffer overflow in has_padding function
28
aspeed/scu: Add trace events for read ops
29
aspeed/i2c: Change trace event for NORMAL_STOP states
30
aspeed/smc: Fix potential overflow
31
21
32
Graeme Gregory (1):
22
Steven Lee (1):
33
hw/arm/aspeed: add Qualcomm Firework BMC machine
23
hw/intc/aspeed: Fix IRQ handler mask check
34
24
35
Iris Chen (2):
25
Troy Lee (1):
36
hw: m25p80: add WP# pin and SRWD bit for write protection
26
aspeed: Fix maximum number of spi controller
37
hw: m25p80: add tests for write protect (WP# and SRWD bit)
38
27
39
Jae Hyun Yoo (2):
28
include/hw/arm/aspeed_soc.h | 2 +-
40
hw/arm/aspeed: add support for the Qualcomm DC-SCM v1 board
29
hw/intc/aspeed_intc.c | 2 +-
41
hw/arm/aspeed: firework: add I2C MUXes for VR channels
30
hw/misc/aspeed_hace.c | 5 +++++
42
31
3 files changed, 7 insertions(+), 2 deletions(-)
43
Joel Stanley (1):
44
aspeed/hace: Accumulative mode supported
45
46
Klaus Jensen (3):
47
hw/i2c: support multiple masters
48
hw/i2c: add asynchronous send
49
hw/i2c/aspeed: add slave device in old register mode
50
51
Maheswara Kurapati (4):
52
hw/i2c: pmbus: Page #255 is valid page for read requests.
53
hw/sensor: add Maxim MAX31785 device
54
hw/arm/aspeed: Add MAX31785 Fan controllers
55
hw/arm/aspeed: firework: Add Thermal Diodes
56
57
Peter Delevoryas (10):
58
aspeed: Set CPU memory property explicitly
59
aspeed: Add memory property to Aspeed SoC
60
aspeed: Remove usage of sysbus_mmio_map
61
aspeed: Map unimplemented devices in SoC memory
62
aspeed: Remove use of qemu_get_cpu
63
hw/i2c/aspeed: Fix R_I2CD_FUN_CTRL reference
64
hw/i2c/aspeed: Fix DMA len write-enable bit handling
65
hw/i2c/aspeed: Fix MASTER_EN missing error message
66
hw/i2c/aspeed: Add new-registers DMA slave mode RX support
67
hw/misc/aspeed: Add PECI controller
68
69
include/hw/arm/aspeed_soc.h | 16 ++
70
include/hw/i2c/aspeed_i2c.h | 11 +
71
include/hw/i2c/i2c.h | 30 +++
72
include/hw/misc/aspeed_peci.h | 29 +++
73
hw/arm/aspeed.c | 136 +++++++---
74
hw/arm/aspeed_ast10x0.c | 59 +++--
75
hw/arm/aspeed_ast2600.c | 104 +++++---
76
hw/arm/aspeed_soc.c | 143 ++++++++---
77
hw/arm/pxa2xx.c | 2 +
78
hw/block/m25p80.c | 82 ++++--
79
hw/display/sii9022.c | 2 +
80
hw/display/ssd0303.c | 2 +
81
hw/i2c/aspeed_i2c.c | 236 ++++++++++++++---
82
hw/i2c/core.c | 70 +++++-
83
hw/i2c/pmbus_device.c | 6 +-
84
hw/i2c/smbus_slave.c | 4 +
85
hw/misc/aspeed_hace.c | 6 +-
86
hw/misc/aspeed_peci.c | 152 +++++++++++
87
hw/misc/aspeed_scu.c | 2 +
88
hw/nvram/eeprom_at24c.c | 2 +
89
hw/sensor/lsm303dlhc_mag.c | 2 +
90
hw/sensor/max31785.c | 573 ++++++++++++++++++++++++++++++++++++++++++
91
hw/ssi/aspeed_smc.c | 4 +-
92
tests/qtest/aspeed_smc-test.c | 62 +++++
93
hw/arm/Kconfig | 2 +
94
hw/i2c/trace-events | 2 +
95
hw/misc/meson.build | 3 +-
96
hw/misc/trace-events | 6 +
97
hw/sensor/Kconfig | 4 +
98
hw/sensor/meson.build | 1 +
99
30 files changed, 1573 insertions(+), 180 deletions(-)
100
create mode 100644 include/hw/misc/aspeed_peci.h
101
create mode 100644 hw/misc/aspeed_peci.c
102
create mode 100644 hw/sensor/max31785.c
103
diff view generated by jsdifflib
Deleted patch
1
From: Iris Chen <irischenlj@gmail.com>
2
1
3
Signed-off-by: Iris Chen <irischenlj@gmail.com>
4
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
Message-Id: <20220621202427.2680413-1-irischenlj@fb.com>
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
---
8
hw/block/m25p80.c | 82 ++++++++++++++++++++++++++++++++++++++---------
9
1 file changed, 67 insertions(+), 15 deletions(-)
10
11
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/block/m25p80.c
14
+++ b/hw/block/m25p80.c
15
@@ -XXX,XX +XXX,XX @@ struct Flash {
16
uint8_t spansion_cr2v;
17
uint8_t spansion_cr3v;
18
uint8_t spansion_cr4v;
19
+ bool wp_level;
20
bool write_enable;
21
bool four_bytes_address_mode;
22
bool reset_enable;
23
bool quad_enable;
24
bool aai_enable;
25
+ bool status_register_write_disabled;
26
uint8_t ear;
27
28
int64_t dirty_page;
29
@@ -XXX,XX +XXX,XX @@ static void complete_collecting_data(Flash *s)
30
flash_erase(s, s->cur_addr, s->cmd_in_progress);
31
break;
32
case WRSR:
33
+ s->status_register_write_disabled = extract32(s->data[0], 7, 1);
34
+
35
switch (get_man(s)) {
36
case MAN_SPANSION:
37
s->quad_enable = !!(s->data[1] & 0x02);
38
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
39
break;
40
41
case WRSR:
42
- if (s->write_enable) {
43
- switch (get_man(s)) {
44
- case MAN_SPANSION:
45
- s->needed_bytes = 2;
46
- s->state = STATE_COLLECTING_DATA;
47
- break;
48
- case MAN_MACRONIX:
49
- s->needed_bytes = 2;
50
- s->state = STATE_COLLECTING_VAR_LEN_DATA;
51
- break;
52
- default:
53
- s->needed_bytes = 1;
54
- s->state = STATE_COLLECTING_DATA;
55
- }
56
- s->pos = 0;
57
+ /*
58
+ * If WP# is low and status_register_write_disabled is high,
59
+ * status register writes are disabled.
60
+ * This is also called "hardware protected mode" (HPM). All other
61
+ * combinations of the two states are called "software protected mode"
62
+ * (SPM), and status register writes are permitted.
63
+ */
64
+ if ((s->wp_level == 0 && s->status_register_write_disabled)
65
+ || !s->write_enable) {
66
+ qemu_log_mask(LOG_GUEST_ERROR,
67
+ "M25P80: Status register write is disabled!\n");
68
+ break;
69
+ }
70
+
71
+ switch (get_man(s)) {
72
+ case MAN_SPANSION:
73
+ s->needed_bytes = 2;
74
+ s->state = STATE_COLLECTING_DATA;
75
+ break;
76
+ case MAN_MACRONIX:
77
+ s->needed_bytes = 2;
78
+ s->state = STATE_COLLECTING_VAR_LEN_DATA;
79
+ break;
80
+ default:
81
+ s->needed_bytes = 1;
82
+ s->state = STATE_COLLECTING_DATA;
83
}
84
+ s->pos = 0;
85
break;
86
87
case WRDI:
88
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
89
90
case RDSR:
91
s->data[0] = (!!s->write_enable) << 1;
92
+ s->data[0] |= (!!s->status_register_write_disabled) << 7;
93
+
94
if (get_man(s) == MAN_MACRONIX || get_man(s) == MAN_ISSI) {
95
s->data[0] |= (!!s->quad_enable) << 6;
96
}
97
@@ -XXX,XX +XXX,XX @@ static uint32_t m25p80_transfer8(SSIPeripheral *ss, uint32_t tx)
98
return r;
99
}
100
101
+static void m25p80_write_protect_pin_irq_handler(void *opaque, int n, int level)
102
+{
103
+ Flash *s = M25P80(opaque);
104
+ /* WP# is just a single pin. */
105
+ assert(n == 0);
106
+ s->wp_level = !!level;
107
+}
108
+
109
static void m25p80_realize(SSIPeripheral *ss, Error **errp)
110
{
111
Flash *s = M25P80(ss);
112
@@ -XXX,XX +XXX,XX @@ static void m25p80_realize(SSIPeripheral *ss, Error **errp)
113
s->storage = blk_blockalign(NULL, s->size);
114
memset(s->storage, 0xFF, s->size);
115
}
116
+
117
+ qdev_init_gpio_in_named(DEVICE(s),
118
+ m25p80_write_protect_pin_irq_handler, "WP#", 1);
119
}
120
121
static void m25p80_reset(DeviceState *d)
122
{
123
Flash *s = M25P80(d);
124
125
+ s->wp_level = true;
126
+ s->status_register_write_disabled = false;
127
+
128
reset_memory(s);
129
}
130
131
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m25p80_aai_enable = {
132
}
133
};
134
135
+static bool m25p80_wp_level_srwd_needed(void *opaque)
136
+{
137
+ Flash *s = (Flash *)opaque;
138
+
139
+ return !s->wp_level || s->status_register_write_disabled;
140
+}
141
+
142
+static const VMStateDescription vmstate_m25p80_write_protect = {
143
+ .name = "m25p80/write_protect",
144
+ .version_id = 1,
145
+ .minimum_version_id = 1,
146
+ .needed = m25p80_wp_level_srwd_needed,
147
+ .fields = (VMStateField[]) {
148
+ VMSTATE_BOOL(wp_level, Flash),
149
+ VMSTATE_BOOL(status_register_write_disabled, Flash),
150
+ VMSTATE_END_OF_LIST()
151
+ }
152
+};
153
+
154
static const VMStateDescription vmstate_m25p80 = {
155
.name = "m25p80",
156
.version_id = 0,
157
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m25p80 = {
158
.subsections = (const VMStateDescription * []) {
159
&vmstate_m25p80_data_read_loop,
160
&vmstate_m25p80_aai_enable,
161
+ &vmstate_m25p80_write_protect,
162
NULL
163
}
164
};
165
--
166
2.35.3
167
168
diff view generated by jsdifflib
Deleted patch
1
From: Iris Chen <irischenlj@fb.com>
2
1
3
Signed-off-by: Iris Chen <irischenlj@fb.com>
4
Message-Id: <20220624183016.2125264-1-irischenlj@fb.com>
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
---
7
tests/qtest/aspeed_smc-test.c | 62 +++++++++++++++++++++++++++++++++++
8
1 file changed, 62 insertions(+)
9
10
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tests/qtest/aspeed_smc-test.c
13
+++ b/tests/qtest/aspeed_smc-test.c
14
@@ -XXX,XX +XXX,XX @@ enum {
15
BULK_ERASE = 0xc7,
16
READ = 0x03,
17
PP = 0x02,
18
+ WRSR = 0x1,
19
WREN = 0x6,
20
+ SRWD = 0x80,
21
RESET_ENABLE = 0x66,
22
RESET_MEMORY = 0x99,
23
EN_4BYTE_ADDR = 0xB7,
24
@@ -XXX,XX +XXX,XX @@ static void test_read_status_reg(void)
25
flash_reset();
26
}
27
28
+static void test_status_reg_write_protection(void)
29
+{
30
+ uint8_t r;
31
+
32
+ spi_conf(CONF_ENABLE_W0);
33
+
34
+ /* default case: WP# is high and SRWD is low -> status register writable */
35
+ spi_ctrl_start_user();
36
+ writeb(ASPEED_FLASH_BASE, WREN);
37
+ /* test ability to write SRWD */
38
+ writeb(ASPEED_FLASH_BASE, WRSR);
39
+ writeb(ASPEED_FLASH_BASE, SRWD);
40
+ writeb(ASPEED_FLASH_BASE, RDSR);
41
+ r = readb(ASPEED_FLASH_BASE);
42
+ spi_ctrl_stop_user();
43
+ g_assert_cmphex(r & SRWD, ==, SRWD);
44
+
45
+ /* WP# high and SRWD high -> status register writable */
46
+ spi_ctrl_start_user();
47
+ writeb(ASPEED_FLASH_BASE, WREN);
48
+ /* test ability to write SRWD */
49
+ writeb(ASPEED_FLASH_BASE, WRSR);
50
+ writeb(ASPEED_FLASH_BASE, 0);
51
+ writeb(ASPEED_FLASH_BASE, RDSR);
52
+ r = readb(ASPEED_FLASH_BASE);
53
+ spi_ctrl_stop_user();
54
+ g_assert_cmphex(r & SRWD, ==, 0);
55
+
56
+ /* WP# low and SRWD low -> status register writable */
57
+ qtest_set_irq_in(global_qtest,
58
+ "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 0);
59
+ spi_ctrl_start_user();
60
+ writeb(ASPEED_FLASH_BASE, WREN);
61
+ /* test ability to write SRWD */
62
+ writeb(ASPEED_FLASH_BASE, WRSR);
63
+ writeb(ASPEED_FLASH_BASE, SRWD);
64
+ writeb(ASPEED_FLASH_BASE, RDSR);
65
+ r = readb(ASPEED_FLASH_BASE);
66
+ spi_ctrl_stop_user();
67
+ g_assert_cmphex(r & SRWD, ==, SRWD);
68
+
69
+ /* WP# low and SRWD high -> status register NOT writable */
70
+ spi_ctrl_start_user();
71
+ writeb(ASPEED_FLASH_BASE, WREN);
72
+ /* test ability to write SRWD */
73
+ writeb(ASPEED_FLASH_BASE, WRSR);
74
+ writeb(ASPEED_FLASH_BASE, 0);
75
+ writeb(ASPEED_FLASH_BASE, RDSR);
76
+ r = readb(ASPEED_FLASH_BASE);
77
+ spi_ctrl_stop_user();
78
+ /* write is not successful */
79
+ g_assert_cmphex(r & SRWD, ==, SRWD);
80
+
81
+ qtest_set_irq_in(global_qtest,
82
+ "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 1);
83
+ flash_reset();
84
+}
85
+
86
static char tmp_path[] = "/tmp/qtest.m25p80.XXXXXX";
87
88
int main(int argc, char **argv)
89
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
90
qtest_add_func("/ast2400/smc/read_page_mem", test_read_page_mem);
91
qtest_add_func("/ast2400/smc/write_page_mem", test_write_page_mem);
92
qtest_add_func("/ast2400/smc/read_status_reg", test_read_status_reg);
93
+ qtest_add_func("/ast2400/smc/status_reg_write_protection",
94
+ test_status_reg_write_protection);
95
96
flash_reset();
97
ret = g_test_run();
98
--
99
2.35.3
100
101
diff view generated by jsdifflib
Deleted patch
1
Currently, the Aspeed machines allocate a ram container region in
2
which the machine ram region is mapped. See commit ad1a9782186d
3
("aspeed: add a RAM memory region container"). An extra region is
4
mapped after ram in the ram container to catch invalid access done by
5
FW. That's how FW determines the size of ram. See commit ebe31c0a8ef7
6
("aspeed: add a max_ram_size property to the memory controller").
7
1
8
Let's move all the logic under the SoC where it should be. It will
9
also ease the work on multi SoC support.
10
11
Reviewed-by: Peter Delevoryas <pdel@fb.com>
12
Message-Id: <20220623202123.3972977-1-clg@kaod.org>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
---
15
include/hw/arm/aspeed_soc.h | 2 ++
16
hw/arm/aspeed.c | 39 ++---------------------------
17
hw/arm/aspeed_ast2600.c | 7 ++++--
18
hw/arm/aspeed_soc.c | 49 +++++++++++++++++++++++++++++++++++--
19
4 files changed, 56 insertions(+), 41 deletions(-)
20
21
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/aspeed_soc.h
24
+++ b/include/hw/arm/aspeed_soc.h
25
@@ -XXX,XX +XXX,XX @@ struct AspeedSoCState {
26
A15MPPrivState a7mpcore;
27
ARMv7MState armv7m;
28
MemoryRegion *dram_mr;
29
+ MemoryRegion dram_container;
30
MemoryRegion sram;
31
AspeedVICState vic;
32
AspeedRtcState rtc;
33
@@ -XXX,XX +XXX,XX @@ enum {
34
35
qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev);
36
void aspeed_soc_uart_init(AspeedSoCState *s);
37
+bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp);
38
39
#endif /* ASPEED_SOC_H */
40
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/aspeed.c
43
+++ b/hw/arm/aspeed.c
44
@@ -XXX,XX +XXX,XX @@ struct AspeedMachineState {
45
#define BLETCHLEY_BMC_HW_STRAP1 AST2600_EVB_HW_STRAP1
46
#define BLETCHLEY_BMC_HW_STRAP2 AST2600_EVB_HW_STRAP2
47
48
-/*
49
- * The max ram region is for firmwares that scan the address space
50
- * with load/store to guess how much RAM the SoC has.
51
- */
52
-static uint64_t max_ram_read(void *opaque, hwaddr offset, unsigned size)
53
-{
54
- return 0;
55
-}
56
-
57
-static void max_ram_write(void *opaque, hwaddr offset, uint64_t value,
58
- unsigned size)
59
-{
60
- /* Discard writes */
61
-}
62
-
63
-static const MemoryRegionOps max_ram_ops = {
64
- .read = max_ram_read,
65
- .write = max_ram_write,
66
- .endianness = DEVICE_NATIVE_ENDIAN,
67
-};
68
-
69
#define AST_SMP_MAILBOX_BASE 0x1e6e2180
70
#define AST_SMP_MBOX_FIELD_ENTRY (AST_SMP_MAILBOX_BASE + 0x0)
71
#define AST_SMP_MBOX_FIELD_GOSIGN (AST_SMP_MAILBOX_BASE + 0x4)
72
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_init(MachineState *machine)
73
AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
74
AspeedSoCClass *sc;
75
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
76
- ram_addr_t max_ram_size;
77
int i;
78
NICInfo *nd = &nd_table[0];
79
80
- memory_region_init(&bmc->ram_container, NULL, "aspeed-ram-container",
81
- 4 * GiB);
82
- memory_region_add_subregion(&bmc->ram_container, 0, machine->ram);
83
-
84
object_initialize_child(OBJECT(machine), "soc", &bmc->soc, amc->soc_name);
85
86
sc = ASPEED_SOC_GET_CLASS(&bmc->soc);
87
88
/*
89
- * This will error out if isize is not supported by memory controller.
90
+ * This will error out if the RAM size is not supported by the
91
+ * memory controller of the SoC.
92
*/
93
object_property_set_uint(OBJECT(&bmc->soc), "ram-size", machine->ram_size,
94
&error_fatal);
95
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_init(MachineState *machine)
96
amc->uart_default);
97
qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
98
99
- memory_region_add_subregion(get_system_memory(),
100
- sc->memmap[ASPEED_DEV_SDRAM],
101
- &bmc->ram_container);
102
-
103
- max_ram_size = object_property_get_uint(OBJECT(&bmc->soc), "max-ram-size",
104
- &error_abort);
105
- memory_region_init_io(&bmc->max_ram, NULL, &max_ram_ops, NULL,
106
- "max_ram", max_ram_size - machine->ram_size);
107
- memory_region_add_subregion(&bmc->ram_container, machine->ram_size, &bmc->max_ram);
108
-
109
aspeed_board_init_flashes(&bmc->soc.fmc,
110
bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
111
amc->num_cs, 0);
112
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/hw/arm/aspeed_ast2600.c
115
+++ b/hw/arm/aspeed_ast2600.c
116
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
117
object_initialize_child(obj, "sdmc", &s->sdmc, typename);
118
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
119
"ram-size");
120
- object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc),
121
- "max-ram-size");
122
123
for (i = 0; i < sc->wdts_num; i++) {
124
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
125
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
126
sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
127
}
128
129
+ /* RAM */
130
+ if (!aspeed_soc_dram_init(s, errp)) {
131
+ return;
132
+ }
133
+
134
/* Net */
135
for (i = 0; i < sc->macs_num; i++) {
136
object_property_set_bool(OBJECT(&s->ftgmac100[i]), "aspeed", true,
137
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/hw/arm/aspeed_soc.c
140
+++ b/hw/arm/aspeed_soc.c
141
@@ -XXX,XX +XXX,XX @@
142
*/
143
144
#include "qemu/osdep.h"
145
+#include "qemu/units.h"
146
#include "qapi/error.h"
147
#include "hw/misc/unimp.h"
148
#include "hw/arm/aspeed_soc.h"
149
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
150
object_initialize_child(obj, "sdmc", &s->sdmc, typename);
151
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
152
"ram-size");
153
- object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc),
154
- "max-ram-size");
155
156
for (i = 0; i < sc->wdts_num; i++) {
157
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
158
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
159
sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
160
}
161
162
+ /* RAM */
163
+ if (!aspeed_soc_dram_init(s, errp)) {
164
+ return;
165
+ }
166
+
167
/* Net */
168
for (i = 0; i < sc->macs_num; i++) {
169
object_property_set_bool(OBJECT(&s->ftgmac100[i]), "aspeed", true,
170
@@ -XXX,XX +XXX,XX @@ void aspeed_soc_uart_init(AspeedSoCState *s)
171
serial_hd(i), DEVICE_LITTLE_ENDIAN);
172
}
173
}
174
+
175
+/*
176
+ * SDMC should be realized first to get correct RAM size and max size
177
+ * values
178
+ */
179
+bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp)
180
+{
181
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
182
+ ram_addr_t ram_size, max_ram_size;
183
+
184
+ ram_size = object_property_get_uint(OBJECT(&s->sdmc), "ram-size",
185
+ &error_abort);
186
+ max_ram_size = object_property_get_uint(OBJECT(&s->sdmc), "max-ram-size",
187
+ &error_abort);
188
+
189
+ memory_region_init(&s->dram_container, OBJECT(s), "ram-container",
190
+ max_ram_size);
191
+ memory_region_add_subregion(&s->dram_container, 0, s->dram_mr);
192
+
193
+ /*
194
+ * Add a memory region beyond the RAM region to let firmwares scan
195
+ * the address space with load/store and guess how much RAM the
196
+ * SoC has.
197
+ */
198
+ if (ram_size < max_ram_size) {
199
+ DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE);
200
+
201
+ qdev_prop_set_string(dev, "name", "ram-empty");
202
+ qdev_prop_set_uint64(dev, "size", max_ram_size - ram_size);
203
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp)) {
204
+ return false;
205
+ }
206
+
207
+ memory_region_add_subregion_overlap(&s->dram_container, ram_size,
208
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0), -1000);
209
+ }
210
+
211
+ memory_region_add_subregion(get_system_memory(),
212
+ sc->memmap[ASPEED_DEV_SDRAM], &s->dram_container);
213
+ return true;
214
+}
215
--
216
2.35.3
217
218
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Peter Delevoryas <pdel@fb.com>
2
Message-Id: <20220628154740.1117349-2-clg@kaod.org>
3
Signed-off-by: Cédric Le Goater <clg@kaod.org>
4
---
5
hw/misc/aspeed_scu.c | 2 ++
6
hw/misc/trace-events | 1 +
7
2 files changed, 3 insertions(+)
8
1
9
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/misc/aspeed_scu.c
12
+++ b/hw/misc/aspeed_scu.c
13
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
14
break;
15
}
16
17
+ trace_aspeed_scu_read(offset, size, s->regs[reg]);
18
return s->regs[reg];
19
}
20
21
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_ast2600_scu_read(void *opaque, hwaddr offset,
22
break;
23
}
24
25
+ trace_aspeed_scu_read(offset, size, s->regs[reg]);
26
return s->regs[reg];
27
}
28
29
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/misc/trace-events
32
+++ b/hw/misc/trace-events
33
@@ -XXX,XX +XXX,XX @@ slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED 0x%04x"
34
35
# aspeed_scu.c
36
aspeed_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
37
+aspeed_scu_read(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
38
39
# mps2-scc.c
40
mps2_scc_read(uint64_t offset, uint64_t data, unsigned size) "MPS2 SCC read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
41
--
42
2.35.3
43
44
diff view generated by jsdifflib
1
From: Peter Delevoryas <pdel@fb.com>
1
From: Troy Lee <troy_lee@aspeedtech.com>
2
2
3
This introduces a really basic PECI controller that responses to
3
Commit 6de4aa8dc544 ("hw/arm/aspeed_ast27x0: Add SoC Support for AST2700
4
commands by always setting the response code to success and then raising
4
A1") extends ast2700a1 spis_num to 3, but ASPEED_SPIS_NUM defines the
5
an interrupt to indicate the command is done. This helps avoid getting
5
maximum number of spi controller to 2, result in ehci[0] is being
6
hit with constant errors if the driver continuously attempts to send a
6
overwritten in runtime.
7
command and keeps timing out.
8
7
9
The AST2400 and AST2500 only included registers up to 0x5C, not 0xFC.
8
Signed-off-by: Troy Lee <troy_lee@aspeedtech.com>
10
They supported PECI 1.1, 2.0, and 3.0. The AST2600 and AST1030 support
9
Fixes: 6de4aa8dc544 ("hw/arm/aspeed_ast27x0: Add SoC Support for AST2700 A1")
11
PECI 4.0, which includes more read/write buffer registers from 0x80 to
10
Reviewed-by: Cédric Le Goater <clg@redhat.com>
12
0xFC to support 64-byte mode.
11
Link: https://lore.kernel.org/qemu-devel/20250317065938.1902272-1-troy_lee@aspeedtech.com
13
12
Signed-off-by: Cédric Le Goater <clg@redhat.com>
14
This patch doesn't attempt to handle that, or to create a different
15
version of the controller for the different generations, since it's only
16
implementing functionality that is common to all generations.
17
18
The basic sequence of events is that the firmware will read and write to
19
various registers and then trigger a command by setting the FIRE bit in
20
the command register (similar to the I2C controller).
21
22
Then the firmware waits for an interrupt from the PECI controller,
23
expecting the interrupt status register to be filled in with info on
24
what happened. If the command was transmitted and received successfully,
25
then response codes from the host CPU will be found in the data buffer
26
registers.
27
28
Signed-off-by: Peter Delevoryas <pdel@fb.com>
29
Reviewed-by: Cédric Le Goater <clg@kaod.org>
30
Message-Id: <20220630045133.32251-12-me@pjd.dev>
31
[ clg: s/sysbus_mmio_map/aspeed_mmio_map/ ]
32
Signed-off-by: Cédric Le Goater <clg@kaod.org>
33
---
13
---
34
include/hw/arm/aspeed_soc.h | 3 +
14
include/hw/arm/aspeed_soc.h | 2 +-
35
include/hw/misc/aspeed_peci.h | 29 +++++++
15
1 file changed, 1 insertion(+), 1 deletion(-)
36
hw/arm/aspeed_ast10x0.c | 13 +++
37
hw/arm/aspeed_ast2600.c | 13 +++
38
hw/arm/aspeed_soc.c | 14 ++++
39
hw/misc/aspeed_peci.c | 152 ++++++++++++++++++++++++++++++++++
40
hw/misc/meson.build | 3 +-
41
hw/misc/trace-events | 5 ++
42
8 files changed, 231 insertions(+), 1 deletion(-)
43
create mode 100644 include/hw/misc/aspeed_peci.h
44
create mode 100644 hw/misc/aspeed_peci.c
45
16
46
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
17
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
47
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
48
--- a/include/hw/arm/aspeed_soc.h
19
--- a/include/hw/arm/aspeed_soc.h
49
+++ b/include/hw/arm/aspeed_soc.h
20
+++ b/include/hw/arm/aspeed_soc.h
50
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
51
#include "qom/object.h"
22
#include "hw/char/serial-mm.h"
52
#include "hw/misc/aspeed_lpc.h"
23
#include "hw/intc/arm_gicv3.h"
53
#include "hw/misc/unimp.h"
24
54
+#include "hw/misc/aspeed_peci.h"
25
-#define ASPEED_SPIS_NUM 2
55
26
+#define ASPEED_SPIS_NUM 3
56
#define ASPEED_SPIS_NUM 2
57
#define ASPEED_EHCIS_NUM 2
27
#define ASPEED_EHCIS_NUM 2
58
@@ -XXX,XX +XXX,XX @@ struct AspeedSoCState {
28
#define ASPEED_WDTS_NUM 8
59
AspeedSDHCIState sdhci;
29
#define ASPEED_CPUS_NUM 4
60
AspeedSDHCIState emmc;
61
AspeedLPCState lpc;
62
+ AspeedPECIState peci;
63
uint32_t uart_default;
64
Clock *sysclk;
65
UnimplementedDeviceState iomem;
66
@@ -XXX,XX +XXX,XX @@ enum {
67
ASPEED_DEV_LPC,
68
ASPEED_DEV_IBT,
69
ASPEED_DEV_I2C,
70
+ ASPEED_DEV_PECI,
71
ASPEED_DEV_ETH1,
72
ASPEED_DEV_ETH2,
73
ASPEED_DEV_ETH3,
74
diff --git a/include/hw/misc/aspeed_peci.h b/include/hw/misc/aspeed_peci.h
75
new file mode 100644
76
index XXXXXXX..XXXXXXX
77
--- /dev/null
78
+++ b/include/hw/misc/aspeed_peci.h
79
@@ -XXX,XX +XXX,XX @@
80
+/*
81
+ * Aspeed PECI Controller
82
+ *
83
+ * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
84
+ *
85
+ * This code is licensed under the GPL version 2 or later. See the COPYING
86
+ * file in the top-level directory.
87
+ */
88
+
89
+#ifndef ASPEED_PECI_H
90
+#define ASPEED_PECI_H
91
+
92
+#include "hw/sysbus.h"
93
+
94
+#define ASPEED_PECI_NR_REGS ((0xFC + 4) >> 2)
95
+#define TYPE_ASPEED_PECI "aspeed.peci"
96
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedPECIState, ASPEED_PECI);
97
+
98
+struct AspeedPECIState {
99
+ /* <private> */
100
+ SysBusDevice parent;
101
+
102
+ MemoryRegion mmio;
103
+ qemu_irq irq;
104
+
105
+ uint32_t regs[ASPEED_PECI_NR_REGS];
106
+};
107
+
108
+#endif
109
diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/hw/arm/aspeed_ast10x0.c
112
+++ b/hw/arm/aspeed_ast10x0.c
113
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast1030_memmap[] = {
114
[ASPEED_DEV_UART13] = 0x7E790700,
115
[ASPEED_DEV_WDT] = 0x7E785000,
116
[ASPEED_DEV_LPC] = 0x7E789000,
117
+ [ASPEED_DEV_PECI] = 0x7E78B000,
118
[ASPEED_DEV_I2C] = 0x7E7B0000,
119
};
120
121
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast1030_irqmap[] = {
122
[ASPEED_DEV_TIMER8] = 23,
123
[ASPEED_DEV_WDT] = 24,
124
[ASPEED_DEV_LPC] = 35,
125
+ [ASPEED_DEV_PECI] = 38,
126
[ASPEED_DEV_FMC] = 39,
127
[ASPEED_DEV_PWM] = 44,
128
[ASPEED_DEV_ADC] = 46,
129
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_init(Object *obj)
130
131
object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC);
132
133
+ object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI);
134
+
135
object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_SBC);
136
137
for (i = 0; i < sc->wdts_num; i++) {
138
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
139
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c.busses[i]), 0, irq);
140
}
141
142
+ /* PECI */
143
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->peci), errp)) {
144
+ return;
145
+ }
146
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->peci), 0,
147
+ sc->memmap[ASPEED_DEV_PECI]);
148
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->peci), 0,
149
+ aspeed_soc_get_irq(s, ASPEED_DEV_PECI));
150
+
151
/* LPC */
152
if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) {
153
return;
154
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/hw/arm/aspeed_ast2600.c
157
+++ b/hw/arm/aspeed_ast2600.c
158
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
159
[ASPEED_DEV_LPC] = 0x1E789000,
160
[ASPEED_DEV_IBT] = 0x1E789140,
161
[ASPEED_DEV_I2C] = 0x1E78A000,
162
+ [ASPEED_DEV_PECI] = 0x1E78B000,
163
[ASPEED_DEV_UART1] = 0x1E783000,
164
[ASPEED_DEV_UART2] = 0x1E78D000,
165
[ASPEED_DEV_UART3] = 0x1E78E000,
166
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2600_irqmap[] = {
167
[ASPEED_DEV_LPC] = 35,
168
[ASPEED_DEV_IBT] = 143,
169
[ASPEED_DEV_I2C] = 110, /* 110 -> 125 */
170
+ [ASPEED_DEV_PECI] = 38,
171
[ASPEED_DEV_ETH1] = 2,
172
[ASPEED_DEV_ETH2] = 3,
173
[ASPEED_DEV_HACE] = 4,
174
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
175
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
176
object_initialize_child(obj, "i2c", &s->i2c, typename);
177
178
+ object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI);
179
+
180
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
181
object_initialize_child(obj, "fmc", &s->fmc, typename);
182
183
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
184
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c.busses[i]), 0, irq);
185
}
186
187
+ /* PECI */
188
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->peci), errp)) {
189
+ return;
190
+ }
191
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->peci), 0,
192
+ sc->memmap[ASPEED_DEV_PECI]);
193
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->peci), 0,
194
+ aspeed_soc_get_irq(s, ASPEED_DEV_PECI));
195
+
196
/* FMC, The number of CS is set at the board level */
197
object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr),
198
&error_abort);
199
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/hw/arm/aspeed_soc.c
202
+++ b/hw/arm/aspeed_soc.c
203
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
204
[ASPEED_DEV_LPC] = 0x1E789000,
205
[ASPEED_DEV_IBT] = 0x1E789140,
206
[ASPEED_DEV_I2C] = 0x1E78A000,
207
+ [ASPEED_DEV_PECI] = 0x1E78B000,
208
[ASPEED_DEV_ETH1] = 0x1E660000,
209
[ASPEED_DEV_ETH2] = 0x1E680000,
210
[ASPEED_DEV_UART1] = 0x1E783000,
211
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
212
[ASPEED_DEV_LPC] = 0x1E789000,
213
[ASPEED_DEV_IBT] = 0x1E789140,
214
[ASPEED_DEV_I2C] = 0x1E78A000,
215
+ [ASPEED_DEV_PECI] = 0x1E78B000,
216
[ASPEED_DEV_ETH1] = 0x1E660000,
217
[ASPEED_DEV_ETH2] = 0x1E680000,
218
[ASPEED_DEV_UART1] = 0x1E783000,
219
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2400_irqmap[] = {
220
[ASPEED_DEV_PWM] = 28,
221
[ASPEED_DEV_LPC] = 8,
222
[ASPEED_DEV_I2C] = 12,
223
+ [ASPEED_DEV_PECI] = 15,
224
[ASPEED_DEV_ETH1] = 2,
225
[ASPEED_DEV_ETH2] = 3,
226
[ASPEED_DEV_XDMA] = 6,
227
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
228
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
229
object_initialize_child(obj, "i2c", &s->i2c, typename);
230
231
+ object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI);
232
+
233
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
234
object_initialize_child(obj, "fmc", &s->fmc, typename);
235
236
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
237
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
238
aspeed_soc_get_irq(s, ASPEED_DEV_I2C));
239
240
+ /* PECI */
241
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->peci), errp)) {
242
+ return;
243
+ }
244
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->peci), 0,
245
+ sc->memmap[ASPEED_DEV_PECI]);
246
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->peci), 0,
247
+ aspeed_soc_get_irq(s, ASPEED_DEV_PECI));
248
+
249
/* FMC, The number of CS is set at the board level */
250
object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr),
251
&error_abort);
252
diff --git a/hw/misc/aspeed_peci.c b/hw/misc/aspeed_peci.c
253
new file mode 100644
254
index XXXXXXX..XXXXXXX
255
--- /dev/null
256
+++ b/hw/misc/aspeed_peci.c
257
@@ -XXX,XX +XXX,XX @@
258
+/*
259
+ * Aspeed PECI Controller
260
+ *
261
+ * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
262
+ *
263
+ * This code is licensed under the GPL version 2 or later. See the COPYING
264
+ * file in the top-level directory.
265
+ */
266
+
267
+#include "qemu/osdep.h"
268
+#include "qemu/log.h"
269
+#include "hw/irq.h"
270
+#include "hw/misc/aspeed_peci.h"
271
+#include "hw/registerfields.h"
272
+#include "trace.h"
273
+
274
+#define ASPEED_PECI_CC_RSP_SUCCESS (0x40U)
275
+
276
+/* Command Register */
277
+REG32(PECI_CMD, 0x08)
278
+ FIELD(PECI_CMD, FIRE, 0, 1)
279
+
280
+/* Interrupt Control Register */
281
+REG32(PECI_INT_CTRL, 0x18)
282
+
283
+/* Interrupt Status Register */
284
+REG32(PECI_INT_STS, 0x1C)
285
+ FIELD(PECI_INT_STS, CMD_DONE, 0, 1)
286
+
287
+/* Rx/Tx Data Buffer Registers */
288
+REG32(PECI_WR_DATA0, 0x20)
289
+REG32(PECI_RD_DATA0, 0x30)
290
+
291
+static void aspeed_peci_raise_interrupt(AspeedPECIState *s, uint32_t status)
292
+{
293
+ trace_aspeed_peci_raise_interrupt(s->regs[R_PECI_INT_CTRL], status);
294
+
295
+ s->regs[R_PECI_INT_STS] = s->regs[R_PECI_INT_CTRL] & status;
296
+ if (!s->regs[R_PECI_INT_STS]) {
297
+ return;
298
+ }
299
+ qemu_irq_raise(s->irq);
300
+}
301
+
302
+static uint64_t aspeed_peci_read(void *opaque, hwaddr offset, unsigned size)
303
+{
304
+ AspeedPECIState *s = ASPEED_PECI(opaque);
305
+ uint64_t data;
306
+
307
+ if (offset >= ASPEED_PECI_NR_REGS << 2) {
308
+ qemu_log_mask(LOG_GUEST_ERROR,
309
+ "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
310
+ __func__, offset);
311
+ return 0;
312
+ }
313
+ data = s->regs[offset >> 2];
314
+
315
+ trace_aspeed_peci_read(offset, data);
316
+ return data;
317
+}
318
+
319
+static void aspeed_peci_write(void *opaque, hwaddr offset, uint64_t data,
320
+ unsigned size)
321
+{
322
+ AspeedPECIState *s = ASPEED_PECI(opaque);
323
+
324
+ trace_aspeed_peci_write(offset, data);
325
+
326
+ if (offset >= ASPEED_PECI_NR_REGS << 2) {
327
+ qemu_log_mask(LOG_GUEST_ERROR,
328
+ "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
329
+ __func__, offset);
330
+ return;
331
+ }
332
+
333
+ switch (offset) {
334
+ case A_PECI_INT_STS:
335
+ s->regs[R_PECI_INT_STS] &= ~data;
336
+ if (!s->regs[R_PECI_INT_STS]) {
337
+ qemu_irq_lower(s->irq);
338
+ }
339
+ break;
340
+ case A_PECI_CMD:
341
+ /*
342
+ * Only the FIRE bit is writable. Once the command is complete, it
343
+ * should be cleared. Since we complete the command immediately, the
344
+ * value is not stored in the register array.
345
+ */
346
+ if (!FIELD_EX32(data, PECI_CMD, FIRE)) {
347
+ break;
348
+ }
349
+ if (s->regs[R_PECI_INT_STS]) {
350
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Interrupt status must be "
351
+ "cleared before firing another command: 0x%08x\n",
352
+ __func__, s->regs[R_PECI_INT_STS]);
353
+ break;
354
+ }
355
+ s->regs[R_PECI_RD_DATA0] = ASPEED_PECI_CC_RSP_SUCCESS;
356
+ s->regs[R_PECI_WR_DATA0] = ASPEED_PECI_CC_RSP_SUCCESS;
357
+ aspeed_peci_raise_interrupt(s,
358
+ FIELD_DP32(0, PECI_INT_STS, CMD_DONE, 1));
359
+ break;
360
+ default:
361
+ s->regs[offset / sizeof(s->regs[0])] = data;
362
+ break;
363
+ }
364
+}
365
+
366
+static const MemoryRegionOps aspeed_peci_ops = {
367
+ .read = aspeed_peci_read,
368
+ .write = aspeed_peci_write,
369
+ .endianness = DEVICE_LITTLE_ENDIAN,
370
+};
371
+
372
+static void aspeed_peci_realize(DeviceState *dev, Error **errp)
373
+{
374
+ AspeedPECIState *s = ASPEED_PECI(dev);
375
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
376
+
377
+ memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_peci_ops, s,
378
+ TYPE_ASPEED_PECI, 0x1000);
379
+ sysbus_init_mmio(sbd, &s->mmio);
380
+ sysbus_init_irq(sbd, &s->irq);
381
+}
382
+
383
+static void aspeed_peci_reset(DeviceState *dev)
384
+{
385
+ AspeedPECIState *s = ASPEED_PECI(dev);
386
+
387
+ memset(s->regs, 0, sizeof(s->regs));
388
+}
389
+
390
+static void aspeed_peci_class_init(ObjectClass *klass, void *data)
391
+{
392
+ DeviceClass *dc = DEVICE_CLASS(klass);
393
+
394
+ dc->realize = aspeed_peci_realize;
395
+ dc->reset = aspeed_peci_reset;
396
+ dc->desc = "Aspeed PECI Controller";
397
+}
398
+
399
+static const TypeInfo aspeed_peci_types[] = {
400
+ {
401
+ .name = TYPE_ASPEED_PECI,
402
+ .parent = TYPE_SYS_BUS_DEVICE,
403
+ .instance_size = sizeof(AspeedPECIState),
404
+ .class_init = aspeed_peci_class_init,
405
+ .abstract = false,
406
+ },
407
+};
408
+
409
+DEFINE_TYPES(aspeed_peci_types);
410
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
411
index XXXXXXX..XXXXXXX 100644
412
--- a/hw/misc/meson.build
413
+++ b/hw/misc/meson.build
414
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
415
'aspeed_scu.c',
416
'aspeed_sbc.c',
417
'aspeed_sdmc.c',
418
- 'aspeed_xdma.c'))
419
+ 'aspeed_xdma.c',
420
+ 'aspeed_peci.c'))
421
422
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c'))
423
softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_rng.c'))
424
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
425
index XXXXXXX..XXXXXXX 100644
426
--- a/hw/misc/trace-events
427
+++ b/hw/misc/trace-events
428
@@ -XXX,XX +XXX,XX @@ aspeed_i3c_device_write(uint32_t deviceid, uint64_t offset, uint64_t data) "I3C
429
aspeed_sdmc_write(uint64_t reg, uint64_t data) "reg @0x%" PRIx64 " data: 0x%" PRIx64
430
aspeed_sdmc_read(uint64_t reg, uint64_t data) "reg @0x%" PRIx64 " data: 0x%" PRIx64
431
432
+# aspeed_peci.c
433
+aspeed_peci_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
434
+aspeed_peci_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
435
+aspeed_peci_raise_interrupt(uint32_t ctrl, uint32_t status) "ctrl 0x%" PRIx32 " status 0x%" PRIx32
436
+
437
# bcm2835_property.c
438
bcm2835_mbox_property(uint32_t tag, uint32_t bufsize, size_t resplen) "mbox property tag:0x%08x in_sz:%u out_sz:%zu"
439
440
--
30
--
441
2.35.3
31
2.49.0
442
32
443
33
diff view generated by jsdifflib
1
Using a 'stop' string seems more appropriate than 'normal'.
1
From: Steven Lee <steven_lee@aspeedtech.com>
2
2
3
Reviewed-by: Peter Delevoryas <pdel@fb.com>
3
Updated the IRQ handler mask check to AND with select variable.
4
Message-Id: <20220628154740.1117349-3-clg@kaod.org>
4
This ensures that the interrupt service routine is correctly triggered
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
5
for the interrupts within the same irq group.
6
7
For example, both `eth0` and the debug UART are handled in `GICINT132`.
8
Without this fix, the debug console may hang if the `eth0` ISR is not
9
handled.
10
11
Signed-off-by: Steven Lee <steven_lee@aspeedtech.com>
12
Change-Id: Ic3609eb72218dfd68be6057d78b8953b18828709
13
Reviewed-by: Cédric Le Goater <clg@redhat.com>
14
Fixes: d831c5fd8682 ("aspeed/intc: Add AST2700 support")
15
Link: https://lore.kernel.org/qemu-devel/20250320092543.4040672-2-steven_lee@aspeedtech.com
16
Signed-off-by: Cédric Le Goater <clg@redhat.com>
6
---
17
---
7
hw/i2c/aspeed_i2c.c | 2 +-
18
hw/intc/aspeed_intc.c | 2 +-
8
1 file changed, 1 insertion(+), 1 deletion(-)
19
1 file changed, 1 insertion(+), 1 deletion(-)
9
20
10
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
21
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
11
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/i2c/aspeed_i2c.c
23
--- a/hw/intc/aspeed_intc.c
13
+++ b/hw/i2c/aspeed_i2c.c
24
+++ b/hw/intc/aspeed_intc.c
14
@@ -XXX,XX +XXX,XX @@ static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
25
@@ -XXX,XX +XXX,XX @@ static void aspeed_intc_set_irq_handler(AspeedINTCState *s,
15
ARRAY_FIELD_EX32(bus->regs, I2CD_INTR_STS, SLAVE_ADDR_RX_MATCH) ?
26
outpin_idx = intc_irq->outpin_idx;
16
"slave-match|" : "",
27
inpin_idx = intc_irq->inpin_idx;
17
SHARED_ARRAY_FIELD_EX32(bus->regs, reg_intr_sts, NORMAL_STOP) ?
28
18
- "normal|" : "",
29
- if (s->mask[inpin_idx] || s->regs[status_reg]) {
19
+ "stop|" : "",
30
+ if ((s->mask[inpin_idx] & select) || (s->regs[status_reg] & select)) {
20
SHARED_ARRAY_FIELD_EX32(bus->regs, reg_intr_sts, ABNORMAL) ?
31
/*
21
"abnormal" : "");
32
* a. mask is not 0 means in ISR mode
22
33
* sources interrupt routine are executing.
23
--
34
--
24
2.35.3
35
2.49.0
25
36
26
37
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
2
3
While the HMAC mode is not modelled, the accumulative mode is.
3
The maximum padding size is either 64 or 128 bytes and should always be smaller
4
than "req_len". If "padding_size" exceeds "req_len", then
5
"req_len - padding_size" underflows due to "uint32_t" data type, leading to a
6
large incorrect value (e.g., `0xFFXXXXXX`). This causes an out-of-bounds memory
7
access, potentially leading to a buffer overflow.
4
8
5
Accumulative mode is enabled by setting one of the bits in the HMAC
9
Added a check to ensure "padding_size" does not exceed "req_len" before
6
engine command mode part of the register, so fix the unimplemented check
10
computing "pad_offset". This prevents "req_len - padding_size" from underflowing
7
to only look at the upper of the two bits.
11
and avoids accessing invalid memory.
8
12
9
Fixes: 5cd7d8564a8b ("aspeed/hace: Support AST2600 HACE")
13
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
14
Reviewed-by: Cédric Le Goater <clg@redhat.com>
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
15
Fixes: 5cd7d8564a8b563da724b9e6264c967f0a091afa ("aspeed/hace: Support AST2600 HACE ")
12
Message-Id: <20220627100816.125956-1-joel@jms.id.au>
16
Link: https://lore.kernel.org/qemu-devel/20250321092623.2097234-3-jamin_lin@aspeedtech.com
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
17
Signed-off-by: Cédric Le Goater <clg@redhat.com>
14
---
18
---
15
hw/misc/aspeed_hace.c | 6 +++---
19
hw/misc/aspeed_hace.c | 5 +++++
16
1 file changed, 3 insertions(+), 3 deletions(-)
20
1 file changed, 5 insertions(+)
17
21
18
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
22
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
19
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/misc/aspeed_hace.c
24
--- a/hw/misc/aspeed_hace.c
21
+++ b/hw/misc/aspeed_hace.c
25
+++ b/hw/misc/aspeed_hace.c
22
@@ -XXX,XX +XXX,XX @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
26
@@ -XXX,XX +XXX,XX @@ static bool has_padding(AspeedHACEState *s, struct iovec *iov,
23
int algo;
27
if (*total_msg_len <= s->total_req_len) {
24
data &= ahc->hash_mask;
28
uint32_t padding_size = s->total_req_len - *total_msg_len;
25
29
uint8_t *padding = iov->iov_base;
26
- if ((data & HASH_HMAC_MASK)) {
30
+
27
+ if ((data & HASH_DIGEST_HMAC)) {
31
+ if (padding_size > req_len) {
28
qemu_log_mask(LOG_UNIMP,
32
+ return false;
29
- "%s: HMAC engine command mode %"PRIx64" not implemented\n",
33
+ }
30
- __func__, (data & HASH_HMAC_MASK) >> 8);
34
+
31
+ "%s: HMAC mode not implemented\n",
35
*pad_offset = req_len - padding_size;
32
+ __func__);
36
if (padding[*pad_offset] == 0x80) {
33
}
37
return true;
34
if (data & BIT(1)) {
35
qemu_log_mask(LOG_UNIMP,
36
--
38
--
37
2.35.3
39
2.49.0
38
40
39
41
diff view generated by jsdifflib
Deleted patch
1
Coverity warns that "ssi_transfer(s->spi, 0U) << 8 * i" might overflow
2
because the expression is evaluated using 32-bit arithmetic and then
3
used in a context expecting a uint64_t.
4
1
5
Fixes: Coverity CID 1487244
6
Message-Id: <20220628165512.1133590-1-clg@kaod.org>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
---
9
hw/ssi/aspeed_smc.c | 4 ++--
10
1 file changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/ssi/aspeed_smc.c
15
+++ b/hw/ssi/aspeed_smc.c
16
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
17
switch (aspeed_smc_flash_mode(fl)) {
18
case CTRL_USERMODE:
19
for (i = 0; i < size; i++) {
20
- ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
21
+ ret |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * i);
22
}
23
break;
24
case CTRL_READMODE:
25
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
26
aspeed_smc_flash_setup(fl, addr);
27
28
for (i = 0; i < size; i++) {
29
- ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
30
+ ret |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * i);
31
}
32
33
aspeed_smc_flash_unselect(fl);
34
--
35
2.35.3
36
37
diff view generated by jsdifflib
Deleted patch
1
From: Peter Delevoryas <pdel@fb.com>
2
1
3
Signed-off-by: Peter Delevoryas <pdel@fb.com>
4
Message-Id: <20220624003701.1363500-2-pdel@fb.com>
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
---
7
hw/arm/aspeed_ast2600.c | 2 ++
8
hw/arm/aspeed_soc.c | 2 ++
9
2 files changed, 4 insertions(+)
10
11
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/aspeed_ast2600.c
14
+++ b/hw/arm/aspeed_ast2600.c
15
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
16
17
object_property_set_int(OBJECT(&s->cpu[i]), "cntfrq", 1125000000,
18
&error_abort);
19
+ object_property_set_link(OBJECT(&s->cpu[i]), "memory",
20
+ OBJECT(get_system_memory()), &error_abort);
21
22
if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
23
return;
24
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/aspeed_soc.c
27
+++ b/hw/arm/aspeed_soc.c
28
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
29
30
/* CPU */
31
for (i = 0; i < sc->num_cpus; i++) {
32
+ object_property_set_link(OBJECT(&s->cpu[i]), "memory",
33
+ OBJECT(get_system_memory()), &error_abort);
34
if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
35
return;
36
}
37
--
38
2.35.3
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Peter Delevoryas <pdel@fb.com>
2
1
3
Multi-SoC machines can use this property to specify a memory container
4
for each SoC. Single SoC machines will just specify get_system_memory().
5
6
Signed-off-by: Peter Delevoryas <pdel@fb.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-Id: <20220624003701.1363500-3-pdel@fb.com>
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
---
11
include/hw/arm/aspeed_soc.h | 1 +
12
hw/arm/aspeed.c | 4 ++++
13
hw/arm/aspeed_ast10x0.c | 5 ++---
14
hw/arm/aspeed_ast2600.c | 4 ++--
15
hw/arm/aspeed_soc.c | 12 +++++++-----
16
5 files changed, 16 insertions(+), 10 deletions(-)
17
18
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/aspeed_soc.h
21
+++ b/include/hw/arm/aspeed_soc.h
22
@@ -XXX,XX +XXX,XX @@ struct AspeedSoCState {
23
ARMCPU cpu[ASPEED_CPUS_NUM];
24
A15MPPrivState a7mpcore;
25
ARMv7MState armv7m;
26
+ MemoryRegion *memory;
27
MemoryRegion *dram_mr;
28
MemoryRegion dram_container;
29
MemoryRegion sram;
30
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/aspeed.c
33
+++ b/hw/arm/aspeed.c
34
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_init(MachineState *machine)
35
&error_abort);
36
object_property_set_int(OBJECT(&bmc->soc), "hw-strap2", amc->hw_strap2,
37
&error_abort);
38
+ object_property_set_link(OBJECT(&bmc->soc), "memory",
39
+ OBJECT(get_system_memory()), &error_abort);
40
object_property_set_link(OBJECT(&bmc->soc), "dram",
41
OBJECT(machine->ram), &error_abort);
42
if (machine->kernel_filename) {
43
@@ -XXX,XX +XXX,XX @@ static void aspeed_minibmc_machine_init(MachineState *machine)
44
object_initialize_child(OBJECT(machine), "soc", &bmc->soc, amc->soc_name);
45
qdev_connect_clock_in(DEVICE(&bmc->soc), "sysclk", sysclk);
46
47
+ object_property_set_link(OBJECT(&bmc->soc), "memory",
48
+ OBJECT(get_system_memory()), &error_abort);
49
qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
50
amc->uart_default);
51
qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
52
diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/arm/aspeed_ast10x0.c
55
+++ b/hw/arm/aspeed_ast10x0.c
56
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
57
{
58
AspeedSoCState *s = ASPEED_SOC(dev_soc);
59
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
60
- MemoryRegion *system_memory = get_system_memory();
61
DeviceState *armv7m;
62
Error *err = NULL;
63
int i;
64
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
65
qdev_prop_set_string(armv7m, "cpu-type", sc->cpu_type);
66
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
67
object_property_set_link(OBJECT(&s->armv7m), "memory",
68
- OBJECT(system_memory), &error_abort);
69
+ OBJECT(s->memory), &error_abort);
70
sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), &error_abort);
71
72
/* Internal SRAM */
73
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
74
error_propagate(errp, err);
75
return;
76
}
77
- memory_region_add_subregion(system_memory,
78
+ memory_region_add_subregion(s->memory,
79
sc->memmap[ASPEED_DEV_SRAM],
80
&s->sram);
81
82
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/arm/aspeed_ast2600.c
85
+++ b/hw/arm/aspeed_ast2600.c
86
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
87
object_property_set_int(OBJECT(&s->cpu[i]), "cntfrq", 1125000000,
88
&error_abort);
89
object_property_set_link(OBJECT(&s->cpu[i]), "memory",
90
- OBJECT(get_system_memory()), &error_abort);
91
+ OBJECT(s->memory), &error_abort);
92
93
if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
94
return;
95
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
96
error_propagate(errp, err);
97
return;
98
}
99
- memory_region_add_subregion(get_system_memory(),
100
+ memory_region_add_subregion(s->memory,
101
sc->memmap[ASPEED_DEV_SRAM], &s->sram);
102
103
/* DPMCU */
104
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/arm/aspeed_soc.c
107
+++ b/hw/arm/aspeed_soc.c
108
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
109
/* CPU */
110
for (i = 0; i < sc->num_cpus; i++) {
111
object_property_set_link(OBJECT(&s->cpu[i]), "memory",
112
- OBJECT(get_system_memory()), &error_abort);
113
+ OBJECT(s->memory), &error_abort);
114
if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
115
return;
116
}
117
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
118
error_propagate(errp, err);
119
return;
120
}
121
- memory_region_add_subregion(get_system_memory(),
122
+ memory_region_add_subregion(s->memory,
123
sc->memmap[ASPEED_DEV_SRAM], &s->sram);
124
125
/* SCU */
126
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
127
aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
128
}
129
static Property aspeed_soc_properties[] = {
130
+ DEFINE_PROP_LINK("memory", AspeedSoCState, memory, TYPE_MEMORY_REGION,
131
+ MemoryRegion *),
132
DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
133
MemoryRegion *),
134
DEFINE_PROP_UINT32("uart-default", AspeedSoCState, uart_default,
135
@@ -XXX,XX +XXX,XX @@ void aspeed_soc_uart_init(AspeedSoCState *s)
136
int i, uart;
137
138
/* Attach an 8250 to the IO space as our UART */
139
- serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2,
140
+ serial_mm_init(s->memory, sc->memmap[s->uart_default], 2,
141
aspeed_soc_get_irq(s, s->uart_default), 38400,
142
serial_hd(0), DEVICE_LITTLE_ENDIAN);
143
for (i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
144
if (uart == s->uart_default) {
145
uart++;
146
}
147
- serial_mm_init(get_system_memory(), sc->memmap[uart], 2,
148
+ serial_mm_init(s->memory, sc->memmap[uart], 2,
149
aspeed_soc_get_irq(s, uart), 38400,
150
serial_hd(i), DEVICE_LITTLE_ENDIAN);
151
}
152
@@ -XXX,XX +XXX,XX @@ bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp)
153
sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0), -1000);
154
}
155
156
- memory_region_add_subregion(get_system_memory(),
157
+ memory_region_add_subregion(s->memory,
158
sc->memmap[ASPEED_DEV_SDRAM], &s->dram_container);
159
return true;
160
}
161
--
162
2.35.3
163
164
diff view generated by jsdifflib
Deleted patch
1
From: Peter Delevoryas <pdel@fb.com>
2
1
3
sysbus_mmio_map maps devices into "get_system_memory()".
4
5
With the new SoC memory attribute, we want to make sure that each device is
6
mapped into the SoC memory.
7
8
In single SoC machines, the SoC memory is the same as "get_system_memory()",
9
but in multi SoC machines it will be different.
10
11
Signed-off-by: Peter Delevoryas <pdel@fb.com>
12
Reviewed-by: Cédric Le Goater <clg@kaod.org>
13
Message-Id: <20220624003701.1363500-4-pdel@fb.com>
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
---
16
include/hw/arm/aspeed_soc.h | 1 +
17
hw/arm/aspeed_ast10x0.c | 25 +++++++++---------
18
hw/arm/aspeed_ast2600.c | 51 ++++++++++++++++++++-----------------
19
hw/arm/aspeed_soc.c | 47 ++++++++++++++++++++--------------
20
4 files changed, 69 insertions(+), 55 deletions(-)
21
22
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/aspeed_soc.h
25
+++ b/include/hw/arm/aspeed_soc.h
26
@@ -XXX,XX +XXX,XX @@ enum {
27
qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev);
28
void aspeed_soc_uart_init(AspeedSoCState *s);
29
bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp);
30
+void aspeed_mmio_map(AspeedSoCState *s, SysBusDevice *dev, int n, hwaddr addr);
31
32
#endif /* ASPEED_SOC_H */
33
diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/aspeed_ast10x0.c
36
+++ b/hw/arm/aspeed_ast10x0.c
37
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
38
if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
39
return;
40
}
41
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
42
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
43
44
/* I2C */
45
46
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
47
if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
48
return;
49
}
50
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]);
51
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]);
52
for (i = 0; i < ASPEED_I2C_GET_CLASS(&s->i2c)->num_busses; i++) {
53
qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->armv7m),
54
sc->irqmap[ASPEED_DEV_I2C] + i);
55
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
56
if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) {
57
return;
58
}
59
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
60
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
61
62
/* Connect the LPC IRQ to the GIC. It is otherwise unused. */
63
sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0,
64
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
65
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) {
66
return;
67
}
68
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0,
69
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->timerctrl), 0,
70
sc->memmap[ASPEED_DEV_TIMER1]);
71
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
72
qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_DEV_TIMER1 + i);
73
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
74
if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) {
75
return;
76
}
77
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]);
78
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]);
79
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
80
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
81
82
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
83
if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) {
84
return;
85
}
86
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
87
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
88
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
89
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->fmc), 1,
90
ASPEED_SMC_GET_CLASS(&s->fmc)->flash_window_base);
91
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
92
aspeed_soc_get_irq(s, ASPEED_DEV_FMC));
93
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
94
if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
95
return;
96
}
97
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
98
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 0,
99
sc->memmap[ASPEED_DEV_SPI1 + i]);
100
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
101
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 1,
102
ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
103
}
104
105
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
106
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sbc), errp)) {
107
return;
108
}
109
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sbc), 0, sc->memmap[ASPEED_DEV_SBC]);
110
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->sbc), 0, sc->memmap[ASPEED_DEV_SBC]);
111
112
/* Watch dog */
113
for (i = 0; i < sc->wdts_num; i++) {
114
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
115
if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) {
116
return;
117
}
118
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
119
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->wdt[i]), 0,
120
sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
121
}
122
123
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
124
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
125
return;
126
}
127
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]);
128
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->gpio), 0,
129
+ sc->memmap[ASPEED_DEV_GPIO]);
130
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
131
aspeed_soc_get_irq(s, ASPEED_DEV_GPIO));
132
}
133
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/arm/aspeed_ast2600.c
136
+++ b/hw/arm/aspeed_ast2600.c
137
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
138
&error_abort);
139
140
sysbus_realize(SYS_BUS_DEVICE(&s->a7mpcore), &error_abort);
141
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, ASPEED_A7MPCORE_ADDR);
142
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->a7mpcore), 0, ASPEED_A7MPCORE_ADDR);
143
144
for (i = 0; i < sc->num_cpus; i++) {
145
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
146
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
147
if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
148
return;
149
}
150
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
151
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
152
153
/* RTC */
154
if (!sysbus_realize(SYS_BUS_DEVICE(&s->rtc), errp)) {
155
return;
156
}
157
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_DEV_RTC]);
158
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_DEV_RTC]);
159
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0,
160
aspeed_soc_get_irq(s, ASPEED_DEV_RTC));
161
162
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
163
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) {
164
return;
165
}
166
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0,
167
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->timerctrl), 0,
168
sc->memmap[ASPEED_DEV_TIMER1]);
169
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
170
qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_DEV_TIMER1 + i);
171
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
172
if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) {
173
return;
174
}
175
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]);
176
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]);
177
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
178
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
179
180
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
181
if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
182
return;
183
}
184
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]);
185
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]);
186
for (i = 0; i < ASPEED_I2C_GET_CLASS(&s->i2c)->num_busses; i++) {
187
qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore),
188
sc->irqmap[ASPEED_DEV_I2C] + i);
189
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
190
if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) {
191
return;
192
}
193
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
194
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
195
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
196
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->fmc), 1,
197
ASPEED_SMC_GET_CLASS(&s->fmc)->flash_window_base);
198
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
199
aspeed_soc_get_irq(s, ASPEED_DEV_FMC));
200
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
201
if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
202
return;
203
}
204
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
205
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 0,
206
sc->memmap[ASPEED_DEV_SPI1 + i]);
207
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
208
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 1,
209
ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
210
}
211
212
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
213
if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) {
214
return;
215
}
216
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
217
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->ehci[i]), 0,
218
sc->memmap[ASPEED_DEV_EHCI1 + i]);
219
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
220
aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
221
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
222
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
223
return;
224
}
225
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_DEV_SDMC]);
226
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->sdmc), 0,
227
+ sc->memmap[ASPEED_DEV_SDMC]);
228
229
/* Watch dog */
230
for (i = 0; i < sc->wdts_num; i++) {
231
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
232
if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) {
233
return;
234
}
235
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
236
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->wdt[i]), 0,
237
sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
238
}
239
240
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
241
if (!sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), errp)) {
242
return;
243
}
244
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
245
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
246
sc->memmap[ASPEED_DEV_ETH1 + i]);
247
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
248
aspeed_soc_get_irq(s, ASPEED_DEV_ETH1 + i));
249
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
250
return;
251
}
252
253
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->mii[i]), 0,
254
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->mii[i]), 0,
255
sc->memmap[ASPEED_DEV_MII1 + i]);
256
}
257
258
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
259
if (!sysbus_realize(SYS_BUS_DEVICE(&s->xdma), errp)) {
260
return;
261
}
262
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0,
263
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->xdma), 0,
264
sc->memmap[ASPEED_DEV_XDMA]);
265
sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0,
266
aspeed_soc_get_irq(s, ASPEED_DEV_XDMA));
267
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
268
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
269
return;
270
}
271
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]);
272
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]);
273
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
274
aspeed_soc_get_irq(s, ASPEED_DEV_GPIO));
275
276
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio_1_8v), errp)) {
277
return;
278
}
279
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio_1_8v), 0,
280
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->gpio_1_8v), 0,
281
sc->memmap[ASPEED_DEV_GPIO_1_8V]);
282
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio_1_8v), 0,
283
aspeed_soc_get_irq(s, ASPEED_DEV_GPIO_1_8V));
284
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
285
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp)) {
286
return;
287
}
288
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0,
289
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->sdhci), 0,
290
sc->memmap[ASPEED_DEV_SDHCI]);
291
sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
292
aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI));
293
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
294
if (!sysbus_realize(SYS_BUS_DEVICE(&s->emmc), errp)) {
295
return;
296
}
297
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->emmc), 0, sc->memmap[ASPEED_DEV_EMMC]);
298
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->emmc), 0,
299
+ sc->memmap[ASPEED_DEV_EMMC]);
300
sysbus_connect_irq(SYS_BUS_DEVICE(&s->emmc), 0,
301
aspeed_soc_get_irq(s, ASPEED_DEV_EMMC));
302
303
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
304
if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) {
305
return;
306
}
307
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
308
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
309
310
/* Connect the LPC IRQ to the GIC. It is otherwise unused. */
311
sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0,
312
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
313
if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) {
314
return;
315
}
316
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]);
317
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->hace), 0,
318
+ sc->memmap[ASPEED_DEV_HACE]);
319
sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
320
aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
321
322
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
323
if (!sysbus_realize(SYS_BUS_DEVICE(&s->i3c), errp)) {
324
return;
325
}
326
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->i3c), 0, sc->memmap[ASPEED_DEV_I3C]);
327
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->i3c), 0, sc->memmap[ASPEED_DEV_I3C]);
328
for (i = 0; i < ASPEED_I3C_NR_DEVICES; i++) {
329
qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore),
330
sc->irqmap[ASPEED_DEV_I3C] + i);
331
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
332
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sbc), errp)) {
333
return;
334
}
335
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sbc), 0, sc->memmap[ASPEED_DEV_SBC]);
336
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->sbc), 0, sc->memmap[ASPEED_DEV_SBC]);
337
}
338
339
static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
340
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
341
index XXXXXXX..XXXXXXX 100644
342
--- a/hw/arm/aspeed_soc.c
343
+++ b/hw/arm/aspeed_soc.c
344
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
345
if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
346
return;
347
}
348
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
349
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
350
351
/* VIC */
352
if (!sysbus_realize(SYS_BUS_DEVICE(&s->vic), errp)) {
353
return;
354
}
355
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_DEV_VIC]);
356
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_DEV_VIC]);
357
sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
358
qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
359
sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
360
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
361
if (!sysbus_realize(SYS_BUS_DEVICE(&s->rtc), errp)) {
362
return;
363
}
364
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_DEV_RTC]);
365
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_DEV_RTC]);
366
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0,
367
aspeed_soc_get_irq(s, ASPEED_DEV_RTC));
368
369
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
370
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) {
371
return;
372
}
373
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0,
374
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->timerctrl), 0,
375
sc->memmap[ASPEED_DEV_TIMER1]);
376
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
377
qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_DEV_TIMER1 + i);
378
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
379
if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) {
380
return;
381
}
382
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]);
383
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]);
384
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
385
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
386
387
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
388
if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
389
return;
390
}
391
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]);
392
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]);
393
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
394
aspeed_soc_get_irq(s, ASPEED_DEV_I2C));
395
396
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
397
if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) {
398
return;
399
}
400
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
401
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
402
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
403
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->fmc), 1,
404
ASPEED_SMC_GET_CLASS(&s->fmc)->flash_window_base);
405
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
406
aspeed_soc_get_irq(s, ASPEED_DEV_FMC));
407
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
408
if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
409
return;
410
}
411
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
412
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 0,
413
sc->memmap[ASPEED_DEV_SPI1 + i]);
414
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
415
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 1,
416
ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
417
}
418
419
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
420
if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) {
421
return;
422
}
423
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
424
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->ehci[i]), 0,
425
sc->memmap[ASPEED_DEV_EHCI1 + i]);
426
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
427
aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
428
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
429
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
430
return;
431
}
432
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_DEV_SDMC]);
433
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->sdmc), 0,
434
+ sc->memmap[ASPEED_DEV_SDMC]);
435
436
/* Watch dog */
437
for (i = 0; i < sc->wdts_num; i++) {
438
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
439
if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) {
440
return;
441
}
442
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
443
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->wdt[i]), 0,
444
sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
445
}
446
447
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
448
if (!sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), errp)) {
449
return;
450
}
451
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
452
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
453
sc->memmap[ASPEED_DEV_ETH1 + i]);
454
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
455
aspeed_soc_get_irq(s, ASPEED_DEV_ETH1 + i));
456
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
457
if (!sysbus_realize(SYS_BUS_DEVICE(&s->xdma), errp)) {
458
return;
459
}
460
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0,
461
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->xdma), 0,
462
sc->memmap[ASPEED_DEV_XDMA]);
463
sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0,
464
aspeed_soc_get_irq(s, ASPEED_DEV_XDMA));
465
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
466
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
467
return;
468
}
469
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]);
470
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->gpio), 0,
471
+ sc->memmap[ASPEED_DEV_GPIO]);
472
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
473
aspeed_soc_get_irq(s, ASPEED_DEV_GPIO));
474
475
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
476
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp)) {
477
return;
478
}
479
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0,
480
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->sdhci), 0,
481
sc->memmap[ASPEED_DEV_SDHCI]);
482
sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
483
aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI));
484
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
485
if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) {
486
return;
487
}
488
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
489
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
490
491
/* Connect the LPC IRQ to the VIC */
492
sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0,
493
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
494
if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) {
495
return;
496
}
497
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]);
498
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->hace), 0,
499
+ sc->memmap[ASPEED_DEV_HACE]);
500
sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
501
aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
502
}
503
@@ -XXX,XX +XXX,XX @@ bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp)
504
sc->memmap[ASPEED_DEV_SDRAM], &s->dram_container);
505
return true;
506
}
507
+
508
+void aspeed_mmio_map(AspeedSoCState *s, SysBusDevice *dev, int n, hwaddr addr)
509
+{
510
+ memory_region_add_subregion(s->memory, addr,
511
+ sysbus_mmio_get_region(dev, n));
512
+}
513
--
514
2.35.3
515
516
diff view generated by jsdifflib
Deleted patch
1
From: Peter Delevoryas <pdel@fb.com>
2
1
3
Signed-off-by: Peter Delevoryas <pdel@fb.com>
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
5
Message-Id: <20220624003701.1363500-5-pdel@fb.com>
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
---
8
include/hw/arm/aspeed_soc.h | 9 +++++++++
9
hw/arm/aspeed_ast10x0.c | 16 ++++++++++------
10
hw/arm/aspeed_ast2600.c | 27 ++++++++++++++++++---------
11
hw/arm/aspeed_soc.c | 23 +++++++++++++++++++----
12
4 files changed, 56 insertions(+), 19 deletions(-)
13
14
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/aspeed_soc.h
17
+++ b/include/hw/arm/aspeed_soc.h
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/usb/hcd-ehci.h"
20
#include "qom/object.h"
21
#include "hw/misc/aspeed_lpc.h"
22
+#include "hw/misc/unimp.h"
23
24
#define ASPEED_SPIS_NUM 2
25
#define ASPEED_EHCIS_NUM 2
26
@@ -XXX,XX +XXX,XX @@ struct AspeedSoCState {
27
AspeedSMCState spi[ASPEED_SPIS_NUM];
28
EHCISysBusState ehci[ASPEED_EHCIS_NUM];
29
AspeedSBCState sbc;
30
+ UnimplementedDeviceState sbc_unimplemented;
31
AspeedSDMCState sdmc;
32
AspeedWDTState wdt[ASPEED_WDTS_NUM];
33
FTGMAC100State ftgmac100[ASPEED_MACS_NUM];
34
@@ -XXX,XX +XXX,XX @@ struct AspeedSoCState {
35
AspeedLPCState lpc;
36
uint32_t uart_default;
37
Clock *sysclk;
38
+ UnimplementedDeviceState iomem;
39
+ UnimplementedDeviceState video;
40
+ UnimplementedDeviceState emmc_boot_controller;
41
+ UnimplementedDeviceState dpmcu;
42
};
43
44
#define TYPE_ASPEED_SOC "aspeed-soc"
45
@@ -XXX,XX +XXX,XX @@ qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev);
46
void aspeed_soc_uart_init(AspeedSoCState *s);
47
bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp);
48
void aspeed_mmio_map(AspeedSoCState *s, SysBusDevice *dev, int n, hwaddr addr);
49
+void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,
50
+ const char *name, hwaddr addr,
51
+ uint64_t size);
52
53
#endif /* ASPEED_SOC_H */
54
diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/aspeed_ast10x0.c
57
+++ b/hw/arm/aspeed_ast10x0.c
58
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_init(Object *obj)
59
60
snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
61
object_initialize_child(obj, "gpio", &s->gpio, typename);
62
+
63
+ object_initialize_child(obj, "iomem", &s->iomem, TYPE_UNIMPLEMENTED_DEVICE);
64
+ object_initialize_child(obj, "sbc-unimplemented", &s->sbc_unimplemented,
65
+ TYPE_UNIMPLEMENTED_DEVICE);
66
}
67
68
static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
69
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
70
}
71
72
/* General I/O memory space to catch all unimplemented device */
73
- create_unimplemented_device("aspeed.sbc",
74
- sc->memmap[ASPEED_DEV_SBC],
75
- 0x40000);
76
- create_unimplemented_device("aspeed.io",
77
- sc->memmap[ASPEED_DEV_IOMEM],
78
- ASPEED_SOC_IOMEM_SIZE);
79
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->iomem), "aspeed.io",
80
+ sc->memmap[ASPEED_DEV_IOMEM],
81
+ ASPEED_SOC_IOMEM_SIZE);
82
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->sbc_unimplemented),
83
+ "aspeed.sbc", sc->memmap[ASPEED_DEV_SBC],
84
+ 0x40000);
85
86
/* AST1030 CPU Core */
87
armv7m = DEVICE(&s->armv7m);
88
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/hw/arm/aspeed_ast2600.c
91
+++ b/hw/arm/aspeed_ast2600.c
92
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
93
object_initialize_child(obj, "i3c", &s->i3c, TYPE_ASPEED_I3C);
94
95
object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_SBC);
96
+
97
+ object_initialize_child(obj, "iomem", &s->iomem, TYPE_UNIMPLEMENTED_DEVICE);
98
+ object_initialize_child(obj, "video", &s->video, TYPE_UNIMPLEMENTED_DEVICE);
99
+ object_initialize_child(obj, "dpmcu", &s->dpmcu, TYPE_UNIMPLEMENTED_DEVICE);
100
+ object_initialize_child(obj, "emmc-boot-controller",
101
+ &s->emmc_boot_controller,
102
+ TYPE_UNIMPLEMENTED_DEVICE);
103
}
104
105
/*
106
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
107
qemu_irq irq;
108
109
/* IO space */
110
- create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_DEV_IOMEM],
111
- ASPEED_SOC_IOMEM_SIZE);
112
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->iomem), "aspeed.io",
113
+ sc->memmap[ASPEED_DEV_IOMEM],
114
+ ASPEED_SOC_IOMEM_SIZE);
115
116
/* Video engine stub */
117
- create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_DEV_VIDEO],
118
- 0x1000);
119
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->video), "aspeed.video",
120
+ sc->memmap[ASPEED_DEV_VIDEO], 0x1000);
121
122
/* eMMC Boot Controller stub */
123
- create_unimplemented_device("aspeed.emmc-boot-controller",
124
- sc->memmap[ASPEED_DEV_EMMC_BC],
125
- 0x1000);
126
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->emmc_boot_controller),
127
+ "aspeed.emmc-boot-controller",
128
+ sc->memmap[ASPEED_DEV_EMMC_BC], 0x1000);
129
130
/* CPU */
131
for (i = 0; i < sc->num_cpus; i++) {
132
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
133
sc->memmap[ASPEED_DEV_SRAM], &s->sram);
134
135
/* DPMCU */
136
- create_unimplemented_device("aspeed.dpmcu", sc->memmap[ASPEED_DEV_DPMCU],
137
- ASPEED_SOC_DPMCU_SIZE);
138
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->dpmcu), "aspeed.dpmcu",
139
+ sc->memmap[ASPEED_DEV_DPMCU],
140
+ ASPEED_SOC_DPMCU_SIZE);
141
142
/* SCU */
143
if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
144
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/hw/arm/aspeed_soc.c
147
+++ b/hw/arm/aspeed_soc.c
148
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
149
150
snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
151
object_initialize_child(obj, "hace", &s->hace, typename);
152
+
153
+ object_initialize_child(obj, "iomem", &s->iomem, TYPE_UNIMPLEMENTED_DEVICE);
154
+ object_initialize_child(obj, "video", &s->video, TYPE_UNIMPLEMENTED_DEVICE);
155
}
156
157
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
158
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
159
Error *err = NULL;
160
161
/* IO space */
162
- create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_DEV_IOMEM],
163
- ASPEED_SOC_IOMEM_SIZE);
164
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->iomem), "aspeed.io",
165
+ sc->memmap[ASPEED_DEV_IOMEM],
166
+ ASPEED_SOC_IOMEM_SIZE);
167
168
/* Video engine stub */
169
- create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_DEV_VIDEO],
170
- 0x1000);
171
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->video), "aspeed.video",
172
+ sc->memmap[ASPEED_DEV_VIDEO], 0x1000);
173
174
/* CPU */
175
for (i = 0; i < sc->num_cpus; i++) {
176
@@ -XXX,XX +XXX,XX @@ void aspeed_mmio_map(AspeedSoCState *s, SysBusDevice *dev, int n, hwaddr addr)
177
memory_region_add_subregion(s->memory, addr,
178
sysbus_mmio_get_region(dev, n));
179
}
180
+
181
+void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,
182
+ const char *name, hwaddr addr, uint64_t size)
183
+{
184
+ qdev_prop_set_string(DEVICE(dev), "name", name);
185
+ qdev_prop_set_uint64(DEVICE(dev), "size", size);
186
+ sysbus_realize(dev, &error_abort);
187
+
188
+ memory_region_add_subregion_overlap(s->memory, addr,
189
+ sysbus_mmio_get_region(dev, 0), -1000);
190
+}
191
--
192
2.35.3
193
194
diff view generated by jsdifflib
Deleted patch
1
From: Peter Delevoryas <pdel@fb.com>
2
1
3
Signed-off-by: Peter Delevoryas <pdel@fb.com>
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
5
Message-Id: <20220624003701.1363500-6-pdel@fb.com>
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
---
8
hw/arm/aspeed_ast2600.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/aspeed_ast2600.c
14
+++ b/hw/arm/aspeed_ast2600.c
15
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
16
17
for (i = 0; i < sc->num_cpus; i++) {
18
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
19
- DeviceState *d = DEVICE(qemu_get_cpu(i));
20
+ DeviceState *d = DEVICE(&s->cpu[i]);
21
22
irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
23
sysbus_connect_irq(sbd, i, irq);
24
--
25
2.35.3
26
27
diff view generated by jsdifflib
Deleted patch
1
From: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
2
1
3
Add qcom-dc-scm-v1 board support.
4
5
Signed-off-by: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Message-Id: <20220627154703.148943-2-quic_jaehyoo@quicinc.com>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
---
10
hw/arm/aspeed.c | 35 +++++++++++++++++++++++++++++++++++
11
1 file changed, 35 insertions(+)
12
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/aspeed.c
16
+++ b/hw/arm/aspeed.c
17
@@ -XXX,XX +XXX,XX @@ struct AspeedMachineState {
18
#define BLETCHLEY_BMC_HW_STRAP1 AST2600_EVB_HW_STRAP1
19
#define BLETCHLEY_BMC_HW_STRAP2 AST2600_EVB_HW_STRAP2
20
21
+/* Qualcomm DC-SCM hardware value */
22
+#define QCOM_DC_SCM_V1_BMC_HW_STRAP1 0x00000000
23
+#define QCOM_DC_SCM_V1_BMC_HW_STRAP2 0x00000041
24
+
25
#define AST_SMP_MAILBOX_BASE 0x1e6e2180
26
#define AST_SMP_MBOX_FIELD_ENTRY (AST_SMP_MAILBOX_BASE + 0x0)
27
#define AST_SMP_MBOX_FIELD_GOSIGN (AST_SMP_MAILBOX_BASE + 0x4)
28
@@ -XXX,XX +XXX,XX @@ static void fby35_i2c_init(AspeedMachineState *bmc)
29
*/
30
}
31
32
+static void qcom_dc_scm_bmc_i2c_init(AspeedMachineState *bmc)
33
+{
34
+ AspeedSoCState *soc = &bmc->soc;
35
+
36
+ i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 15), "tmp105", 0x4d);
37
+}
38
+
39
static bool aspeed_get_mmio_exec(Object *obj, Error **errp)
40
{
41
return ASPEED_MACHINE(obj)->mmio_exec;
42
@@ -XXX,XX +XXX,XX @@ static void aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
43
amc->macs_mask = 0;
44
}
45
46
+static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass *oc,
47
+ void *data)
48
+{
49
+ MachineClass *mc = MACHINE_CLASS(oc);
50
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
51
+
52
+ mc->desc = "Qualcomm DC-SCM V1 BMC (Cortex A7)";
53
+ amc->soc_name = "ast2600-a3";
54
+ amc->hw_strap1 = QCOM_DC_SCM_V1_BMC_HW_STRAP1;
55
+ amc->hw_strap2 = QCOM_DC_SCM_V1_BMC_HW_STRAP2;
56
+ amc->fmc_model = "n25q512a";
57
+ amc->spi_model = "n25q512a";
58
+ amc->num_cs = 2;
59
+ amc->macs_mask = ASPEED_MAC2_ON | ASPEED_MAC3_ON;
60
+ amc->i2c_init = qcom_dc_scm_bmc_i2c_init;
61
+ mc->default_ram_size = 1 * GiB;
62
+ mc->default_cpus = mc->min_cpus = mc->max_cpus =
63
+ aspeed_soc_num_cpus(amc->soc_name);
64
+};
65
+
66
static const TypeInfo aspeed_machine_types[] = {
67
{
68
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
69
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
70
.name = MACHINE_TYPE_NAME("g220a-bmc"),
71
.parent = TYPE_ASPEED_MACHINE,
72
.class_init = aspeed_machine_g220a_class_init,
73
+ }, {
74
+ .name = MACHINE_TYPE_NAME("qcom-dc-scm-v1-bmc"),
75
+ .parent = TYPE_ASPEED_MACHINE,
76
+ .class_init = aspeed_machine_qcom_dc_scm_v1_class_init,
77
}, {
78
.name = MACHINE_TYPE_NAME("fp5280g2-bmc"),
79
.parent = TYPE_ASPEED_MACHINE,
80
--
81
2.35.3
82
83
diff view generated by jsdifflib
Deleted patch
1
From: Graeme Gregory <quic_ggregory@quicinc.com>
2
1
3
Add base for Qualcomm Firework BMC machine.
4
5
Signed-off-by: Graeme Gregory <quic_ggregory@quicinc.com>
6
Signed-off-by: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-Id: <20220627154703.148943-3-quic_jaehyoo@quicinc.com>
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
---
11
hw/arm/aspeed.c | 34 ++++++++++++++++++++++++++++++++++
12
1 file changed, 34 insertions(+)
13
14
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/aspeed.c
17
+++ b/hw/arm/aspeed.c
18
@@ -XXX,XX +XXX,XX @@ static void qcom_dc_scm_bmc_i2c_init(AspeedMachineState *bmc)
19
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 15), "tmp105", 0x4d);
20
}
21
22
+static void qcom_dc_scm_firework_i2c_init(AspeedMachineState *bmc)
23
+{
24
+ AspeedSoCState *soc = &bmc->soc;
25
+
26
+ /* Create the generic DC-SCM hardware */
27
+ qcom_dc_scm_bmc_i2c_init(bmc);
28
+
29
+ /* Now create the Firework specific hardware */
30
+}
31
+
32
static bool aspeed_get_mmio_exec(Object *obj, Error **errp)
33
{
34
return ASPEED_MACHINE(obj)->mmio_exec;
35
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass *oc,
36
aspeed_soc_num_cpus(amc->soc_name);
37
};
38
39
+static void aspeed_machine_qcom_firework_class_init(ObjectClass *oc,
40
+ void *data)
41
+{
42
+ MachineClass *mc = MACHINE_CLASS(oc);
43
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
44
+
45
+ mc->desc = "Qualcomm DC-SCM V1/Firework BMC (Cortex A7)";
46
+ amc->soc_name = "ast2600-a3";
47
+ amc->hw_strap1 = QCOM_DC_SCM_V1_BMC_HW_STRAP1;
48
+ amc->hw_strap2 = QCOM_DC_SCM_V1_BMC_HW_STRAP2;
49
+ amc->fmc_model = "n25q512a";
50
+ amc->spi_model = "n25q512a";
51
+ amc->num_cs = 2;
52
+ amc->macs_mask = ASPEED_MAC2_ON | ASPEED_MAC3_ON;
53
+ amc->i2c_init = qcom_dc_scm_firework_i2c_init;
54
+ mc->default_ram_size = 1 * GiB;
55
+ mc->default_cpus = mc->min_cpus = mc->max_cpus =
56
+ aspeed_soc_num_cpus(amc->soc_name);
57
+};
58
+
59
static const TypeInfo aspeed_machine_types[] = {
60
{
61
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
62
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
63
.name = MACHINE_TYPE_NAME("qcom-dc-scm-v1-bmc"),
64
.parent = TYPE_ASPEED_MACHINE,
65
.class_init = aspeed_machine_qcom_dc_scm_v1_class_init,
66
+ }, {
67
+ .name = MACHINE_TYPE_NAME("qcom-firework-bmc"),
68
+ .parent = TYPE_ASPEED_MACHINE,
69
+ .class_init = aspeed_machine_qcom_firework_class_init,
70
}, {
71
.name = MACHINE_TYPE_NAME("fp5280g2-bmc"),
72
.parent = TYPE_ASPEED_MACHINE,
73
--
74
2.35.3
75
76
diff view generated by jsdifflib
Deleted patch
1
From: Maheswara Kurapati <quic_mkurapat@quicinc.com>
2
1
3
Current implementation of the pmbus core driver treats the read request
4
for page 255 as invalid request and sets the invalid command bit (bit 7)
5
in the STATUS_CML register. As per the PMBus specification it is a valid
6
request.
7
8
Refer to the PMBus specification, revision 1.3.1, section 11.10 PAGE,
9
on the page 58:
10
"Setting the PAGE to FFh means that all subsequent comands are to be
11
applied to all outputs.
12
13
Some commands, such as READ_TEMPERATURE, may use a common sensor but
14
be available on all pages of a device. Such implementations are the
15
decision of each device manufacturer or are specified in a PMBus
16
Application Profile. Consult the manufacturer's documents or the
17
Application Profile Specification as needed."
18
19
For e.g.,
20
The VOUT_MODE is a valid command for page 255 for maxim 31785 device.
21
refer to Table 1. PMBus Command Codes on page 14 in the datasheet.
22
https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf
23
24
Fixes: 38870253f1d1 ("hw/i2c: pmbus: fix error returns and guard against out of range accesses")
25
26
Signed-off-by: Maheswara Kurapati <quic_mkurapat@quicinc.com>
27
Signed-off-by: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
28
Reviewed-by: Titus Rwantare <titusr@google.com>
29
Reviewed-by: Cédric Le Goater <clg@kaod.org>
30
Message-Id: <20220627154703.148943-4-quic_jaehyoo@quicinc.com>
31
Signed-off-by: Cédric Le Goater <clg@kaod.org>
32
---
33
hw/i2c/pmbus_device.c | 6 +-----
34
1 file changed, 1 insertion(+), 5 deletions(-)
35
36
diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/i2c/pmbus_device.c
39
+++ b/hw/i2c/pmbus_device.c
40
@@ -XXX,XX +XXX,XX @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
41
42
/*
43
* Reading from all pages will return the value from page 0,
44
- * this is unspecified behaviour in general.
45
+ * means that all subsequent commands are to be applied to all output.
46
*/
47
if (pmdev->page == PB_ALL_PAGES) {
48
index = 0;
49
- qemu_log_mask(LOG_GUEST_ERROR,
50
- "%s: tried to read from all pages\n",
51
- __func__);
52
- pmbus_cml_error(pmdev);
53
} else if (pmdev->page > pmdev->num_pages - 1) {
54
qemu_log_mask(LOG_GUEST_ERROR,
55
"%s: page %d is out of range\n",
56
--
57
2.35.3
58
59
diff view generated by jsdifflib
Deleted patch
1
From: Maheswara Kurapati <quic_mkurapat@quicinc.com>
2
1
3
MAX31785 is a PMBus compliant 6-Channel fan controller. It supports 6 fan
4
channels, 11 temperature sensors, and 6-Channel ADC to measure the remote
5
voltages. Datasheet can be found here:
6
https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf
7
8
This initial version of the driver has skeleton and support for the
9
fan channels. Requests for temperature sensors, and ADC Channels the
10
are serviced with the default values as per the datasheet. No additional
11
instrumentation is done. NV Log feature is not supported.
12
13
Signed-off-by: Maheswara Kurapati <quic_mkurapat@quicinc.com>
14
Signed-off-by: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
15
Reviewed-by: Joel Stanley <joel@jms.id.au>
16
Reviewed-by: Cédric Le Goater <clg@kaod.org>
17
Message-Id: <20220627154703.148943-5-quic_jaehyoo@quicinc.com>
18
Signed-off-by: Cédric Le Goater <clg@kaod.org>
19
---
20
hw/sensor/max31785.c | 573 ++++++++++++++++++++++++++++++++++++++++++
21
hw/sensor/Kconfig | 4 +
22
hw/sensor/meson.build | 1 +
23
3 files changed, 578 insertions(+)
24
create mode 100644 hw/sensor/max31785.c
25
26
diff --git a/hw/sensor/max31785.c b/hw/sensor/max31785.c
27
new file mode 100644
28
index XXXXXXX..XXXXXXX
29
--- /dev/null
30
+++ b/hw/sensor/max31785.c
31
@@ -XXX,XX +XXX,XX @@
32
+// SPDX-License-Identifier: GPL-2.0-or-later
33
+/*
34
+ * Maxim MAX31785 PMBus 6-Channel Fan Controller
35
+ *
36
+ * Datasheet:
37
+ * https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf
38
+ *
39
+ * Copyright(c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
40
+ */
41
+
42
+#include "qemu/osdep.h"
43
+#include "hw/i2c/pmbus_device.h"
44
+#include "hw/irq.h"
45
+#include "migration/vmstate.h"
46
+#include "qapi/error.h"
47
+#include "qapi/visitor.h"
48
+#include "qemu/log.h"
49
+#include "qemu/module.h"
50
+
51
+#define TYPE_MAX31785 "max31785"
52
+#define MAX31785(obj) OBJECT_CHECK(MAX31785State, (obj), TYPE_MAX31785)
53
+
54
+/* MAX31785 mfr specific PMBus commands */
55
+#define MAX31785_MFR_MODE 0xD1
56
+#define MAX31785_MFR_PSEN_CONFIG 0xD2
57
+#define MAX31785_MFR_VOUT_PEAK 0xD4
58
+#define MAX31785_MFR_TEMPERATURE_PEAK 0xD6
59
+#define MAX31785_MFR_VOUT_MIN 0xD7
60
+#define MAX31785_MFR_FAULT_RESPONSE 0xD9
61
+#define MAX31785_MFR_NV_FAULT_LOG 0xDC
62
+#define MAX31785_MFR_TIME_COUNT 0xDD
63
+#define MAX31785_MFR_TEMP_SENSOR_CONFIG 0xF0
64
+#define MAX31785_MFR_FAN_CONFIG 0xF1
65
+#define MAX31785_MFR_FAN_LUT 0xF2
66
+#define MAX31785_MFR_READ_FAN_PWM 0xF3
67
+#define MAX31785_MFR_FAN_FAULT_LIMIT 0xF5
68
+#define MAX31785_MFR_FAN_WARN_LIMIT 0xF6
69
+#define MAX31785_MFR_FAN_RUN_TIME 0xF7
70
+#define MAX31785_MFR_FAN_PWM_AVG 0xF8
71
+#define MAX31785_MFR_FAN_PWM2RPM 0xF9
72
+
73
+/* defaults as per the data sheet */
74
+#define MAX31785_DEFAULT_CAPABILITY 0x10
75
+#define MAX31785_DEFAULT_VOUT_MODE 0x40
76
+#define MAX31785_DEFAULT_VOUT_SCALE_MONITOR 0x7FFF
77
+#define MAX31785_DEFAULT_FAN_COMMAND_1 0x7FFF
78
+#define MAX31785_DEFAULT_OV_FAULT_LIMIT 0x7FFF
79
+#define MAX31785_DEFAULT_OV_WARN_LIMIT 0x7FFF
80
+#define MAX31785_DEFAULT_OT_FAULT_LIMIT 0x7FFF
81
+#define MAX31785_DEFAULT_OT_WARN_LIMIT 0x7FFF
82
+#define MAX31785_DEFAULT_PMBUS_REVISION 0x11
83
+#define MAX31785_DEFAULT_MFR_ID 0x4D
84
+#define MAX31785_DEFAULT_MFR_MODEL 0x53
85
+#define MAX31785_DEFAULT_MFR_REVISION 0x3030
86
+#define MAX31785A_DEFAULT_MFR_REVISION 0x3040
87
+#define MAX31785B_DEFAULT_MFR_REVISION 0x3061
88
+#define MAX31785B_DEFAULT_MFR_TEMPERATURE_PEAK 0x8000
89
+#define MAX31785B_DEFAULT_MFR_VOUT_MIN 0x7FFF
90
+#define MAX31785_DEFAULT_TEXT 0x3130313031303130
91
+
92
+/* MAX31785 pages */
93
+#define MAX31785_TOTAL_NUM_PAGES 23
94
+#define MAX31785_FAN_PAGES 6
95
+#define MAX31785_MIN_FAN_PAGE 0
96
+#define MAX31785_MAX_FAN_PAGE 5
97
+#define MAX31785_MIN_TEMP_PAGE 6
98
+#define MAX31785_MAX_TEMP_PAGE 16
99
+#define MAX31785_MIN_ADC_VOLTAGE_PAGE 17
100
+#define MAX31785_MAX_ADC_VOLTAGE_PAGE 22
101
+
102
+/* FAN_CONFIG_1_2 */
103
+#define MAX31785_MFR_FAN_CONFIG 0xF1
104
+#define MAX31785_FAN_CONFIG_ENABLE BIT(7)
105
+#define MAX31785_FAN_CONFIG_RPM_PWM BIT(6)
106
+#define MAX31785_FAN_CONFIG_PULSE(pulse) (pulse << 4)
107
+#define MAX31785_DEFAULT_FAN_CONFIG_1_2(pulse) \
108
+ (MAX31785_FAN_CONFIG_ENABLE | MAX31785_FAN_CONFIG_PULSE(pulse))
109
+#define MAX31785_DEFAULT_MFR_FAN_CONFIG 0x0000
110
+
111
+/* fan speed in RPM */
112
+#define MAX31785_DEFAULT_FAN_SPEED 0x7fff
113
+#define MAX31785_DEFAULT_FAN_STATUS 0x00
114
+
115
+#define MAX31785_DEFAULT_FAN_MAX_PWM 0x2710
116
+
117
+/*
118
+ * MAX31785State:
119
+ * @code: The command code received
120
+ * @page: Each page corresponds to a device monitored by the Max 31785
121
+ * The page register determines the available commands depending on device
122
+ * _____________________________________________________________________________
123
+ * | 0 | Fan Connected to PWM0 |
124
+ * |_______|___________________________________________________________________|
125
+ * | 1 | Fan Connected to PWM1 |
126
+ * |_______|___________________________________________________________________|
127
+ * | 2 | Fan Connected to PWM2 |
128
+ * |_______|___________________________________________________________________|
129
+ * | 3 | Fan Connected to PWM3 |
130
+ * |_______|___________________________________________________________________|
131
+ * | 4 | Fan Connected to PWM4 |
132
+ * |_______|___________________________________________________________________|
133
+ * | 5 | Fan Connected to PWM5 |
134
+ * |_______|___________________________________________________________________|
135
+ * | 6 | Remote Thermal Diode Connected to ADC 0 |
136
+ * |_______|___________________________________________________________________|
137
+ * | 7 | Remote Thermal Diode Connected to ADC 1 |
138
+ * |_______|___________________________________________________________________|
139
+ * | 8 | Remote Thermal Diode Connected to ADC 2 |
140
+ * |_______|___________________________________________________________________|
141
+ * | 9 | Remote Thermal Diode Connected to ADC 3 |
142
+ * |_______|___________________________________________________________________|
143
+ * | 10 | Remote Thermal Diode Connected to ADC 4 |
144
+ * |_______|___________________________________________________________________|
145
+ * | 11 | Remote Thermal Diode Connected to ADC 5 |
146
+ * |_______|___________________________________________________________________|
147
+ * | 12 | Internal Temperature Sensor |
148
+ * |_______|___________________________________________________________________|
149
+ * | 13 | Remote I2C Temperature Sensor with Address 0 |
150
+ * |_______|___________________________________________________________________|
151
+ * | 14 | Remote I2C Temperature Sensor with Address 1 |
152
+ * |_______|___________________________________________________________________|
153
+ * | 15 | Remote I2C Temperature Sensor with Address 2 |
154
+ * |_______|___________________________________________________________________|
155
+ * | 16 | Remote I2C Temperature Sensor with Address 3 |
156
+ * |_______|___________________________________________________________________|
157
+ * | 17 | Remote I2C Temperature Sensor with Address 4 |
158
+ * |_______|___________________________________________________________________|
159
+ * | 17 | Remote Voltage Connected to ADC0 |
160
+ * |_______|___________________________________________________________________|
161
+ * | 18 | Remote Voltage Connected to ADC1 |
162
+ * |_______|___________________________________________________________________|
163
+ * | 19 | Remote Voltage Connected to ADC2 |
164
+ * |_______|___________________________________________________________________|
165
+ * | 20 | Remote Voltage Connected to ADC3 |
166
+ * |_______|___________________________________________________________________|
167
+ * | 21 | Remote Voltage Connected to ADC4 |
168
+ * |_______|___________________________________________________________________|
169
+ * | 22 | Remote Voltage Connected to ADC5 |
170
+ * |_______|___________________________________________________________________|
171
+ * |23-254 | Reserved |
172
+ * |_______|___________________________________________________________________|
173
+ * | 255 | Applies to all pages |
174
+ * |_______|___________________________________________________________________|
175
+ */
176
+
177
+/* Place holder to save the max31785 mfr specific registers */
178
+typedef struct MAX31785State {
179
+ PMBusDevice parent;
180
+ uint16_t mfr_mode[MAX31785_TOTAL_NUM_PAGES];
181
+ uint16_t vout_peak[MAX31785_TOTAL_NUM_PAGES];
182
+ uint16_t temperature_peak[MAX31785_TOTAL_NUM_PAGES];
183
+ uint16_t vout_min[MAX31785_TOTAL_NUM_PAGES];
184
+ uint8_t fault_response[MAX31785_TOTAL_NUM_PAGES];
185
+ uint32_t time_count[MAX31785_TOTAL_NUM_PAGES];
186
+ uint16_t temp_sensor_config[MAX31785_TOTAL_NUM_PAGES];
187
+ uint16_t fan_config[MAX31785_TOTAL_NUM_PAGES];
188
+ uint16_t read_fan_pwm[MAX31785_TOTAL_NUM_PAGES];
189
+ uint16_t fan_fault_limit[MAX31785_TOTAL_NUM_PAGES];
190
+ uint16_t fan_warn_limit[MAX31785_TOTAL_NUM_PAGES];
191
+ uint16_t fan_run_time[MAX31785_TOTAL_NUM_PAGES];
192
+ uint16_t fan_pwm_avg[MAX31785_TOTAL_NUM_PAGES];
193
+ uint64_t fan_pwm2rpm[MAX31785_TOTAL_NUM_PAGES];
194
+ uint64_t mfr_location;
195
+ uint64_t mfr_date;
196
+ uint64_t mfr_serial;
197
+ uint16_t mfr_revision;
198
+} MAX31785State;
199
+
200
+static uint8_t max31785_read_byte(PMBusDevice *pmdev)
201
+{
202
+ MAX31785State *s = MAX31785(pmdev);
203
+ switch (pmdev->code) {
204
+
205
+ case PMBUS_FAN_CONFIG_1_2:
206
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
207
+ pmbus_send8(pmdev, pmdev->pages[pmdev->page].fan_config_1_2);
208
+ }
209
+ break;
210
+
211
+ case PMBUS_FAN_COMMAND_1:
212
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
213
+ pmbus_send16(pmdev, pmdev->pages[pmdev->page].fan_command_1);
214
+ }
215
+ break;
216
+
217
+ case PMBUS_READ_FAN_SPEED_1:
218
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
219
+ pmbus_send16(pmdev, pmdev->pages[pmdev->page].read_fan_speed_1);
220
+ }
221
+ break;
222
+
223
+ case PMBUS_STATUS_FANS_1_2:
224
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
225
+ pmbus_send16(pmdev, pmdev->pages[pmdev->page].status_fans_1_2);
226
+ }
227
+ break;
228
+
229
+ case PMBUS_MFR_REVISION:
230
+ pmbus_send16(pmdev, MAX31785_DEFAULT_MFR_REVISION);
231
+ break;
232
+
233
+ case PMBUS_MFR_ID:
234
+ pmbus_send8(pmdev, 0x4d); /* Maxim */
235
+ break;
236
+
237
+ case PMBUS_MFR_MODEL:
238
+ pmbus_send8(pmdev, 0x53);
239
+ break;
240
+
241
+ case PMBUS_MFR_LOCATION:
242
+ pmbus_send64(pmdev, s->mfr_location);
243
+ break;
244
+
245
+ case PMBUS_MFR_DATE:
246
+ pmbus_send64(pmdev, s->mfr_date);
247
+ break;
248
+
249
+ case PMBUS_MFR_SERIAL:
250
+ pmbus_send64(pmdev, s->mfr_serial);
251
+ break;
252
+
253
+ case MAX31785_MFR_MODE:
254
+ pmbus_send16(pmdev, s->mfr_mode[pmdev->page]);
255
+ break;
256
+
257
+ case MAX31785_MFR_VOUT_PEAK:
258
+ if ((pmdev->page >= MAX31785_MIN_ADC_VOLTAGE_PAGE) &&
259
+ (pmdev->page <= MAX31785_MAX_ADC_VOLTAGE_PAGE)) {
260
+ pmbus_send16(pmdev, s->vout_peak[pmdev->page]);
261
+ }
262
+ break;
263
+
264
+ case MAX31785_MFR_TEMPERATURE_PEAK:
265
+ if ((pmdev->page >= MAX31785_MIN_TEMP_PAGE) &&
266
+ (pmdev->page <= MAX31785_MAX_TEMP_PAGE)) {
267
+ pmbus_send16(pmdev, s->temperature_peak[pmdev->page]);
268
+ }
269
+ break;
270
+
271
+ case MAX31785_MFR_VOUT_MIN:
272
+ if ((pmdev->page >= MAX31785_MIN_ADC_VOLTAGE_PAGE) &&
273
+ (pmdev->page <= MAX31785_MAX_ADC_VOLTAGE_PAGE)) {
274
+ pmbus_send16(pmdev, s->vout_min[pmdev->page]);
275
+ }
276
+ break;
277
+
278
+ case MAX31785_MFR_FAULT_RESPONSE:
279
+ pmbus_send8(pmdev, s->fault_response[pmdev->page]);
280
+ break;
281
+
282
+ case MAX31785_MFR_TIME_COUNT: /* R/W 32 */
283
+ pmbus_send32(pmdev, s->time_count[pmdev->page]);
284
+ break;
285
+
286
+ case MAX31785_MFR_TEMP_SENSOR_CONFIG: /* R/W 16 */
287
+ if ((pmdev->page >= MAX31785_MIN_TEMP_PAGE) &&
288
+ (pmdev->page <= MAX31785_MAX_TEMP_PAGE)) {
289
+ pmbus_send16(pmdev, s->temp_sensor_config[pmdev->page]);
290
+ }
291
+ break;
292
+
293
+ case MAX31785_MFR_FAN_CONFIG: /* R/W 16 */
294
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
295
+ pmbus_send16(pmdev, s->fan_config[pmdev->page]);
296
+ }
297
+ break;
298
+
299
+ case MAX31785_MFR_READ_FAN_PWM: /* R/W 16 */
300
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
301
+ pmbus_send16(pmdev, s->read_fan_pwm[pmdev->page]);
302
+ }
303
+ break;
304
+
305
+ case MAX31785_MFR_FAN_FAULT_LIMIT: /* R/W 16 */
306
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
307
+ pmbus_send16(pmdev, s->fan_fault_limit[pmdev->page]);
308
+ }
309
+ break;
310
+
311
+ case MAX31785_MFR_FAN_WARN_LIMIT: /* R/W 16 */
312
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
313
+ pmbus_send16(pmdev, s->fan_warn_limit[pmdev->page]);
314
+ }
315
+ break;
316
+
317
+ case MAX31785_MFR_FAN_RUN_TIME: /* R/W 16 */
318
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
319
+ pmbus_send16(pmdev, s->fan_run_time[pmdev->page]);
320
+ }
321
+ break;
322
+
323
+ case MAX31785_MFR_FAN_PWM_AVG: /* R/W 16 */
324
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
325
+ pmbus_send16(pmdev, s->fan_pwm_avg[pmdev->page]);
326
+ }
327
+ break;
328
+
329
+ case MAX31785_MFR_FAN_PWM2RPM: /* R/W 64 */
330
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
331
+ pmbus_send64(pmdev, s->fan_pwm2rpm[pmdev->page]);
332
+ }
333
+ break;
334
+
335
+ default:
336
+ qemu_log_mask(LOG_GUEST_ERROR,
337
+ "%s: reading from unsupported register: 0x%02x\n",
338
+ __func__, pmdev->code);
339
+ break;
340
+ }
341
+
342
+ return 0xFF;
343
+}
344
+
345
+static int max31785_write_data(PMBusDevice *pmdev, const uint8_t *buf,
346
+ uint8_t len)
347
+{
348
+ MAX31785State *s = MAX31785(pmdev);
349
+ if (len == 0) {
350
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: writing empty data\n", __func__);
351
+ return -1;
352
+ }
353
+
354
+ pmdev->code = buf[0]; /* PMBus command code */
355
+
356
+ if (len == 1) {
357
+ return 0;
358
+ }
359
+
360
+ /* Exclude command code from buffer */
361
+ buf++;
362
+ len--;
363
+
364
+ switch (pmdev->code) {
365
+
366
+ case PMBUS_FAN_CONFIG_1_2:
367
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
368
+ pmdev->pages[pmdev->page].fan_config_1_2 = pmbus_receive8(pmdev);
369
+ }
370
+ break;
371
+
372
+ case PMBUS_FAN_COMMAND_1:
373
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
374
+ pmdev->pages[pmdev->page].fan_command_1 = pmbus_receive16(pmdev);
375
+ pmdev->pages[pmdev->page].read_fan_speed_1 =
376
+ ((MAX31785_DEFAULT_FAN_SPEED / MAX31785_DEFAULT_FAN_MAX_PWM) *
377
+ pmdev->pages[pmdev->page].fan_command_1);
378
+ }
379
+ break;
380
+
381
+ case PMBUS_MFR_LOCATION: /* R/W 64 */
382
+ s->mfr_location = pmbus_receive64(pmdev);
383
+ break;
384
+
385
+ case PMBUS_MFR_DATE: /* R/W 64 */
386
+ s->mfr_date = pmbus_receive64(pmdev);
387
+ break;
388
+
389
+ case PMBUS_MFR_SERIAL: /* R/W 64 */
390
+ s->mfr_serial = pmbus_receive64(pmdev);
391
+ break;
392
+
393
+ case MAX31785_MFR_MODE: /* R/W word */
394
+ s->mfr_mode[pmdev->page] = pmbus_receive16(pmdev);
395
+ break;
396
+
397
+ case MAX31785_MFR_VOUT_PEAK: /* R/W word */
398
+ if ((pmdev->page >= MAX31785_MIN_ADC_VOLTAGE_PAGE) &&
399
+ (pmdev->page <= MAX31785_MAX_ADC_VOLTAGE_PAGE)) {
400
+ s->vout_peak[pmdev->page] = pmbus_receive16(pmdev);
401
+ }
402
+ break;
403
+
404
+ case MAX31785_MFR_TEMPERATURE_PEAK: /* R/W word */
405
+ if ((pmdev->page >= 6) && (pmdev->page <= 16)) {
406
+ s->temperature_peak[pmdev->page] = pmbus_receive16(pmdev);
407
+ }
408
+ break;
409
+
410
+ case MAX31785_MFR_VOUT_MIN: /* R/W word */
411
+ if ((pmdev->page >= MAX31785_MIN_ADC_VOLTAGE_PAGE) &&
412
+ (pmdev->page <= MAX31785_MAX_ADC_VOLTAGE_PAGE)) {
413
+ s->vout_min[pmdev->page] = pmbus_receive16(pmdev);
414
+ }
415
+ break;
416
+
417
+ case MAX31785_MFR_FAULT_RESPONSE: /* R/W 8 */
418
+ s->fault_response[pmdev->page] = pmbus_receive8(pmdev);
419
+ break;
420
+
421
+ case MAX31785_MFR_TIME_COUNT: /* R/W 32 */
422
+ s->time_count[pmdev->page] = pmbus_receive32(pmdev);
423
+ break;
424
+
425
+ case MAX31785_MFR_TEMP_SENSOR_CONFIG: /* R/W 16 */
426
+ if ((pmdev->page >= MAX31785_MIN_TEMP_PAGE) &&
427
+ (pmdev->page <= MAX31785_MAX_TEMP_PAGE)) {
428
+ s->temp_sensor_config[pmdev->page] = pmbus_receive16(pmdev);
429
+ }
430
+ break;
431
+
432
+ case MAX31785_MFR_FAN_CONFIG: /* R/W 16 */
433
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
434
+ s->fan_config[pmdev->page] = pmbus_receive16(pmdev);
435
+ }
436
+ break;
437
+
438
+ case MAX31785_MFR_FAN_FAULT_LIMIT: /* R/W 16 */
439
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
440
+ s->fan_fault_limit[pmdev->page] = pmbus_receive16(pmdev);
441
+ }
442
+ break;
443
+
444
+ case MAX31785_MFR_FAN_WARN_LIMIT: /* R/W 16 */
445
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
446
+ s->fan_warn_limit[pmdev->page] = pmbus_receive16(pmdev);
447
+ }
448
+ break;
449
+
450
+ case MAX31785_MFR_FAN_RUN_TIME: /* R/W 16 */
451
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
452
+ s->fan_run_time[pmdev->page] = pmbus_receive16(pmdev);
453
+ }
454
+ break;
455
+
456
+ case MAX31785_MFR_FAN_PWM_AVG: /* R/W 16 */
457
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
458
+ s->fan_pwm_avg[pmdev->page] = pmbus_receive16(pmdev);
459
+ }
460
+ break;
461
+
462
+ case MAX31785_MFR_FAN_PWM2RPM: /* R/W 64 */
463
+ if (pmdev->page <= MAX31785_MAX_FAN_PAGE) {
464
+ s->fan_pwm2rpm[pmdev->page] = pmbus_receive64(pmdev);
465
+ }
466
+ break;
467
+
468
+ default:
469
+ qemu_log_mask(LOG_GUEST_ERROR,
470
+ "%s: writing to unsupported register: 0x%02x\n",
471
+ __func__, pmdev->code);
472
+ break;
473
+ }
474
+
475
+ return 0;
476
+}
477
+
478
+static void max31785_exit_reset(Object *obj)
479
+{
480
+ PMBusDevice *pmdev = PMBUS_DEVICE(obj);
481
+ MAX31785State *s = MAX31785(obj);
482
+
483
+ pmdev->capability = MAX31785_DEFAULT_CAPABILITY;
484
+
485
+ for (int i = MAX31785_MIN_FAN_PAGE; i <= MAX31785_MAX_FAN_PAGE; i++) {
486
+ pmdev->pages[i].vout_mode = MAX31785_DEFAULT_VOUT_MODE;
487
+ pmdev->pages[i].fan_command_1 = MAX31785_DEFAULT_FAN_COMMAND_1;
488
+ pmdev->pages[i].revision = MAX31785_DEFAULT_PMBUS_REVISION;
489
+ pmdev->pages[i].fan_config_1_2 = MAX31785_DEFAULT_FAN_CONFIG_1_2(0);
490
+ pmdev->pages[i].read_fan_speed_1 = MAX31785_DEFAULT_FAN_SPEED;
491
+ pmdev->pages[i].status_fans_1_2 = MAX31785_DEFAULT_FAN_STATUS;
492
+ }
493
+
494
+ for (int i = MAX31785_MIN_TEMP_PAGE; i <= MAX31785_MAX_TEMP_PAGE; i++) {
495
+ pmdev->pages[i].vout_mode = MAX31785_DEFAULT_VOUT_MODE;
496
+ pmdev->pages[i].revision = MAX31785_DEFAULT_PMBUS_REVISION;
497
+ pmdev->pages[i].ot_fault_limit = MAX31785_DEFAULT_OT_FAULT_LIMIT;
498
+ pmdev->pages[i].ot_warn_limit = MAX31785_DEFAULT_OT_WARN_LIMIT;
499
+ }
500
+
501
+ for (int i = MAX31785_MIN_ADC_VOLTAGE_PAGE;
502
+ i <= MAX31785_MAX_ADC_VOLTAGE_PAGE;
503
+ i++) {
504
+ pmdev->pages[i].vout_mode = MAX31785_DEFAULT_VOUT_MODE;
505
+ pmdev->pages[i].revision = MAX31785_DEFAULT_PMBUS_REVISION;
506
+ pmdev->pages[i].vout_scale_monitor =
507
+ MAX31785_DEFAULT_VOUT_SCALE_MONITOR;
508
+ pmdev->pages[i].vout_ov_fault_limit = MAX31785_DEFAULT_OV_FAULT_LIMIT;
509
+ pmdev->pages[i].vout_ov_warn_limit = MAX31785_DEFAULT_OV_WARN_LIMIT;
510
+ }
511
+
512
+ s->mfr_location = MAX31785_DEFAULT_TEXT;
513
+ s->mfr_date = MAX31785_DEFAULT_TEXT;
514
+ s->mfr_serial = MAX31785_DEFAULT_TEXT;
515
+}
516
+
517
+static const VMStateDescription vmstate_max31785 = {
518
+ .name = TYPE_MAX31785,
519
+ .version_id = 0,
520
+ .minimum_version_id = 0,
521
+ .fields = (VMStateField[]){
522
+ VMSTATE_PMBUS_DEVICE(parent, MAX31785State),
523
+ VMSTATE_UINT16_ARRAY(mfr_mode, MAX31785State,
524
+ MAX31785_TOTAL_NUM_PAGES),
525
+ VMSTATE_UINT16_ARRAY(vout_peak, MAX31785State,
526
+ MAX31785_TOTAL_NUM_PAGES),
527
+ VMSTATE_UINT16_ARRAY(temperature_peak, MAX31785State,
528
+ MAX31785_TOTAL_NUM_PAGES),
529
+ VMSTATE_UINT16_ARRAY(vout_min, MAX31785State,
530
+ MAX31785_TOTAL_NUM_PAGES),
531
+ VMSTATE_UINT8_ARRAY(fault_response, MAX31785State,
532
+ MAX31785_TOTAL_NUM_PAGES),
533
+ VMSTATE_UINT32_ARRAY(time_count, MAX31785State,
534
+ MAX31785_TOTAL_NUM_PAGES),
535
+ VMSTATE_UINT16_ARRAY(temp_sensor_config, MAX31785State,
536
+ MAX31785_TOTAL_NUM_PAGES),
537
+ VMSTATE_UINT16_ARRAY(fan_config, MAX31785State,
538
+ MAX31785_TOTAL_NUM_PAGES),
539
+ VMSTATE_UINT16_ARRAY(read_fan_pwm, MAX31785State,
540
+ MAX31785_TOTAL_NUM_PAGES),
541
+ VMSTATE_UINT16_ARRAY(fan_fault_limit, MAX31785State,
542
+ MAX31785_TOTAL_NUM_PAGES),
543
+ VMSTATE_UINT16_ARRAY(fan_warn_limit, MAX31785State,
544
+ MAX31785_TOTAL_NUM_PAGES),
545
+ VMSTATE_UINT16_ARRAY(fan_run_time, MAX31785State,
546
+ MAX31785_TOTAL_NUM_PAGES),
547
+ VMSTATE_UINT16_ARRAY(fan_pwm_avg, MAX31785State,
548
+ MAX31785_TOTAL_NUM_PAGES),
549
+ VMSTATE_UINT64_ARRAY(fan_pwm2rpm, MAX31785State,
550
+ MAX31785_TOTAL_NUM_PAGES),
551
+ VMSTATE_UINT64(mfr_location, MAX31785State),
552
+ VMSTATE_UINT64(mfr_date, MAX31785State),
553
+ VMSTATE_UINT64(mfr_serial, MAX31785State),
554
+ VMSTATE_END_OF_LIST()
555
+ }
556
+};
557
+
558
+static void max31785_init(Object *obj)
559
+{
560
+ PMBusDevice *pmdev = PMBUS_DEVICE(obj);
561
+
562
+ for (int i = MAX31785_MIN_FAN_PAGE; i <= MAX31785_MAX_FAN_PAGE; i++) {
563
+ pmbus_page_config(pmdev, i, PB_HAS_VOUT_MODE);
564
+ }
565
+
566
+ for (int i = MAX31785_MIN_TEMP_PAGE; i <= MAX31785_MAX_TEMP_PAGE; i++) {
567
+ pmbus_page_config(pmdev, i, PB_HAS_VOUT_MODE | PB_HAS_TEMPERATURE);
568
+ }
569
+
570
+ for (int i = MAX31785_MIN_ADC_VOLTAGE_PAGE;
571
+ i <= MAX31785_MAX_ADC_VOLTAGE_PAGE;
572
+ i++) {
573
+ pmbus_page_config(pmdev, i, PB_HAS_VOUT_MODE | PB_HAS_VOUT |
574
+ PB_HAS_VOUT_RATING);
575
+ }
576
+}
577
+
578
+static void max31785_class_init(ObjectClass *klass, void *data)
579
+{
580
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
581
+ DeviceClass *dc = DEVICE_CLASS(klass);
582
+ PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass);
583
+ dc->desc = "Maxim MAX31785 6-Channel Fan Controller";
584
+ dc->vmsd = &vmstate_max31785;
585
+ k->write_data = max31785_write_data;
586
+ k->receive_byte = max31785_read_byte;
587
+ k->device_num_pages = MAX31785_TOTAL_NUM_PAGES;
588
+ rc->phases.exit = max31785_exit_reset;
589
+}
590
+
591
+static const TypeInfo max31785_info = {
592
+ .name = TYPE_MAX31785,
593
+ .parent = TYPE_PMBUS_DEVICE,
594
+ .instance_size = sizeof(MAX31785State),
595
+ .instance_init = max31785_init,
596
+ .class_init = max31785_class_init,
597
+};
598
+
599
+static void max31785_register_types(void)
600
+{
601
+ type_register_static(&max31785_info);
602
+}
603
+
604
+type_init(max31785_register_types)
605
diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
606
index XXXXXXX..XXXXXXX 100644
607
--- a/hw/sensor/Kconfig
608
+++ b/hw/sensor/Kconfig
609
@@ -XXX,XX +XXX,XX @@ config LSM303DLHC_MAG
610
config ISL_PMBUS_VR
611
bool
612
depends on PMBUS
613
+
614
+config MAX31785
615
+ bool
616
+ depends on PMBUS
617
diff --git a/hw/sensor/meson.build b/hw/sensor/meson.build
618
index XXXXXXX..XXXXXXX 100644
619
--- a/hw/sensor/meson.build
620
+++ b/hw/sensor/meson.build
621
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ADM1272', if_true: files('adm1272.c'))
622
softmmu_ss.add(when: 'CONFIG_MAX34451', if_true: files('max34451.c'))
623
softmmu_ss.add(when: 'CONFIG_LSM303DLHC_MAG', if_true: files('lsm303dlhc_mag.c'))
624
softmmu_ss.add(when: 'CONFIG_ISL_PMBUS_VR', if_true: files('isl_pmbus_vr.c'))
625
+softmmu_ss.add(when: 'CONFIG_MAX31785', if_true: files('max31785.c'))
626
--
627
2.35.3
628
629
diff view generated by jsdifflib
Deleted patch
1
From: Maheswara Kurapati <quic_mkurapat@quicinc.com>
2
1
3
Add MAX31785 fan controllers in machines so that the Linux driver
4
populates the sysfs interface.
5
6
Firework has two MAX31785 Fan controllers at 0x52, and 0x54 on bus 9.
7
Witherspoon has one at 0x52 on bus 3.
8
Rainier has one at 0x52 on bus 7.
9
10
Signed-off-by: Maheswara Kurapati <quic_mkurapat@quicinc.com>
11
Signed-off-by: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
12
Reviewed-by: Cédric Le Goater <clg@kaod.org>
13
Message-Id: <20220627154703.148943-6-quic_jaehyoo@quicinc.com>
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
---
16
hw/arm/aspeed.c | 8 ++++++--
17
hw/arm/Kconfig | 2 ++
18
2 files changed, 8 insertions(+), 2 deletions(-)
19
20
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/aspeed.c
23
+++ b/hw/arm/aspeed.c
24
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedMachineState *bmc)
25
LEDState *led;
26
27
/* Bus 3: TODO bmp280@77 */
28
- /* Bus 3: TODO max31785@52 */
29
dev = DEVICE(i2c_slave_new(TYPE_PCA9552, 0x60));
30
qdev_prop_set_string(dev, "description", "pca1");
31
i2c_slave_realize_and_unref(I2C_SLAVE(dev),
32
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedMachineState *bmc)
33
qdev_get_gpio_in(DEVICE(led), 0));
34
}
35
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 3), "dps310", 0x76);
36
+ i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 3), "max31785", 0x52);
37
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), "tmp423", 0x4c);
38
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5), "tmp423", 0x4c);
39
40
@@ -XXX,XX +XXX,XX @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
41
create_pca9552(soc, 7, 0x31);
42
create_pca9552(soc, 7, 0x32);
43
create_pca9552(soc, 7, 0x33);
44
- /* Bus 7: TODO max31785@52 */
45
create_pca9552(soc, 7, 0x60);
46
create_pca9552(soc, 7, 0x61);
47
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "dps310", 0x76);
48
/* Bus 7: TODO si7021-a20@20 */
49
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), TYPE_TMP105,
50
0x48);
51
+ i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "max31785", 0x52);
52
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 7), 0x50, 64 * KiB);
53
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 7), 0x51, 64 * KiB);
54
55
@@ -XXX,XX +XXX,XX @@ static void qcom_dc_scm_firework_i2c_init(AspeedMachineState *bmc)
56
qcom_dc_scm_bmc_i2c_init(bmc);
57
58
/* Now create the Firework specific hardware */
59
+
60
+ /* I2C9 Fan Controller (MAX31785) */
61
+ i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "max31785", 0x52);
62
+ i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "max31785", 0x54);
63
}
64
65
static bool aspeed_get_mmio_exec(Object *obj, Error **errp)
66
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/Kconfig
69
+++ b/hw/arm/Kconfig
70
@@ -XXX,XX +XXX,XX @@ config ASPEED_SOC
71
select EMC141X
72
select UNIMP
73
select LED
74
+ select PMBUS
75
+ select MAX31785
76
77
config MPS2
78
bool
79
--
80
2.35.3
81
82
diff view generated by jsdifflib
Deleted patch
1
From: Maheswara Kurapati <quic_mkurapat@quicinc.com>
2
1
3
Add Thermal Diodes for Firework machine.
4
5
Signed-off-by: Maheswara Kurapati <quic_mkurapat@quicinc.com>
6
Signed-off-by: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-Id: <20220627154703.148943-7-quic_jaehyoo@quicinc.com>
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
---
11
hw/arm/aspeed.c | 10 ++++++++++
12
1 file changed, 10 insertions(+)
13
14
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/aspeed.c
17
+++ b/hw/arm/aspeed.c
18
@@ -XXX,XX +XXX,XX @@ static void qcom_dc_scm_bmc_i2c_init(AspeedMachineState *bmc)
19
static void qcom_dc_scm_firework_i2c_init(AspeedMachineState *bmc)
20
{
21
AspeedSoCState *soc = &bmc->soc;
22
+ I2CSlave *therm_mux;
23
24
/* Create the generic DC-SCM hardware */
25
qcom_dc_scm_bmc_i2c_init(bmc);
26
27
/* Now create the Firework specific hardware */
28
29
+ /* I2C8 Thermal Diodes*/
30
+ therm_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8),
31
+ "pca9548", 0x70);
32
+ i2c_slave_create_simple(pca954x_i2c_get_bus(therm_mux, 0), TYPE_LM75, 0x4C);
33
+ i2c_slave_create_simple(pca954x_i2c_get_bus(therm_mux, 1), TYPE_LM75, 0x4C);
34
+ i2c_slave_create_simple(pca954x_i2c_get_bus(therm_mux, 2), TYPE_LM75, 0x48);
35
+ i2c_slave_create_simple(pca954x_i2c_get_bus(therm_mux, 3), TYPE_LM75, 0x48);
36
+ i2c_slave_create_simple(pca954x_i2c_get_bus(therm_mux, 4), TYPE_LM75, 0x48);
37
+
38
/* I2C9 Fan Controller (MAX31785) */
39
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "max31785", 0x52);
40
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "max31785", 0x54);
41
--
42
2.35.3
43
44
diff view generated by jsdifflib
Deleted patch
1
From: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
2
1
3
Add 2-level cascaded I2C MUXes for SOC VR channels into the Firework
4
machine.
5
6
Signed-off-by: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-Id: <20220627154703.148943-8-quic_jaehyoo@quicinc.com>
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
---
11
hw/arm/aspeed.c | 10 +++++++++-
12
1 file changed, 9 insertions(+), 1 deletion(-)
13
14
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/aspeed.c
17
+++ b/hw/arm/aspeed.c
18
@@ -XXX,XX +XXX,XX @@ static void qcom_dc_scm_bmc_i2c_init(AspeedMachineState *bmc)
19
static void qcom_dc_scm_firework_i2c_init(AspeedMachineState *bmc)
20
{
21
AspeedSoCState *soc = &bmc->soc;
22
- I2CSlave *therm_mux;
23
+ I2CSlave *therm_mux, *cpuvr_mux;
24
25
/* Create the generic DC-SCM hardware */
26
qcom_dc_scm_bmc_i2c_init(bmc);
27
28
/* Now create the Firework specific hardware */
29
30
+ /* I2C7 CPUVR MUX */
31
+ cpuvr_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7),
32
+ "pca9546", 0x70);
33
+ i2c_slave_create_simple(pca954x_i2c_get_bus(cpuvr_mux, 0), "pca9548", 0x72);
34
+ i2c_slave_create_simple(pca954x_i2c_get_bus(cpuvr_mux, 1), "pca9548", 0x72);
35
+ i2c_slave_create_simple(pca954x_i2c_get_bus(cpuvr_mux, 2), "pca9548", 0x72);
36
+ i2c_slave_create_simple(pca954x_i2c_get_bus(cpuvr_mux, 3), "pca9548", 0x72);
37
+
38
/* I2C8 Thermal Diodes*/
39
therm_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8),
40
"pca9548", 0x70);
41
--
42
2.35.3
43
44
diff view generated by jsdifflib
Deleted patch
1
From: Peter Delevoryas <pdel@fb.com>
2
1
3
Very minor, doesn't effect functionality, but this is supposed to be
4
R_I2CC_FUN_CTRL (new-mode, not old-mode).
5
6
Fixes: ba2cccd64e9 ("aspeed: i2c: Add new mode support")
7
Signed-off-by: Peter Delevoryas <pdel@fb.com>
8
Message-Id: <20220630045133.32251-2-me@pjd.dev>
9
Reviewed-by: Cédric Le Goater <clg@kaod.org>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
---
12
hw/i2c/aspeed_i2c.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/aspeed_i2c.c
18
+++ b/hw/i2c/aspeed_i2c.c
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
20
__func__);
21
break;
22
}
23
- bus->regs[R_I2CD_FUN_CTRL] = value & 0x007dc3ff;
24
+ bus->regs[R_I2CC_FUN_CTRL] = value & 0x007dc3ff;
25
break;
26
case A_I2CC_AC_TIMING:
27
bus->regs[R_I2CC_AC_TIMING] = value & 0x1ffff0ff;
28
--
29
2.35.3
30
31
diff view generated by jsdifflib
Deleted patch
1
From: Peter Delevoryas <pdel@fb.com>
2
1
3
I noticed i2c rx transfers were getting shortened to "1" on Zephyr. It
4
seems to be because the Zephyr i2c driver sets the RX DMA len with the
5
RX field write-enable bit set (bit 31) to avoid a read-modify-write. [1]
6
7
/* 0x1C : I2CM Master DMA Transfer Length Register */
8
9
I think we should be checking the write-enable bits on the incoming
10
value, not checking the register array. I'm not sure we're even writing
11
the write-enable bits to the register array, actually.
12
13
[1] https://github.com/AspeedTech-BMC/zephyr/blob/db3dbcc9c52e67a47180890ac938ed380b33f91c/drivers/i2c/i2c_aspeed.c#L145-L148
14
15
Fixes: ba2cccd64e90f34 ("aspeed: i2c: Add new mode support")
16
Signed-off-by: Peter Delevoryas <pdel@fb.com>
17
Message-Id: <20220630045133.32251-3-me@pjd.dev>
18
Reviewed-by: Cédric Le Goater <clg@kaod.org>
19
Signed-off-by: Cédric Le Goater <clg@kaod.org>
20
---
21
hw/i2c/aspeed_i2c.c | 8 ++++----
22
1 file changed, 4 insertions(+), 4 deletions(-)
23
24
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/i2c/aspeed_i2c.c
27
+++ b/hw/i2c/aspeed_i2c.c
28
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
29
RX_BUF_LEN) + 1;
30
break;
31
case A_I2CM_DMA_LEN:
32
- w1t = ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, RX_BUF_LEN_W1T) ||
33
- ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, TX_BUF_LEN_W1T);
34
+ w1t = FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T) ||
35
+ FIELD_EX32(value, I2CM_DMA_LEN, TX_BUF_LEN_W1T);
36
/* If none of the w1t bits are set, just write to the reg as normal. */
37
if (!w1t) {
38
bus->regs[R_I2CM_DMA_LEN] = value;
39
break;
40
}
41
- if (ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, RX_BUF_LEN_W1T)) {
42
+ if (FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T)) {
43
ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN, RX_BUF_LEN,
44
FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN));
45
}
46
- if (ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, TX_BUF_LEN_W1T)) {
47
+ if (FIELD_EX32(value, I2CM_DMA_LEN, TX_BUF_LEN_W1T)) {
48
ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN, TX_BUF_LEN,
49
FIELD_EX32(value, I2CM_DMA_LEN, TX_BUF_LEN));
50
}
51
--
52
2.35.3
53
54
diff view generated by jsdifflib
Deleted patch
1
From: Peter Delevoryas <pdel@fb.com>
2
1
3
aspeed_i2c_bus_is_master is checking if master mode is enabled in the I2C
4
bus controller's function-control register, not that slave mode is enabled
5
or something. The error here is that the guest is trying to trigger an I2C
6
master mode command while master mode is not enabled.
7
8
Fixes: ba2cccd64e90f342 ("aspeed: i2c: Add new mode support")
9
Signed-off-by: Peter Delevoryas <pdel@fb.com>
10
Message-Id: <20220630045133.32251-4-me@pjd.dev>
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
---
14
hw/i2c/aspeed_i2c.c | 4 ++--
15
1 file changed, 2 insertions(+), 2 deletions(-)
16
17
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/i2c/aspeed_i2c.c
20
+++ b/hw/i2c/aspeed_i2c.c
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
22
}
23
24
if (!aspeed_i2c_bus_is_master(bus)) {
25
- qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
26
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Master mode is not enabled\n",
27
__func__);
28
break;
29
}
30
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_old_write(AspeedI2CBus *bus, hwaddr offset,
31
}
32
33
if (!aspeed_i2c_bus_is_master(bus)) {
34
- qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
35
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Master mode is not enabled\n",
36
__func__);
37
break;
38
}
39
--
40
2.35.3
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Klaus Jensen <k.jensen@samsung.com>
2
1
3
Allow slaves to master the bus by registering a bottom halve. If the bus
4
is busy, the bottom half is queued up. When a slave has succesfully
5
mastered the bus, the bottom half is scheduled.
6
7
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
8
[ clg : - fixed typos in commit log ]
9
Message-Id: <20220601210831.67259-4-its@irrelevant.dk>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-Id: <20220630045133.32251-5-me@pjd.dev>
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
---
14
include/hw/i2c/i2c.h | 14 ++++++++++++++
15
hw/i2c/core.c | 34 +++++++++++++++++++++++++++++++++-
16
2 files changed, 47 insertions(+), 1 deletion(-)
17
18
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/i2c/i2c.h
21
+++ b/include/hw/i2c/i2c.h
22
@@ -XXX,XX +XXX,XX @@ struct I2CNode {
23
QLIST_ENTRY(I2CNode) next;
24
};
25
26
+typedef struct I2CPendingMaster I2CPendingMaster;
27
+
28
+struct I2CPendingMaster {
29
+ QEMUBH *bh;
30
+ QSIMPLEQ_ENTRY(I2CPendingMaster) entry;
31
+};
32
+
33
typedef QLIST_HEAD(I2CNodeList, I2CNode) I2CNodeList;
34
+typedef QSIMPLEQ_HEAD(I2CPendingMasters, I2CPendingMaster) I2CPendingMasters;
35
36
struct I2CBus {
37
BusState qbus;
38
I2CNodeList current_devs;
39
+ I2CPendingMasters pending_masters;
40
uint8_t saved_address;
41
bool broadcast;
42
+
43
+ /* Set from slave currently mastering the bus. */
44
+ QEMUBH *bh;
45
};
46
47
I2CBus *i2c_init_bus(DeviceState *parent, const char *name);
48
@@ -XXX,XX +XXX,XX @@ int i2c_start_send(I2CBus *bus, uint8_t address);
49
50
void i2c_end_transfer(I2CBus *bus);
51
void i2c_nack(I2CBus *bus);
52
+void i2c_bus_master(I2CBus *bus, QEMUBH *bh);
53
+void i2c_bus_release(I2CBus *bus);
54
int i2c_send(I2CBus *bus, uint8_t data);
55
uint8_t i2c_recv(I2CBus *bus);
56
bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
57
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/i2c/core.c
60
+++ b/hw/i2c/core.c
61
@@ -XXX,XX +XXX,XX @@
62
#include "migration/vmstate.h"
63
#include "qapi/error.h"
64
#include "qemu/module.h"
65
+#include "qemu/main-loop.h"
66
#include "trace.h"
67
68
#define I2C_BROADCAST 0x00
69
@@ -XXX,XX +XXX,XX @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
70
71
bus = I2C_BUS(qbus_new(TYPE_I2C_BUS, parent, name));
72
QLIST_INIT(&bus->current_devs);
73
+ QSIMPLEQ_INIT(&bus->pending_masters);
74
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_i2c_bus, bus);
75
return bus;
76
}
77
@@ -XXX,XX +XXX,XX @@ void i2c_slave_set_address(I2CSlave *dev, uint8_t address)
78
/* Return nonzero if bus is busy. */
79
int i2c_bus_busy(I2CBus *bus)
80
{
81
- return !QLIST_EMPTY(&bus->current_devs);
82
+ return !QLIST_EMPTY(&bus->current_devs) || bus->bh;
83
}
84
85
bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
86
@@ -XXX,XX +XXX,XX @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, bool is_recv)
87
: I2C_START_SEND);
88
}
89
90
+void i2c_bus_master(I2CBus *bus, QEMUBH *bh)
91
+{
92
+ if (i2c_bus_busy(bus)) {
93
+ I2CPendingMaster *node = g_new(struct I2CPendingMaster, 1);
94
+ node->bh = bh;
95
+
96
+ QSIMPLEQ_INSERT_TAIL(&bus->pending_masters, node, entry);
97
+
98
+ return;
99
+ }
100
+
101
+ bus->bh = bh;
102
+ qemu_bh_schedule(bus->bh);
103
+}
104
+
105
+void i2c_bus_release(I2CBus *bus)
106
+{
107
+ bus->bh = NULL;
108
+}
109
+
110
int i2c_start_recv(I2CBus *bus, uint8_t address)
111
{
112
return i2c_do_start_transfer(bus, address, I2C_START_RECV);
113
@@ -XXX,XX +XXX,XX @@ void i2c_end_transfer(I2CBus *bus)
114
g_free(node);
115
}
116
bus->broadcast = false;
117
+
118
+ if (!QSIMPLEQ_EMPTY(&bus->pending_masters)) {
119
+ I2CPendingMaster *node = QSIMPLEQ_FIRST(&bus->pending_masters);
120
+ bus->bh = node->bh;
121
+
122
+ QSIMPLEQ_REMOVE_HEAD(&bus->pending_masters, entry);
123
+ g_free(node);
124
+
125
+ qemu_bh_schedule(bus->bh);
126
+ }
127
}
128
129
int i2c_send(I2CBus *bus, uint8_t data)
130
--
131
2.35.3
132
133
diff view generated by jsdifflib
Deleted patch
1
From: Klaus Jensen <k.jensen@samsung.com>
2
1
3
Add an asynchronous version of i2c_send() that requires the slave to
4
explicitly acknowledge on the bus with i2c_ack().
5
6
The current master must use the new i2c_start_send_async() to indicate
7
that it wants to do an asynchronous transfer. This allows the i2c core
8
to check if the target slave supports this or not. This approach relies
9
on adding a new enum i2c_event member, which is why a bunch of other
10
devices needs changes in their event handling switches.
11
12
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
13
Message-Id: <20220601210831.67259-5-its@irrelevant.dk>
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Message-Id: <20220630045133.32251-6-me@pjd.dev>
16
Signed-off-by: Cédric Le Goater <clg@kaod.org>
17
---
18
include/hw/i2c/i2c.h | 16 ++++++++++++++++
19
hw/arm/pxa2xx.c | 2 ++
20
hw/display/sii9022.c | 2 ++
21
hw/display/ssd0303.c | 2 ++
22
hw/i2c/core.c | 36 +++++++++++++++++++++++++++++++++++-
23
hw/i2c/smbus_slave.c | 4 ++++
24
hw/nvram/eeprom_at24c.c | 2 ++
25
hw/sensor/lsm303dlhc_mag.c | 2 ++
26
hw/i2c/trace-events | 2 ++
27
9 files changed, 67 insertions(+), 1 deletion(-)
28
29
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/i2c/i2c.h
32
+++ b/include/hw/i2c/i2c.h
33
@@ -XXX,XX +XXX,XX @@
34
enum i2c_event {
35
I2C_START_RECV,
36
I2C_START_SEND,
37
+ I2C_START_SEND_ASYNC,
38
I2C_FINISH,
39
I2C_NACK /* Masker NACKed a receive byte. */
40
};
41
@@ -XXX,XX +XXX,XX @@ struct I2CSlaveClass {
42
/* Master to slave. Returns non-zero for a NAK, 0 for success. */
43
int (*send)(I2CSlave *s, uint8_t data);
44
45
+ /* Master to slave (asynchronous). Receiving slave must call i2c_ack(). */
46
+ void (*send_async)(I2CSlave *s, uint8_t data);
47
+
48
/*
49
* Slave to master. This cannot fail, the device should always
50
* return something here.
51
@@ -XXX,XX +XXX,XX @@ int i2c_start_recv(I2CBus *bus, uint8_t address);
52
*/
53
int i2c_start_send(I2CBus *bus, uint8_t address);
54
55
+/**
56
+ * i2c_start_send_async: start an asynchronous 'send' transfer on an I2C bus.
57
+ *
58
+ * @bus: #I2CBus to be used
59
+ * @address: address of the slave
60
+ *
61
+ * Return: 0 on success, -1 on error
62
+ */
63
+int i2c_start_send_async(I2CBus *bus, uint8_t address);
64
+
65
void i2c_end_transfer(I2CBus *bus);
66
void i2c_nack(I2CBus *bus);
67
+void i2c_ack(I2CBus *bus);
68
void i2c_bus_master(I2CBus *bus, QEMUBH *bh);
69
void i2c_bus_release(I2CBus *bus);
70
int i2c_send(I2CBus *bus, uint8_t data);
71
+int i2c_send_async(I2CBus *bus, uint8_t data);
72
uint8_t i2c_recv(I2CBus *bus);
73
bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
74
I2CNodeList *current_devs);
75
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/arm/pxa2xx.c
78
+++ b/hw/arm/pxa2xx.c
79
@@ -XXX,XX +XXX,XX @@ static int pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
80
case I2C_NACK:
81
s->status |= 1 << 1;                /* set ACKNAK */
82
break;
83
+ default:
84
+ return -1;
85
}
86
pxa2xx_i2c_update(s);
87
88
diff --git a/hw/display/sii9022.c b/hw/display/sii9022.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/hw/display/sii9022.c
91
+++ b/hw/display/sii9022.c
92
@@ -XXX,XX +XXX,XX @@ static int sii9022_event(I2CSlave *i2c, enum i2c_event event)
93
break;
94
case I2C_NACK:
95
break;
96
+ default:
97
+ return -1;
98
}
99
100
return 0;
101
diff --git a/hw/display/ssd0303.c b/hw/display/ssd0303.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/hw/display/ssd0303.c
104
+++ b/hw/display/ssd0303.c
105
@@ -XXX,XX +XXX,XX @@ static int ssd0303_event(I2CSlave *i2c, enum i2c_event event)
106
case I2C_NACK:
107
/* Nothing to do. */
108
break;
109
+ default:
110
+ return -1;
111
}
112
113
return 0;
114
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/hw/i2c/core.c
117
+++ b/hw/i2c/core.c
118
@@ -XXX,XX +XXX,XX @@ static int i2c_do_start_transfer(I2CBus *bus, uint8_t address,
119
start condition. */
120
121
if (sc->event) {
122
- trace_i2c_event("start", s->address);
123
+ trace_i2c_event(event == I2C_START_SEND ? "start" : "start_async",
124
+ s->address);
125
rv = sc->event(s, event);
126
if (rv && !bus->broadcast) {
127
if (bus_scanned) {
128
@@ -XXX,XX +XXX,XX @@ int i2c_start_send(I2CBus *bus, uint8_t address)
129
return i2c_do_start_transfer(bus, address, I2C_START_SEND);
130
}
131
132
+int i2c_start_send_async(I2CBus *bus, uint8_t address)
133
+{
134
+ return i2c_do_start_transfer(bus, address, I2C_START_SEND_ASYNC);
135
+}
136
+
137
void i2c_end_transfer(I2CBus *bus)
138
{
139
I2CSlaveClass *sc;
140
@@ -XXX,XX +XXX,XX @@ int i2c_send(I2CBus *bus, uint8_t data)
141
return ret ? -1 : 0;
142
}
143
144
+int i2c_send_async(I2CBus *bus, uint8_t data)
145
+{
146
+ I2CNode *node = QLIST_FIRST(&bus->current_devs);
147
+ I2CSlave *slave = node->elt;
148
+ I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(slave);
149
+
150
+ if (!sc->send_async) {
151
+ return -1;
152
+ }
153
+
154
+ trace_i2c_send_async(slave->address, data);
155
+
156
+ sc->send_async(slave, data);
157
+
158
+ return 0;
159
+}
160
+
161
uint8_t i2c_recv(I2CBus *bus)
162
{
163
uint8_t data = 0xff;
164
@@ -XXX,XX +XXX,XX @@ void i2c_nack(I2CBus *bus)
165
}
166
}
167
168
+void i2c_ack(I2CBus *bus)
169
+{
170
+ if (!bus->bh) {
171
+ return;
172
+ }
173
+
174
+ trace_i2c_ack();
175
+
176
+ qemu_bh_schedule(bus->bh);
177
+}
178
+
179
static int i2c_slave_post_load(void *opaque, int version_id)
180
{
181
I2CSlave *dev = opaque;
182
diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/hw/i2c/smbus_slave.c
185
+++ b/hw/i2c/smbus_slave.c
186
@@ -XXX,XX +XXX,XX @@ static int smbus_i2c_event(I2CSlave *s, enum i2c_event event)
187
dev->mode = SMBUS_CONFUSED;
188
break;
189
}
190
+ break;
191
+
192
+ default:
193
+ return -1;
194
}
195
196
return 0;
197
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
198
index XXXXXXX..XXXXXXX 100644
199
--- a/hw/nvram/eeprom_at24c.c
200
+++ b/hw/nvram/eeprom_at24c.c
201
@@ -XXX,XX +XXX,XX @@ int at24c_eeprom_event(I2CSlave *s, enum i2c_event event)
202
break;
203
case I2C_NACK:
204
break;
205
+ default:
206
+ return -1;
207
}
208
return 0;
209
}
210
diff --git a/hw/sensor/lsm303dlhc_mag.c b/hw/sensor/lsm303dlhc_mag.c
211
index XXXXXXX..XXXXXXX 100644
212
--- a/hw/sensor/lsm303dlhc_mag.c
213
+++ b/hw/sensor/lsm303dlhc_mag.c
214
@@ -XXX,XX +XXX,XX @@ static int lsm303dlhc_mag_event(I2CSlave *i2c, enum i2c_event event)
215
break;
216
case I2C_NACK:
217
break;
218
+ default:
219
+ return -1;
220
}
221
222
s->len = 0;
223
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
224
index XXXXXXX..XXXXXXX 100644
225
--- a/hw/i2c/trace-events
226
+++ b/hw/i2c/trace-events
227
@@ -XXX,XX +XXX,XX @@
228
229
i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
230
i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
231
+i2c_send_async(uint8_t address, uint8_t data) "send_async(addr:0x%02x) data:0x%02x"
232
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
233
+i2c_ack(void) ""
234
235
# aspeed_i2c.c
236
237
--
238
2.35.3
239
240
diff view generated by jsdifflib
Deleted patch
1
From: Klaus Jensen <k.jensen@samsung.com>
2
1
3
Add slave mode functionality for the Aspeed I2C controller in old
4
register mode. This is implemented by realizing an I2C slave device
5
owned by the I2C controller and attached to its own bus.
6
7
The I2C slave device only implements asynchronous sends on the bus, so
8
slaves not supporting that will not be able to communicate with it.
9
10
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
11
[ clg: checkpatch fixes ]
12
Message-Id: <20220601210831.67259-6-its@irrelevant.dk>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-Id: <20220630045133.32251-7-me@pjd.dev>
15
Signed-off-by: Cédric Le Goater <clg@kaod.org>
16
---
17
include/hw/i2c/aspeed_i2c.h | 8 ++++
18
hw/i2c/aspeed_i2c.c | 89 +++++++++++++++++++++++++++++++++----
19
2 files changed, 88 insertions(+), 9 deletions(-)
20
21
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/i2c/aspeed_i2c.h
24
+++ b/include/hw/i2c/aspeed_i2c.h
25
@@ -XXX,XX +XXX,XX @@ struct AspeedI2CBus {
26
27
struct AspeedI2CState *controller;
28
29
+ /* slave mode */
30
+ I2CSlave *slave;
31
+
32
MemoryRegion mr;
33
34
I2CBus *bus;
35
@@ -XXX,XX +XXX,XX @@ struct AspeedI2CState {
36
AddressSpace dram_as;
37
};
38
39
+#define TYPE_ASPEED_I2C_BUS_SLAVE "aspeed.i2c.slave"
40
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedI2CBusSlave, ASPEED_I2C_BUS_SLAVE)
41
+struct AspeedI2CBusSlave {
42
+ I2CSlave i2c;
43
+};
44
45
struct AspeedI2CClass {
46
SysBusDeviceClass parent_class;
47
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/i2c/aspeed_i2c.c
50
+++ b/hw/i2c/aspeed_i2c.c
51
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_old_write(AspeedI2CBus *bus, hwaddr offset,
52
switch (offset) {
53
case A_I2CD_FUN_CTRL:
54
if (SHARED_FIELD_EX32(value, SLAVE_EN)) {
55
- qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
56
- __func__);
57
- break;
58
+ i2c_slave_set_address(bus->slave, bus->regs[R_I2CD_DEV_ADDR]);
59
}
60
bus->regs[R_I2CD_FUN_CTRL] = value & 0x0071C3FF;
61
break;
62
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_old_write(AspeedI2CBus *bus, hwaddr offset,
63
bus->controller->intr_status &= ~(1 << bus->id);
64
qemu_irq_lower(aic->bus_get_irq(bus));
65
}
66
- if (handle_rx && (SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CD_CMD,
67
- M_RX_CMD) ||
68
- SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CD_CMD,
69
- M_S_RX_CMD_LAST))) {
70
- aspeed_i2c_handle_rx_cmd(bus);
71
- aspeed_i2c_bus_raise_interrupt(bus);
72
+ if (handle_rx) {
73
+ if (SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CD_CMD, M_RX_CMD) ||
74
+ SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CD_CMD,
75
+ M_S_RX_CMD_LAST)) {
76
+ aspeed_i2c_handle_rx_cmd(bus);
77
+ aspeed_i2c_bus_raise_interrupt(bus);
78
+ } else if (aspeed_i2c_get_state(bus) == I2CD_STXD) {
79
+ i2c_ack(bus->bus);
80
+ }
81
}
82
break;
83
case A_I2CD_DEV_ADDR:
84
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_i2c_info = {
85
.abstract = true,
86
};
87
88
+static int aspeed_i2c_bus_slave_event(I2CSlave *slave, enum i2c_event event)
89
+{
90
+ BusState *qbus = qdev_get_parent_bus(DEVICE(slave));
91
+ AspeedI2CBus *bus = ASPEED_I2C_BUS(qbus->parent);
92
+ uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus);
93
+ uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus);
94
+ uint32_t value;
95
+
96
+ switch (event) {
97
+ case I2C_START_SEND_ASYNC:
98
+ value = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_byte_buf, TX_BUF);
99
+ SHARED_ARRAY_FIELD_DP32(bus->regs, reg_byte_buf, RX_BUF, value << 1);
100
+
101
+ ARRAY_FIELD_DP32(bus->regs, I2CD_INTR_STS, SLAVE_ADDR_RX_MATCH, 1);
102
+ SHARED_ARRAY_FIELD_DP32(bus->regs, reg_intr_sts, RX_DONE, 1);
103
+
104
+ aspeed_i2c_set_state(bus, I2CD_STXD);
105
+
106
+ break;
107
+
108
+ case I2C_FINISH:
109
+ SHARED_ARRAY_FIELD_DP32(bus->regs, reg_intr_sts, NORMAL_STOP, 1);
110
+
111
+ aspeed_i2c_set_state(bus, I2CD_IDLE);
112
+
113
+ break;
114
+
115
+ default:
116
+ return -1;
117
+ }
118
+
119
+ aspeed_i2c_bus_raise_interrupt(bus);
120
+
121
+ return 0;
122
+}
123
+
124
+static void aspeed_i2c_bus_slave_send_async(I2CSlave *slave, uint8_t data)
125
+{
126
+ BusState *qbus = qdev_get_parent_bus(DEVICE(slave));
127
+ AspeedI2CBus *bus = ASPEED_I2C_BUS(qbus->parent);
128
+ uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus);
129
+ uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus);
130
+
131
+ SHARED_ARRAY_FIELD_DP32(bus->regs, reg_byte_buf, RX_BUF, data);
132
+ SHARED_ARRAY_FIELD_DP32(bus->regs, reg_intr_sts, RX_DONE, 1);
133
+
134
+ aspeed_i2c_bus_raise_interrupt(bus);
135
+}
136
+
137
+static void aspeed_i2c_bus_slave_class_init(ObjectClass *klass, void *data)
138
+{
139
+ DeviceClass *dc = DEVICE_CLASS(klass);
140
+ I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
141
+
142
+ dc->desc = "Aspeed I2C Bus Slave";
143
+
144
+ sc->event = aspeed_i2c_bus_slave_event;
145
+ sc->send_async = aspeed_i2c_bus_slave_send_async;
146
+}
147
+
148
+static const TypeInfo aspeed_i2c_bus_slave_info = {
149
+ .name = TYPE_ASPEED_I2C_BUS_SLAVE,
150
+ .parent = TYPE_I2C_SLAVE,
151
+ .instance_size = sizeof(AspeedI2CBusSlave),
152
+ .class_init = aspeed_i2c_bus_slave_class_init,
153
+};
154
+
155
static void aspeed_i2c_bus_reset(DeviceState *dev)
156
{
157
AspeedI2CBus *s = ASPEED_I2C_BUS(dev);
158
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_realize(DeviceState *dev, Error **errp)
159
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
160
161
s->bus = i2c_init_bus(dev, name);
162
+ s->slave = i2c_slave_create_simple(s->bus, TYPE_ASPEED_I2C_BUS_SLAVE,
163
+ 0xff);
164
165
memory_region_init_io(&s->mr, OBJECT(s), &aspeed_i2c_bus_ops,
166
s, name, aic->reg_size);
167
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_1030_i2c_info = {
168
static void aspeed_i2c_register_types(void)
169
{
170
type_register_static(&aspeed_i2c_bus_info);
171
+ type_register_static(&aspeed_i2c_bus_slave_info);
172
type_register_static(&aspeed_i2c_info);
173
type_register_static(&aspeed_2400_i2c_info);
174
type_register_static(&aspeed_2500_i2c_info);
175
--
176
2.35.3
177
178
diff view generated by jsdifflib
Deleted patch
1
From: Peter Delevoryas <pdel@fb.com>
2
1
3
This commit adds support for DMA RX in slave mode while using the new
4
register set in the AST2600 and AST1030. This patch also pretty much
5
assumes packet mode is enabled, I'm not sure if this will work in DMA
6
step mode.
7
8
This is particularly useful for testing IPMB exchanges between Zephyr
9
and external devices, which requires multi-master I2C support and DMA in
10
the new register mode, because the Zephyr drivers from Aspeed use DMA in
11
the new mode by default. The Zephyr drivers are also using packet mode.
12
13
The typical sequence of events for receiving data in DMA slave + packet
14
mode is that the Zephyr firmware will configure the slave address
15
register with an address to receive on and configure the bus's function
16
control register to enable master mode and slave mode simultaneously at
17
startup, before any transfers are initiated.
18
19
RX DMA is enabled in the slave mode command register, and the slave RX
20
DMA buffer address and slave RX DMA buffer length are set. TX DMA is not
21
covered in this patch.
22
23
When the Aspeed I2C controller receives data from some other I2C master,
24
it will reset the I2CS_DMA_LEN RX_LEN value to zero, then buffer
25
incoming data in the RX DMA buffer while incrementing the I2CC_DMA_ADDR
26
address counter and decrementing the I2CC_DMA_LEN counter. It will also
27
update the I2CS_DMA_LEN RX_LEN value along the way.
28
29
Once all the data has been received, the bus controller will raise an
30
interrupt indicating a packet command was completed, the slave address
31
matched, a normal stop condition was seen, and the transfer was an RX
32
operation.
33
34
If the master sent a NACK instead of a normal stop condition, or the
35
transfer timed out, then a slightly different set of interrupt status
36
values would be set. Those conditions are not handled in this commit.
37
38
The Zephyr firmware then collects data from the RX DMA buffer and clears
39
the status register by writing the PKT_MODE_EN bit to the status
40
register. In packet mode, clearing the packet mode interrupt enable bit
41
also clears most of the other interrupt bits automatically (except for a
42
few bits above it).
43
44
Note: if the master transmit or receive functions were in use
45
simultaneously with the slave mode receive functionality, then the
46
master mode functions may have raised the interrupt line for the bus
47
before the DMA slave transfer is complete. It's important to have the
48
slave's interrupt status register clear throughout the receive
49
operation, and if the slave attempts to raise the interrupt before the
50
master interrupt status is cleared, then it needs to re-raise the
51
interrupt once the master interrupt status is cleared. (And vice-versa).
52
That's why in this commit, when the master interrupt status is cleared
53
and the interrupt line is lowered, we call the slave interrupt _raise_
54
function, to see if the interrupt was pending. (And again, vice-versa).
55
56
Signed-off-by: Peter Delevoryas <pdel@fb.com>
57
Message-Id: <20220630045133.32251-8-me@pjd.dev>
58
Signed-off-by: Cédric Le Goater <clg@kaod.org>
59
---
60
include/hw/i2c/aspeed_i2c.h | 3 +
61
hw/i2c/aspeed_i2c.c | 133 ++++++++++++++++++++++++++++++++----
62
2 files changed, 124 insertions(+), 12 deletions(-)
63
64
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
65
index XXXXXXX..XXXXXXX 100644
66
--- a/include/hw/i2c/aspeed_i2c.h
67
+++ b/include/hw/i2c/aspeed_i2c.h
68
@@ -XXX,XX +XXX,XX @@ REG32(I2CM_DMA_LEN, 0x1c)
69
FIELD(I2CM_DMA_LEN, TX_BUF_LEN_W1T, 15, 1)
70
FIELD(I2CM_DMA_LEN, TX_BUF_LEN, 0, 11)
71
REG32(I2CS_INTR_CTRL, 0x20)
72
+ FIELD(I2CS_INTR_CTRL, PKT_CMD_FAIL, 17, 1)
73
+ FIELD(I2CS_INTR_CTRL, PKT_CMD_DONE, 16, 1)
74
REG32(I2CS_INTR_STS, 0x24)
75
/* 31:29 shared with I2CD_INTR_STS[31:29] */
76
FIELD(I2CS_INTR_STS, SLAVE_PARKING_STS, 24, 2)
77
@@ -XXX,XX +XXX,XX @@ REG32(I2CS_INTR_STS, 0x24)
78
FIELD(I2CS_INTR_STS, PKT_CMD_FAIL, 17, 1)
79
FIELD(I2CS_INTR_STS, PKT_CMD_DONE, 16, 1)
80
/* 14:0 shared with I2CD_INTR_STS[14:0] */
81
+ FIELD(I2CS_INTR_STS, SLAVE_ADDR_RX_MATCH, 7, 1)
82
REG32(I2CS_CMD, 0x28)
83
FIELD(I2CS_CMD, W1_CTRL, 31, 1)
84
FIELD(I2CS_CMD, PKT_MODE_ACTIVE_ADDR, 17, 2)
85
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/i2c/aspeed_i2c.c
88
+++ b/hw/i2c/aspeed_i2c.c
89
@@ -XXX,XX +XXX,XX @@ static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
90
}
91
}
92
93
+static inline void aspeed_i2c_bus_raise_slave_interrupt(AspeedI2CBus *bus)
94
+{
95
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
96
+
97
+ if (!bus->regs[R_I2CS_INTR_STS]) {
98
+ return;
99
+ }
100
+
101
+ bus->controller->intr_status |= 1 << bus->id;
102
+ qemu_irq_raise(aic->bus_get_irq(bus));
103
+}
104
+
105
static uint64_t aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,
106
unsigned size)
107
{
108
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_new_read(AspeedI2CBus *bus, hwaddr offset,
109
case A_I2CM_DMA_LEN_STS:
110
case A_I2CC_DMA_ADDR:
111
case A_I2CC_DMA_LEN:
112
+
113
+ case A_I2CS_DEV_ADDR:
114
+ case A_I2CS_DMA_RX_ADDR:
115
+ case A_I2CS_DMA_LEN:
116
+ case A_I2CS_CMD:
117
+ case A_I2CS_INTR_CTRL:
118
+ case A_I2CS_DMA_LEN_STS:
119
/* Value is already set, don't do anything. */
120
break;
121
+ case A_I2CS_INTR_STS:
122
+ break;
123
case A_I2CM_CMD:
124
value = SHARED_FIELD_DP32(value, BUS_BUSY_STS, i2c_bus_busy(bus->bus));
125
break;
126
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
127
128
switch (offset) {
129
case A_I2CC_FUN_CTRL:
130
- if (SHARED_FIELD_EX32(value, SLAVE_EN)) {
131
- qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
132
- __func__);
133
- break;
134
- }
135
- bus->regs[R_I2CC_FUN_CTRL] = value & 0x007dc3ff;
136
+ bus->regs[R_I2CC_FUN_CTRL] = value;
137
break;
138
case A_I2CC_AC_TIMING:
139
bus->regs[R_I2CC_AC_TIMING] = value & 0x1ffff0ff;
140
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
141
bus->controller->intr_status &= ~(1 << bus->id);
142
qemu_irq_lower(aic->bus_get_irq(bus));
143
}
144
+ aspeed_i2c_bus_raise_slave_interrupt(bus);
145
break;
146
}
147
bus->regs[R_I2CM_INTR_STS] &= ~(value & 0xf007f07f);
148
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
149
case A_I2CC_DMA_LEN:
150
/* RO */
151
break;
152
- case A_I2CS_DMA_LEN_STS:
153
- case A_I2CS_DMA_TX_ADDR:
154
- case A_I2CS_DMA_RX_ADDR:
155
case A_I2CS_DEV_ADDR:
156
+ bus->regs[R_I2CS_DEV_ADDR] = value;
157
+ break;
158
+ case A_I2CS_DMA_RX_ADDR:
159
+ bus->regs[R_I2CS_DMA_RX_ADDR] = value;
160
+ break;
161
+ case A_I2CS_DMA_LEN:
162
+ assert(FIELD_EX32(value, I2CS_DMA_LEN, TX_BUF_LEN) == 0);
163
+ if (FIELD_EX32(value, I2CS_DMA_LEN, RX_BUF_LEN_W1T)) {
164
+ ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN, RX_BUF_LEN,
165
+ FIELD_EX32(value, I2CS_DMA_LEN, RX_BUF_LEN));
166
+ } else {
167
+ bus->regs[R_I2CS_DMA_LEN] = value;
168
+ }
169
+ break;
170
+ case A_I2CS_CMD:
171
+ if (FIELD_EX32(value, I2CS_CMD, W1_CTRL)) {
172
+ bus->regs[R_I2CS_CMD] |= value;
173
+ } else {
174
+ bus->regs[R_I2CS_CMD] = value;
175
+ }
176
+ i2c_slave_set_address(bus->slave, bus->regs[R_I2CS_DEV_ADDR]);
177
+ break;
178
case A_I2CS_INTR_CTRL:
179
+ bus->regs[R_I2CS_INTR_CTRL] = value;
180
+ break;
181
+
182
case A_I2CS_INTR_STS:
183
- case A_I2CS_CMD:
184
- case A_I2CS_DMA_LEN:
185
- qemu_log_mask(LOG_UNIMP, "%s: Slave mode is not implemented\n",
186
+ if (ARRAY_FIELD_EX32(bus->regs, I2CS_INTR_CTRL, PKT_CMD_DONE)) {
187
+ if (ARRAY_FIELD_EX32(bus->regs, I2CS_INTR_STS, PKT_CMD_DONE) &&
188
+ FIELD_EX32(value, I2CS_INTR_STS, PKT_CMD_DONE)) {
189
+ bus->regs[R_I2CS_INTR_STS] &= 0xfffc0000;
190
+ }
191
+ } else {
192
+ bus->regs[R_I2CS_INTR_STS] &= ~value;
193
+ }
194
+ if (!bus->regs[R_I2CS_INTR_STS]) {
195
+ bus->controller->intr_status &= ~(1 << bus->id);
196
+ qemu_irq_lower(aic->bus_get_irq(bus));
197
+ }
198
+ aspeed_i2c_bus_raise_interrupt(bus);
199
+ break;
200
+ case A_I2CS_DMA_LEN_STS:
201
+ bus->regs[R_I2CS_DMA_LEN_STS] = 0;
202
+ break;
203
+ case A_I2CS_DMA_TX_ADDR:
204
+ qemu_log_mask(LOG_UNIMP, "%s: Slave mode DMA TX is not implemented\n",
205
__func__);
206
break;
207
default:
208
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_i2c_info = {
209
.abstract = true,
210
};
211
212
+static int aspeed_i2c_bus_new_slave_event(AspeedI2CBus *bus,
213
+ enum i2c_event event)
214
+{
215
+ switch (event) {
216
+ case I2C_START_SEND_ASYNC:
217
+ if (!SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CS_CMD, RX_DMA_EN)) {
218
+ qemu_log_mask(LOG_GUEST_ERROR,
219
+ "%s: Slave mode RX DMA is not enabled\n", __func__);
220
+ return -1;
221
+ }
222
+ ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN, 0);
223
+ bus->regs[R_I2CC_DMA_ADDR] =
224
+ ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_RX_ADDR, ADDR);
225
+ bus->regs[R_I2CC_DMA_LEN] =
226
+ ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_LEN, RX_BUF_LEN) + 1;
227
+ i2c_ack(bus->bus);
228
+ break;
229
+ case I2C_FINISH:
230
+ ARRAY_FIELD_DP32(bus->regs, I2CS_INTR_STS, PKT_CMD_DONE, 1);
231
+ ARRAY_FIELD_DP32(bus->regs, I2CS_INTR_STS, SLAVE_ADDR_RX_MATCH, 1);
232
+ SHARED_ARRAY_FIELD_DP32(bus->regs, R_I2CS_INTR_STS, NORMAL_STOP, 1);
233
+ SHARED_ARRAY_FIELD_DP32(bus->regs, R_I2CS_INTR_STS, RX_DONE, 1);
234
+ aspeed_i2c_bus_raise_slave_interrupt(bus);
235
+ break;
236
+ default:
237
+ qemu_log_mask(LOG_UNIMP, "%s: i2c event %d unimplemented\n",
238
+ __func__, event);
239
+ return -1;
240
+ }
241
+
242
+ return 0;
243
+}
244
+
245
static int aspeed_i2c_bus_slave_event(I2CSlave *slave, enum i2c_event event)
246
{
247
BusState *qbus = qdev_get_parent_bus(DEVICE(slave));
248
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_slave_event(I2CSlave *slave, enum i2c_event event)
249
uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus);
250
uint32_t value;
251
252
+ if (aspeed_i2c_is_new_mode(bus->controller)) {
253
+ return aspeed_i2c_bus_new_slave_event(bus, event);
254
+ }
255
+
256
switch (event) {
257
case I2C_START_SEND_ASYNC:
258
value = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_byte_buf, TX_BUF);
259
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_slave_event(I2CSlave *slave, enum i2c_event event)
260
return 0;
261
}
262
263
+static void aspeed_i2c_bus_new_slave_send_async(AspeedI2CBus *bus, uint8_t data)
264
+{
265
+ assert(address_space_write(&bus->controller->dram_as,
266
+ bus->regs[R_I2CC_DMA_ADDR],
267
+ MEMTXATTRS_UNSPECIFIED, &data, 1) == MEMTX_OK);
268
+
269
+ bus->regs[R_I2CC_DMA_ADDR]++;
270
+ bus->regs[R_I2CC_DMA_LEN]--;
271
+ ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN,
272
+ ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN) + 1);
273
+ i2c_ack(bus->bus);
274
+}
275
+
276
static void aspeed_i2c_bus_slave_send_async(I2CSlave *slave, uint8_t data)
277
{
278
BusState *qbus = qdev_get_parent_bus(DEVICE(slave));
279
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_slave_send_async(I2CSlave *slave, uint8_t data)
280
uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus);
281
uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus);
282
283
+ if (aspeed_i2c_is_new_mode(bus->controller)) {
284
+ return aspeed_i2c_bus_new_slave_send_async(bus, data);
285
+ }
286
+
287
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_byte_buf, RX_BUF, data);
288
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_intr_sts, RX_DONE, 1);
289
290
--
291
2.35.3
292
293
diff view generated by jsdifflib