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 |