1
The following changes since commit c09124dcb8401a0d635b4a52b295e9b3fc12392a:
1
The following changes since commit ae35f033b874c627d81d51070187fbf55f0bf1a7:
2
2
3
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2021-10-11 08:15:32 -0700)
3
Update version for v9.2.0 release (2024-12-10 16:20:54 +0000)
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-20211012
7
https://github.com/legoater/qemu/ tags/pull-aspeed-20241211
8
8
9
for you to fetch changes up to e2804a1ec97ceede14b69a2a6e9a8b5dfa0b15c2:
9
for you to fetch changes up to 124f4dc0d832c1bf3a4513c05a2b93bac0a5fac0:
10
10
11
aspeed/smc: Dump address offset in trace events (2021-10-12 08:20:08 +0200)
11
test/qtest/ast2700-smc-test: Support to test AST2700 (2024-12-11 07:25:53 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Aspeed patches :
14
aspeed queue:
15
15
16
* I2C QOMify (Cedric)
16
* Removed tacoma-bmc machine
17
* SMC model cleanup and QOMify (Cedric)
17
* Added support for SDHCI on AST2700 SoC
18
* ADC model (Peter and Andrew)
18
* Improved functional tests
19
* GPIO fixes (Peter)
19
* Extended SMC qtest to all Aspeed SoCs
20
20
21
----------------------------------------------------------------
21
----------------------------------------------------------------
22
Andrew Jeffery (2):
22
Cédric Le Goater (8):
23
hw/adc: Add basic Aspeed ADC model
23
arm: Remove tacoma-bmc machine
24
hw/arm: Integrate ADC model into Aspeed SoC
24
tests/functional: Introduce a specific test for ast1030 SoC
25
tests/functional: Introduce a specific test for palmetto-bmc machine
26
tests/functional: Introduce a specific test for romulus-bmc machine
27
tests/functional: Introduce a specific test for ast2500 SoC
28
tests/functional: Introduce a specific test for ast2600 SoC
29
tests/functional: Introduce a specific test for rainier-bmc machine
30
tests/functional: Move debian boot test from avocado
25
31
26
Cédric Le Goater (14):
32
Jamin Lin (16):
27
aspeed/smc: Add watchdog Control/Status Registers
33
hw/sd/aspeed_sdhci: Fix coding style
28
aspeed/smc: Introduce aspeed_smc_error() helper
34
hw/arm/aspeed: Fix coding style
29
aspeed/smc: Stop using the model name for the memory regions
35
hw:sdhci: Introduce a new "capareg" class member to set the different Capability Registers
30
aspeed/smc: Drop AspeedSMCController structure
36
hw/sd/aspeed_sdhci: Add AST2700 Support
31
aspeed/smc: Remove the 'flash' attribute from AspeedSMCFlash
37
aspeed/soc: Support SDHCI for AST2700
32
aspeed/smc: Remove the 'size' attribute from AspeedSMCFlash
38
aspeed/soc: Support eMMC for AST2700
33
aspeed/smc: Rename AspeedSMCFlash 'id' to 'cs'
39
test/qtest/aspeed_smc-test: Move testcases to test_palmetto_bmc function
34
aspeed/smc: QOMify AspeedSMCFlash
40
test/qtest/aspeed_smc-test: Introduce a new TestData to test different BMC SOCs
35
aspeed/smc: Add default reset values
41
test/qtest/aspeed_smc-test: Support to test all CE pins
36
aspeed/smc: Introduce a new addr_width() class handler
42
test/qtest/aspeed_smc-test: Introducing a "page_addr" data field
37
aspeed/smc: Remove unused attribute 'irqline'
43
test/qtest/aspeed_smc-test: Support to test AST2500
38
aspeed/i2c: QOMify AspeedI2CBus
44
test/qtest/aspeed_smc-test: Support to test AST2600
39
aspeed/wdt: Add trace events
45
test/qtest/aspeed_smc-test: Support to test AST1030
40
aspeed/smc: Dump address offset in trace events
46
test/qtest/aspeed_smc-test: Support write page command with QPI mode
47
test/qtest: Introduce a new aspeed-smc-utils.c to place common testcases
48
test/qtest/ast2700-smc-test: Support to test AST2700
41
49
42
Peter Delevoryas (2):
50
docs/about/deprecated.rst | 8 -
43
hw: aspeed_gpio: Fix pin I/O type declarations
51
docs/about/removed-features.rst | 10 +
44
hw: aspeed_gpio: Fix GPIO array indexing
52
docs/system/arm/aspeed.rst | 1 -
53
include/hw/sd/aspeed_sdhci.h | 13 +-
54
tests/qtest/aspeed-smc-utils.h | 95 ++++
55
hw/arm/aspeed.c | 28 -
56
hw/arm/aspeed_ast2400.c | 3 +-
57
hw/arm/aspeed_ast2600.c | 10 +-
58
hw/arm/aspeed_ast27x0.c | 35 ++
59
hw/sd/aspeed_sdhci.c | 67 ++-
60
tests/qtest/aspeed-smc-utils.c | 686 ++++++++++++++++++++++++
61
tests/qtest/aspeed_smc-test.c | 775 ++++++---------------------
62
tests/qtest/ast2700-smc-test.c | 71 +++
63
tests/avocado/boot_linux_console.py | 26 -
64
tests/functional/aspeed.py | 56 ++
65
tests/functional/meson.build | 13 +-
66
tests/functional/test_arm_aspeed.py | 351 ------------
67
tests/functional/test_arm_aspeed_ast1030.py | 81 +++
68
tests/functional/test_arm_aspeed_ast2500.py | 59 ++
69
tests/functional/test_arm_aspeed_ast2600.py | 143 +++++
70
tests/functional/test_arm_aspeed_palmetto.py | 24 +
71
tests/functional/test_arm_aspeed_rainier.py | 64 +++
72
tests/functional/test_arm_aspeed_romulus.py | 24 +
73
tests/qtest/meson.build | 5 +-
74
24 files changed, 1623 insertions(+), 1025 deletions(-)
75
create mode 100644 tests/qtest/aspeed-smc-utils.h
76
create mode 100644 tests/qtest/aspeed-smc-utils.c
77
create mode 100644 tests/qtest/ast2700-smc-test.c
78
create mode 100644 tests/functional/aspeed.py
79
delete mode 100755 tests/functional/test_arm_aspeed.py
80
create mode 100644 tests/functional/test_arm_aspeed_ast1030.py
81
create mode 100644 tests/functional/test_arm_aspeed_ast2500.py
82
create mode 100644 tests/functional/test_arm_aspeed_ast2600.py
83
create mode 100644 tests/functional/test_arm_aspeed_palmetto.py
84
create mode 100644 tests/functional/test_arm_aspeed_rainier.py
85
create mode 100644 tests/functional/test_arm_aspeed_romulus.py
45
86
46
include/hw/adc/aspeed_adc.h | 55 ++
47
include/hw/arm/aspeed_soc.h | 2 +
48
include/hw/gpio/aspeed_gpio.h | 5 +-
49
include/hw/i2c/aspeed_i2c.h | 8 +-
50
include/hw/ssi/aspeed_smc.h | 82 ++-
51
hw/adc/aspeed_adc.c | 427 ++++++++++++++++
52
hw/arm/aspeed.c | 18 +-
53
hw/arm/aspeed_ast2600.c | 22 +-
54
hw/arm/aspeed_soc.c | 15 +-
55
hw/gpio/aspeed_gpio.c | 88 ++--
56
hw/i2c/aspeed_i2c.c | 101 +++-
57
hw/ssi/aspeed_smc.c | 1134 +++++++++++++++++++++++------------------
58
hw/watchdog/wdt_aspeed.c | 5 +
59
hw/adc/meson.build | 1 +
60
hw/adc/trace-events | 3 +
61
hw/watchdog/trace-events | 4 +
62
16 files changed, 1352 insertions(+), 618 deletions(-)
63
create mode 100644 include/hw/adc/aspeed_adc.h
64
create mode 100644 hw/adc/aspeed_adc.c
65
87
diff view generated by jsdifflib
1
AspeedSMCFlash::size is only used to compute the initial size of the
1
Removal was scheduled for 10.0. Use the rainier-bmc machine or the
2
boot_rom region. Not very useful, so directly call memory_region_size()
2
ast2600-evb as a replacement.
3
instead.
4
3
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
5
Link: https://lore.kernel.org/r/20241119071352.515790-1-clg@redhat.com
6
Signed-off-by: Cédric Le Goater <clg@redhat.com>
7
---
7
---
8
include/hw/ssi/aspeed_smc.h | 1 -
8
docs/about/deprecated.rst | 8 --------
9
hw/arm/aspeed.c | 7 ++++---
9
docs/about/removed-features.rst | 10 ++++++++++
10
hw/ssi/aspeed_smc.c | 5 ++---
10
docs/system/arm/aspeed.rst | 1 -
11
3 files changed, 6 insertions(+), 7 deletions(-)
11
hw/arm/aspeed.c | 28 ----------------------------
12
4 files changed, 10 insertions(+), 37 deletions(-)
12
13
13
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
14
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/ssi/aspeed_smc.h
16
--- a/docs/about/deprecated.rst
16
+++ b/include/hw/ssi/aspeed_smc.h
17
+++ b/docs/about/deprecated.rst
17
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCFlash {
18
@@ -XXX,XX +XXX,XX @@ images are not available, OpenWRT dropped support in 2019, U-Boot in
18
struct AspeedSMCState *controller;
19
2017, Linux also is dropping support in 2024. It is time to let go of
19
20
this ancient hardware and focus on newer CPUs and platforms.
20
uint8_t id;
21
21
- uint32_t size;
22
-Arm ``tacoma-bmc`` machine (since 9.1)
22
23
-''''''''''''''''''''''''''''''''''''''''
23
MemoryRegion mmio;
24
-
24
} AspeedSMCFlash;
25
-The ``tacoma-bmc`` machine was a board including an AST2600 SoC based
26
-BMC and a witherspoon like OpenPOWER system. It was used for bring up
27
-of the AST2600 SoC in labs. It can be easily replaced by the
28
-``rainier-bmc`` machine which is a real product.
29
-
30
Big-Endian variants of MicroBlaze ``petalogix-ml605`` and ``xlnx-zynqmp-pmu`` machines (since 9.2)
31
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
32
33
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
34
index XXXXXXX..XXXXXXX 100644
35
--- a/docs/about/removed-features.rst
36
+++ b/docs/about/removed-features.rst
37
@@ -XXX,XX +XXX,XX @@ Aspeed ``swift-bmc`` machine (removed in 7.0)
38
This machine was removed because it was unused. Alternative AST2500 based
39
OpenPOWER machines are ``witherspoon-bmc`` and ``romulus-bmc``.
40
41
+Aspeed ``tacoma-bmc`` machine (removed in 10.0)
42
+'''''''''''''''''''''''''''''''''''''''''''''''
43
+
44
+The ``tacoma-bmc`` machine was removed because it didn't bring much
45
+compared to the ``rainier-bmc`` machine. Also, the ``tacoma-bmc`` was
46
+a board used for bring up of the AST2600 SoC that never left the
47
+labs. It can be easily replaced by the ``rainier-bmc`` machine, which
48
+was the actual final product, or by the ``ast2600-evb`` with some
49
+tweaks.
50
+
51
ppc ``taihu`` machine (removed in 7.2)
52
'''''''''''''''''''''''''''''''''''''''''''''
53
54
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
55
index XXXXXXX..XXXXXXX 100644
56
--- a/docs/system/arm/aspeed.rst
57
+++ b/docs/system/arm/aspeed.rst
58
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
59
AST2600 SoC based machines :
60
61
- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
62
-- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
63
- ``rainier-bmc`` IBM Rainier POWER10 BMC
64
- ``fuji-bmc`` Facebook Fuji BMC
65
- ``bletchley-bmc`` Facebook Bletchley BMC
25
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
66
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
26
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/aspeed.c
68
--- a/hw/arm/aspeed.c
28
+++ b/hw/arm/aspeed.c
69
+++ b/hw/arm/aspeed.c
29
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_init(MachineState *machine)
70
@@ -XXX,XX +XXX,XX @@ struct AspeedMachineState {
30
if (drive0) {
71
#define AST2700_EVB_HW_STRAP2 0x00000003
31
AspeedSMCFlash *fl = &bmc->soc.fmc.flashes[0];
72
#endif
32
MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
73
33
+ uint64_t size = memory_region_size(&fl->mmio);
74
-/* Tacoma hardware value */
34
75
-#define TACOMA_BMC_HW_STRAP1 0x00000000
35
/*
76
-#define TACOMA_BMC_HW_STRAP2 0x00000040
36
* create a ROM region using the default mapping window size of
77
-
37
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_init(MachineState *machine)
78
/* Rainier hardware value: (QEMU prototype) */
38
*/
79
#define RAINIER_BMC_HW_STRAP1 (0x00422016 | SCU_AST2600_HW_STRAP_BOOT_SRC_EMMC)
39
if (ASPEED_MACHINE(machine)->mmio_exec) {
80
#define RAINIER_BMC_HW_STRAP2 0x80000848
40
memory_region_init_alias(boot_rom, NULL, "aspeed.boot_rom",
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
41
- &fl->mmio, 0, fl->size);
82
aspeed_machine_ast2600_class_emmc_init(oc);
42
+ &fl->mmio, 0, size);
83
};
43
memory_region_add_subregion(get_system_memory(), FIRMWARE_ADDR,
84
44
boot_rom);
85
-static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
45
} else {
86
-{
46
memory_region_init_rom(boot_rom, NULL, "aspeed.boot_rom",
87
- MachineClass *mc = MACHINE_CLASS(oc);
47
- fl->size, &error_abort);
88
- AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
48
+ size, &error_abort);
89
-
49
memory_region_add_subregion(get_system_memory(), FIRMWARE_ADDR,
90
- mc->desc = "OpenPOWER Tacoma BMC (Cortex-A7)";
50
boot_rom);
91
- amc->soc_name = "ast2600-a3";
51
- write_boot_rom(drive0, FIRMWARE_ADDR, fl->size, &error_abort);
92
- amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
52
+ write_boot_rom(drive0, FIRMWARE_ADDR, size, &error_abort);
93
- amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
53
}
94
- amc->fmc_model = "mx66l1g45g";
54
}
95
- amc->spi_model = "mx66l1g45g";
55
96
- amc->num_cs = 2;
56
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
97
- amc->macs_mask = ASPEED_MAC2_ON;
57
index XXXXXXX..XXXXXXX 100644
98
- amc->i2c_init = witherspoon_bmc_i2c_init; /* Same board layout */
58
--- a/hw/ssi/aspeed_smc.c
99
- mc->default_ram_size = 1 * GiB;
59
+++ b/hw/ssi/aspeed_smc.c
100
- aspeed_machine_class_init_cpus_defaults(mc);
60
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
101
-
61
102
- mc->deprecation_reason = "Please use the similar 'rainier-bmc' machine";
62
fl->id = i;
103
-};
63
fl->controller = s;
104
-
64
- fl->size = asc->segments[i].size;
105
static void aspeed_machine_g220a_class_init(ObjectClass *oc, void *data)
65
memory_region_init_io(&fl->mmio, OBJECT(s), &aspeed_smc_flash_ops,
106
{
66
- fl, name, fl->size);
107
MachineClass *mc = MACHINE_CLASS(oc);
67
+ fl, name, asc->segments[i].size);
108
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
68
memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio);
109
.name = MACHINE_TYPE_NAME("yosemitev2-bmc"),
69
- offset += fl->size;
110
.parent = TYPE_ASPEED_MACHINE,
70
+ offset += asc->segments[i].size;
111
.class_init = aspeed_machine_yosemitev2_class_init,
71
}
112
- }, {
72
113
- .name = MACHINE_TYPE_NAME("tacoma-bmc"),
73
/* DMA support */
114
- .parent = TYPE_ASPEED_MACHINE,
115
- .class_init = aspeed_machine_tacoma_class_init,
116
}, {
117
.name = MACHINE_TYPE_NAME("tiogapass-bmc"),
118
.parent = TYPE_ASPEED_MACHINE,
74
--
119
--
75
2.31.1
120
2.47.1
76
121
77
122
diff view generated by jsdifflib
New patch
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
1
2
3
Fix coding style issues from checkpatch.pl.
4
5
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
6
Reviewed-by: Cédric Le Goater <clg@redhat.com>
7
Link: https://lore.kernel.org/r/20241204084453.610660-2-jamin_lin@aspeedtech.com
8
Signed-off-by: Cédric Le Goater <clg@redhat.com>
9
---
10
hw/sd/aspeed_sdhci.c | 6 ++++--
11
1 file changed, 4 insertions(+), 2 deletions(-)
12
13
diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/sd/aspeed_sdhci.c
16
+++ b/hw/sd/aspeed_sdhci.c
17
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdhci_write(void *opaque, hwaddr addr, uint64_t val,
18
sdhci->regs[TO_REG(addr)] = (uint32_t)val & ~ASPEED_SDHCI_INFO_RESET;
19
break;
20
case ASPEED_SDHCI_SDIO_140:
21
- sdhci->slots[0].capareg = deposit64(sdhci->slots[0].capareg, 0, 32, val);
22
+ sdhci->slots[0].capareg = deposit64(sdhci->slots[0].capareg,
23
+ 0, 32, val);
24
break;
25
case ASPEED_SDHCI_SDIO_144:
26
- sdhci->slots[0].capareg = deposit64(sdhci->slots[0].capareg, 32, 32, val);
27
+ sdhci->slots[0].capareg = deposit64(sdhci->slots[0].capareg,
28
+ 32, 32, val);
29
break;
30
case ASPEED_SDHCI_SDIO_148:
31
sdhci->slots[0].maxcurr = deposit64(sdhci->slots[0].maxcurr,
32
--
33
2.47.1
34
35
diff view generated by jsdifflib
1
From: Andrew Jeffery <andrew@aj.id.au>
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
2
3
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
3
Fix coding style issues from checkpatch.pl.
4
Signed-off-by: Cédric Le Goater <clg@kaod.org>
4
5
Signed-off-by: Peter Delevoryas <pdel@fb.com>
5
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
6
Message-Id: <20211005052604.1674891-3-pdel@fb.com>
6
Reviewed-by: Cédric Le Goater <clg@redhat.com>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Link: https://lore.kernel.org/r/20241204084453.610660-3-jamin_lin@aspeedtech.com
8
Signed-off-by: Cédric Le Goater <clg@redhat.com>
8
---
9
---
9
include/hw/arm/aspeed_soc.h | 2 ++
10
hw/arm/aspeed_ast2600.c | 3 ++-
10
hw/arm/aspeed_ast2600.c | 11 +++++++++++
11
1 file changed, 2 insertions(+), 1 deletion(-)
11
hw/arm/aspeed_soc.c | 11 +++++++++++
12
3 files changed, 24 insertions(+)
13
12
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/cpu/a15mpcore.h"
20
#include "hw/intc/aspeed_vic.h"
21
#include "hw/misc/aspeed_scu.h"
22
+#include "hw/adc/aspeed_adc.h"
23
#include "hw/misc/aspeed_sdmc.h"
24
#include "hw/misc/aspeed_xdma.h"
25
#include "hw/timer/aspeed_timer.h"
26
@@ -XXX,XX +XXX,XX @@ struct AspeedSoCState {
27
AspeedSCUState scu;
28
AspeedHACEState hace;
29
AspeedXDMAState xdma;
30
+ AspeedADCState adc;
31
AspeedSMCState fmc;
32
AspeedSMCState spi[ASPEED_SPIS_NUM];
33
EHCISysBusState ehci[ASPEED_EHCIS_NUM];
34
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
13
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
35
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/aspeed_ast2600.c
15
--- a/hw/arm/aspeed_ast2600.c
37
+++ b/hw/arm/aspeed_ast2600.c
16
+++ b/hw/arm/aspeed_ast2600.c
38
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
39
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
40
object_initialize_child(obj, "timerctrl", &s->timerctrl, typename);
41
42
+ snprintf(typename, sizeof(typename), "aspeed.adc-%s", socname);
43
+ object_initialize_child(obj, "adc", &s->adc, typename);
44
+
45
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
46
object_initialize_child(obj, "i2c", &s->i2c, typename);
47
48
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
49
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
18
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
19
return;
50
}
20
}
51
21
- aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]);
52
+ /* ADC */
22
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->gpio), 0,
53
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) {
23
+ sc->memmap[ASPEED_DEV_GPIO]);
54
+ return;
24
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
55
+ }
25
aspeed_soc_get_irq(s, ASPEED_DEV_GPIO));
56
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]);
26
57
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
58
+ aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
59
+
60
/* UART - attach an 8250 to the IO space as our UART */
61
serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2,
62
aspeed_soc_get_irq(s, s->uart_default), 38400,
63
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/aspeed_soc.c
66
+++ b/hw/arm/aspeed_soc.c
67
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
68
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
69
object_initialize_child(obj, "timerctrl", &s->timerctrl, typename);
70
71
+ snprintf(typename, sizeof(typename), "aspeed.adc-%s", socname);
72
+ object_initialize_child(obj, "adc", &s->adc, typename);
73
+
74
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
75
object_initialize_child(obj, "i2c", &s->i2c, typename);
76
77
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
78
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
79
}
80
81
+ /* ADC */
82
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) {
83
+ return;
84
+ }
85
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]);
86
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
87
+ aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
88
+
89
/* UART - attach an 8250 to the IO space as our UART */
90
serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2,
91
aspeed_soc_get_irq(s, s->uart_default), 38400,
92
--
27
--
93
2.31.1
28
2.47.1
94
29
95
30
diff view generated by jsdifflib
1
The characteristics of the Aspeed controllers are described in a
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
AspeedSMCController structure which is redundant with the
3
AspeedSMCClass. Move all attributes under the class and adapt the code
4
to use class attributes instead.
5
2
6
This is a large change but it is functionally equivalent.
3
Currently, it set the hardcode value of capability registers to all ASPEED SOCs
4
However, the value of capability registers should be different for all ASPEED
5
SOCs. For example: the bit 28 of the Capability Register 1 should be 1 for
6
64-bits System Bus support for AST2700.
7
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Introduce a new "capareg" class member whose data type is uint_64 to set the
9
different Capability Registers to all ASPEED SOCs.
10
11
The value of Capability Register is "0x0000000001e80080" for AST2400 and
12
AST2500. The value of Capability Register is "0x0000000701f80080" for AST2600.
13
14
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
15
Reviewed-by: Cédric Le Goater <clg@redhat.com>
16
Link: https://lore.kernel.org/r/20241204084453.610660-4-jamin_lin@aspeedtech.com
17
Signed-off-by: Cédric Le Goater <clg@redhat.com>
9
---
18
---
10
include/hw/ssi/aspeed_smc.h | 64 ++-
19
include/hw/sd/aspeed_sdhci.h | 12 +++++++--
11
hw/arm/aspeed_ast2600.c | 4 +-
20
hw/arm/aspeed_ast2400.c | 3 ++-
12
hw/arm/aspeed_soc.c | 4 +-
21
hw/arm/aspeed_ast2600.c | 7 +++---
13
hw/ssi/aspeed_smc.c | 861 ++++++++++++++++++++----------------
22
hw/sd/aspeed_sdhci.c | 47 +++++++++++++++++++++++++++++++++++-
14
4 files changed, 511 insertions(+), 422 deletions(-)
23
4 files changed, 61 insertions(+), 8 deletions(-)
15
24
16
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
25
diff --git a/include/hw/sd/aspeed_sdhci.h b/include/hw/sd/aspeed_sdhci.h
17
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/ssi/aspeed_smc.h
27
--- a/include/hw/sd/aspeed_sdhci.h
19
+++ b/include/hw/ssi/aspeed_smc.h
28
+++ b/include/hw/sd/aspeed_sdhci.h
20
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@
21
#include "hw/sysbus.h"
22
#include "qom/object.h"
30
#include "qom/object.h"
23
31
24
-typedef struct AspeedSegments {
32
#define TYPE_ASPEED_SDHCI "aspeed.sdhci"
25
- hwaddr addr;
33
-OBJECT_DECLARE_SIMPLE_TYPE(AspeedSDHCIState, ASPEED_SDHCI)
26
- uint32_t size;
34
+#define TYPE_ASPEED_2400_SDHCI TYPE_ASPEED_SDHCI "-ast2400"
27
-} AspeedSegments;
35
+#define TYPE_ASPEED_2500_SDHCI TYPE_ASPEED_SDHCI "-ast2500"
28
-
36
+#define TYPE_ASPEED_2600_SDHCI TYPE_ASPEED_SDHCI "-ast2600"
29
struct AspeedSMCState;
37
+OBJECT_DECLARE_TYPE(AspeedSDHCIState, AspeedSDHCIClass, ASPEED_SDHCI)
30
-typedef struct AspeedSMCController {
38
31
- const char *name;
39
-#define ASPEED_SDHCI_CAPABILITIES 0x01E80080
32
- uint8_t r_conf;
40
#define ASPEED_SDHCI_NUM_SLOTS 2
33
- uint8_t r_ce_ctrl;
41
#define ASPEED_SDHCI_NUM_REGS (ASPEED_SDHCI_REG_SIZE / sizeof(uint32_t))
34
- uint8_t r_ctrl0;
42
#define ASPEED_SDHCI_REG_SIZE 0x100
35
- uint8_t r_timings;
43
@@ -XXX,XX +XXX,XX @@ struct AspeedSDHCIState {
36
- uint8_t nregs_timings;
44
uint32_t regs[ASPEED_SDHCI_NUM_REGS];
37
- uint8_t conf_enable_w0;
38
- uint8_t max_peripherals;
39
- const AspeedSegments *segments;
40
- hwaddr flash_window_base;
41
- uint32_t flash_window_size;
42
- uint32_t features;
43
- hwaddr dma_flash_mask;
44
- hwaddr dma_dram_mask;
45
- uint32_t nregs;
46
- uint32_t (*segment_to_reg)(const struct AspeedSMCState *s,
47
- const AspeedSegments *seg);
48
- void (*reg_to_segment)(const struct AspeedSMCState *s, uint32_t reg,
49
- AspeedSegments *seg);
50
- void (*dma_ctrl)(struct AspeedSMCState *s, uint32_t value);
51
-} AspeedSMCController;
52
-
53
typedef struct AspeedSMCFlash {
54
struct AspeedSMCState *controller;
55
56
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCFlash {
57
#define TYPE_ASPEED_SMC "aspeed.smc"
58
OBJECT_DECLARE_TYPE(AspeedSMCState, AspeedSMCClass, ASPEED_SMC)
59
60
-struct AspeedSMCClass {
61
- SysBusDevice parent_obj;
62
- const AspeedSMCController *ctrl;
63
-};
64
-
65
#define ASPEED_SMC_R_MAX (0x100 / 4)
66
67
struct AspeedSMCState {
68
SysBusDevice parent_obj;
69
70
- const AspeedSMCController *ctrl;
71
-
72
MemoryRegion mmio;
73
MemoryRegion mmio_flash;
74
MemoryRegion mmio_flash_alias;
75
@@ -XXX,XX +XXX,XX @@ struct AspeedSMCState {
76
uint8_t snoop_dummies;
77
};
45
};
78
46
79
+typedef struct AspeedSegments {
47
+struct AspeedSDHCIClass {
80
+ hwaddr addr;
48
+ SysBusDeviceClass parent_class;
81
+ uint32_t size;
82
+} AspeedSegments;
83
+
49
+
84
+struct AspeedSMCClass {
50
+ uint64_t capareg;
85
+ SysBusDeviceClass parent_obj;
86
+
87
+ uint8_t r_conf;
88
+ uint8_t r_ce_ctrl;
89
+ uint8_t r_ctrl0;
90
+ uint8_t r_timings;
91
+ uint8_t nregs_timings;
92
+ uint8_t conf_enable_w0;
93
+ uint8_t max_peripherals;
94
+ const AspeedSegments *segments;
95
+ hwaddr flash_window_base;
96
+ uint32_t flash_window_size;
97
+ uint32_t features;
98
+ hwaddr dma_flash_mask;
99
+ hwaddr dma_dram_mask;
100
+ uint32_t nregs;
101
+ uint32_t (*segment_to_reg)(const AspeedSMCState *s,
102
+ const AspeedSegments *seg);
103
+ void (*reg_to_segment)(const AspeedSMCState *s, uint32_t reg,
104
+ AspeedSegments *seg);
105
+ void (*dma_ctrl)(AspeedSMCState *s, uint32_t value);
106
+};
51
+};
107
+
52
+
108
#endif /* ASPEED_SMC_H */
53
#endif /* ASPEED_SDHCI_H */
54
diff --git a/hw/arm/aspeed_ast2400.c b/hw/arm/aspeed_ast2400.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/aspeed_ast2400.c
57
+++ b/hw/arm/aspeed_ast2400.c
58
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2400_soc_init(Object *obj)
59
snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
60
object_initialize_child(obj, "gpio", &s->gpio, typename);
61
62
- object_initialize_child(obj, "sdc", &s->sdhci, TYPE_ASPEED_SDHCI);
63
+ snprintf(typename, sizeof(typename), "aspeed.sdhci-%s", socname);
64
+ object_initialize_child(obj, "sdc", &s->sdhci, typename);
65
66
object_property_set_int(OBJECT(&s->sdhci), "num-slots", 2, &error_abort);
67
109
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
68
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
110
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
111
--- a/hw/arm/aspeed_ast2600.c
70
--- a/hw/arm/aspeed_ast2600.c
112
+++ b/hw/arm/aspeed_ast2600.c
71
+++ b/hw/arm/aspeed_ast2600.c
113
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
72
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
73
snprintf(typename, sizeof(typename), "aspeed.gpio-%s-1_8v", socname);
74
object_initialize_child(obj, "gpio_1_8v", &s->gpio_1_8v, typename);
75
76
- object_initialize_child(obj, "sd-controller", &s->sdhci,
77
- TYPE_ASPEED_SDHCI);
78
+ snprintf(typename, sizeof(typename), "aspeed.sdhci-%s", socname);
79
+ object_initialize_child(obj, "sd-controller", &s->sdhci, typename);
80
81
object_property_set_int(OBJECT(&s->sdhci), "num-slots", 2, &error_abort);
82
83
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
84
&s->sdhci.slots[i], TYPE_SYSBUS_SDHCI);
114
}
85
}
115
sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
86
116
sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
87
- object_initialize_child(obj, "emmc-controller", &s->emmc,
117
- s->fmc.ctrl->flash_window_base);
88
- TYPE_ASPEED_SDHCI);
118
+ ASPEED_SMC_GET_CLASS(&s->fmc)->flash_window_base);
89
+ object_initialize_child(obj, "emmc-controller", &s->emmc, typename);
119
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
90
120
aspeed_soc_get_irq(s, ASPEED_DEV_FMC));
91
object_property_set_int(OBJECT(&s->emmc), "num-slots", 1, &error_abort);
121
92
122
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
93
diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c
123
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
124
sc->memmap[ASPEED_DEV_SPI1 + i]);
125
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
126
- s->spi[i].ctrl->flash_window_base);
127
+ ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
128
}
129
130
/* EHCI */
131
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
132
index XXXXXXX..XXXXXXX 100644
94
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/arm/aspeed_soc.c
95
--- a/hw/sd/aspeed_sdhci.c
134
+++ b/hw/arm/aspeed_soc.c
96
+++ b/hw/sd/aspeed_sdhci.c
135
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
97
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdhci_realize(DeviceState *dev, Error **errp)
136
}
137
sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
138
sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
139
- s->fmc.ctrl->flash_window_base);
140
+ ASPEED_SMC_GET_CLASS(&s->fmc)->flash_window_base);
141
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
142
aspeed_soc_get_irq(s, ASPEED_DEV_FMC));
143
144
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
145
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
146
sc->memmap[ASPEED_DEV_SPI1 + i]);
147
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
148
- s->spi[i].ctrl->flash_window_base);
149
+ ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
150
}
151
152
/* EHCI */
153
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/ssi/aspeed_smc.c
156
+++ b/hw/ssi/aspeed_smc.c
157
@@ -XXX,XX +XXX,XX @@
158
#define ASPEED_SMC_R_SPI_MAX (0x20 / 4)
159
#define ASPEED_SMC_R_SMC_MAX (0x20 / 4)
160
161
-#define ASPEED_SOC_SMC_FLASH_BASE 0x10000000
162
-#define ASPEED_SOC_FMC_FLASH_BASE 0x20000000
163
-#define ASPEED_SOC_SPI_FLASH_BASE 0x30000000
164
-#define ASPEED_SOC_SPI2_FLASH_BASE 0x38000000
165
-
166
/*
167
* DMA DRAM addresses should be 4 bytes aligned and the valid address
168
* range is 0x40000000 - 0x5FFFFFFF (AST2400)
169
@@ -XXX,XX +XXX,XX @@
170
* 0: 4 bytes
171
* 0x7FFFFF: 32M bytes
172
*/
173
-#define DMA_DRAM_ADDR(s, val) ((val) & (s)->ctrl->dma_dram_mask)
174
-#define DMA_FLASH_ADDR(s, val) ((val) & (s)->ctrl->dma_flash_mask)
175
+#define DMA_DRAM_ADDR(asc, val) ((val) & (asc)->dma_dram_mask)
176
+#define DMA_FLASH_ADDR(asc, val) ((val) & (asc)->dma_flash_mask)
177
#define DMA_LENGTH(val) ((val) & 0x01FFFFFC)
178
179
/* Flash opcodes. */
180
@@ -XXX,XX +XXX,XX @@
181
* controller. These can be changed when board is initialized with the
182
* Segment Address Registers.
183
*/
184
-static const AspeedSegments aspeed_segments_legacy[] = {
185
- { 0x10000000, 32 * 1024 * 1024 },
186
-};
187
-
188
-static const AspeedSegments aspeed_segments_fmc[] = {
189
- { 0x20000000, 64 * 1024 * 1024 }, /* start address is readonly */
190
- { 0x24000000, 32 * 1024 * 1024 },
191
- { 0x26000000, 32 * 1024 * 1024 },
192
- { 0x28000000, 32 * 1024 * 1024 },
193
- { 0x2A000000, 32 * 1024 * 1024 }
194
-};
195
-
196
-static const AspeedSegments aspeed_segments_spi[] = {
197
- { 0x30000000, 64 * 1024 * 1024 },
198
-};
199
-
200
-static const AspeedSegments aspeed_segments_ast2500_fmc[] = {
201
- { 0x20000000, 128 * 1024 * 1024 }, /* start address is readonly */
202
- { 0x28000000, 32 * 1024 * 1024 },
203
- { 0x2A000000, 32 * 1024 * 1024 },
204
-};
205
-
206
-static const AspeedSegments aspeed_segments_ast2500_spi1[] = {
207
- { 0x30000000, 32 * 1024 * 1024 }, /* start address is readonly */
208
- { 0x32000000, 96 * 1024 * 1024 }, /* end address is readonly */
209
-};
210
-
211
-static const AspeedSegments aspeed_segments_ast2500_spi2[] = {
212
- { 0x38000000, 32 * 1024 * 1024 }, /* start address is readonly */
213
- { 0x3A000000, 96 * 1024 * 1024 }, /* end address is readonly */
214
-};
215
-static uint32_t aspeed_smc_segment_to_reg(const AspeedSMCState *s,
216
- const AspeedSegments *seg);
217
-static void aspeed_smc_reg_to_segment(const AspeedSMCState *s, uint32_t reg,
218
- AspeedSegments *seg);
219
-static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint32_t value);
220
-
221
-/*
222
- * AST2600 definitions
223
- */
224
-#define ASPEED26_SOC_FMC_FLASH_BASE 0x20000000
225
-#define ASPEED26_SOC_SPI_FLASH_BASE 0x30000000
226
-#define ASPEED26_SOC_SPI2_FLASH_BASE 0x50000000
227
-
228
-static const AspeedSegments aspeed_segments_ast2600_fmc[] = {
229
- { 0x0, 128 * MiB }, /* start address is readonly */
230
- { 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
231
- { 0x0, 0 }, /* disabled */
232
-};
233
-
234
-static const AspeedSegments aspeed_segments_ast2600_spi1[] = {
235
- { 0x0, 128 * MiB }, /* start address is readonly */
236
- { 0x0, 0 }, /* disabled */
237
-};
238
-
239
-static const AspeedSegments aspeed_segments_ast2600_spi2[] = {
240
- { 0x0, 128 * MiB }, /* start address is readonly */
241
- { 0x0, 0 }, /* disabled */
242
- { 0x0, 0 }, /* disabled */
243
-};
244
-
245
-static uint32_t aspeed_2600_smc_segment_to_reg(const AspeedSMCState *s,
246
- const AspeedSegments *seg);
247
-static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
248
- uint32_t reg, AspeedSegments *seg);
249
-static void aspeed_2600_smc_dma_ctrl(AspeedSMCState *s, uint32_t value);
250
+static const AspeedSegments aspeed_2400_fmc_segments[];
251
+static const AspeedSegments aspeed_2400_spi1_segments[];
252
+static const AspeedSegments aspeed_2500_fmc_segments[];
253
+static const AspeedSegments aspeed_2500_spi1_segments[];
254
+static const AspeedSegments aspeed_2500_spi2_segments[];
255
+static const AspeedSegments aspeed_2600_fmc_segments[];
256
257
#define ASPEED_SMC_FEATURE_DMA 0x1
258
#define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
259
#define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
260
261
-static inline bool aspeed_smc_has_dma(const AspeedSMCState *s)
262
-{
263
- return !!(s->ctrl->features & ASPEED_SMC_FEATURE_DMA);
264
-}
265
-
266
-static inline bool aspeed_smc_has_wdt_control(const AspeedSMCState *s)
267
-{
268
- return !!(s->ctrl->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
269
-}
270
-
271
-static const AspeedSMCController controllers[] = {
272
- {
273
- .name = "aspeed.smc-ast2400",
274
- .r_conf = R_CONF,
275
- .r_ce_ctrl = R_CE_CTRL,
276
- .r_ctrl0 = R_CTRL0,
277
- .r_timings = R_TIMINGS,
278
- .nregs_timings = 1,
279
- .conf_enable_w0 = CONF_ENABLE_W0,
280
- .max_peripherals = 1,
281
- .segments = aspeed_segments_legacy,
282
- .flash_window_base = ASPEED_SOC_SMC_FLASH_BASE,
283
- .flash_window_size = 0x6000000,
284
- .features = 0x0,
285
- .nregs = ASPEED_SMC_R_SMC_MAX,
286
- .segment_to_reg = aspeed_smc_segment_to_reg,
287
- .reg_to_segment = aspeed_smc_reg_to_segment,
288
- .dma_ctrl = aspeed_smc_dma_ctrl,
289
- }, {
290
- .name = "aspeed.fmc-ast2400",
291
- .r_conf = R_CONF,
292
- .r_ce_ctrl = R_CE_CTRL,
293
- .r_ctrl0 = R_CTRL0,
294
- .r_timings = R_TIMINGS,
295
- .nregs_timings = 1,
296
- .conf_enable_w0 = CONF_ENABLE_W0,
297
- .max_peripherals = 5,
298
- .segments = aspeed_segments_fmc,
299
- .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
300
- .flash_window_size = 0x10000000,
301
- .features = ASPEED_SMC_FEATURE_DMA,
302
- .dma_flash_mask = 0x0FFFFFFC,
303
- .dma_dram_mask = 0x1FFFFFFC,
304
- .nregs = ASPEED_SMC_R_MAX,
305
- .segment_to_reg = aspeed_smc_segment_to_reg,
306
- .reg_to_segment = aspeed_smc_reg_to_segment,
307
- .dma_ctrl = aspeed_smc_dma_ctrl,
308
- }, {
309
- .name = "aspeed.spi1-ast2400",
310
- .r_conf = R_SPI_CONF,
311
- .r_ce_ctrl = 0xff,
312
- .r_ctrl0 = R_SPI_CTRL0,
313
- .r_timings = R_SPI_TIMINGS,
314
- .nregs_timings = 1,
315
- .conf_enable_w0 = SPI_CONF_ENABLE_W0,
316
- .max_peripherals = 1,
317
- .segments = aspeed_segments_spi,
318
- .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
319
- .flash_window_size = 0x10000000,
320
- .features = 0x0,
321
- .nregs = ASPEED_SMC_R_SPI_MAX,
322
- .segment_to_reg = aspeed_smc_segment_to_reg,
323
- .reg_to_segment = aspeed_smc_reg_to_segment,
324
- .dma_ctrl = aspeed_smc_dma_ctrl,
325
- }, {
326
- .name = "aspeed.fmc-ast2500",
327
- .r_conf = R_CONF,
328
- .r_ce_ctrl = R_CE_CTRL,
329
- .r_ctrl0 = R_CTRL0,
330
- .r_timings = R_TIMINGS,
331
- .nregs_timings = 1,
332
- .conf_enable_w0 = CONF_ENABLE_W0,
333
- .max_peripherals = 3,
334
- .segments = aspeed_segments_ast2500_fmc,
335
- .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
336
- .flash_window_size = 0x10000000,
337
- .features = ASPEED_SMC_FEATURE_DMA,
338
- .dma_flash_mask = 0x0FFFFFFC,
339
- .dma_dram_mask = 0x3FFFFFFC,
340
- .nregs = ASPEED_SMC_R_MAX,
341
- .segment_to_reg = aspeed_smc_segment_to_reg,
342
- .reg_to_segment = aspeed_smc_reg_to_segment,
343
- .dma_ctrl = aspeed_smc_dma_ctrl,
344
- }, {
345
- .name = "aspeed.spi1-ast2500",
346
- .r_conf = R_CONF,
347
- .r_ce_ctrl = R_CE_CTRL,
348
- .r_ctrl0 = R_CTRL0,
349
- .r_timings = R_TIMINGS,
350
- .nregs_timings = 1,
351
- .conf_enable_w0 = CONF_ENABLE_W0,
352
- .max_peripherals = 2,
353
- .segments = aspeed_segments_ast2500_spi1,
354
- .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
355
- .flash_window_size = 0x8000000,
356
- .features = 0x0,
357
- .nregs = ASPEED_SMC_R_MAX,
358
- .segment_to_reg = aspeed_smc_segment_to_reg,
359
- .reg_to_segment = aspeed_smc_reg_to_segment,
360
- .dma_ctrl = aspeed_smc_dma_ctrl,
361
- }, {
362
- .name = "aspeed.spi2-ast2500",
363
- .r_conf = R_CONF,
364
- .r_ce_ctrl = R_CE_CTRL,
365
- .r_ctrl0 = R_CTRL0,
366
- .r_timings = R_TIMINGS,
367
- .nregs_timings = 1,
368
- .conf_enable_w0 = CONF_ENABLE_W0,
369
- .max_peripherals = 2,
370
- .segments = aspeed_segments_ast2500_spi2,
371
- .flash_window_base = ASPEED_SOC_SPI2_FLASH_BASE,
372
- .flash_window_size = 0x8000000,
373
- .features = 0x0,
374
- .nregs = ASPEED_SMC_R_MAX,
375
- .segment_to_reg = aspeed_smc_segment_to_reg,
376
- .reg_to_segment = aspeed_smc_reg_to_segment,
377
- .dma_ctrl = aspeed_smc_dma_ctrl,
378
- }, {
379
- .name = "aspeed.fmc-ast2600",
380
- .r_conf = R_CONF,
381
- .r_ce_ctrl = R_CE_CTRL,
382
- .r_ctrl0 = R_CTRL0,
383
- .r_timings = R_TIMINGS,
384
- .nregs_timings = 1,
385
- .conf_enable_w0 = CONF_ENABLE_W0,
386
- .max_peripherals = 3,
387
- .segments = aspeed_segments_ast2600_fmc,
388
- .flash_window_base = ASPEED26_SOC_FMC_FLASH_BASE,
389
- .flash_window_size = 0x10000000,
390
- .features = ASPEED_SMC_FEATURE_DMA |
391
- ASPEED_SMC_FEATURE_WDT_CONTROL,
392
- .dma_flash_mask = 0x0FFFFFFC,
393
- .dma_dram_mask = 0x3FFFFFFC,
394
- .nregs = ASPEED_SMC_R_MAX,
395
- .segment_to_reg = aspeed_2600_smc_segment_to_reg,
396
- .reg_to_segment = aspeed_2600_smc_reg_to_segment,
397
- .dma_ctrl = aspeed_2600_smc_dma_ctrl,
398
- }, {
399
- .name = "aspeed.spi1-ast2600",
400
- .r_conf = R_CONF,
401
- .r_ce_ctrl = R_CE_CTRL,
402
- .r_ctrl0 = R_CTRL0,
403
- .r_timings = R_TIMINGS,
404
- .nregs_timings = 2,
405
- .conf_enable_w0 = CONF_ENABLE_W0,
406
- .max_peripherals = 2,
407
- .segments = aspeed_segments_ast2600_spi1,
408
- .flash_window_base = ASPEED26_SOC_SPI_FLASH_BASE,
409
- .flash_window_size = 0x10000000,
410
- .features = ASPEED_SMC_FEATURE_DMA |
411
- ASPEED_SMC_FEATURE_DMA_GRANT,
412
- .dma_flash_mask = 0x0FFFFFFC,
413
- .dma_dram_mask = 0x3FFFFFFC,
414
- .nregs = ASPEED_SMC_R_MAX,
415
- .segment_to_reg = aspeed_2600_smc_segment_to_reg,
416
- .reg_to_segment = aspeed_2600_smc_reg_to_segment,
417
- .dma_ctrl = aspeed_2600_smc_dma_ctrl,
418
- }, {
419
- .name = "aspeed.spi2-ast2600",
420
- .r_conf = R_CONF,
421
- .r_ce_ctrl = R_CE_CTRL,
422
- .r_ctrl0 = R_CTRL0,
423
- .r_timings = R_TIMINGS,
424
- .nregs_timings = 3,
425
- .conf_enable_w0 = CONF_ENABLE_W0,
426
- .max_peripherals = 3,
427
- .segments = aspeed_segments_ast2600_spi2,
428
- .flash_window_base = ASPEED26_SOC_SPI2_FLASH_BASE,
429
- .flash_window_size = 0x10000000,
430
- .features = ASPEED_SMC_FEATURE_DMA |
431
- ASPEED_SMC_FEATURE_DMA_GRANT,
432
- .dma_flash_mask = 0x0FFFFFFC,
433
- .dma_dram_mask = 0x3FFFFFFC,
434
- .nregs = ASPEED_SMC_R_MAX,
435
- .segment_to_reg = aspeed_2600_smc_segment_to_reg,
436
- .reg_to_segment = aspeed_2600_smc_reg_to_segment,
437
- .dma_ctrl = aspeed_2600_smc_dma_ctrl,
438
- },
439
-};
440
-
441
-/*
442
- * The Segment Registers of the AST2400 and AST2500 have a 8MB
443
- * unit. The address range of a flash SPI peripheral is encoded with
444
- * absolute addresses which should be part of the overall controller
445
- * window.
446
- */
447
-static uint32_t aspeed_smc_segment_to_reg(const AspeedSMCState *s,
448
- const AspeedSegments *seg)
449
-{
450
- uint32_t reg = 0;
451
- reg |= ((seg->addr >> 23) & SEG_START_MASK) << SEG_START_SHIFT;
452
- reg |= (((seg->addr + seg->size) >> 23) & SEG_END_MASK) << SEG_END_SHIFT;
453
- return reg;
454
-}
455
-
456
-static void aspeed_smc_reg_to_segment(const AspeedSMCState *s,
457
- uint32_t reg, AspeedSegments *seg)
458
-{
459
- seg->addr = ((reg >> SEG_START_SHIFT) & SEG_START_MASK) << 23;
460
- seg->size = (((reg >> SEG_END_SHIFT) & SEG_END_MASK) << 23) - seg->addr;
461
-}
462
-
463
-/*
464
- * The Segment Registers of the AST2600 have a 1MB unit. The address
465
- * range of a flash SPI peripheral is encoded with offsets in the overall
466
- * controller window. The previous SoC AST2400 and AST2500 used
467
- * absolute addresses. Only bits [27:20] are relevant and the end
468
- * address is an upper bound limit.
469
- */
470
-#define AST2600_SEG_ADDR_MASK 0x0ff00000
471
-
472
-static uint32_t aspeed_2600_smc_segment_to_reg(const AspeedSMCState *s,
473
- const AspeedSegments *seg)
474
+static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
475
{
476
- uint32_t reg = 0;
477
-
478
- /* Disabled segments have a nil register */
479
- if (!seg->size) {
480
- return 0;
481
- }
482
-
483
- reg |= (seg->addr & AST2600_SEG_ADDR_MASK) >> 16; /* start offset */
484
- reg |= (seg->addr + seg->size - 1) & AST2600_SEG_ADDR_MASK; /* end offset */
485
- return reg;
486
+ return !!(asc->features & ASPEED_SMC_FEATURE_DMA);
487
}
488
489
-static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
490
- uint32_t reg, AspeedSegments *seg)
491
+static inline bool aspeed_smc_has_wdt_control(const AspeedSMCClass *asc)
492
{
493
- uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
494
- uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
495
-
496
- if (reg) {
497
- seg->addr = s->ctrl->flash_window_base + start_offset;
498
- seg->size = end_offset + MiB - start_offset;
499
- } else {
500
- seg->addr = s->ctrl->flash_window_base;
501
- seg->size = 0;
502
- }
503
+ return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
504
}
505
506
#define aspeed_smc_error(fmt, ...) \
507
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
508
const AspeedSegments *new,
509
int cs)
510
{
511
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
512
AspeedSegments seg;
513
int i;
514
515
- for (i = 0; i < s->ctrl->max_peripherals; i++) {
516
+ for (i = 0; i < asc->max_peripherals; i++) {
517
if (i == cs) {
518
continue;
519
}
520
521
- s->ctrl->reg_to_segment(s, s->regs[R_SEG_ADDR0 + i], &seg);
522
+ asc->reg_to_segment(s, s->regs[R_SEG_ADDR0 + i], &seg);
523
524
if (new->addr + new->size > seg.addr &&
525
new->addr < seg.addr + seg.size) {
526
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
527
static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
528
uint64_t regval)
529
{
530
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
531
AspeedSMCFlash *fl = &s->flashes[cs];
532
AspeedSegments seg;
533
534
- s->ctrl->reg_to_segment(s, regval, &seg);
535
+ asc->reg_to_segment(s, regval, &seg);
536
537
memory_region_transaction_begin();
538
memory_region_set_size(&fl->mmio, seg.size);
539
- memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
540
+ memory_region_set_address(&fl->mmio, seg.addr - asc->flash_window_base);
541
memory_region_set_enabled(&fl->mmio, !!seg.size);
542
memory_region_transaction_commit();
543
544
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
545
static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
546
uint64_t new)
547
{
548
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
549
AspeedSegments seg;
550
551
- s->ctrl->reg_to_segment(s, new, &seg);
552
+ asc->reg_to_segment(s, new, &seg);
553
554
trace_aspeed_smc_flash_set_segment(cs, new, seg.addr, seg.addr + seg.size);
555
556
/* The start address of CS0 is read-only */
557
- if (cs == 0 && seg.addr != s->ctrl->flash_window_base) {
558
+ if (cs == 0 && seg.addr != asc->flash_window_base) {
559
aspeed_smc_error("Tried to change CS0 start address to 0x%"
560
HWADDR_PRIx, seg.addr);
561
- seg.addr = s->ctrl->flash_window_base;
562
- new = s->ctrl->segment_to_reg(s, &seg);
563
+ seg.addr = asc->flash_window_base;
564
+ new = asc->segment_to_reg(s, &seg);
565
}
566
567
/*
568
* The end address of the AST2500 spi controllers is also
569
* read-only.
570
*/
571
- if ((s->ctrl->segments == aspeed_segments_ast2500_spi1 ||
572
- s->ctrl->segments == aspeed_segments_ast2500_spi2) &&
573
- cs == s->ctrl->max_peripherals &&
574
- seg.addr + seg.size != s->ctrl->segments[cs].addr +
575
- s->ctrl->segments[cs].size) {
576
+ if ((asc->segments == aspeed_2500_spi1_segments ||
577
+ asc->segments == aspeed_2500_spi2_segments) &&
578
+ cs == asc->max_peripherals &&
579
+ seg.addr + seg.size != asc->segments[cs].addr +
580
+ asc->segments[cs].size) {
581
aspeed_smc_error("Tried to change CS%d end address to 0x%"
582
HWADDR_PRIx, cs, seg.addr + seg.size);
583
- seg.size = s->ctrl->segments[cs].addr + s->ctrl->segments[cs].size -
584
+ seg.size = asc->segments[cs].addr + asc->segments[cs].size -
585
seg.addr;
586
- new = s->ctrl->segment_to_reg(s, &seg);
587
+ new = asc->segment_to_reg(s, &seg);
588
}
589
590
/* Keep the segment in the overall flash window */
591
if (seg.size &&
592
- (seg.addr + seg.size <= s->ctrl->flash_window_base ||
593
- seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size)) {
594
+ (seg.addr + seg.size <= asc->flash_window_base ||
595
+ seg.addr > asc->flash_window_base + asc->flash_window_size)) {
596
aspeed_smc_error("new segment for CS%d is invalid : "
597
"[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
598
cs, seg.addr, seg.addr + seg.size);
599
@@ -XXX,XX +XXX,XX @@ static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
600
static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl)
601
{
602
const AspeedSMCState *s = fl->controller;
603
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
604
605
- if (s->ctrl->segments == aspeed_segments_spi) {
606
+ if (asc->segments == aspeed_2400_spi1_segments) {
607
return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
608
} else {
609
return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->id));
610
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
611
uint32_t addr)
612
{
613
const AspeedSMCState *s = fl->controller;
614
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
615
AspeedSegments seg;
616
617
- s->ctrl->reg_to_segment(s, s->regs[R_SEG_ADDR0 + fl->id], &seg);
618
+ asc->reg_to_segment(s, s->regs[R_SEG_ADDR0 + fl->id], &seg);
619
if ((addr % seg.size) != addr) {
620
aspeed_smc_error("invalid address 0x%08x for CS%d segment : "
621
"[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
622
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_update_ctrl(AspeedSMCFlash *fl, uint32_t value)
623
static void aspeed_smc_reset(DeviceState *d)
624
{
625
AspeedSMCState *s = ASPEED_SMC(d);
626
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
627
int i;
628
629
memset(s->regs, 0, sizeof s->regs);
630
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
631
}
632
633
/* setup the default segment register values and regions for all */
634
- for (i = 0; i < s->ctrl->max_peripherals; ++i) {
635
+ for (i = 0; i < asc->max_peripherals; ++i) {
636
aspeed_smc_flash_set_segment_region(s, i,
637
- s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]));
638
+ asc->segment_to_reg(s, &asc->segments[i]));
639
}
640
641
/* HW strapping flash type for the AST2600 controllers */
642
- if (s->ctrl->segments == aspeed_segments_ast2600_fmc) {
643
+ if (asc->segments == aspeed_2600_fmc_segments) {
644
/* flash type is fixed to SPI for all */
645
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
646
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1);
647
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
648
}
649
650
/* HW strapping flash type for FMC controllers */
651
- if (s->ctrl->segments == aspeed_segments_ast2500_fmc) {
652
+ if (asc->segments == aspeed_2500_fmc_segments) {
653
/* flash type is fixed to SPI for CE0 and CE1 */
654
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
655
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1);
656
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
657
658
/* HW strapping for AST2400 FMC controllers (SCU70). Let's use the
659
* configuration of the palmetto-bmc machine */
660
- if (s->ctrl->segments == aspeed_segments_fmc) {
661
+ if (asc->segments == aspeed_2400_fmc_segments) {
662
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
663
}
664
665
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
666
static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
667
{
668
AspeedSMCState *s = ASPEED_SMC(opaque);
669
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(opaque);
670
671
addr >>= 2;
672
673
if (addr == s->r_conf ||
674
(addr >= s->r_timings &&
675
- addr < s->r_timings + s->ctrl->nregs_timings) ||
676
+ addr < s->r_timings + asc->nregs_timings) ||
677
addr == s->r_ce_ctrl ||
678
addr == R_CE_CMD_CTRL ||
679
addr == R_INTR_CTRL ||
680
addr == R_DUMMY_DATA ||
681
- (aspeed_smc_has_wdt_control(s) && addr == R_FMC_WDT2_CTRL) ||
682
- (aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) ||
683
- (aspeed_smc_has_dma(s) && addr == R_DMA_FLASH_ADDR) ||
684
- (aspeed_smc_has_dma(s) && addr == R_DMA_DRAM_ADDR) ||
685
- (aspeed_smc_has_dma(s) && addr == R_DMA_LEN) ||
686
- (aspeed_smc_has_dma(s) && addr == R_DMA_CHECKSUM) ||
687
+ (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) ||
688
+ (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
689
+ (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR) ||
690
+ (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR) ||
691
+ (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
692
+ (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM) ||
693
(addr >= R_SEG_ADDR0 &&
694
- addr < R_SEG_ADDR0 + s->ctrl->max_peripherals) ||
695
- (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->ctrl->max_peripherals)) {
696
+ addr < R_SEG_ADDR0 + asc->max_peripherals) ||
697
+ (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->max_peripherals)) {
698
699
trace_aspeed_smc_read(addr, size, s->regs[addr]);
700
701
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint32_t dma_ctrl)
702
703
static inline bool aspeed_smc_dma_granted(AspeedSMCState *s)
704
{
705
- if (!(s->ctrl->features & ASPEED_SMC_FEATURE_DMA_GRANT)) {
706
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
707
+
708
+ if (!(asc->features & ASPEED_SMC_FEATURE_DMA_GRANT)) {
709
return true;
710
}
711
712
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
713
unsigned int size)
714
{
715
AspeedSMCState *s = ASPEED_SMC(opaque);
716
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
717
uint32_t value = data;
718
719
addr >>= 2;
720
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
721
722
if (addr == s->r_conf ||
723
(addr >= s->r_timings &&
724
- addr < s->r_timings + s->ctrl->nregs_timings) ||
725
+ addr < s->r_timings + asc->nregs_timings) ||
726
addr == s->r_ce_ctrl) {
727
s->regs[addr] = value;
728
} else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
729
int cs = addr - s->r_ctrl0;
730
aspeed_smc_flash_update_ctrl(&s->flashes[cs], value);
731
} else if (addr >= R_SEG_ADDR0 &&
732
- addr < R_SEG_ADDR0 + s->ctrl->max_peripherals) {
733
+ addr < R_SEG_ADDR0 + asc->max_peripherals) {
734
int cs = addr - R_SEG_ADDR0;
735
736
if (value != s->regs[R_SEG_ADDR0 + cs]) {
737
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
738
s->regs[addr] = value & 0xff;
739
} else if (addr == R_DUMMY_DATA) {
740
s->regs[addr] = value & 0xff;
741
- } else if (aspeed_smc_has_wdt_control(s) && addr == R_FMC_WDT2_CTRL) {
742
+ } else if (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) {
743
s->regs[addr] = value & FMC_WDT2_CTRL_EN;
744
} else if (addr == R_INTR_CTRL) {
745
s->regs[addr] = value;
746
- } else if (aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) {
747
- s->ctrl->dma_ctrl(s, value);
748
- } else if (aspeed_smc_has_dma(s) && addr == R_DMA_DRAM_ADDR &&
749
+ } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) {
750
+ asc->dma_ctrl(s, value);
751
+ } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR &&
752
aspeed_smc_dma_granted(s)) {
753
- s->regs[addr] = DMA_DRAM_ADDR(s, value);
754
- } else if (aspeed_smc_has_dma(s) && addr == R_DMA_FLASH_ADDR &&
755
+ s->regs[addr] = DMA_DRAM_ADDR(asc, value);
756
+ } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR &&
757
aspeed_smc_dma_granted(s)) {
758
- s->regs[addr] = DMA_FLASH_ADDR(s, value);
759
- } else if (aspeed_smc_has_dma(s) && addr == R_DMA_LEN &&
760
+ s->regs[addr] = DMA_FLASH_ADDR(asc, value);
761
+ } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN &&
762
aspeed_smc_dma_granted(s)) {
763
s->regs[addr] = DMA_LENGTH(value);
764
} else {
765
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
766
{
98
{
767
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
99
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
768
AspeedSMCState *s = ASPEED_SMC(dev);
100
AspeedSDHCIState *sdhci = ASPEED_SDHCI(dev);
769
- AspeedSMCClass *mc = ASPEED_SMC_GET_CLASS(s);
101
+ AspeedSDHCIClass *asc = ASPEED_SDHCI_GET_CLASS(sdhci);
770
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
102
771
int i;
103
/* Create input irqs for the slots */
772
char name[32];
104
qdev_init_gpio_in_named_with_opaque(DEVICE(sbd), aspeed_sdhci_set_irq,
773
hwaddr offset = 0;
105
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdhci_realize(DeviceState *dev, Error **errp)
774
106
}
775
- s->ctrl = mc->ctrl;
107
776
-
108
if (!object_property_set_uint(sdhci_slot, "capareg",
777
/* keep a copy under AspeedSMCState to speed up accesses */
109
- ASPEED_SDHCI_CAPABILITIES, errp)) {
778
- s->r_conf = s->ctrl->r_conf;
110
+ asc->capareg, errp)) {
779
- s->r_ce_ctrl = s->ctrl->r_ce_ctrl;
111
return;
780
- s->r_ctrl0 = s->ctrl->r_ctrl0;
112
}
781
- s->r_timings = s->ctrl->r_timings;
113
782
- s->conf_enable_w0 = s->ctrl->conf_enable_w0;
114
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
783
+ s->r_conf = asc->r_conf;
115
device_class_set_props(dc, aspeed_sdhci_properties);
784
+ s->r_ce_ctrl = asc->r_ce_ctrl;
785
+ s->r_ctrl0 = asc->r_ctrl0;
786
+ s->r_timings = asc->r_timings;
787
+ s->conf_enable_w0 = asc->conf_enable_w0;
788
789
/* Enforce some real HW limits */
790
- if (s->num_cs > s->ctrl->max_peripherals) {
791
- aspeed_smc_error("num_cs cannot exceed: %d", s->ctrl->max_peripherals);
792
- s->num_cs = s->ctrl->max_peripherals;
793
+ if (s->num_cs > asc->max_peripherals) {
794
+ aspeed_smc_error("num_cs cannot exceed: %d", asc->max_peripherals);
795
+ s->num_cs = asc->max_peripherals;
796
}
797
798
/* DMA irq. Keep it first for the initialization in the SoC */
799
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
800
801
/* The memory region for the controller registers */
802
memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
803
- TYPE_ASPEED_SMC, s->ctrl->nregs * 4);
804
+ TYPE_ASPEED_SMC, asc->nregs * 4);
805
sysbus_init_mmio(sbd, &s->mmio);
806
807
/*
808
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
809
memory_region_init_io(&s->mmio_flash, OBJECT(s),
810
&aspeed_smc_flash_default_ops, s,
811
TYPE_ASPEED_SMC ".flash",
812
- s->ctrl->flash_window_size);
813
+ asc->flash_window_size);
814
memory_region_init_alias(&s->mmio_flash_alias, OBJECT(s),
815
TYPE_ASPEED_SMC ".flash",
816
- &s->mmio_flash, 0, s->ctrl->flash_window_size);
817
+ &s->mmio_flash, 0, asc->flash_window_size);
818
sysbus_init_mmio(sbd, &s->mmio_flash_alias);
819
820
- s->flashes = g_new0(AspeedSMCFlash, s->ctrl->max_peripherals);
821
+ s->flashes = g_new0(AspeedSMCFlash, asc->max_peripherals);
822
823
/*
824
* Let's create a sub memory region for each possible peripheral. All
825
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
826
* module behind to handle the memory accesses. This depends on
827
* the board configuration.
828
*/
829
- for (i = 0; i < s->ctrl->max_peripherals; ++i) {
830
+ for (i = 0; i < asc->max_peripherals; ++i) {
831
AspeedSMCFlash *fl = &s->flashes[i];
832
833
snprintf(name, sizeof(name), TYPE_ASPEED_SMC ".flash.%d", i);
834
835
fl->id = i;
836
fl->controller = s;
837
- fl->size = s->ctrl->segments[i].size;
838
+ fl->size = asc->segments[i].size;
839
memory_region_init_io(&fl->mmio, OBJECT(s), &aspeed_smc_flash_ops,
840
fl, name, fl->size);
841
memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio);
842
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
843
}
844
845
/* DMA support */
846
- if (aspeed_smc_has_dma(s)) {
847
+ if (aspeed_smc_has_dma(asc)) {
848
aspeed_smc_dma_setup(s, errp);
849
}
850
}
116
}
851
@@ -XXX,XX +XXX,XX @@ static Property aspeed_smc_properties[] = {
117
852
static void aspeed_smc_class_init(ObjectClass *klass, void *data)
118
+static void aspeed_2400_sdhci_class_init(ObjectClass *klass, void *data)
853
{
119
+{
854
DeviceClass *dc = DEVICE_CLASS(klass);
120
+ DeviceClass *dc = DEVICE_CLASS(klass);
855
- AspeedSMCClass *mc = ASPEED_SMC_CLASS(klass);
121
+ AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass);
856
857
dc->realize = aspeed_smc_realize;
858
dc->reset = aspeed_smc_reset;
859
device_class_set_props(dc, aspeed_smc_properties);
860
dc->vmsd = &vmstate_aspeed_smc;
861
- mc->ctrl = data;
862
}
863
864
static const TypeInfo aspeed_smc_info = {
865
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_smc_info = {
866
.parent = TYPE_SYS_BUS_DEVICE,
867
.instance_size = sizeof(AspeedSMCState),
868
.class_size = sizeof(AspeedSMCClass),
869
+ .class_init = aspeed_smc_class_init,
870
.abstract = true,
871
};
872
873
-static void aspeed_smc_register_types(void)
874
+
122
+
875
+/*
123
+ dc->desc = "ASPEED 2400 SDHCI Controller";
876
+ * The Segment Registers of the AST2400 and AST2500 have a 8MB
124
+ asc->capareg = 0x0000000001e80080;
877
+ * unit. The address range of a flash SPI peripheral is encoded with
878
+ * absolute addresses which should be part of the overall controller
879
+ * window.
880
+ */
881
+static uint32_t aspeed_smc_segment_to_reg(const AspeedSMCState *s,
882
+ const AspeedSegments *seg)
883
{
884
- int i;
885
+ uint32_t reg = 0;
886
+ reg |= ((seg->addr >> 23) & SEG_START_MASK) << SEG_START_SHIFT;
887
+ reg |= (((seg->addr + seg->size) >> 23) & SEG_END_MASK) << SEG_END_SHIFT;
888
+ return reg;
889
+}
890
891
- type_register_static(&aspeed_smc_info);
892
- for (i = 0; i < ARRAY_SIZE(controllers); ++i) {
893
- TypeInfo ti = {
894
- .name = controllers[i].name,
895
- .parent = TYPE_ASPEED_SMC,
896
- .class_init = aspeed_smc_class_init,
897
- .class_data = (void *)&controllers[i],
898
- };
899
- type_register(&ti);
900
+static void aspeed_smc_reg_to_segment(const AspeedSMCState *s,
901
+ uint32_t reg, AspeedSegments *seg)
902
+{
903
+ seg->addr = ((reg >> SEG_START_SHIFT) & SEG_START_MASK) << 23;
904
+ seg->size = (((reg >> SEG_END_SHIFT) & SEG_END_MASK) << 23) - seg->addr;
905
+}
125
+}
906
+
126
+
907
+static const AspeedSegments aspeed_2400_smc_segments[] = {
127
+static void aspeed_2500_sdhci_class_init(ObjectClass *klass, void *data)
908
+ { 0x10000000, 32 * MiB },
909
+};
910
+
911
+static void aspeed_2400_smc_class_init(ObjectClass *klass, void *data)
912
+{
128
+{
913
+ DeviceClass *dc = DEVICE_CLASS(klass);
129
+ DeviceClass *dc = DEVICE_CLASS(klass);
914
+ AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
130
+ AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass);
915
+
131
+
916
+ dc->desc = "Aspeed 2400 SMC Controller";
132
+ dc->desc = "ASPEED 2500 SDHCI Controller";
917
+ asc->r_conf = R_CONF;
133
+ asc->capareg = 0x0000000001e80080;
918
+ asc->r_ce_ctrl = R_CE_CTRL;
919
+ asc->r_ctrl0 = R_CTRL0;
920
+ asc->r_timings = R_TIMINGS;
921
+ asc->nregs_timings = 1;
922
+ asc->conf_enable_w0 = CONF_ENABLE_W0;
923
+ asc->max_peripherals = 1;
924
+ asc->segments = aspeed_2400_smc_segments;
925
+ asc->flash_window_base = 0x10000000;
926
+ asc->flash_window_size = 0x6000000;
927
+ asc->features = 0x0;
928
+ asc->nregs = ASPEED_SMC_R_SMC_MAX;
929
+ asc->segment_to_reg = aspeed_smc_segment_to_reg;
930
+ asc->reg_to_segment = aspeed_smc_reg_to_segment;
931
+ asc->dma_ctrl = aspeed_smc_dma_ctrl;
932
+}
134
+}
933
+
135
+
934
+static const TypeInfo aspeed_2400_smc_info = {
136
+static void aspeed_2600_sdhci_class_init(ObjectClass *klass, void *data)
935
+ .name = "aspeed.smc-ast2400",
936
+ .parent = TYPE_ASPEED_SMC,
937
+ .class_init = aspeed_2400_smc_class_init,
938
+};
939
+
940
+static const AspeedSegments aspeed_2400_fmc_segments[] = {
941
+ { 0x20000000, 64 * MiB }, /* start address is readonly */
942
+ { 0x24000000, 32 * MiB },
943
+ { 0x26000000, 32 * MiB },
944
+ { 0x28000000, 32 * MiB },
945
+ { 0x2A000000, 32 * MiB }
946
+};
947
+
948
+static void aspeed_2400_fmc_class_init(ObjectClass *klass, void *data)
949
+{
137
+{
950
+ DeviceClass *dc = DEVICE_CLASS(klass);
138
+ DeviceClass *dc = DEVICE_CLASS(klass);
951
+ AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
139
+ AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass);
952
+
140
+
953
+ dc->desc = "Aspeed 2400 FMC Controller";
141
+ dc->desc = "ASPEED 2600 SDHCI Controller";
954
+ asc->r_conf = R_CONF;
142
+ asc->capareg = 0x0000000701f80080;
955
+ asc->r_ce_ctrl = R_CE_CTRL;
956
+ asc->r_ctrl0 = R_CTRL0;
957
+ asc->r_timings = R_TIMINGS;
958
+ asc->nregs_timings = 1;
959
+ asc->conf_enable_w0 = CONF_ENABLE_W0;
960
+ asc->max_peripherals = 5;
961
+ asc->segments = aspeed_2400_fmc_segments;
962
+ asc->flash_window_base = 0x20000000;
963
+ asc->flash_window_size = 0x10000000;
964
+ asc->features = ASPEED_SMC_FEATURE_DMA;
965
+ asc->dma_flash_mask = 0x0FFFFFFC;
966
+ asc->dma_dram_mask = 0x1FFFFFFC;
967
+ asc->nregs = ASPEED_SMC_R_MAX;
968
+ asc->segment_to_reg = aspeed_smc_segment_to_reg;
969
+ asc->reg_to_segment = aspeed_smc_reg_to_segment;
970
+ asc->dma_ctrl = aspeed_smc_dma_ctrl;
971
+}
143
+}
972
+
144
+
973
+static const TypeInfo aspeed_2400_fmc_info = {
145
static const TypeInfo aspeed_sdhci_types[] = {
974
+ .name = "aspeed.fmc-ast2400",
146
{
975
+ .parent = TYPE_ASPEED_SMC,
147
.name = TYPE_ASPEED_SDHCI,
976
+ .class_init = aspeed_2400_fmc_class_init,
148
.parent = TYPE_SYS_BUS_DEVICE,
977
+};
149
.instance_size = sizeof(AspeedSDHCIState),
978
+
150
.class_init = aspeed_sdhci_class_init,
979
+static const AspeedSegments aspeed_2400_spi1_segments[] = {
151
+ .class_size = sizeof(AspeedSDHCIClass),
980
+ { 0x30000000, 64 * MiB },
152
+ .abstract = true,
981
+};
153
+ },
982
+
154
+ {
983
+static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
155
+ .name = TYPE_ASPEED_2400_SDHCI,
984
+{
156
+ .parent = TYPE_ASPEED_SDHCI,
985
+ DeviceClass *dc = DEVICE_CLASS(klass);
157
+ .class_init = aspeed_2400_sdhci_class_init,
986
+ AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
158
+ },
987
+
159
+ {
988
+ dc->desc = "Aspeed 2400 SPI1 Controller";
160
+ .name = TYPE_ASPEED_2500_SDHCI,
989
+ asc->r_conf = R_SPI_CONF;
161
+ .parent = TYPE_ASPEED_SDHCI,
990
+ asc->r_ce_ctrl = 0xff;
162
+ .class_init = aspeed_2500_sdhci_class_init,
991
+ asc->r_ctrl0 = R_SPI_CTRL0;
163
+ },
992
+ asc->r_timings = R_SPI_TIMINGS;
164
+ {
993
+ asc->nregs_timings = 1;
165
+ .name = TYPE_ASPEED_2600_SDHCI,
994
+ asc->conf_enable_w0 = SPI_CONF_ENABLE_W0;
166
+ .parent = TYPE_ASPEED_SDHCI,
995
+ asc->max_peripherals = 1;
167
+ .class_init = aspeed_2600_sdhci_class_init,
996
+ asc->segments = aspeed_2400_spi1_segments;
168
},
997
+ asc->flash_window_base = 0x30000000;
169
};
998
+ asc->flash_window_size = 0x10000000;
170
999
+ asc->features = 0x0;
1000
+ asc->nregs = ASPEED_SMC_R_SPI_MAX;
1001
+ asc->segment_to_reg = aspeed_smc_segment_to_reg;
1002
+ asc->reg_to_segment = aspeed_smc_reg_to_segment;
1003
+ asc->dma_ctrl = aspeed_smc_dma_ctrl;
1004
+}
1005
+
1006
+static const TypeInfo aspeed_2400_spi1_info = {
1007
+ .name = "aspeed.spi1-ast2400",
1008
+ .parent = TYPE_ASPEED_SMC,
1009
+ .class_init = aspeed_2400_spi1_class_init,
1010
+};
1011
+
1012
+static const AspeedSegments aspeed_2500_fmc_segments[] = {
1013
+ { 0x20000000, 128 * MiB }, /* start address is readonly */
1014
+ { 0x28000000, 32 * MiB },
1015
+ { 0x2A000000, 32 * MiB },
1016
+};
1017
+
1018
+static void aspeed_2500_fmc_class_init(ObjectClass *klass, void *data)
1019
+{
1020
+ DeviceClass *dc = DEVICE_CLASS(klass);
1021
+ AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1022
+
1023
+ dc->desc = "Aspeed 2600 FMC Controller";
1024
+ asc->r_conf = R_CONF;
1025
+ asc->r_ce_ctrl = R_CE_CTRL;
1026
+ asc->r_ctrl0 = R_CTRL0;
1027
+ asc->r_timings = R_TIMINGS;
1028
+ asc->nregs_timings = 1;
1029
+ asc->conf_enable_w0 = CONF_ENABLE_W0;
1030
+ asc->max_peripherals = 3;
1031
+ asc->segments = aspeed_2500_fmc_segments;
1032
+ asc->flash_window_base = 0x20000000;
1033
+ asc->flash_window_size = 0x10000000;
1034
+ asc->features = ASPEED_SMC_FEATURE_DMA;
1035
+ asc->dma_flash_mask = 0x0FFFFFFC;
1036
+ asc->dma_dram_mask = 0x3FFFFFFC;
1037
+ asc->nregs = ASPEED_SMC_R_MAX;
1038
+ asc->segment_to_reg = aspeed_smc_segment_to_reg;
1039
+ asc->reg_to_segment = aspeed_smc_reg_to_segment;
1040
+ asc->dma_ctrl = aspeed_smc_dma_ctrl;
1041
+}
1042
+
1043
+static const TypeInfo aspeed_2500_fmc_info = {
1044
+ .name = "aspeed.fmc-ast2500",
1045
+ .parent = TYPE_ASPEED_SMC,
1046
+ .class_init = aspeed_2500_fmc_class_init,
1047
+};
1048
+
1049
+static const AspeedSegments aspeed_2500_spi1_segments[] = {
1050
+ { 0x30000000, 32 * MiB }, /* start address is readonly */
1051
+ { 0x32000000, 96 * MiB }, /* end address is readonly */
1052
+};
1053
+
1054
+static void aspeed_2500_spi1_class_init(ObjectClass *klass, void *data)
1055
+{
1056
+ DeviceClass *dc = DEVICE_CLASS(klass);
1057
+ AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1058
+
1059
+ dc->desc = "Aspeed 2600 SPI1 Controller";
1060
+ asc->r_conf = R_CONF;
1061
+ asc->r_ce_ctrl = R_CE_CTRL;
1062
+ asc->r_ctrl0 = R_CTRL0;
1063
+ asc->r_timings = R_TIMINGS;
1064
+ asc->nregs_timings = 1;
1065
+ asc->conf_enable_w0 = CONF_ENABLE_W0;
1066
+ asc->max_peripherals = 2;
1067
+ asc->segments = aspeed_2500_spi1_segments;
1068
+ asc->flash_window_base = 0x30000000;
1069
+ asc->flash_window_size = 0x8000000;
1070
+ asc->features = 0x0;
1071
+ asc->nregs = ASPEED_SMC_R_MAX;
1072
+ asc->segment_to_reg = aspeed_smc_segment_to_reg;
1073
+ asc->reg_to_segment = aspeed_smc_reg_to_segment;
1074
+ asc->dma_ctrl = aspeed_smc_dma_ctrl;
1075
+}
1076
+
1077
+static const TypeInfo aspeed_2500_spi1_info = {
1078
+ .name = "aspeed.spi1-ast2500",
1079
+ .parent = TYPE_ASPEED_SMC,
1080
+ .class_init = aspeed_2500_spi1_class_init,
1081
+};
1082
+
1083
+static const AspeedSegments aspeed_2500_spi2_segments[] = {
1084
+ { 0x38000000, 32 * MiB }, /* start address is readonly */
1085
+ { 0x3A000000, 96 * MiB }, /* end address is readonly */
1086
+};
1087
+
1088
+static void aspeed_2500_spi2_class_init(ObjectClass *klass, void *data)
1089
+{
1090
+ DeviceClass *dc = DEVICE_CLASS(klass);
1091
+ AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1092
+
1093
+ dc->desc = "Aspeed 2600 SPI2 Controller";
1094
+ asc->r_conf = R_CONF;
1095
+ asc->r_ce_ctrl = R_CE_CTRL;
1096
+ asc->r_ctrl0 = R_CTRL0;
1097
+ asc->r_timings = R_TIMINGS;
1098
+ asc->nregs_timings = 1;
1099
+ asc->conf_enable_w0 = CONF_ENABLE_W0;
1100
+ asc->max_peripherals = 2;
1101
+ asc->segments = aspeed_2500_spi2_segments;
1102
+ asc->flash_window_base = 0x38000000;
1103
+ asc->flash_window_size = 0x8000000;
1104
+ asc->features = 0x0;
1105
+ asc->nregs = ASPEED_SMC_R_MAX;
1106
+ asc->segment_to_reg = aspeed_smc_segment_to_reg;
1107
+ asc->reg_to_segment = aspeed_smc_reg_to_segment;
1108
+ asc->dma_ctrl = aspeed_smc_dma_ctrl;
1109
+}
1110
+
1111
+static const TypeInfo aspeed_2500_spi2_info = {
1112
+ .name = "aspeed.spi2-ast2500",
1113
+ .parent = TYPE_ASPEED_SMC,
1114
+ .class_init = aspeed_2500_spi2_class_init,
1115
+};
1116
+
1117
+/*
1118
+ * The Segment Registers of the AST2600 have a 1MB unit. The address
1119
+ * range of a flash SPI peripheral is encoded with offsets in the overall
1120
+ * controller window. The previous SoC AST2400 and AST2500 used
1121
+ * absolute addresses. Only bits [27:20] are relevant and the end
1122
+ * address is an upper bound limit.
1123
+ */
1124
+#define AST2600_SEG_ADDR_MASK 0x0ff00000
1125
+
1126
+static uint32_t aspeed_2600_smc_segment_to_reg(const AspeedSMCState *s,
1127
+ const AspeedSegments *seg)
1128
+{
1129
+ uint32_t reg = 0;
1130
+
1131
+ /* Disabled segments have a nil register */
1132
+ if (!seg->size) {
1133
+ return 0;
1134
+ }
1135
+
1136
+ reg |= (seg->addr & AST2600_SEG_ADDR_MASK) >> 16; /* start offset */
1137
+ reg |= (seg->addr + seg->size - 1) & AST2600_SEG_ADDR_MASK; /* end offset */
1138
+ return reg;
1139
+}
1140
+
1141
+static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
1142
+ uint32_t reg, AspeedSegments *seg)
1143
+{
1144
+ uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
1145
+ uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
1146
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
1147
+
1148
+ if (reg) {
1149
+ seg->addr = asc->flash_window_base + start_offset;
1150
+ seg->size = end_offset + MiB - start_offset;
1151
+ } else {
1152
+ seg->addr = asc->flash_window_base;
1153
+ seg->size = 0;
1154
}
1155
}
1156
1157
+static const AspeedSegments aspeed_2600_fmc_segments[] = {
1158
+ { 0x0, 128 * MiB }, /* start address is readonly */
1159
+ { 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
1160
+ { 0x0, 0 }, /* disabled */
1161
+};
1162
+
1163
+static void aspeed_2600_fmc_class_init(ObjectClass *klass, void *data)
1164
+{
1165
+ DeviceClass *dc = DEVICE_CLASS(klass);
1166
+ AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1167
+
1168
+ dc->desc = "Aspeed 2600 FMC Controller";
1169
+ asc->r_conf = R_CONF;
1170
+ asc->r_ce_ctrl = R_CE_CTRL;
1171
+ asc->r_ctrl0 = R_CTRL0;
1172
+ asc->r_timings = R_TIMINGS;
1173
+ asc->nregs_timings = 1;
1174
+ asc->conf_enable_w0 = CONF_ENABLE_W0;
1175
+ asc->max_peripherals = 3;
1176
+ asc->segments = aspeed_2600_fmc_segments;
1177
+ asc->flash_window_base = 0x20000000;
1178
+ asc->flash_window_size = 0x10000000;
1179
+ asc->features = ASPEED_SMC_FEATURE_DMA |
1180
+ ASPEED_SMC_FEATURE_WDT_CONTROL;
1181
+ asc->dma_flash_mask = 0x0FFFFFFC;
1182
+ asc->dma_dram_mask = 0x3FFFFFFC;
1183
+ asc->nregs = ASPEED_SMC_R_MAX;
1184
+ asc->segment_to_reg = aspeed_2600_smc_segment_to_reg;
1185
+ asc->reg_to_segment = aspeed_2600_smc_reg_to_segment;
1186
+ asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
1187
+}
1188
+
1189
+static const TypeInfo aspeed_2600_fmc_info = {
1190
+ .name = "aspeed.fmc-ast2600",
1191
+ .parent = TYPE_ASPEED_SMC,
1192
+ .class_init = aspeed_2600_fmc_class_init,
1193
+};
1194
+
1195
+static const AspeedSegments aspeed_2600_spi1_segments[] = {
1196
+ { 0x0, 128 * MiB }, /* start address is readonly */
1197
+ { 0x0, 0 }, /* disabled */
1198
+};
1199
+
1200
+static void aspeed_2600_spi1_class_init(ObjectClass *klass, void *data)
1201
+{
1202
+ DeviceClass *dc = DEVICE_CLASS(klass);
1203
+ AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1204
+
1205
+ dc->desc = "Aspeed 2600 SPI1 Controller";
1206
+ asc->r_conf = R_CONF;
1207
+ asc->r_ce_ctrl = R_CE_CTRL;
1208
+ asc->r_ctrl0 = R_CTRL0;
1209
+ asc->r_timings = R_TIMINGS;
1210
+ asc->nregs_timings = 2;
1211
+ asc->conf_enable_w0 = CONF_ENABLE_W0;
1212
+ asc->max_peripherals = 2;
1213
+ asc->segments = aspeed_2600_spi1_segments;
1214
+ asc->flash_window_base = 0x30000000;
1215
+ asc->flash_window_size = 0x10000000;
1216
+ asc->features = ASPEED_SMC_FEATURE_DMA |
1217
+ ASPEED_SMC_FEATURE_DMA_GRANT;
1218
+ asc->dma_flash_mask = 0x0FFFFFFC;
1219
+ asc->dma_dram_mask = 0x3FFFFFFC;
1220
+ asc->nregs = ASPEED_SMC_R_MAX;
1221
+ asc->segment_to_reg = aspeed_2600_smc_segment_to_reg;
1222
+ asc->reg_to_segment = aspeed_2600_smc_reg_to_segment;
1223
+ asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
1224
+}
1225
+
1226
+static const TypeInfo aspeed_2600_spi1_info = {
1227
+ .name = "aspeed.spi1-ast2600",
1228
+ .parent = TYPE_ASPEED_SMC,
1229
+ .class_init = aspeed_2600_spi1_class_init,
1230
+};
1231
+
1232
+static const AspeedSegments aspeed_2600_spi2_segments[] = {
1233
+ { 0x0, 128 * MiB }, /* start address is readonly */
1234
+ { 0x0, 0 }, /* disabled */
1235
+ { 0x0, 0 }, /* disabled */
1236
+};
1237
+
1238
+static void aspeed_2600_spi2_class_init(ObjectClass *klass, void *data)
1239
+{
1240
+ DeviceClass *dc = DEVICE_CLASS(klass);
1241
+ AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1242
+
1243
+ dc->desc = "Aspeed 2600 SPI2 Controller";
1244
+ asc->r_conf = R_CONF;
1245
+ asc->r_ce_ctrl = R_CE_CTRL;
1246
+ asc->r_ctrl0 = R_CTRL0;
1247
+ asc->r_timings = R_TIMINGS;
1248
+ asc->nregs_timings = 3;
1249
+ asc->conf_enable_w0 = CONF_ENABLE_W0;
1250
+ asc->max_peripherals = 3;
1251
+ asc->segments = aspeed_2600_spi2_segments;
1252
+ asc->flash_window_base = 0x50000000;
1253
+ asc->flash_window_size = 0x10000000;
1254
+ asc->features = ASPEED_SMC_FEATURE_DMA |
1255
+ ASPEED_SMC_FEATURE_DMA_GRANT;
1256
+ asc->dma_flash_mask = 0x0FFFFFFC;
1257
+ asc->dma_dram_mask = 0x3FFFFFFC;
1258
+ asc->nregs = ASPEED_SMC_R_MAX;
1259
+ asc->segment_to_reg = aspeed_2600_smc_segment_to_reg;
1260
+ asc->reg_to_segment = aspeed_2600_smc_reg_to_segment;
1261
+ asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
1262
+}
1263
+
1264
+static const TypeInfo aspeed_2600_spi2_info = {
1265
+ .name = "aspeed.spi2-ast2600",
1266
+ .parent = TYPE_ASPEED_SMC,
1267
+ .class_init = aspeed_2600_spi2_class_init,
1268
+};
1269
+
1270
+static void aspeed_smc_register_types(void)
1271
+{
1272
+ type_register_static(&aspeed_smc_info);
1273
+ type_register_static(&aspeed_2400_smc_info);
1274
+ type_register_static(&aspeed_2400_fmc_info);
1275
+ type_register_static(&aspeed_2400_spi1_info);
1276
+ type_register_static(&aspeed_2500_fmc_info);
1277
+ type_register_static(&aspeed_2500_spi1_info);
1278
+ type_register_static(&aspeed_2500_spi2_info);
1279
+ type_register_static(&aspeed_2600_fmc_info);
1280
+ type_register_static(&aspeed_2600_spi1_info);
1281
+ type_register_static(&aspeed_2600_spi2_info);
1282
+}
1283
+
1284
type_init(aspeed_smc_register_types)
1285
--
171
--
1286
2.31.1
172
2.47.1
1287
173
1288
174
diff view generated by jsdifflib
1
AspeedSMCFlash is a small structure representing the AHB memory window
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
through which the contents of a flash device can be accessed with MMIOs.
3
2
4
Introduce an AspeedSMCFlash SysBusDevice model and attach the associated
3
Introduce a new ast2700 class to support AST2700. Add a new ast2700 SDHCI class
5
memory region to the newly instantiated objects.
4
init function and set the value of capability register to "0x0000000719f80080".
6
5
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Cédric Le Goater <clg@redhat.com>
8
Link: https://lore.kernel.org/r/20241204084453.610660-5-jamin_lin@aspeedtech.com
9
Signed-off-by: Cédric Le Goater <clg@redhat.com>
9
---
10
---
10
include/hw/ssi/aspeed_smc.h | 13 +++++--
11
include/hw/sd/aspeed_sdhci.h | 1 +
11
hw/ssi/aspeed_smc.c | 76 +++++++++++++++++++++++++++++++++----
12
hw/sd/aspeed_sdhci.c | 14 ++++++++++++++
12
2 files changed, 77 insertions(+), 12 deletions(-)
13
2 files changed, 15 insertions(+)
13
14
14
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
15
diff --git a/include/hw/sd/aspeed_sdhci.h b/include/hw/sd/aspeed_sdhci.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/ssi/aspeed_smc.h
17
--- a/include/hw/sd/aspeed_sdhci.h
17
+++ b/include/hw/ssi/aspeed_smc.h
18
+++ b/include/hw/sd/aspeed_sdhci.h
18
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
19
#include "qom/object.h"
20
#define TYPE_ASPEED_2400_SDHCI TYPE_ASPEED_SDHCI "-ast2400"
20
21
#define TYPE_ASPEED_2500_SDHCI TYPE_ASPEED_SDHCI "-ast2500"
21
struct AspeedSMCState;
22
#define TYPE_ASPEED_2600_SDHCI TYPE_ASPEED_SDHCI "-ast2600"
22
-typedef struct AspeedSMCFlash {
23
+#define TYPE_ASPEED_2700_SDHCI TYPE_ASPEED_SDHCI "-ast2700"
23
- struct AspeedSMCState *controller;
24
OBJECT_DECLARE_TYPE(AspeedSDHCIState, AspeedSDHCIClass, ASPEED_SDHCI)
24
25
25
+#define TYPE_ASPEED_SMC_FLASH "aspeed.smc.flash"
26
#define ASPEED_SDHCI_NUM_SLOTS 2
26
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedSMCFlash, ASPEED_SMC_FLASH)
27
diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c
27
+struct AspeedSMCFlash {
28
index XXXXXXX..XXXXXXX 100644
28
+ SysBusDevice parent_obj;
29
--- a/hw/sd/aspeed_sdhci.c
30
+++ b/hw/sd/aspeed_sdhci.c
31
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_sdhci_class_init(ObjectClass *klass, void *data)
32
asc->capareg = 0x0000000701f80080;
33
}
34
35
+static void aspeed_2700_sdhci_class_init(ObjectClass *klass, void *data)
36
+{
37
+ DeviceClass *dc = DEVICE_CLASS(klass);
38
+ AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass);
29
+
39
+
30
+ struct AspeedSMCState *controller;
40
+ dc->desc = "ASPEED 2700 SDHCI Controller";
31
uint8_t cs;
41
+ asc->capareg = 0x0000000719f80080;
32
33
MemoryRegion mmio;
34
-} AspeedSMCFlash;
35
+};
36
37
#define TYPE_ASPEED_SMC "aspeed.smc"
38
OBJECT_DECLARE_TYPE(AspeedSMCState, AspeedSMCClass, ASPEED_SMC)
39
40
#define ASPEED_SMC_R_MAX (0x100 / 4)
41
+#define ASPEED_SMC_CS_MAX 5
42
43
struct AspeedSMCState {
44
SysBusDevice parent_obj;
45
@@ -XXX,XX +XXX,XX @@ struct AspeedSMCState {
46
MemoryRegion *dram_mr;
47
AddressSpace dram_as;
48
49
- AspeedSMCFlash *flashes;
50
+ AspeedSMCFlash flashes[ASPEED_SMC_CS_MAX];
51
52
uint8_t snoop_index;
53
uint8_t snoop_dummies;
54
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/ssi/aspeed_smc.c
57
+++ b/hw/ssi/aspeed_smc.c
58
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_smc_ops = {
59
.endianness = DEVICE_LITTLE_ENDIAN,
60
};
61
62
+static void aspeed_smc_instance_init(Object *obj)
63
+{
64
+ AspeedSMCState *s = ASPEED_SMC(obj);
65
+ AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
66
+ int i;
67
+
68
+ for (i = 0; i < asc->max_peripherals; i++) {
69
+ object_initialize_child(obj, "flash[*]", &s->flashes[i],
70
+ TYPE_ASPEED_SMC_FLASH);
71
+ }
72
+}
42
+}
73
+
43
+
74
/*
44
static const TypeInfo aspeed_sdhci_types[] = {
75
* Initialize the custom address spaces for DMAs
45
{
76
*/
46
.name = TYPE_ASPEED_SDHCI,
77
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
47
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_sdhci_types[] = {
78
AspeedSMCState *s = ASPEED_SMC(dev);
48
.parent = TYPE_ASPEED_SDHCI,
79
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
49
.class_init = aspeed_2600_sdhci_class_init,
80
int i;
50
},
81
- char name[32];
51
+ {
82
hwaddr offset = 0;
52
+ .name = TYPE_ASPEED_2700_SDHCI,
83
53
+ .parent = TYPE_ASPEED_SDHCI,
84
/* keep a copy under AspeedSMCState to speed up accesses */
54
+ .class_init = aspeed_2700_sdhci_class_init,
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
55
+ },
86
&s->mmio_flash, 0, asc->flash_window_size);
87
sysbus_init_mmio(sbd, &s->mmio_flash_alias);
88
89
- s->flashes = g_new0(AspeedSMCFlash, asc->max_peripherals);
90
-
91
/*
92
* Let's create a sub memory region for each possible peripheral. All
93
* have a configurable memory segment in the overall flash mapping
94
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
95
for (i = 0; i < asc->max_peripherals; ++i) {
96
AspeedSMCFlash *fl = &s->flashes[i];
97
98
- snprintf(name, sizeof(name), TYPE_ASPEED_SMC ".flash.%d", i);
99
+ if (!object_property_set_link(OBJECT(fl), "controller", OBJECT(s),
100
+ errp)) {
101
+ return;
102
+ }
103
+ if (!object_property_set_uint(OBJECT(fl), "cs", i, errp)) {
104
+ return;
105
+ }
106
+ if (!sysbus_realize(SYS_BUS_DEVICE(fl), errp)) {
107
+ return;
108
+ }
109
110
- fl->cs = i;
111
- fl->controller = s;
112
- memory_region_init_io(&fl->mmio, OBJECT(s), &aspeed_smc_flash_ops,
113
- fl, name, asc->segments[i].size);
114
memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio);
115
offset += asc->segments[i].size;
116
}
117
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_class_init(ObjectClass *klass, void *data)
118
static const TypeInfo aspeed_smc_info = {
119
.name = TYPE_ASPEED_SMC,
120
.parent = TYPE_SYS_BUS_DEVICE,
121
+ .instance_init = aspeed_smc_instance_init,
122
.instance_size = sizeof(AspeedSMCState),
123
.class_size = sizeof(AspeedSMCClass),
124
.class_init = aspeed_smc_class_init,
125
.abstract = true,
126
};
56
};
127
57
128
+static void aspeed_smc_flash_realize(DeviceState *dev, Error **errp)
58
DEFINE_TYPES(aspeed_sdhci_types)
129
+{
130
+ AspeedSMCFlash *s = ASPEED_SMC_FLASH(dev);
131
+ AspeedSMCClass *asc;
132
+ g_autofree char *name = g_strdup_printf(TYPE_ASPEED_SMC_FLASH ".%d", s->cs);
133
+
134
+ if (!s->controller) {
135
+ error_setg(errp, TYPE_ASPEED_SMC_FLASH ": 'controller' link not set");
136
+ return;
137
+ }
138
+
139
+ asc = ASPEED_SMC_GET_CLASS(s->controller);
140
+
141
+ /*
142
+ * Use the default segment value to size the memory region. This
143
+ * can be changed by FW at runtime.
144
+ */
145
+ memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_flash_ops,
146
+ s, name, asc->segments[s->cs].size);
147
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
148
+}
149
+
150
+static Property aspeed_smc_flash_properties[] = {
151
+ DEFINE_PROP_UINT8("cs", AspeedSMCFlash, cs, 0),
152
+ DEFINE_PROP_LINK("controller", AspeedSMCFlash, controller, TYPE_ASPEED_SMC,
153
+ AspeedSMCState *),
154
+ DEFINE_PROP_END_OF_LIST(),
155
+};
156
+
157
+static void aspeed_smc_flash_class_init(ObjectClass *klass, void *data)
158
+{
159
+ DeviceClass *dc = DEVICE_CLASS(klass);
160
+
161
+ dc->desc = "Aspeed SMC Flash device region";
162
+ dc->realize = aspeed_smc_flash_realize;
163
+ device_class_set_props(dc, aspeed_smc_flash_properties);
164
+}
165
+
166
+static const TypeInfo aspeed_smc_flash_info = {
167
+ .name = TYPE_ASPEED_SMC_FLASH,
168
+ .parent = TYPE_SYS_BUS_DEVICE,
169
+ .instance_size = sizeof(AspeedSMCFlash),
170
+ .class_init = aspeed_smc_flash_class_init,
171
+};
172
173
/*
174
* The Segment Registers of the AST2400 and AST2500 have a 8MB
175
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_2600_spi2_info = {
176
177
static void aspeed_smc_register_types(void)
178
{
179
+ type_register_static(&aspeed_smc_flash_info);
180
type_register_static(&aspeed_smc_info);
181
type_register_static(&aspeed_2400_smc_info);
182
type_register_static(&aspeed_2400_fmc_info);
183
--
59
--
184
2.31.1
60
2.47.1
185
61
186
62
diff view generated by jsdifflib
1
From: Peter Delevoryas <pdel@fb.com>
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
2
3
Some of the pin declarations in the Aspeed GPIO module were incorrect,
3
Add SDHCI model for AST2700 SDHCI support. The SDHCI controller only support 1
4
probably because of confusion over which bits in the input and output
4
slot and registers base address is start at 0x1408_0000 and its interrupt is
5
uint32_t's correspond to which groups in the label array. Since the
5
connected to GICINT133_INTC at bit 1.
6
uint32_t literals are in big endian, it's sort of the opposite of what
7
would be intuitive. The least significant bit in ast2500_set_props[6]
8
corresponds to GPIOY0, not GPIOAB7.
9
6
10
GPIOxx indicates input and output capabilities, GPIxx indicates only
7
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
11
input, GPOxx indicates only output.
8
Reviewed-by: Cédric Le Goater <clg@redhat.com>
9
Link: https://lore.kernel.org/r/20241204084453.610660-6-jamin_lin@aspeedtech.com
10
Signed-off-by: Cédric Le Goater <clg@redhat.com>
11
---
12
hw/arm/aspeed_ast27x0.c | 20 ++++++++++++++++++++
13
1 file changed, 20 insertions(+)
12
14
13
AST2500:
15
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
14
- Previously had GPIW0..GPIW7 and GPIX0..GPIX7, that's correct.
15
- Previously had GPIOY0..GPIOY3, should have been GPIOY0..GPIOY7.
16
- Previously had GPIOAB0..GPIOAB3 and GPIAB4..GPIAB7, should only have
17
been GPIOAB0..GPIOAB3.
18
19
AST2600:
20
- GPIOT0..GPIOT7 should have been GPIT0..GPIT7.
21
- GPIOU0..GPIOU7 should have been GPIU0..GPIU7.
22
- GPIW0..GPIW7 should have been GPIOW0..GPIOW7.
23
- GPIOY0..GPIOY7 and GPIOZ0...GPIOZ7 were disabled.
24
25
Fixes: 4b7f956862dc2db4c5c ("hw/gpio: Add basic Aspeed GPIO model for AST2400 and AST2500")
26
Fixes: 36d737ee82b2972167e ("hw/gpio: Add in AST2600 specific implementation")
27
Signed-off-by: Peter Delevoryas <pdel@fb.com>
28
Reviewed-by: Damien Hedde <damien.hedde@greensocs.com>
29
Reviewed-by: Rashmica Gupta <rashmica.g@gmail.com>
30
Message-Id: <20210928032456.3192603-2-pdel@fb.com>
31
Signed-off-by: Cédric Le Goater <clg@kaod.org>
32
---
33
hw/gpio/aspeed_gpio.c | 8 ++++----
34
1 file changed, 4 insertions(+), 4 deletions(-)
35
36
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
37
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/gpio/aspeed_gpio.c
17
--- a/hw/arm/aspeed_ast27x0.c
39
+++ b/hw/gpio/aspeed_gpio.c
18
+++ b/hw/arm/aspeed_ast27x0.c
40
@@ -XXX,XX +XXX,XX @@ static const GPIOSetProperties ast2500_set_props[] = {
19
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
41
[3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
20
[ASPEED_DEV_I2C] = 0x14C0F000,
42
[4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
21
[ASPEED_DEV_GPIO] = 0x14C0B000,
43
[5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
22
[ASPEED_DEV_RTC] = 0x12C0F000,
44
- [6] = {0xffffff0f, 0x0fffff0f, {"Y", "Z", "AA", "AB"} },
23
+ [ASPEED_DEV_SDHCI] = 0x14080000,
45
+ [6] = {0x0fffffff, 0x0fffffff, {"Y", "Z", "AA", "AB"} },
46
[7] = {0x000000ff, 0x000000ff, {"AC"} },
47
};
24
};
48
25
49
@@ -XXX,XX +XXX,XX @@ static GPIOSetProperties ast2600_3_3v_set_props[] = {
26
#define AST2700_MAX_IRQ 256
50
[1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
27
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2700_irqmap[] = {
51
[2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
28
[ASPEED_DEV_KCS] = 128,
52
[3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
29
[ASPEED_DEV_DP] = 28,
53
- [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
30
[ASPEED_DEV_I3C] = 131,
54
- [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
31
+ [ASPEED_DEV_SDHCI] = 133,
55
- [6] = {0xffff0000, 0x0fff0000, {"Y", "Z", "", ""} },
56
+ [4] = {0xffffffff, 0x00ffffff, {"Q", "R", "S", "T"} },
57
+ [5] = {0xffffffff, 0xffffff00, {"U", "V", "W", "X"} },
58
+ [6] = {0x0000ffff, 0x0000ffff, {"Y", "Z"} },
59
};
32
};
60
33
61
static GPIOSetProperties ast2600_1_8v_set_props[] = {
34
/* GICINT 128 */
35
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2700_gic132_intcmap[] = {
36
37
/* GICINT 133 */
38
static const int aspeed_soc_ast2700_gic133_intcmap[] = {
39
+ [ASPEED_DEV_SDHCI] = 1,
40
[ASPEED_DEV_PECI] = 4,
41
};
42
43
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700_init(Object *obj)
44
object_initialize_child(obj, "gpio", &s->gpio, typename);
45
46
object_initialize_child(obj, "rtc", &s->rtc, TYPE_ASPEED_RTC);
47
+
48
+ snprintf(typename, sizeof(typename), "aspeed.sdhci-%s", socname);
49
+ object_initialize_child(obj, "sd-controller", &s->sdhci, typename);
50
+ object_property_set_int(OBJECT(&s->sdhci), "num-slots", 1, &error_abort);
51
+
52
+ /* Init sd card slot class here so that they're under the correct parent */
53
+ object_initialize_child(obj, "sd-controller.sdhci",
54
+ &s->sdhci.slots[0], TYPE_SYSBUS_SDHCI);
55
}
56
57
/*
58
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
59
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0,
60
aspeed_soc_get_irq(s, ASPEED_DEV_RTC));
61
62
+ /* SDHCI */
63
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp)) {
64
+ return;
65
+ }
66
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->sdhci), 0,
67
+ sc->memmap[ASPEED_DEV_SDHCI]);
68
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
69
+ aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI));
70
+
71
create_unimplemented_device("ast2700.dpmcu", 0x11000000, 0x40000);
72
create_unimplemented_device("ast2700.iomem0", 0x12000000, 0x01000000);
73
create_unimplemented_device("ast2700.iomem1", 0x14000000, 0x01000000);
62
--
74
--
63
2.31.1
75
2.47.1
64
76
65
77
diff view generated by jsdifflib
1
There is no real reason to use this name. It's simply nice to have in
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
the monitor output but it's a burden for the following patch which
3
removes the AspeedSMCController structure describing the controller.
4
2
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
3
Add SDHCI model for AST2700 eMMC support. The eMMC controller only support 1
4
slot and registers base address is start at 0x1209_0000 and its interrupt is
5
connected to GICINT 15.
6
7
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
8
Reviewed-by: Cédric Le Goater <clg@redhat.com>
9
Link: https://lore.kernel.org/r/20241204084453.610660-7-jamin_lin@aspeedtech.com
10
Signed-off-by: Cédric Le Goater <clg@redhat.com>
6
---
11
---
7
hw/ssi/aspeed_smc.c | 25 ++++++++++---------------
12
hw/arm/aspeed_ast27x0.c | 15 +++++++++++++++
8
1 file changed, 10 insertions(+), 15 deletions(-)
13
1 file changed, 15 insertions(+)
9
14
10
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
15
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
11
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/ssi/aspeed_smc.c
17
--- a/hw/arm/aspeed_ast27x0.c
13
+++ b/hw/ssi/aspeed_smc.c
18
+++ b/hw/arm/aspeed_ast27x0.c
14
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_smc_ops = {
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700_init(Object *obj)
15
*/
20
/* Init sd card slot class here so that they're under the correct parent */
16
static void aspeed_smc_dma_setup(AspeedSMCState *s, Error **errp)
21
object_initialize_child(obj, "sd-controller.sdhci",
17
{
22
&s->sdhci.slots[0], TYPE_SYSBUS_SDHCI);
18
- char *name;
23
+
19
-
24
+ object_initialize_child(obj, "emmc-controller", &s->emmc, typename);
20
if (!s->dram_mr) {
25
+ object_property_set_int(OBJECT(&s->emmc), "num-slots", 1, &error_abort);
21
error_setg(errp, TYPE_ASPEED_SMC ": 'dram' link not set");
26
+
22
return;
27
+ object_initialize_child(obj, "emmc-controller.sdhci", &s->emmc.slots[0],
23
}
28
+ TYPE_SYSBUS_SDHCI);
24
25
- name = g_strdup_printf("%s-dma-flash", s->ctrl->name);
26
- address_space_init(&s->flash_as, &s->mmio_flash, name);
27
- g_free(name);
28
-
29
- name = g_strdup_printf("%s-dma-dram", s->ctrl->name);
30
- address_space_init(&s->dram_as, s->dram_mr, name);
31
- g_free(name);
32
+ address_space_init(&s->flash_as, &s->mmio_flash,
33
+ TYPE_ASPEED_SMC ".dma-flash");
34
+ address_space_init(&s->dram_as, s->dram_mr,
35
+ TYPE_ASPEED_SMC ".dma-dram");
36
}
29
}
37
30
38
static void aspeed_smc_realize(DeviceState *dev, Error **errp)
31
/*
39
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
32
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
40
33
sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
41
/* The memory region for the controller registers */
34
aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI));
42
memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
35
43
- s->ctrl->name, s->ctrl->nregs * 4);
36
+ /* eMMC */
44
+ TYPE_ASPEED_SMC, s->ctrl->nregs * 4);
37
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->emmc), errp)) {
45
sysbus_init_mmio(sbd, &s->mmio);
38
+ return;
46
39
+ }
47
/*
40
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->emmc), 0,
48
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
41
+ sc->memmap[ASPEED_DEV_EMMC]);
49
* window in which the flash modules are mapped. The size and
42
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->emmc), 0,
50
* address depends on the SoC model and controller type.
43
+ aspeed_soc_get_irq(s, ASPEED_DEV_EMMC));
51
*/
44
+
52
- snprintf(name, sizeof(name), "%s.flash", s->ctrl->name);
45
create_unimplemented_device("ast2700.dpmcu", 0x11000000, 0x40000);
53
-
46
create_unimplemented_device("ast2700.iomem0", 0x12000000, 0x01000000);
54
memory_region_init_io(&s->mmio_flash, OBJECT(s),
47
create_unimplemented_device("ast2700.iomem1", 0x14000000, 0x01000000);
55
- &aspeed_smc_flash_default_ops, s, name,
56
+ &aspeed_smc_flash_default_ops, s,
57
+ TYPE_ASPEED_SMC ".flash",
58
s->ctrl->flash_window_size);
59
- memory_region_init_alias(&s->mmio_flash_alias, OBJECT(s), name,
60
+ memory_region_init_alias(&s->mmio_flash_alias, OBJECT(s),
61
+ TYPE_ASPEED_SMC ".flash",
62
&s->mmio_flash, 0, s->ctrl->flash_window_size);
63
sysbus_init_mmio(sbd, &s->mmio_flash_alias);
64
65
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
66
for (i = 0; i < s->ctrl->max_peripherals; ++i) {
67
AspeedSMCFlash *fl = &s->flashes[i];
68
69
- snprintf(name, sizeof(name), "%s.%d", s->ctrl->name, i);
70
+ snprintf(name, sizeof(name), TYPE_ASPEED_SMC ".flash.%d", i);
71
72
fl->id = i;
73
fl->controller = s;
74
--
48
--
75
2.31.1
49
2.47.1
76
50
77
51
diff view generated by jsdifflib
New patch
1
This simply moves the ast1030 tests to a new test file. No changes.
1
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Link: https://lore.kernel.org/r/20241206131132.520911-2-clg@redhat.com
5
Signed-off-by: Cédric Le Goater <clg@redhat.com>
6
---
7
tests/functional/meson.build | 1 +
8
tests/functional/test_arm_aspeed.py | 64 ----------------
9
tests/functional/test_arm_aspeed_ast1030.py | 81 +++++++++++++++++++++
10
3 files changed, 82 insertions(+), 64 deletions(-)
11
create mode 100644 tests/functional/test_arm_aspeed_ast1030.py
12
13
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/functional/meson.build
16
+++ b/tests/functional/meson.build
17
@@ -XXX,XX +XXX,XX @@ tests_alpha_system_thorough = [
18
19
tests_arm_system_thorough = [
20
'arm_aspeed',
21
+ 'arm_aspeed_ast1030',
22
'arm_bpim2u',
23
'arm_canona1100',
24
'arm_collie',
25
diff --git a/tests/functional/test_arm_aspeed.py b/tests/functional/test_arm_aspeed.py
26
index XXXXXXX..XXXXXXX 100755
27
--- a/tests/functional/test_arm_aspeed.py
28
+++ b/tests/functional/test_arm_aspeed.py
29
@@ -XXX,XX +XXX,XX @@
30
from zipfile import ZipFile
31
from unittest import skipUnless
32
33
-class AST1030Machine(LinuxKernelTest):
34
-
35
- ASSET_ZEPHYR_1_04 = Asset(
36
- ('https://github.com/AspeedTech-BMC'
37
- '/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip'),
38
- '4ac6210adcbc61294927918707c6762483fd844dde5e07f3ba834ad1f91434d3')
39
-
40
- def test_ast1030_zephyros_1_04(self):
41
- self.set_machine('ast1030-evb')
42
-
43
- zip_file = self.ASSET_ZEPHYR_1_04.fetch()
44
-
45
- kernel_name = "ast1030-evb-demo/zephyr.elf"
46
- with ZipFile(zip_file, 'r') as zf:
47
- zf.extract(kernel_name, path=self.workdir)
48
- kernel_file = os.path.join(self.workdir, kernel_name)
49
-
50
- self.vm.set_console()
51
- self.vm.add_args('-kernel', kernel_file, '-nographic')
52
- self.vm.launch()
53
- self.wait_for_console_pattern("Booting Zephyr OS")
54
- exec_command_and_wait_for_pattern(self, "help",
55
- "Available commands")
56
-
57
- ASSET_ZEPHYR_1_07 = Asset(
58
- ('https://github.com/AspeedTech-BMC'
59
- '/zephyr/releases/download/v00.01.07/ast1030-evb-demo.zip'),
60
- 'ad52e27959746988afaed8429bf4e12ab988c05c4d07c9d90e13ec6f7be4574c')
61
-
62
- def test_ast1030_zephyros_1_07(self):
63
- self.set_machine('ast1030-evb')
64
-
65
- zip_file = self.ASSET_ZEPHYR_1_07.fetch()
66
-
67
- kernel_name = "ast1030-evb-demo/zephyr.bin"
68
- with ZipFile(zip_file, 'r') as zf:
69
- zf.extract(kernel_name, path=self.workdir)
70
- kernel_file = os.path.join(self.workdir, kernel_name)
71
-
72
- self.vm.set_console()
73
- self.vm.add_args('-kernel', kernel_file, '-nographic')
74
- self.vm.launch()
75
- self.wait_for_console_pattern("Booting Zephyr OS")
76
- for shell_cmd in [
77
- 'kernel stacks',
78
- 'otp info conf',
79
- 'otp info scu',
80
- 'hwinfo devid',
81
- 'crypto aes256_cbc_vault',
82
- 'random get',
83
- 'jtag JTAG1 sw_xfer high TMS',
84
- 'adc ADC0 resolution 12',
85
- 'adc ADC0 read 42',
86
- 'adc ADC1 read 69',
87
- 'i2c scan I2C_0',
88
- 'i3c attach I3C_0',
89
- 'hash test',
90
- 'kernel uptime',
91
- 'kernel reboot warm',
92
- 'kernel uptime',
93
- 'kernel reboot cold',
94
- 'kernel uptime',
95
- ]: exec_command_and_wait_for_pattern(self, shell_cmd, "uart:~$")
96
-
97
class AST2x00Machine(LinuxKernelTest):
98
99
def do_test_arm_aspeed(self, machine, image):
100
diff --git a/tests/functional/test_arm_aspeed_ast1030.py b/tests/functional/test_arm_aspeed_ast1030.py
101
new file mode 100644
102
index XXXXXXX..XXXXXXX
103
--- /dev/null
104
+++ b/tests/functional/test_arm_aspeed_ast1030.py
105
@@ -XXX,XX +XXX,XX @@
106
+#!/usr/bin/env python3
107
+#
108
+# Functional test that boots the ASPEED SoCs with firmware
109
+#
110
+# Copyright (C) 2022 ASPEED Technology Inc
111
+#
112
+# SPDX-License-Identifier: GPL-2.0-or-later
113
+
114
+import os
115
+
116
+from qemu_test import LinuxKernelTest, Asset
117
+from qemu_test import exec_command_and_wait_for_pattern
118
+from zipfile import ZipFile
119
+
120
+class AST1030Machine(LinuxKernelTest):
121
+
122
+ ASSET_ZEPHYR_1_04 = Asset(
123
+ ('https://github.com/AspeedTech-BMC'
124
+ '/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip'),
125
+ '4ac6210adcbc61294927918707c6762483fd844dde5e07f3ba834ad1f91434d3')
126
+
127
+ def test_ast1030_zephyros_1_04(self):
128
+ self.set_machine('ast1030-evb')
129
+
130
+ zip_file = self.ASSET_ZEPHYR_1_04.fetch()
131
+
132
+ kernel_name = "ast1030-evb-demo/zephyr.elf"
133
+ with ZipFile(zip_file, 'r') as zf:
134
+ zf.extract(kernel_name, path=self.workdir)
135
+ kernel_file = os.path.join(self.workdir, kernel_name)
136
+
137
+ self.vm.set_console()
138
+ self.vm.add_args('-kernel', kernel_file, '-nographic')
139
+ self.vm.launch()
140
+ self.wait_for_console_pattern("Booting Zephyr OS")
141
+ exec_command_and_wait_for_pattern(self, "help",
142
+ "Available commands")
143
+
144
+ ASSET_ZEPHYR_1_07 = Asset(
145
+ ('https://github.com/AspeedTech-BMC'
146
+ '/zephyr/releases/download/v00.01.07/ast1030-evb-demo.zip'),
147
+ 'ad52e27959746988afaed8429bf4e12ab988c05c4d07c9d90e13ec6f7be4574c')
148
+
149
+ def test_ast1030_zephyros_1_07(self):
150
+ self.set_machine('ast1030-evb')
151
+
152
+ zip_file = self.ASSET_ZEPHYR_1_07.fetch()
153
+
154
+ kernel_name = "ast1030-evb-demo/zephyr.bin"
155
+ with ZipFile(zip_file, 'r') as zf:
156
+ zf.extract(kernel_name, path=self.workdir)
157
+ kernel_file = os.path.join(self.workdir, kernel_name)
158
+
159
+ self.vm.set_console()
160
+ self.vm.add_args('-kernel', kernel_file, '-nographic')
161
+ self.vm.launch()
162
+ self.wait_for_console_pattern("Booting Zephyr OS")
163
+ for shell_cmd in [
164
+ 'kernel stacks',
165
+ 'otp info conf',
166
+ 'otp info scu',
167
+ 'hwinfo devid',
168
+ 'crypto aes256_cbc_vault',
169
+ 'random get',
170
+ 'jtag JTAG1 sw_xfer high TMS',
171
+ 'adc ADC0 resolution 12',
172
+ 'adc ADC0 read 42',
173
+ 'adc ADC1 read 69',
174
+ 'i2c scan I2C_0',
175
+ 'i3c attach I3C_0',
176
+ 'hash test',
177
+ 'kernel uptime',
178
+ 'kernel reboot warm',
179
+ 'kernel uptime',
180
+ 'kernel reboot cold',
181
+ 'kernel uptime',
182
+ ]: exec_command_and_wait_for_pattern(self, shell_cmd, "uart:~$")
183
+
184
+
185
+if __name__ == '__main__':
186
+ LinuxKernelTest.main()
187
--
188
2.47.1
189
190
diff view generated by jsdifflib
New patch
1
This introduces a new aspeed module for sharing code between tests and
2
moves the palmetto test to a new test file. No changes in the test.
1
3
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Link: https://lore.kernel.org/r/20241206131132.520911-3-clg@redhat.com
6
Signed-off-by: Cédric Le Goater <clg@redhat.com>
7
---
8
tests/functional/aspeed.py | 23 +++++++++++++++++++
9
tests/functional/meson.build | 2 ++
10
tests/functional/test_arm_aspeed.py | 10 --------
11
tests/functional/test_arm_aspeed_palmetto.py | 24 ++++++++++++++++++++
12
4 files changed, 49 insertions(+), 10 deletions(-)
13
create mode 100644 tests/functional/aspeed.py
14
create mode 100644 tests/functional/test_arm_aspeed_palmetto.py
15
16
diff --git a/tests/functional/aspeed.py b/tests/functional/aspeed.py
17
new file mode 100644
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
20
+++ b/tests/functional/aspeed.py
21
@@ -XXX,XX +XXX,XX @@
22
+# Test class to boot aspeed machines
23
+#
24
+# SPDX-License-Identifier: GPL-2.0-or-later
25
+
26
+from qemu_test import LinuxKernelTest
27
+
28
+class AspeedTest(LinuxKernelTest):
29
+
30
+ def do_test_arm_aspeed(self, machine, image):
31
+ self.set_machine(machine)
32
+ self.vm.set_console()
33
+ self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
34
+ '-net', 'nic', '-snapshot')
35
+ self.vm.launch()
36
+
37
+ self.wait_for_console_pattern("U-Boot 2016.07")
38
+ self.wait_for_console_pattern("## Loading kernel from FIT Image at 20080000")
39
+ self.wait_for_console_pattern("Starting kernel ...")
40
+ self.wait_for_console_pattern("Booting Linux on physical CPU 0x0")
41
+ self.wait_for_console_pattern(
42
+ "aspeed-smc 1e620000.spi: read control register: 203b0641")
43
+ self.wait_for_console_pattern("ftgmac100 1e660000.ethernet eth0: irq ")
44
+ self.wait_for_console_pattern("systemd[1]: Set hostname to")
45
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
46
index XXXXXXX..XXXXXXX 100644
47
--- a/tests/functional/meson.build
48
+++ b/tests/functional/meson.build
49
@@ -XXX,XX +XXX,XX @@ test_timeouts = {
50
'aarch64_tuxrun' : 240,
51
'aarch64_virt' : 720,
52
'acpi_bits' : 420,
53
+ 'arm_aspeed_palmetto' : 120,
54
'arm_aspeed' : 600,
55
'arm_bpim2u' : 500,
56
'arm_collie' : 180,
57
@@ -XXX,XX +XXX,XX @@ tests_alpha_system_thorough = [
58
tests_arm_system_thorough = [
59
'arm_aspeed',
60
'arm_aspeed_ast1030',
61
+ 'arm_aspeed_palmetto',
62
'arm_bpim2u',
63
'arm_canona1100',
64
'arm_collie',
65
diff --git a/tests/functional/test_arm_aspeed.py b/tests/functional/test_arm_aspeed.py
66
index XXXXXXX..XXXXXXX 100755
67
--- a/tests/functional/test_arm_aspeed.py
68
+++ b/tests/functional/test_arm_aspeed.py
69
@@ -XXX,XX +XXX,XX @@ def do_test_arm_aspeed(self, machine, image):
70
self.wait_for_console_pattern("ftgmac100 1e660000.ethernet eth0: irq ")
71
self.wait_for_console_pattern("systemd[1]: Set hostname to")
72
73
- ASSET_PALMETTO_FLASH = Asset(
74
- ('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
75
- 'obmc-phosphor-image-palmetto.static.mtd'),
76
- '3e13bbbc28e424865dc42f35ad672b10f2e82cdb11846bb28fa625b48beafd0d');
77
-
78
- def test_arm_ast2400_palmetto_openbmc_v2_9_0(self):
79
- image_path = self.ASSET_PALMETTO_FLASH.fetch()
80
-
81
- self.do_test_arm_aspeed('palmetto-bmc', image_path)
82
-
83
ASSET_ROMULUS_FLASH = Asset(
84
('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
85
'obmc-phosphor-image-romulus.static.mtd'),
86
diff --git a/tests/functional/test_arm_aspeed_palmetto.py b/tests/functional/test_arm_aspeed_palmetto.py
87
new file mode 100644
88
index XXXXXXX..XXXXXXX
89
--- /dev/null
90
+++ b/tests/functional/test_arm_aspeed_palmetto.py
91
@@ -XXX,XX +XXX,XX @@
92
+#!/usr/bin/env python3
93
+#
94
+# Functional test that boots the ASPEED machines
95
+#
96
+# SPDX-License-Identifier: GPL-2.0-or-later
97
+
98
+from qemu_test import Asset
99
+from aspeed import AspeedTest
100
+
101
+class PalmettoMachine(AspeedTest):
102
+
103
+ ASSET_PALMETTO_FLASH = Asset(
104
+ ('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
105
+ 'obmc-phosphor-image-palmetto.static.mtd'),
106
+ '3e13bbbc28e424865dc42f35ad672b10f2e82cdb11846bb28fa625b48beafd0d');
107
+
108
+ def test_arm_ast2400_palmetto_openbmc_v2_9_0(self):
109
+ image_path = self.ASSET_PALMETTO_FLASH.fetch()
110
+
111
+ self.do_test_arm_aspeed('palmetto-bmc', image_path)
112
+
113
+
114
+if __name__ == '__main__':
115
+ AspeedTest.main()
116
--
117
2.47.1
118
119
diff view generated by jsdifflib
New patch
1
This simply moves the romulus-bmc test to a new test file. No changes
2
in the test. The do_test_arm_aspeed routine is removed from the
3
test_arm_aspeed.py file because it is now unused.
1
4
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Link: https://lore.kernel.org/r/20241206131132.520911-4-clg@redhat.com
7
Signed-off-by: Cédric Le Goater <clg@redhat.com>
8
---
9
tests/functional/meson.build | 2 ++
10
tests/functional/test_arm_aspeed.py | 26 ---------------------
11
tests/functional/test_arm_aspeed_romulus.py | 24 +++++++++++++++++++
12
3 files changed, 26 insertions(+), 26 deletions(-)
13
create mode 100644 tests/functional/test_arm_aspeed_romulus.py
14
15
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
16
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/functional/meson.build
18
+++ b/tests/functional/meson.build
19
@@ -XXX,XX +XXX,XX @@ test_timeouts = {
20
'aarch64_virt' : 720,
21
'acpi_bits' : 420,
22
'arm_aspeed_palmetto' : 120,
23
+ 'arm_aspeed_romulus' : 120,
24
'arm_aspeed' : 600,
25
'arm_bpim2u' : 500,
26
'arm_collie' : 180,
27
@@ -XXX,XX +XXX,XX @@ tests_arm_system_thorough = [
28
'arm_aspeed',
29
'arm_aspeed_ast1030',
30
'arm_aspeed_palmetto',
31
+ 'arm_aspeed_romulus',
32
'arm_bpim2u',
33
'arm_canona1100',
34
'arm_collie',
35
diff --git a/tests/functional/test_arm_aspeed.py b/tests/functional/test_arm_aspeed.py
36
index XXXXXXX..XXXXXXX 100755
37
--- a/tests/functional/test_arm_aspeed.py
38
+++ b/tests/functional/test_arm_aspeed.py
39
@@ -XXX,XX +XXX,XX @@
40
41
class AST2x00Machine(LinuxKernelTest):
42
43
- def do_test_arm_aspeed(self, machine, image):
44
- self.set_machine(machine)
45
- self.vm.set_console()
46
- self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
47
- '-net', 'nic', '-snapshot')
48
- self.vm.launch()
49
-
50
- self.wait_for_console_pattern("U-Boot 2016.07")
51
- self.wait_for_console_pattern("## Loading kernel from FIT Image at 20080000")
52
- self.wait_for_console_pattern("Starting kernel ...")
53
- self.wait_for_console_pattern("Booting Linux on physical CPU 0x0")
54
- self.wait_for_console_pattern(
55
- "aspeed-smc 1e620000.spi: read control register: 203b0641")
56
- self.wait_for_console_pattern("ftgmac100 1e660000.ethernet eth0: irq ")
57
- self.wait_for_console_pattern("systemd[1]: Set hostname to")
58
-
59
- ASSET_ROMULUS_FLASH = Asset(
60
- ('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
61
- 'obmc-phosphor-image-romulus.static.mtd'),
62
- '820341076803f1955bc31e647a512c79f9add4f5233d0697678bab4604c7bb25')
63
-
64
- def test_arm_ast2500_romulus_openbmc_v2_9_0(self):
65
- image_path = self.ASSET_ROMULUS_FLASH.fetch()
66
-
67
- self.do_test_arm_aspeed('romulus-bmc', image_path)
68
-
69
def do_test_arm_aspeed_buildroot_start(self, image, cpu_id, pattern='Aspeed EVB'):
70
self.require_netdev('user')
71
self.vm.set_console()
72
diff --git a/tests/functional/test_arm_aspeed_romulus.py b/tests/functional/test_arm_aspeed_romulus.py
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/tests/functional/test_arm_aspeed_romulus.py
77
@@ -XXX,XX +XXX,XX @@
78
+#!/usr/bin/env python3
79
+#
80
+# Functional test that boots the ASPEED machines
81
+#
82
+# SPDX-License-Identifier: GPL-2.0-or-later
83
+
84
+from qemu_test import Asset
85
+from aspeed import AspeedTest
86
+
87
+class RomulusMachine(AspeedTest):
88
+
89
+ ASSET_ROMULUS_FLASH = Asset(
90
+ ('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
91
+ 'obmc-phosphor-image-romulus.static.mtd'),
92
+ '820341076803f1955bc31e647a512c79f9add4f5233d0697678bab4604c7bb25')
93
+
94
+ def test_arm_ast2500_romulus_openbmc_v2_9_0(self):
95
+ image_path = self.ASSET_ROMULUS_FLASH.fetch()
96
+
97
+ self.do_test_arm_aspeed('romulus-bmc', image_path)
98
+
99
+
100
+if __name__ == '__main__':
101
+ AspeedTest.main()
102
--
103
2.47.1
104
105
diff view generated by jsdifflib
New patch
1
1
This moves the ast2500-evb tests to a new test file and extends the
2
aspeed module with routines used to run the buildroot and sdk
3
tests. No changes in the test.
4
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Link: https://lore.kernel.org/r/20241206131132.520911-5-clg@redhat.com
7
Signed-off-by: Cédric Le Goater <clg@redhat.com>
8
---
9
tests/functional/aspeed.py | 33 ++++++++++++
10
tests/functional/meson.build | 2 +
11
tests/functional/test_arm_aspeed.py | 44 ---------------
12
tests/functional/test_arm_aspeed_ast2500.py | 59 +++++++++++++++++++++
13
4 files changed, 94 insertions(+), 44 deletions(-)
14
create mode 100644 tests/functional/test_arm_aspeed_ast2500.py
15
16
diff --git a/tests/functional/aspeed.py b/tests/functional/aspeed.py
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/functional/aspeed.py
19
+++ b/tests/functional/aspeed.py
20
@@ -XXX,XX +XXX,XX @@
21
#
22
# SPDX-License-Identifier: GPL-2.0-or-later
23
24
+from qemu_test import exec_command_and_wait_for_pattern
25
from qemu_test import LinuxKernelTest
26
27
class AspeedTest(LinuxKernelTest):
28
@@ -XXX,XX +XXX,XX @@ def do_test_arm_aspeed(self, machine, image):
29
"aspeed-smc 1e620000.spi: read control register: 203b0641")
30
self.wait_for_console_pattern("ftgmac100 1e660000.ethernet eth0: irq ")
31
self.wait_for_console_pattern("systemd[1]: Set hostname to")
32
+
33
+ def do_test_arm_aspeed_buildroot_start(self, image, cpu_id, pattern='Aspeed EVB'):
34
+ self.require_netdev('user')
35
+ self.vm.set_console()
36
+ self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw,read-only=true',
37
+ '-net', 'nic', '-net', 'user')
38
+ self.vm.launch()
39
+
40
+ self.wait_for_console_pattern('U-Boot 2019.04')
41
+ self.wait_for_console_pattern('## Loading kernel from FIT Image')
42
+ self.wait_for_console_pattern('Starting kernel ...')
43
+ self.wait_for_console_pattern('Booting Linux on physical CPU ' + cpu_id)
44
+ self.wait_for_console_pattern('lease of 10.0.2.15')
45
+ # the line before login:
46
+ self.wait_for_console_pattern(pattern)
47
+ exec_command_and_wait_for_pattern(self, 'root', 'Password:')
48
+ exec_command_and_wait_for_pattern(self, 'passw0rd', '#')
49
+
50
+ def do_test_arm_aspeed_buildroot_poweroff(self):
51
+ exec_command_and_wait_for_pattern(self, 'poweroff',
52
+ 'reboot: System halted');
53
+
54
+ def do_test_arm_aspeed_sdk_start(self, image):
55
+ self.require_netdev('user')
56
+ self.vm.set_console()
57
+ self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
58
+ '-net', 'nic', '-net', 'user', '-snapshot')
59
+ self.vm.launch()
60
+
61
+ self.wait_for_console_pattern('U-Boot 2019.04')
62
+ self.wait_for_console_pattern('## Loading kernel from FIT Image')
63
+ self.wait_for_console_pattern('Starting kernel ...')
64
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
65
index XXXXXXX..XXXXXXX 100644
66
--- a/tests/functional/meson.build
67
+++ b/tests/functional/meson.build
68
@@ -XXX,XX +XXX,XX @@ test_timeouts = {
69
'acpi_bits' : 420,
70
'arm_aspeed_palmetto' : 120,
71
'arm_aspeed_romulus' : 120,
72
+ 'arm_aspeed_ast2500' : 480,
73
'arm_aspeed' : 600,
74
'arm_bpim2u' : 500,
75
'arm_collie' : 180,
76
@@ -XXX,XX +XXX,XX @@ tests_arm_system_thorough = [
77
'arm_aspeed_ast1030',
78
'arm_aspeed_palmetto',
79
'arm_aspeed_romulus',
80
+ 'arm_aspeed_ast2500',
81
'arm_bpim2u',
82
'arm_canona1100',
83
'arm_collie',
84
diff --git a/tests/functional/test_arm_aspeed.py b/tests/functional/test_arm_aspeed.py
85
index XXXXXXX..XXXXXXX 100755
86
--- a/tests/functional/test_arm_aspeed.py
87
+++ b/tests/functional/test_arm_aspeed.py
88
@@ -XXX,XX +XXX,XX @@ def do_test_arm_aspeed_buildroot_start(self, image, cpu_id, pattern='Aspeed EVB'
89
def do_test_arm_aspeed_buildroot_poweroff(self):
90
exec_command_and_wait_for_pattern(self, 'poweroff',
91
'reboot: System halted');
92
-
93
- ASSET_BR2_202311_AST2500_FLASH = Asset(
94
- ('https://github.com/legoater/qemu-aspeed-boot/raw/master/'
95
- 'images/ast2500-evb/buildroot-2023.11/flash.img'),
96
- 'c23db6160cf77d0258397eb2051162c8473a56c441417c52a91ba217186e715f')
97
-
98
- def test_arm_ast2500_evb_buildroot(self):
99
- self.set_machine('ast2500-evb')
100
-
101
- image_path = self.ASSET_BR2_202311_AST2500_FLASH.fetch()
102
-
103
- self.vm.add_args('-device',
104
- 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test');
105
- self.do_test_arm_aspeed_buildroot_start(image_path, '0x0',
106
- 'ast2500-evb login:')
107
-
108
- exec_command_and_wait_for_pattern(self,
109
- 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device',
110
- 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
111
- exec_command_and_wait_for_pattern(self,
112
- 'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
113
- self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
114
- property='temperature', value=18000);
115
- exec_command_and_wait_for_pattern(self,
116
- 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
117
-
118
- self.do_test_arm_aspeed_buildroot_poweroff()
119
-
120
ASSET_BR2_202311_AST2600_FLASH = Asset(
121
('https://github.com/legoater/qemu-aspeed-boot/raw/master/'
122
'images/ast2600-evb/buildroot-2023.11/flash.img'),
123
@@ -XXX,XX +XXX,XX @@ def do_test_arm_aspeed_sdk_start(self, image):
124
self.wait_for_console_pattern('## Loading kernel from FIT Image')
125
self.wait_for_console_pattern('Starting kernel ...')
126
127
- ASSET_SDK_V806_AST2500 = Asset(
128
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2500-default-obmc.tar.gz',
129
- 'e1755f3cadff69190438c688d52dd0f0d399b70a1e14b1d3d5540fc4851d38ca')
130
-
131
- def test_arm_ast2500_evb_sdk(self):
132
- self.set_machine('ast2500-evb')
133
-
134
- image_path = self.ASSET_SDK_V806_AST2500.fetch()
135
-
136
- archive_extract(image_path, self.workdir)
137
-
138
- self.do_test_arm_aspeed_sdk_start(
139
- self.workdir + '/ast2500-default/image-bmc')
140
-
141
- self.wait_for_console_pattern('ast2500-default login:')
142
-
143
ASSET_SDK_V806_AST2600_A2 = Asset(
144
'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2600-a2-obmc.tar.gz',
145
'9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4')
146
diff --git a/tests/functional/test_arm_aspeed_ast2500.py b/tests/functional/test_arm_aspeed_ast2500.py
147
new file mode 100644
148
index XXXXXXX..XXXXXXX
149
--- /dev/null
150
+++ b/tests/functional/test_arm_aspeed_ast2500.py
151
@@ -XXX,XX +XXX,XX @@
152
+#!/usr/bin/env python3
153
+#
154
+# Functional test that boots the ASPEED machines
155
+#
156
+# SPDX-License-Identifier: GPL-2.0-or-later
157
+
158
+from qemu_test import Asset
159
+from aspeed import AspeedTest
160
+from qemu_test import exec_command_and_wait_for_pattern
161
+from qemu_test.utils import archive_extract
162
+
163
+class AST2500Machine(AspeedTest):
164
+
165
+ ASSET_BR2_202311_AST2500_FLASH = Asset(
166
+ ('https://github.com/legoater/qemu-aspeed-boot/raw/master/'
167
+ 'images/ast2500-evb/buildroot-2023.11/flash.img'),
168
+ 'c23db6160cf77d0258397eb2051162c8473a56c441417c52a91ba217186e715f')
169
+
170
+ def test_arm_ast2500_evb_buildroot(self):
171
+ self.set_machine('ast2500-evb')
172
+
173
+ image_path = self.ASSET_BR2_202311_AST2500_FLASH.fetch()
174
+
175
+ self.vm.add_args('-device',
176
+ 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test');
177
+ self.do_test_arm_aspeed_buildroot_start(image_path, '0x0',
178
+ 'ast2500-evb login:')
179
+
180
+ exec_command_and_wait_for_pattern(self,
181
+ 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device',
182
+ 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
183
+ exec_command_and_wait_for_pattern(self,
184
+ 'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
185
+ self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
186
+ property='temperature', value=18000);
187
+ exec_command_and_wait_for_pattern(self,
188
+ 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
189
+
190
+ self.do_test_arm_aspeed_buildroot_poweroff()
191
+
192
+ ASSET_SDK_V806_AST2500 = Asset(
193
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2500-default-obmc.tar.gz',
194
+ 'e1755f3cadff69190438c688d52dd0f0d399b70a1e14b1d3d5540fc4851d38ca')
195
+
196
+ def test_arm_ast2500_evb_sdk(self):
197
+ self.set_machine('ast2500-evb')
198
+
199
+ image_path = self.ASSET_SDK_V806_AST2500.fetch()
200
+
201
+ archive_extract(image_path, self.workdir)
202
+
203
+ self.do_test_arm_aspeed_sdk_start(
204
+ self.workdir + '/ast2500-default/image-bmc')
205
+
206
+ self.wait_for_console_pattern('ast2500-default login:')
207
+
208
+
209
+if __name__ == '__main__':
210
+ AspeedTest.main()
211
--
212
2.47.1
213
214
diff view generated by jsdifflib
1
The register index is currently printed and this is confusing.
1
This moves the ast2600-evb tests to a new test file. No changes in the
2
test. The routines used to run the buildroot and sdk tests are removed
3
from the test_arm_aspeed.py file because now unused.
2
4
3
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Link: https://lore.kernel.org/r/20241206131132.520911-6-clg@redhat.com
7
Signed-off-by: Cédric Le Goater <clg@redhat.com>
5
---
8
---
6
hw/ssi/aspeed_smc.c | 6 +++---
9
tests/functional/meson.build | 2 +
7
1 file changed, 3 insertions(+), 3 deletions(-)
10
tests/functional/test_arm_aspeed.py | 155 --------------------
11
tests/functional/test_arm_aspeed_ast2600.py | 143 ++++++++++++++++++
12
3 files changed, 145 insertions(+), 155 deletions(-)
13
create mode 100644 tests/functional/test_arm_aspeed_ast2600.py
8
14
9
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
15
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
10
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/ssi/aspeed_smc.c
17
--- a/tests/functional/meson.build
12
+++ b/hw/ssi/aspeed_smc.c
18
+++ b/tests/functional/meson.build
13
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
19
@@ -XXX,XX +XXX,XX @@ test_timeouts = {
14
addr < R_SEG_ADDR0 + asc->max_peripherals) ||
20
'arm_aspeed_palmetto' : 120,
15
(addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->max_peripherals)) {
21
'arm_aspeed_romulus' : 120,
16
22
'arm_aspeed_ast2500' : 480,
17
- trace_aspeed_smc_read(addr, size, s->regs[addr]);
23
+ 'arm_aspeed_ast2600' : 720,
18
+ trace_aspeed_smc_read(addr << 2, size, s->regs[addr]);
24
'arm_aspeed' : 600,
19
25
'arm_bpim2u' : 500,
20
return s->regs[addr];
26
'arm_collie' : 180,
21
} else {
27
@@ -XXX,XX +XXX,XX @@ tests_arm_system_thorough = [
22
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
28
'arm_aspeed_palmetto',
23
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
29
'arm_aspeed_romulus',
24
uint32_t value = data;
30
'arm_aspeed_ast2500',
25
31
+ 'arm_aspeed_ast2600',
26
- addr >>= 2;
32
'arm_bpim2u',
27
-
33
'arm_canona1100',
28
trace_aspeed_smc_write(addr, size, data);
34
'arm_collie',
29
35
diff --git a/tests/functional/test_arm_aspeed.py b/tests/functional/test_arm_aspeed.py
30
+ addr >>= 2;
36
index XXXXXXX..XXXXXXX 100755
31
+
37
--- a/tests/functional/test_arm_aspeed.py
32
if (addr == s->r_conf ||
38
+++ b/tests/functional/test_arm_aspeed.py
33
(addr >= s->r_timings &&
39
@@ -XXX,XX +XXX,XX @@
34
addr < s->r_timings + asc->nregs_timings) ||
40
from zipfile import ZipFile
41
from unittest import skipUnless
42
43
-class AST2x00Machine(LinuxKernelTest):
44
-
45
- def do_test_arm_aspeed_buildroot_start(self, image, cpu_id, pattern='Aspeed EVB'):
46
- self.require_netdev('user')
47
- self.vm.set_console()
48
- self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw,read-only=true',
49
- '-net', 'nic', '-net', 'user')
50
- self.vm.launch()
51
-
52
- self.wait_for_console_pattern('U-Boot 2019.04')
53
- self.wait_for_console_pattern('## Loading kernel from FIT Image')
54
- self.wait_for_console_pattern('Starting kernel ...')
55
- self.wait_for_console_pattern('Booting Linux on physical CPU ' + cpu_id)
56
- self.wait_for_console_pattern('lease of 10.0.2.15')
57
- # the line before login:
58
- self.wait_for_console_pattern(pattern)
59
- exec_command_and_wait_for_pattern(self, 'root', 'Password:')
60
- exec_command_and_wait_for_pattern(self, 'passw0rd', '#')
61
-
62
- def do_test_arm_aspeed_buildroot_poweroff(self):
63
- exec_command_and_wait_for_pattern(self, 'poweroff',
64
- 'reboot: System halted');
65
- ASSET_BR2_202311_AST2600_FLASH = Asset(
66
- ('https://github.com/legoater/qemu-aspeed-boot/raw/master/'
67
- 'images/ast2600-evb/buildroot-2023.11/flash.img'),
68
- 'b62808daef48b438d0728ee07662290490ecfa65987bb91294cafb1bb7ad1a68')
69
-
70
- def test_arm_ast2600_evb_buildroot(self):
71
- self.set_machine('ast2600-evb')
72
-
73
- image_path = self.ASSET_BR2_202311_AST2600_FLASH.fetch()
74
-
75
- self.vm.add_args('-device',
76
- 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test');
77
- self.vm.add_args('-device',
78
- 'ds1338,bus=aspeed.i2c.bus.3,address=0x32');
79
- self.vm.add_args('-device',
80
- 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42');
81
- self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00',
82
- 'ast2600-evb login:')
83
-
84
- exec_command_and_wait_for_pattern(self,
85
- 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device',
86
- 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
87
- exec_command_and_wait_for_pattern(self,
88
- 'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
89
- self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
90
- property='temperature', value=18000);
91
- exec_command_and_wait_for_pattern(self,
92
- 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
93
-
94
- exec_command_and_wait_for_pattern(self,
95
- 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-3/device/new_device',
96
- 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32');
97
- year = time.strftime("%Y")
98
- exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year);
99
-
100
- exec_command_and_wait_for_pattern(self,
101
- 'echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-3/new_device',
102
- 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64');
103
- exec_command_and_wait_for_pattern(self,
104
- 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#');
105
- exec_command_and_wait_for_pattern(self,
106
- 'hexdump /sys/bus/i2c/devices/3-1064/slave-eeprom',
107
- '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff');
108
- self.do_test_arm_aspeed_buildroot_poweroff()
109
-
110
- ASSET_BR2_202302_AST2600_TPM_FLASH = Asset(
111
- ('https://github.com/legoater/qemu-aspeed-boot/raw/master/'
112
- 'images/ast2600-evb/buildroot-2023.02-tpm/flash.img'),
113
- 'a46009ae8a5403a0826d607215e731a8c68d27c14c41e55331706b8f9c7bd997')
114
-
115
- @skipUnless(*has_cmd('swtpm'))
116
- def test_arm_ast2600_evb_buildroot_tpm(self):
117
- self.set_machine('ast2600-evb')
118
-
119
- image_path = self.ASSET_BR2_202302_AST2600_TPM_FLASH.fetch()
120
-
121
- tpmstate_dir = tempfile.TemporaryDirectory(prefix="qemu_")
122
- socket = os.path.join(tpmstate_dir.name, 'swtpm-socket')
123
-
124
- # We must put the TPM state dir in /tmp/, not the build dir,
125
- # because some distros use AppArmor to lock down swtpm and
126
- # restrict the set of locations it can access files in.
127
- subprocess.run(['swtpm', 'socket', '-d', '--tpm2',
128
- '--tpmstate', f'dir={tpmstate_dir.name}',
129
- '--ctrl', f'type=unixio,path={socket}'])
130
-
131
- self.vm.add_args('-chardev', f'socket,id=chrtpm,path={socket}')
132
- self.vm.add_args('-tpmdev', 'emulator,id=tpm0,chardev=chrtpm')
133
- self.vm.add_args('-device',
134
- 'tpm-tis-i2c,tpmdev=tpm0,bus=aspeed.i2c.bus.12,address=0x2e')
135
- self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00', 'Aspeed AST2600 EVB')
136
-
137
- exec_command_and_wait_for_pattern(self,
138
- 'echo tpm_tis_i2c 0x2e > /sys/bus/i2c/devices/i2c-12/new_device',
139
- 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)');
140
- exec_command_and_wait_for_pattern(self,
141
- 'cat /sys/class/tpm/tpm0/pcr-sha256/0',
142
- 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0');
143
-
144
- self.do_test_arm_aspeed_buildroot_poweroff()
145
-
146
- def do_test_arm_aspeed_sdk_start(self, image):
147
- self.require_netdev('user')
148
- self.vm.set_console()
149
- self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
150
- '-net', 'nic', '-net', 'user', '-snapshot')
151
- self.vm.launch()
152
-
153
- self.wait_for_console_pattern('U-Boot 2019.04')
154
- self.wait_for_console_pattern('## Loading kernel from FIT Image')
155
- self.wait_for_console_pattern('Starting kernel ...')
156
-
157
- ASSET_SDK_V806_AST2600_A2 = Asset(
158
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2600-a2-obmc.tar.gz',
159
- '9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4')
160
-
161
- def test_arm_ast2600_evb_sdk(self):
162
- self.set_machine('ast2600-evb')
163
-
164
- image_path = self.ASSET_SDK_V806_AST2600_A2.fetch()
165
-
166
- archive_extract(image_path, self.workdir)
167
-
168
- self.vm.add_args('-device',
169
- 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test');
170
- self.vm.add_args('-device',
171
- 'ds1338,bus=aspeed.i2c.bus.5,address=0x32');
172
- self.do_test_arm_aspeed_sdk_start(
173
- self.workdir + '/ast2600-a2/image-bmc')
174
-
175
- self.wait_for_console_pattern('ast2600-a2 login:')
176
-
177
- exec_command_and_wait_for_pattern(self, 'root', 'Password:')
178
- exec_command_and_wait_for_pattern(self, '0penBmc', 'root@ast2600-a2:~#')
179
-
180
- exec_command_and_wait_for_pattern(self,
181
- 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device',
182
- 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d');
183
- exec_command_and_wait_for_pattern(self,
184
- 'cat /sys/class/hwmon/hwmon19/temp1_input', '0')
185
- self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
186
- property='temperature', value=18000);
187
- exec_command_and_wait_for_pattern(self,
188
- 'cat /sys/class/hwmon/hwmon19/temp1_input', '18000')
189
-
190
- exec_command_and_wait_for_pattern(self,
191
- 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device',
192
- 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32');
193
- year = time.strftime("%Y")
194
- exec_command_and_wait_for_pattern(self,
195
- '/sbin/hwclock -f /dev/rtc1', year);
196
-
197
-
198
class AST2x00MachineMMC(LinuxKernelTest):
199
200
ASSET_RAINIER_EMMC = Asset(
201
diff --git a/tests/functional/test_arm_aspeed_ast2600.py b/tests/functional/test_arm_aspeed_ast2600.py
202
new file mode 100644
203
index XXXXXXX..XXXXXXX
204
--- /dev/null
205
+++ b/tests/functional/test_arm_aspeed_ast2600.py
206
@@ -XXX,XX +XXX,XX @@
207
+#!/usr/bin/env python3
208
+#
209
+# Functional test that boots the ASPEED machines
210
+#
211
+# SPDX-License-Identifier: GPL-2.0-or-later
212
+
213
+import os
214
+import time
215
+import tempfile
216
+import subprocess
217
+
218
+from qemu_test import Asset
219
+from aspeed import AspeedTest
220
+from qemu_test import exec_command_and_wait_for_pattern
221
+from qemu_test import has_cmd
222
+from qemu_test.utils import archive_extract
223
+from unittest import skipUnless
224
+
225
+class AST2600Machine(AspeedTest):
226
+
227
+ ASSET_BR2_202311_AST2600_FLASH = Asset(
228
+ ('https://github.com/legoater/qemu-aspeed-boot/raw/master/'
229
+ 'images/ast2600-evb/buildroot-2023.11/flash.img'),
230
+ 'b62808daef48b438d0728ee07662290490ecfa65987bb91294cafb1bb7ad1a68')
231
+
232
+ def test_arm_ast2600_evb_buildroot(self):
233
+ self.set_machine('ast2600-evb')
234
+
235
+ image_path = self.ASSET_BR2_202311_AST2600_FLASH.fetch()
236
+
237
+ self.vm.add_args('-device',
238
+ 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test');
239
+ self.vm.add_args('-device',
240
+ 'ds1338,bus=aspeed.i2c.bus.3,address=0x32');
241
+ self.vm.add_args('-device',
242
+ 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42');
243
+ self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00',
244
+ 'ast2600-evb login:')
245
+
246
+ exec_command_and_wait_for_pattern(self,
247
+ 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device',
248
+ 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
249
+ exec_command_and_wait_for_pattern(self,
250
+ 'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
251
+ self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
252
+ property='temperature', value=18000);
253
+ exec_command_and_wait_for_pattern(self,
254
+ 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
255
+
256
+ exec_command_and_wait_for_pattern(self,
257
+ 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-3/device/new_device',
258
+ 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32');
259
+ year = time.strftime("%Y")
260
+ exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year);
261
+
262
+ exec_command_and_wait_for_pattern(self,
263
+ 'echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-3/new_device',
264
+ 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64');
265
+ exec_command_and_wait_for_pattern(self,
266
+ 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#');
267
+ exec_command_and_wait_for_pattern(self,
268
+ 'hexdump /sys/bus/i2c/devices/3-1064/slave-eeprom',
269
+ '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff');
270
+ self.do_test_arm_aspeed_buildroot_poweroff()
271
+
272
+ ASSET_BR2_202302_AST2600_TPM_FLASH = Asset(
273
+ ('https://github.com/legoater/qemu-aspeed-boot/raw/master/'
274
+ 'images/ast2600-evb/buildroot-2023.02-tpm/flash.img'),
275
+ 'a46009ae8a5403a0826d607215e731a8c68d27c14c41e55331706b8f9c7bd997')
276
+
277
+ @skipUnless(*has_cmd('swtpm'))
278
+ def test_arm_ast2600_evb_buildroot_tpm(self):
279
+ self.set_machine('ast2600-evb')
280
+
281
+ image_path = self.ASSET_BR2_202302_AST2600_TPM_FLASH.fetch()
282
+
283
+ tpmstate_dir = tempfile.TemporaryDirectory(prefix="qemu_")
284
+ socket = os.path.join(tpmstate_dir.name, 'swtpm-socket')
285
+
286
+ # We must put the TPM state dir in /tmp/, not the build dir,
287
+ # because some distros use AppArmor to lock down swtpm and
288
+ # restrict the set of locations it can access files in.
289
+ subprocess.run(['swtpm', 'socket', '-d', '--tpm2',
290
+ '--tpmstate', f'dir={tpmstate_dir.name}',
291
+ '--ctrl', f'type=unixio,path={socket}'])
292
+
293
+ self.vm.add_args('-chardev', f'socket,id=chrtpm,path={socket}')
294
+ self.vm.add_args('-tpmdev', 'emulator,id=tpm0,chardev=chrtpm')
295
+ self.vm.add_args('-device',
296
+ 'tpm-tis-i2c,tpmdev=tpm0,bus=aspeed.i2c.bus.12,address=0x2e')
297
+ self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00', 'Aspeed AST2600 EVB')
298
+
299
+ exec_command_and_wait_for_pattern(self,
300
+ 'echo tpm_tis_i2c 0x2e > /sys/bus/i2c/devices/i2c-12/new_device',
301
+ 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)');
302
+ exec_command_and_wait_for_pattern(self,
303
+ 'cat /sys/class/tpm/tpm0/pcr-sha256/0',
304
+ 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0');
305
+
306
+ self.do_test_arm_aspeed_buildroot_poweroff()
307
+
308
+ ASSET_SDK_V806_AST2600_A2 = Asset(
309
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2600-a2-obmc.tar.gz',
310
+ '9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4')
311
+
312
+ def test_arm_ast2600_evb_sdk(self):
313
+ self.set_machine('ast2600-evb')
314
+
315
+ image_path = self.ASSET_SDK_V806_AST2600_A2.fetch()
316
+
317
+ archive_extract(image_path, self.workdir)
318
+
319
+ self.vm.add_args('-device',
320
+ 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test');
321
+ self.vm.add_args('-device',
322
+ 'ds1338,bus=aspeed.i2c.bus.5,address=0x32');
323
+ self.do_test_arm_aspeed_sdk_start(
324
+ self.workdir + '/ast2600-a2/image-bmc')
325
+
326
+ self.wait_for_console_pattern('ast2600-a2 login:')
327
+
328
+ exec_command_and_wait_for_pattern(self, 'root', 'Password:')
329
+ exec_command_and_wait_for_pattern(self, '0penBmc', 'root@ast2600-a2:~#')
330
+
331
+ exec_command_and_wait_for_pattern(self,
332
+ 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device',
333
+ 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d');
334
+ exec_command_and_wait_for_pattern(self,
335
+ 'cat /sys/class/hwmon/hwmon19/temp1_input', '0')
336
+ self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
337
+ property='temperature', value=18000);
338
+ exec_command_and_wait_for_pattern(self,
339
+ 'cat /sys/class/hwmon/hwmon19/temp1_input', '18000')
340
+
341
+ exec_command_and_wait_for_pattern(self,
342
+ 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device',
343
+ 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32');
344
+ year = time.strftime("%Y")
345
+ exec_command_and_wait_for_pattern(self,
346
+ '/sbin/hwclock -f /dev/rtc1', year);
347
+
348
+if __name__ == '__main__':
349
+ AspeedTest.main()
35
--
350
--
36
2.31.1
351
2.47.1
37
352
38
353
diff view generated by jsdifflib
1
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
1
This simply moves the rainier-bmc test to a new test file. No changes
2
Signed-off-by: Cédric Le Goater <clg@kaod.org>
2
in the test. The test_arm_aspeed.py is deleted.
3
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Link: https://lore.kernel.org/r/20241206131132.520911-7-clg@redhat.com
6
Signed-off-by: Cédric Le Goater <clg@redhat.com>
3
---
7
---
4
hw/watchdog/wdt_aspeed.c | 5 +++++
8
tests/functional/meson.build | 4 ++--
5
hw/watchdog/trace-events | 4 ++++
9
...m_aspeed.py => test_arm_aspeed_rainier.py} | 22 +++++--------------
6
2 files changed, 9 insertions(+)
10
2 files changed, 7 insertions(+), 19 deletions(-)
11
rename tests/functional/{test_arm_aspeed.py => test_arm_aspeed_rainier.py} (71%)
12
mode change 100755 => 100644
7
13
8
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
14
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
9
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/watchdog/wdt_aspeed.c
16
--- a/tests/functional/meson.build
11
+++ b/hw/watchdog/wdt_aspeed.c
17
+++ b/tests/functional/meson.build
18
@@ -XXX,XX +XXX,XX @@ test_timeouts = {
19
'arm_aspeed_romulus' : 120,
20
'arm_aspeed_ast2500' : 480,
21
'arm_aspeed_ast2600' : 720,
22
- 'arm_aspeed' : 600,
23
+ 'arm_aspeed_rainier' : 240,
24
'arm_bpim2u' : 500,
25
'arm_collie' : 180,
26
'arm_orangepi' : 540,
27
@@ -XXX,XX +XXX,XX @@ tests_alpha_system_thorough = [
28
]
29
30
tests_arm_system_thorough = [
31
- 'arm_aspeed',
32
'arm_aspeed_ast1030',
33
'arm_aspeed_palmetto',
34
'arm_aspeed_romulus',
35
'arm_aspeed_ast2500',
36
'arm_aspeed_ast2600',
37
+ 'arm_aspeed_rainier',
38
'arm_bpim2u',
39
'arm_canona1100',
40
'arm_collie',
41
diff --git a/tests/functional/test_arm_aspeed.py b/tests/functional/test_arm_aspeed_rainier.py
42
old mode 100755
43
new mode 100644
44
similarity index 71%
45
rename from tests/functional/test_arm_aspeed.py
46
rename to tests/functional/test_arm_aspeed_rainier.py
47
index XXXXXXX..XXXXXXX
48
--- a/tests/functional/test_arm_aspeed.py
49
+++ b/tests/functional/test_arm_aspeed_rainier.py
12
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@
13
#include "hw/sysbus.h"
51
#!/usr/bin/env python3
14
#include "hw/watchdog/wdt_aspeed.h"
52
#
15
#include "migration/vmstate.h"
53
-# Functional test that boots the ASPEED SoCs with firmware
16
+#include "trace.h"
54
-#
17
55
-# Copyright (C) 2022 ASPEED Technology Inc
18
#define WDT_STATUS (0x00 / 4)
56
+# Functional test that boots the ASPEED machines
19
#define WDT_RELOAD_VALUE (0x04 / 4)
57
#
20
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
58
# SPDX-License-Identifier: GPL-2.0-or-later
21
{
59
22
AspeedWDTState *s = ASPEED_WDT(opaque);
60
-import os
23
61
-import time
24
+ trace_aspeed_wdt_read(offset, size);
62
-import subprocess
25
+
63
-import tempfile
26
offset >>= 2;
64
-
27
65
-from qemu_test import LinuxKernelTest, Asset
28
switch (offset) {
66
-from qemu_test import exec_command_and_wait_for_pattern
29
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
67
-from qemu_test import interrupt_interactive_console_until_pattern
30
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
68
-from qemu_test import has_cmd
31
bool enable;
69
-from qemu_test.utils import archive_extract
32
70
-from zipfile import ZipFile
33
+ trace_aspeed_wdt_write(offset, size, data);
71
-from unittest import skipUnless
34
+
72
+from qemu_test import Asset
35
offset >>= 2;
73
+from aspeed import AspeedTest
36
74
37
switch (offset) {
75
-class AST2x00MachineMMC(LinuxKernelTest):
38
diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
76
+class RainierMachine(AspeedTest):
39
index XXXXXXX..XXXXXXX 100644
77
40
--- a/hw/watchdog/trace-events
78
ASSET_RAINIER_EMMC = Asset(
41
+++ b/hw/watchdog/trace-events
79
('https://fileserver.linaro.org/s/B6pJTwWEkzSDi36/download/'
42
@@ -XXX,XX +XXX,XX @@ cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK AP
80
@@ -XXX,XX +XXX,XX @@ def test_arm_aspeed_emmc_boot(self):
43
cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
81
self.wait_for_console_pattern('IBM eBMC (OpenBMC for IBM Enterprise')
44
cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
82
45
cmsdk_apb_watchdog_lock(uint32_t lock) "CMSDK APB watchdog: lock %" PRIu32
83
if __name__ == '__main__':
46
+
84
- LinuxKernelTest.main()
47
+# wdt-aspeed.c
85
+ AspeedTest.main()
48
+aspeed_wdt_read(uint64_t addr, uint32_t size) "@0x%" PRIx64 " size=%d"
49
+aspeed_wdt_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " size=%d value=0x%"PRIx64
50
--
86
--
51
2.31.1
87
2.47.1
52
88
53
89
diff view generated by jsdifflib
1
Signed-off-by: Cédric Le Goater <clg@kaod.org>
1
This simply moves the debian boot test from the avocado testsuite to
2
the new functional testsuite. No changes in the test.
3
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Link: https://lore.kernel.org/r/20241206131132.520911-8-clg@redhat.com
6
Signed-off-by: Cédric Le Goater <clg@redhat.com>
2
---
7
---
3
include/hw/ssi/aspeed_smc.h | 1 -
8
tests/avocado/boot_linux_console.py | 26 ---------------------
4
1 file changed, 1 deletion(-)
9
tests/functional/test_arm_aspeed_rainier.py | 24 +++++++++++++++++++
10
2 files changed, 24 insertions(+), 26 deletions(-)
5
11
6
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
12
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
7
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
8
--- a/include/hw/ssi/aspeed_smc.h
14
--- a/tests/avocado/boot_linux_console.py
9
+++ b/include/hw/ssi/aspeed_smc.h
15
+++ b/tests/avocado/boot_linux_console.py
10
@@ -XXX,XX +XXX,XX @@ struct AspeedSMCState {
16
@@ -XXX,XX +XXX,XX @@ def test_arm_quanta_gsj_initrd(self):
11
MemoryRegion mmio_flash_alias;
17
self.wait_for_console_pattern('CPU1: thread -1, cpu 1, socket 0')
12
18
self.wait_for_console_pattern(
13
qemu_irq irq;
19
'Give root password for system maintenance')
14
- int irqline;
20
-
15
21
- def test_arm_ast2600_debian(self):
16
uint32_t num_cs;
22
- """
17
qemu_irq *cs_lines;
23
- :avocado: tags=arch:arm
24
- :avocado: tags=machine:rainier-bmc
25
- """
26
- deb_url = ('http://snapshot.debian.org/archive/debian/'
27
- '20220606T211338Z/'
28
- 'pool/main/l/linux/'
29
- 'linux-image-5.17.0-2-armmp_5.17.6-1%2Bb1_armhf.deb')
30
- deb_hash = '8acb2b4439faedc2f3ed4bdb2847ad4f6e0491f73debaeb7f660c8abe4dcdc0e'
31
- deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash,
32
- algorithm='sha256')
33
- kernel_path = self.extract_from_deb(deb_path, '/boot/vmlinuz-5.17.0-2-armmp')
34
- dtb_path = self.extract_from_deb(deb_path,
35
- '/usr/lib/linux-image-5.17.0-2-armmp/aspeed-bmc-ibm-rainier.dtb')
36
-
37
- self.vm.set_console()
38
- self.vm.add_args('-kernel', kernel_path,
39
- '-dtb', dtb_path,
40
- '-net', 'nic')
41
- self.vm.launch()
42
- self.wait_for_console_pattern("Booting Linux on physical CPU 0xf00")
43
- self.wait_for_console_pattern("SMP: Total of 2 processors activated")
44
- self.wait_for_console_pattern("No filesystem could mount root")
45
-
46
diff --git a/tests/functional/test_arm_aspeed_rainier.py b/tests/functional/test_arm_aspeed_rainier.py
47
index XXXXXXX..XXXXXXX 100644
48
--- a/tests/functional/test_arm_aspeed_rainier.py
49
+++ b/tests/functional/test_arm_aspeed_rainier.py
50
@@ -XXX,XX +XXX,XX @@ def test_arm_aspeed_emmc_boot(self):
51
self.wait_for_console_pattern('mmcblk0: p1 p2 p3 p4 p5 p6 p7')
52
self.wait_for_console_pattern('IBM eBMC (OpenBMC for IBM Enterprise')
53
54
+ ASSET_DEBIAN_LINUX_ARMHF_DEB = Asset(
55
+ ('http://snapshot.debian.org/archive/debian/20220606T211338Z/pool/main/l/linux/linux-image-5.17.0-2-armmp_5.17.6-1%2Bb1_armhf.deb'),
56
+ '8acb2b4439faedc2f3ed4bdb2847ad4f6e0491f73debaeb7f660c8abe4dcdc0e')
57
+
58
+ def test_arm_debian_kernel_boot(self):
59
+ self.set_machine('rainier-bmc')
60
+
61
+ deb_path = self.ASSET_DEBIAN_LINUX_ARMHF_DEB.fetch()
62
+
63
+ kernel_path = self.extract_from_deb(deb_path, '/boot/vmlinuz-5.17.0-2-armmp')
64
+ dtb_path = self.extract_from_deb(deb_path,
65
+ '/usr/lib/linux-image-5.17.0-2-armmp/aspeed-bmc-ibm-rainier.dtb')
66
+
67
+ self.vm.set_console()
68
+ self.vm.add_args('-kernel', kernel_path,
69
+ '-dtb', dtb_path,
70
+ '-net', 'nic')
71
+ self.vm.launch()
72
+
73
+ self.wait_for_console_pattern("Booting Linux on physical CPU 0xf00")
74
+ self.wait_for_console_pattern("SMP: Total of 2 processors activated")
75
+ self.wait_for_console_pattern("No filesystem could mount root")
76
+
77
+
78
if __name__ == '__main__':
79
AspeedTest.main()
18
--
80
--
19
2.31.1
81
2.47.1
20
82
21
83
diff view generated by jsdifflib
1
The AST2400 SPI controller has a transitional HW interface and it
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
stores the address width currently in use in a different register than
3
all the other SMC controllers. It needs special handling when working
4
in 4B mode.
5
2
6
Make it clear through a class handler. This also removes another use
3
So far, the test cases are used for testing SMC model with AST2400 BMC.
7
of the segments array.
4
However, AST2400 is end off live and ASPEED is no longer support this SOC.
5
To test SMC model for AST2500, AST2600 and AST1030, move the test cases
6
from main to test_palmetto_bmc function.
8
7
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
9
Reviewed-by: Cédric Le Goater <clg@redhat.com>
10
Link: https://lore.kernel.org/r/20241127091543.1243114-2-jamin_lin@aspeedtech.com
11
Signed-off-by: Cédric Le Goater <clg@redhat.com>
10
---
12
---
11
include/hw/ssi/aspeed_smc.h | 1 +
13
tests/qtest/aspeed_smc-test.c | 16 ++++++++++++----
12
hw/ssi/aspeed_smc.c | 19 ++++++++++++-------
14
1 file changed, 12 insertions(+), 4 deletions(-)
13
2 files changed, 13 insertions(+), 7 deletions(-)
14
15
15
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
16
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/aspeed_smc.h
18
--- a/tests/qtest/aspeed_smc-test.c
18
+++ b/include/hw/ssi/aspeed_smc.h
19
+++ b/tests/qtest/aspeed_smc-test.c
19
@@ -XXX,XX +XXX,XX @@ struct AspeedSMCClass {
20
@@ -XXX,XX +XXX,XX @@ static void test_write_block_protect_bottom_bit(void)
20
void (*reg_to_segment)(const AspeedSMCState *s, uint32_t reg,
21
flash_reset();
21
AspeedSegments *seg);
22
void (*dma_ctrl)(AspeedSMCState *s, uint32_t value);
23
+ int (*addr_width)(const AspeedSMCState *s);
24
};
25
26
#endif /* ASPEED_SMC_H */
27
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/ssi/aspeed_smc.c
30
+++ b/hw/ssi/aspeed_smc.c
31
@@ -XXX,XX +XXX,XX @@
32
* controller. These can be changed when board is initialized with the
33
* Segment Address Registers.
34
*/
35
-static const AspeedSegments aspeed_2400_spi1_segments[];
36
static const AspeedSegments aspeed_2500_spi1_segments[];
37
static const AspeedSegments aspeed_2500_spi2_segments[];
38
39
@@ -XXX,XX +XXX,XX @@ static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
40
return cmd;
41
}
22
}
42
23
43
-static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl)
24
-int main(int argc, char **argv)
44
+static inline int aspeed_smc_flash_addr_width(const AspeedSMCFlash *fl)
25
+static int test_palmetto_bmc(void)
45
{
26
{
46
const AspeedSMCState *s = fl->controller;
27
g_autofree char *tmp_path = NULL;
47
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
28
int ret;
48
29
int fd;
49
- if (asc->segments == aspeed_2400_spi1_segments) {
30
50
- return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
31
- g_test_init(&argc, &argv, NULL);
51
+ if (asc->addr_width) {
32
-
52
+ return asc->addr_width(s);
33
fd = g_file_open_tmp("qtest.m25p80.XXXXXX", &tmp_path, NULL);
53
} else {
34
g_assert(fd >= 0);
54
- return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->cs));
35
ret = ftruncate(fd, FLASH_SIZE);
55
+ return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->cs)) ? 4 : 3;
36
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
56
}
37
57
}
38
flash_reset();
58
39
ret = g_test_run();
59
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr)
40
-
60
{
41
qtest_quit(global_qtest);
61
const AspeedSMCState *s = fl->controller;
42
unlink(tmp_path);
62
uint8_t cmd = aspeed_smc_flash_cmd(fl);
43
+
63
- int i = aspeed_smc_flash_is_4byte(fl) ? 4 : 3;
44
+ return ret;
64
+ int i = aspeed_smc_flash_addr_width(fl);
65
66
/* Flash access can not exceed CS segment */
67
addr = aspeed_smc_check_segment_addr(fl, addr);
68
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_do_snoop(AspeedSMCFlash *fl, uint64_t data,
69
unsigned size)
70
{
71
AspeedSMCState *s = fl->controller;
72
- uint8_t addr_width = aspeed_smc_flash_is_4byte(fl) ? 4 : 3;
73
+ uint8_t addr_width = aspeed_smc_flash_addr_width(fl);
74
75
trace_aspeed_smc_do_snoop(fl->cs, s->snoop_index, s->snoop_dummies,
76
(uint8_t) data & 0xff);
77
@@ -XXX,XX +XXX,XX @@ static const AspeedSegments aspeed_2400_spi1_segments[] = {
78
{ 0x30000000, 64 * MiB },
79
};
80
81
+static int aspeed_2400_spi1_addr_width(const AspeedSMCState *s)
82
+{
83
+ return s->regs[R_SPI_CTRL0] & CTRL_AST2400_SPI_4BYTE ? 4 : 3;
84
+}
45
+}
85
+
46
+
86
static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
47
+int main(int argc, char **argv)
87
{
48
+{
88
DeviceClass *dc = DEVICE_CLASS(klass);
49
+ int ret;
89
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
50
+
90
asc->segment_to_reg = aspeed_smc_segment_to_reg;
51
+ g_test_init(&argc, &argv, NULL);
91
asc->reg_to_segment = aspeed_smc_reg_to_segment;
52
+ ret = test_palmetto_bmc();
92
asc->dma_ctrl = aspeed_smc_dma_ctrl;
53
+
93
+ asc->addr_width = aspeed_2400_spi1_addr_width;
54
return ret;
94
}
55
}
95
96
static const TypeInfo aspeed_2400_spi1_info = {
97
--
56
--
98
2.31.1
57
2.47.1
99
58
100
59
diff view generated by jsdifflib
1
Introduce an AspeedI2CBus SysBusDevice model and attach the associated
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
memory region and IRQ to the newly instantiated objects.
3
2
4
Before this change, the I2C bus IRQs were all attached to the
3
Currently, these test cases are only used for testing fmc_cs0 for AST2400.
5
SysBusDevice model of the I2C controller. Adapt the AST2600 SoC
4
To test others BMC SOCs, introduces a new TestData structure.
6
realize routine to take into account this change.
5
Users can set the spi base address, flash base address, jedesc id and so on
6
for different BMC SOCs and flash model testing.
7
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Introduce new helper functions to make the test case more readable.
9
10
Set spi base address 0x1E620000, flash_base address 0x20000000
11
and jedec id 0x20ba19 for fmc_cs0 with n25q256a flash for AST2400
12
SMC model testing.
13
14
To pass the TestData into the test case, replace qtest_add_func with
15
qtest_add_data_func.
16
17
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
18
Reviewed-by: Cédric Le Goater <clg@redhat.com>
19
Link: https://lore.kernel.org/r/20241127091543.1243114-3-jamin_lin@aspeedtech.com
20
Signed-off-by: Cédric Le Goater <clg@redhat.com>
9
---
21
---
10
include/hw/i2c/aspeed_i2c.h | 8 ++-
22
tests/qtest/aspeed_smc-test.c | 546 +++++++++++++++++++---------------
11
hw/arm/aspeed_ast2600.c | 7 +--
23
1 file changed, 299 insertions(+), 247 deletions(-)
12
hw/i2c/aspeed_i2c.c | 101 +++++++++++++++++++++++++++++-------
13
3 files changed, 91 insertions(+), 25 deletions(-)
14
24
15
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
25
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
16
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/i2c/aspeed_i2c.h
27
--- a/tests/qtest/aspeed_smc-test.c
18
+++ b/include/hw/i2c/aspeed_i2c.h
28
+++ b/tests/qtest/aspeed_smc-test.c
19
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(AspeedI2CState, AspeedI2CClass, ASPEED_I2C)
29
@@ -XXX,XX +XXX,XX @@
20
30
#define CTRL_USERMODE 0x3
21
struct AspeedI2CState;
31
#define SR_WEL BIT(1)
22
32
23
-typedef struct AspeedI2CBus {
33
-#define ASPEED_FMC_BASE 0x1E620000
24
+#define TYPE_ASPEED_I2C_BUS "aspeed.i2c.bus"
34
-#define ASPEED_FLASH_BASE 0x20000000
25
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedI2CBus, ASPEED_I2C_BUS)
35
-
26
+struct AspeedI2CBus {
36
/*
27
+ SysBusDevice parent_obj;
37
* Flash commands
38
*/
39
@@ -XXX,XX +XXX,XX @@ enum {
40
ERASE_SECTOR = 0xd8,
41
};
42
43
-#define FLASH_JEDEC 0x20ba19 /* n25q256a */
44
-#define FLASH_SIZE (32 * 1024 * 1024)
45
-
46
#define FLASH_PAGE_SIZE 256
47
48
+typedef struct TestData {
49
+ QTestState *s;
50
+ uint64_t spi_base;
51
+ uint64_t flash_base;
52
+ uint32_t jedec_id;
53
+ char *tmp_path;
54
+} TestData;
28
+
55
+
29
struct AspeedI2CState *controller;
56
/*
30
57
* Use an explicit bswap for the values read/wrote to the flash region
31
MemoryRegion mr;
58
* as they are BE and the Aspeed CPU is LE.
32
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
59
@@ -XXX,XX +XXX,XX @@ static inline uint32_t make_be32(uint32_t data)
33
uint32_t pool_ctrl;
60
return bswap32(data);
34
uint32_t dma_addr;
61
}
35
uint32_t dma_len;
62
36
-} AspeedI2CBus;
63
-static void spi_conf(uint32_t value)
37
+};
64
+static inline void spi_writel(const TestData *data, uint64_t offset,
38
65
+ uint32_t value)
39
struct AspeedI2CState {
66
+{
40
SysBusDevice parent_obj;
67
+ qtest_writel(data->s, data->spi_base + offset, value);
41
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/aspeed_ast2600.c
44
+++ b/hw/arm/aspeed_ast2600.c
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
46
for (i = 0; i < ASPEED_I2C_GET_CLASS(&s->i2c)->num_busses; i++) {
47
qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore),
48
sc->irqmap[ASPEED_DEV_I2C] + i);
49
- /*
50
- * The AST2600 SoC has one IRQ per I2C bus. Skip the common
51
- * IRQ (AST2400 and AST2500) and connect all bussses.
52
- */
53
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), i + 1, irq);
54
+ /* The AST2600 I2C controller has one IRQ per bus. */
55
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c.busses[i]), 0, irq);
56
}
57
58
/* FMC, The number of CS is set at the board level */
59
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/i2c/aspeed_i2c.c
62
+++ b/hw/i2c/aspeed_i2c.c
63
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_vmstate = {
64
65
static void aspeed_i2c_reset(DeviceState *dev)
66
{
67
- int i;
68
AspeedI2CState *s = ASPEED_I2C(dev);
69
- AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
70
71
s->intr_status = 0;
72
+}
68
+}
73
+
69
+
74
+static void aspeed_i2c_instance_init(Object *obj)
70
+static inline uint32_t spi_readl(const TestData *data, uint64_t offset)
75
+{
71
+{
76
+ AspeedI2CState *s = ASPEED_I2C(obj);
72
+ return qtest_readl(data->s, data->spi_base + offset);
77
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
78
+ int i;
79
80
for (i = 0; i < aic->num_busses; i++) {
81
- s->busses[i].intr_ctrl = 0;
82
- s->busses[i].intr_status = 0;
83
- s->busses[i].cmd = 0;
84
- s->busses[i].buf = 0;
85
- s->busses[i].dma_addr = 0;
86
- s->busses[i].dma_len = 0;
87
- i2c_end_transfer(s->busses[i].bus);
88
+ object_initialize_child(obj, "bus[*]", &s->busses[i],
89
+ TYPE_ASPEED_I2C_BUS);
90
}
91
}
92
93
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
94
sysbus_init_mmio(sbd, &s->iomem);
95
96
for (i = 0; i < aic->num_busses; i++) {
97
- char name[32];
98
+ Object *bus = OBJECT(&s->busses[i]);
99
int offset = i < aic->gap ? 1 : 5;
100
101
- sysbus_init_irq(sbd, &s->busses[i].irq);
102
- snprintf(name, sizeof(name), "aspeed.i2c.%d", i);
103
- s->busses[i].controller = s;
104
- s->busses[i].id = i;
105
- s->busses[i].bus = i2c_init_bus(dev, name);
106
- memory_region_init_io(&s->busses[i].mr, OBJECT(dev),
107
- &aspeed_i2c_bus_ops, &s->busses[i], name,
108
- aic->reg_size);
109
+ if (!object_property_set_link(bus, "controller", OBJECT(s), errp)) {
110
+ return;
111
+ }
112
+
113
+ if (!object_property_set_uint(bus, "bus-id", i, errp)) {
114
+ return;
115
+ }
116
+
117
+ if (!sysbus_realize(SYS_BUS_DEVICE(bus), errp)) {
118
+ return;
119
+ }
120
+
121
memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset),
122
&s->busses[i].mr);
123
}
124
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
125
static const TypeInfo aspeed_i2c_info = {
126
.name = TYPE_ASPEED_I2C,
127
.parent = TYPE_SYS_BUS_DEVICE,
128
+ .instance_init = aspeed_i2c_instance_init,
129
.instance_size = sizeof(AspeedI2CState),
130
.class_init = aspeed_i2c_class_init,
131
.class_size = sizeof(AspeedI2CClass),
132
.abstract = true,
133
};
134
135
+static void aspeed_i2c_bus_reset(DeviceState *dev)
136
+{
137
+ AspeedI2CBus *s = ASPEED_I2C_BUS(dev);
138
+
139
+ s->intr_ctrl = 0;
140
+ s->intr_status = 0;
141
+ s->cmd = 0;
142
+ s->buf = 0;
143
+ s->dma_addr = 0;
144
+ s->dma_len = 0;
145
+ i2c_end_transfer(s->bus);
146
+}
73
+}
147
+
74
+
148
+static void aspeed_i2c_bus_realize(DeviceState *dev, Error **errp)
75
+static inline void flash_writeb(const TestData *data, uint64_t offset,
76
+ uint8_t value)
149
+{
77
+{
150
+ AspeedI2CBus *s = ASPEED_I2C_BUS(dev);
78
+ qtest_writeb(data->s, data->flash_base + offset, value);
151
+ AspeedI2CClass *aic;
152
+ g_autofree char *name = g_strdup_printf(TYPE_ASPEED_I2C_BUS ".%d", s->id);
153
+
154
+ if (!s->controller) {
155
+ error_setg(errp, TYPE_ASPEED_I2C_BUS ": 'controller' link not set");
156
+ return;
157
+ }
158
+
159
+ aic = ASPEED_I2C_GET_CLASS(s->controller);
160
+
161
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
162
+
163
+ s->bus = i2c_init_bus(dev, name);
164
+
165
+ memory_region_init_io(&s->mr, OBJECT(s), &aspeed_i2c_bus_ops,
166
+ s, name, aic->reg_size);
167
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr);
168
+}
79
+}
169
+
80
+
170
+static Property aspeed_i2c_bus_properties[] = {
81
+static inline void flash_writel(const TestData *data, uint64_t offset,
171
+ DEFINE_PROP_UINT8("bus-id", AspeedI2CBus, id, 0),
82
+ uint32_t value)
172
+ DEFINE_PROP_LINK("controller", AspeedI2CBus, controller, TYPE_ASPEED_I2C,
173
+ AspeedI2CState *),
174
+ DEFINE_PROP_END_OF_LIST(),
175
+};
176
+
177
+static void aspeed_i2c_bus_class_init(ObjectClass *klass, void *data)
178
+{
83
+{
179
+ DeviceClass *dc = DEVICE_CLASS(klass);
84
+ qtest_writel(data->s, data->flash_base + offset, value);
180
+
181
+ dc->desc = "Aspeed I2C Bus";
182
+ dc->realize = aspeed_i2c_bus_realize;
183
+ dc->reset = aspeed_i2c_bus_reset;
184
+ device_class_set_props(dc, aspeed_i2c_bus_properties);
185
+}
85
+}
186
+
86
+
187
+static const TypeInfo aspeed_i2c_bus_info = {
87
+static inline uint8_t flash_readb(const TestData *data, uint64_t offset)
188
+ .name = TYPE_ASPEED_I2C_BUS,
88
{
189
+ .parent = TYPE_SYS_BUS_DEVICE,
89
- uint32_t conf = readl(ASPEED_FMC_BASE + R_CONF);
190
+ .instance_size = sizeof(AspeedI2CBus),
90
+ return qtest_readb(data->s, data->flash_base + offset);
191
+ .class_init = aspeed_i2c_bus_class_init,
91
+}
192
+};
193
+
92
+
194
static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus)
93
+static inline uint32_t flash_readl(const TestData *data, uint64_t offset)
195
{
94
+{
196
return bus->controller->irq;
95
+ return qtest_readl(data->s, data->flash_base + offset);
197
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_2600_i2c_info = {
96
+}
198
97
+
199
static void aspeed_i2c_register_types(void)
98
+static void spi_conf(const TestData *data, uint32_t value)
200
{
99
+{
201
+ type_register_static(&aspeed_i2c_bus_info);
100
+ uint32_t conf = spi_readl(data, R_CONF);
202
type_register_static(&aspeed_i2c_info);
101
203
type_register_static(&aspeed_2400_i2c_info);
102
conf |= value;
204
type_register_static(&aspeed_2500_i2c_info);
103
- writel(ASPEED_FMC_BASE + R_CONF, conf);
104
+ spi_writel(data, R_CONF, conf);
105
}
106
107
-static void spi_conf_remove(uint32_t value)
108
+static void spi_conf_remove(const TestData *data, uint32_t value)
109
{
110
- uint32_t conf = readl(ASPEED_FMC_BASE + R_CONF);
111
+ uint32_t conf = spi_readl(data, R_CONF);
112
113
conf &= ~value;
114
- writel(ASPEED_FMC_BASE + R_CONF, conf);
115
+ spi_writel(data, R_CONF, conf);
116
}
117
118
-static void spi_ce_ctrl(uint32_t value)
119
+static void spi_ce_ctrl(const TestData *data, uint32_t value)
120
{
121
- uint32_t conf = readl(ASPEED_FMC_BASE + R_CE_CTRL);
122
+ uint32_t conf = spi_readl(data, R_CE_CTRL);
123
124
conf |= value;
125
- writel(ASPEED_FMC_BASE + R_CE_CTRL, conf);
126
+ spi_writel(data, R_CE_CTRL, conf);
127
}
128
129
-static void spi_ctrl_setmode(uint8_t mode, uint8_t cmd)
130
+static void spi_ctrl_setmode(const TestData *data, uint8_t mode, uint8_t cmd)
131
{
132
- uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0);
133
+ uint32_t ctrl = spi_readl(data, R_CTRL0);
134
ctrl &= ~(CTRL_USERMODE | 0xff << 16);
135
ctrl |= mode | (cmd << 16);
136
- writel(ASPEED_FMC_BASE + R_CTRL0, ctrl);
137
+ spi_writel(data, R_CTRL0, ctrl);
138
}
139
140
-static void spi_ctrl_start_user(void)
141
+static void spi_ctrl_start_user(const TestData *data)
142
{
143
- uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0);
144
+ uint32_t ctrl = spi_readl(data, R_CTRL0);
145
146
ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
147
- writel(ASPEED_FMC_BASE + R_CTRL0, ctrl);
148
+ spi_writel(data, R_CTRL0, ctrl);
149
150
ctrl &= ~CTRL_CE_STOP_ACTIVE;
151
- writel(ASPEED_FMC_BASE + R_CTRL0, ctrl);
152
+ spi_writel(data, R_CTRL0, ctrl);
153
}
154
155
-static void spi_ctrl_stop_user(void)
156
+static void spi_ctrl_stop_user(const TestData *data)
157
{
158
- uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0);
159
+ uint32_t ctrl = spi_readl(data, R_CTRL0);
160
161
ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
162
- writel(ASPEED_FMC_BASE + R_CTRL0, ctrl);
163
+ spi_writel(data, R_CTRL0, ctrl);
164
}
165
166
-static void flash_reset(void)
167
+static void flash_reset(const TestData *data)
168
{
169
- spi_conf(CONF_ENABLE_W0);
170
+ spi_conf(data, CONF_ENABLE_W0);
171
172
- spi_ctrl_start_user();
173
- writeb(ASPEED_FLASH_BASE, RESET_ENABLE);
174
- writeb(ASPEED_FLASH_BASE, RESET_MEMORY);
175
- writeb(ASPEED_FLASH_BASE, WREN);
176
- writeb(ASPEED_FLASH_BASE, BULK_ERASE);
177
- writeb(ASPEED_FLASH_BASE, WRDI);
178
- spi_ctrl_stop_user();
179
+ spi_ctrl_start_user(data);
180
+ flash_writeb(data, 0, RESET_ENABLE);
181
+ flash_writeb(data, 0, RESET_MEMORY);
182
+ flash_writeb(data, 0, WREN);
183
+ flash_writeb(data, 0, BULK_ERASE);
184
+ flash_writeb(data, 0, WRDI);
185
+ spi_ctrl_stop_user(data);
186
187
- spi_conf_remove(CONF_ENABLE_W0);
188
+ spi_conf_remove(data, CONF_ENABLE_W0);
189
}
190
191
-static void test_read_jedec(void)
192
+static void test_read_jedec(const void *data)
193
{
194
+ const TestData *test_data = (const TestData *)data;
195
uint32_t jedec = 0x0;
196
197
- spi_conf(CONF_ENABLE_W0);
198
+ spi_conf(test_data, CONF_ENABLE_W0);
199
200
- spi_ctrl_start_user();
201
- writeb(ASPEED_FLASH_BASE, JEDEC_READ);
202
- jedec |= readb(ASPEED_FLASH_BASE) << 16;
203
- jedec |= readb(ASPEED_FLASH_BASE) << 8;
204
- jedec |= readb(ASPEED_FLASH_BASE);
205
- spi_ctrl_stop_user();
206
+ spi_ctrl_start_user(test_data);
207
+ flash_writeb(test_data, 0, JEDEC_READ);
208
+ jedec |= flash_readb(test_data, 0) << 16;
209
+ jedec |= flash_readb(test_data, 0) << 8;
210
+ jedec |= flash_readb(test_data, 0);
211
+ spi_ctrl_stop_user(test_data);
212
213
- flash_reset();
214
+ flash_reset(test_data);
215
216
- g_assert_cmphex(jedec, ==, FLASH_JEDEC);
217
+ g_assert_cmphex(jedec, ==, test_data->jedec_id);
218
}
219
220
-static void read_page(uint32_t addr, uint32_t *page)
221
+static void read_page(const TestData *data, uint32_t addr, uint32_t *page)
222
{
223
int i;
224
225
- spi_ctrl_start_user();
226
+ spi_ctrl_start_user(data);
227
228
- writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
229
- writeb(ASPEED_FLASH_BASE, READ);
230
- writel(ASPEED_FLASH_BASE, make_be32(addr));
231
+ flash_writeb(data, 0, EN_4BYTE_ADDR);
232
+ flash_writeb(data, 0, READ);
233
+ flash_writel(data, 0, make_be32(addr));
234
235
/* Continuous read are supported */
236
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
237
- page[i] = make_be32(readl(ASPEED_FLASH_BASE));
238
+ page[i] = make_be32(flash_readl(data, 0));
239
}
240
- spi_ctrl_stop_user();
241
+ spi_ctrl_stop_user(data);
242
}
243
244
-static void read_page_mem(uint32_t addr, uint32_t *page)
245
+static void read_page_mem(const TestData *data, uint32_t addr, uint32_t *page)
246
{
247
int i;
248
249
/* move out USER mode to use direct reads from the AHB bus */
250
- spi_ctrl_setmode(CTRL_READMODE, READ);
251
+ spi_ctrl_setmode(data, CTRL_READMODE, READ);
252
253
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
254
- page[i] = make_be32(readl(ASPEED_FLASH_BASE + addr + i * 4));
255
+ page[i] = make_be32(flash_readl(data, addr + i * 4));
256
}
257
}
258
259
-static void write_page_mem(uint32_t addr, uint32_t write_value)
260
+static void write_page_mem(const TestData *data, uint32_t addr,
261
+ uint32_t write_value)
262
{
263
- spi_ctrl_setmode(CTRL_WRITEMODE, PP);
264
+ spi_ctrl_setmode(data, CTRL_WRITEMODE, PP);
265
266
for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
267
- writel(ASPEED_FLASH_BASE + addr + i * 4, write_value);
268
+ flash_writel(data, addr + i * 4, write_value);
269
}
270
}
271
272
-static void assert_page_mem(uint32_t addr, uint32_t expected_value)
273
+static void assert_page_mem(const TestData *data, uint32_t addr,
274
+ uint32_t expected_value)
275
{
276
uint32_t page[FLASH_PAGE_SIZE / 4];
277
- read_page_mem(addr, page);
278
+ read_page_mem(data, addr, page);
279
for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
280
g_assert_cmphex(page[i], ==, expected_value);
281
}
282
}
283
284
-static void test_erase_sector(void)
285
+static void test_erase_sector(const void *data)
286
{
287
+ const TestData *test_data = (const TestData *)data;
288
uint32_t some_page_addr = 0x600 * FLASH_PAGE_SIZE;
289
uint32_t page[FLASH_PAGE_SIZE / 4];
290
int i;
291
292
- spi_conf(CONF_ENABLE_W0);
293
+ spi_conf(test_data, CONF_ENABLE_W0);
294
295
/*
296
* Previous page should be full of 0xffs after backend is
297
* initialized
298
*/
299
- read_page(some_page_addr - FLASH_PAGE_SIZE, page);
300
+ read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page);
301
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
302
g_assert_cmphex(page[i], ==, 0xffffffff);
303
}
304
305
- spi_ctrl_start_user();
306
- writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
307
- writeb(ASPEED_FLASH_BASE, WREN);
308
- writeb(ASPEED_FLASH_BASE, PP);
309
- writel(ASPEED_FLASH_BASE, make_be32(some_page_addr));
310
+ spi_ctrl_start_user(test_data);
311
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
312
+ flash_writeb(test_data, 0, WREN);
313
+ flash_writeb(test_data, 0, PP);
314
+ flash_writel(test_data, 0, make_be32(some_page_addr));
315
316
/* Fill the page with its own addresses */
317
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
318
- writel(ASPEED_FLASH_BASE, make_be32(some_page_addr + i * 4));
319
+ flash_writel(test_data, 0, make_be32(some_page_addr + i * 4));
320
}
321
- spi_ctrl_stop_user();
322
+ spi_ctrl_stop_user(test_data);
323
324
/* Check the page is correctly written */
325
- read_page(some_page_addr, page);
326
+ read_page(test_data, some_page_addr, page);
327
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
328
g_assert_cmphex(page[i], ==, some_page_addr + i * 4);
329
}
330
331
- spi_ctrl_start_user();
332
- writeb(ASPEED_FLASH_BASE, WREN);
333
- writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
334
- writeb(ASPEED_FLASH_BASE, ERASE_SECTOR);
335
- writel(ASPEED_FLASH_BASE, make_be32(some_page_addr));
336
- spi_ctrl_stop_user();
337
+ spi_ctrl_start_user(test_data);
338
+ flash_writeb(test_data, 0, WREN);
339
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
340
+ flash_writeb(test_data, 0, ERASE_SECTOR);
341
+ flash_writel(test_data, 0, make_be32(some_page_addr));
342
+ spi_ctrl_stop_user(test_data);
343
344
/* Check the page is erased */
345
- read_page(some_page_addr, page);
346
+ read_page(test_data, some_page_addr, page);
347
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
348
g_assert_cmphex(page[i], ==, 0xffffffff);
349
}
350
351
- flash_reset();
352
+ flash_reset(test_data);
353
}
354
355
-static void test_erase_all(void)
356
+static void test_erase_all(const void *data)
357
{
358
+ const TestData *test_data = (const TestData *)data;
359
uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE;
360
uint32_t page[FLASH_PAGE_SIZE / 4];
361
int i;
362
363
- spi_conf(CONF_ENABLE_W0);
364
+ spi_conf(test_data, CONF_ENABLE_W0);
365
366
/*
367
* Previous page should be full of 0xffs after backend is
368
* initialized
369
*/
370
- read_page(some_page_addr - FLASH_PAGE_SIZE, page);
371
+ read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page);
372
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
373
g_assert_cmphex(page[i], ==, 0xffffffff);
374
}
375
376
- spi_ctrl_start_user();
377
- writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
378
- writeb(ASPEED_FLASH_BASE, WREN);
379
- writeb(ASPEED_FLASH_BASE, PP);
380
- writel(ASPEED_FLASH_BASE, make_be32(some_page_addr));
381
+ spi_ctrl_start_user(test_data);
382
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
383
+ flash_writeb(test_data, 0, WREN);
384
+ flash_writeb(test_data, 0, PP);
385
+ flash_writel(test_data, 0, make_be32(some_page_addr));
386
387
/* Fill the page with its own addresses */
388
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
389
- writel(ASPEED_FLASH_BASE, make_be32(some_page_addr + i * 4));
390
+ flash_writel(test_data, 0, make_be32(some_page_addr + i * 4));
391
}
392
- spi_ctrl_stop_user();
393
+ spi_ctrl_stop_user(test_data);
394
395
/* Check the page is correctly written */
396
- read_page(some_page_addr, page);
397
+ read_page(test_data, some_page_addr, page);
398
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
399
g_assert_cmphex(page[i], ==, some_page_addr + i * 4);
400
}
401
402
- spi_ctrl_start_user();
403
- writeb(ASPEED_FLASH_BASE, WREN);
404
- writeb(ASPEED_FLASH_BASE, BULK_ERASE);
405
- spi_ctrl_stop_user();
406
+ spi_ctrl_start_user(test_data);
407
+ flash_writeb(test_data, 0, WREN);
408
+ flash_writeb(test_data, 0, BULK_ERASE);
409
+ spi_ctrl_stop_user(test_data);
410
411
/* Check the page is erased */
412
- read_page(some_page_addr, page);
413
+ read_page(test_data, some_page_addr, page);
414
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
415
g_assert_cmphex(page[i], ==, 0xffffffff);
416
}
417
418
- flash_reset();
419
+ flash_reset(test_data);
420
}
421
422
-static void test_write_page(void)
423
+static void test_write_page(const void *data)
424
{
425
+ const TestData *test_data = (const TestData *)data;
426
uint32_t my_page_addr = 0x14000 * FLASH_PAGE_SIZE; /* beyond 16MB */
427
uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE;
428
uint32_t page[FLASH_PAGE_SIZE / 4];
429
int i;
430
431
- spi_conf(CONF_ENABLE_W0);
432
+ spi_conf(test_data, CONF_ENABLE_W0);
433
434
- spi_ctrl_start_user();
435
- writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
436
- writeb(ASPEED_FLASH_BASE, WREN);
437
- writeb(ASPEED_FLASH_BASE, PP);
438
- writel(ASPEED_FLASH_BASE, make_be32(my_page_addr));
439
+ spi_ctrl_start_user(test_data);
440
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
441
+ flash_writeb(test_data, 0, WREN);
442
+ flash_writeb(test_data, 0, PP);
443
+ flash_writel(test_data, 0, make_be32(my_page_addr));
444
445
/* Fill the page with its own addresses */
446
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
447
- writel(ASPEED_FLASH_BASE, make_be32(my_page_addr + i * 4));
448
+ flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
449
}
450
- spi_ctrl_stop_user();
451
+ spi_ctrl_stop_user(test_data);
452
453
/* Check what was written */
454
- read_page(my_page_addr, page);
455
+ read_page(test_data, my_page_addr, page);
456
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
457
g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
458
}
459
460
/* Check some other page. It should be full of 0xff */
461
- read_page(some_page_addr, page);
462
+ read_page(test_data, some_page_addr, page);
463
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
464
g_assert_cmphex(page[i], ==, 0xffffffff);
465
}
466
467
- flash_reset();
468
+ flash_reset(test_data);
469
}
470
471
-static void test_read_page_mem(void)
472
+static void test_read_page_mem(const void *data)
473
{
474
+ const TestData *test_data = (const TestData *)data;
475
uint32_t my_page_addr = 0x14000 * FLASH_PAGE_SIZE; /* beyond 16MB */
476
uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE;
477
uint32_t page[FLASH_PAGE_SIZE / 4];
478
@@ -XXX,XX +XXX,XX @@ static void test_read_page_mem(void)
479
* Enable 4BYTE mode for controller. This is should be strapped by
480
* HW for CE0 anyhow.
481
*/
482
- spi_ce_ctrl(1 << CRTL_EXTENDED0);
483
+ spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0);
484
485
/* Enable 4BYTE mode for flash. */
486
- spi_conf(CONF_ENABLE_W0);
487
- spi_ctrl_start_user();
488
- writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
489
- writeb(ASPEED_FLASH_BASE, WREN);
490
- writeb(ASPEED_FLASH_BASE, PP);
491
- writel(ASPEED_FLASH_BASE, make_be32(my_page_addr));
492
+ spi_conf(test_data, CONF_ENABLE_W0);
493
+ spi_ctrl_start_user(test_data);
494
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
495
+ flash_writeb(test_data, 0, WREN);
496
+ flash_writeb(test_data, 0, PP);
497
+ flash_writel(test_data, 0, make_be32(my_page_addr));
498
499
/* Fill the page with its own addresses */
500
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
501
- writel(ASPEED_FLASH_BASE, make_be32(my_page_addr + i * 4));
502
+ flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
503
}
504
- spi_ctrl_stop_user();
505
- spi_conf_remove(CONF_ENABLE_W0);
506
+ spi_ctrl_stop_user(test_data);
507
+ spi_conf_remove(test_data, CONF_ENABLE_W0);
508
509
/* Check what was written */
510
- read_page_mem(my_page_addr, page);
511
+ read_page_mem(test_data, my_page_addr, page);
512
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
513
g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
514
}
515
516
/* Check some other page. It should be full of 0xff */
517
- read_page_mem(some_page_addr, page);
518
+ read_page_mem(test_data, some_page_addr, page);
519
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
520
g_assert_cmphex(page[i], ==, 0xffffffff);
521
}
522
523
- flash_reset();
524
+ flash_reset(test_data);
525
}
526
527
-static void test_write_page_mem(void)
528
+static void test_write_page_mem(const void *data)
529
{
530
+ const TestData *test_data = (const TestData *)data;
531
uint32_t my_page_addr = 0x15000 * FLASH_PAGE_SIZE;
532
uint32_t page[FLASH_PAGE_SIZE / 4];
533
int i;
534
@@ -XXX,XX +XXX,XX @@ static void test_write_page_mem(void)
535
* Enable 4BYTE mode for controller. This is should be strapped by
536
* HW for CE0 anyhow.
537
*/
538
- spi_ce_ctrl(1 << CRTL_EXTENDED0);
539
+ spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0);
540
541
/* Enable 4BYTE mode for flash. */
542
- spi_conf(CONF_ENABLE_W0);
543
- spi_ctrl_start_user();
544
- writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
545
- writeb(ASPEED_FLASH_BASE, WREN);
546
- spi_ctrl_stop_user();
547
+ spi_conf(test_data, CONF_ENABLE_W0);
548
+ spi_ctrl_start_user(test_data);
549
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
550
+ flash_writeb(test_data, 0, WREN);
551
+ spi_ctrl_stop_user(test_data);
552
553
/* move out USER mode to use direct writes to the AHB bus */
554
- spi_ctrl_setmode(CTRL_WRITEMODE, PP);
555
+ spi_ctrl_setmode(test_data, CTRL_WRITEMODE, PP);
556
557
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
558
- writel(ASPEED_FLASH_BASE + my_page_addr + i * 4,
559
+ flash_writel(test_data, my_page_addr + i * 4,
560
make_be32(my_page_addr + i * 4));
561
}
562
563
/* Check what was written */
564
- read_page_mem(my_page_addr, page);
565
+ read_page_mem(test_data, my_page_addr, page);
566
for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
567
g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
568
}
569
570
- flash_reset();
571
+ flash_reset(test_data);
572
}
573
574
-static void test_read_status_reg(void)
575
+static void test_read_status_reg(const void *data)
576
{
577
+ const TestData *test_data = (const TestData *)data;
578
uint8_t r;
579
580
- spi_conf(CONF_ENABLE_W0);
581
+ spi_conf(test_data, CONF_ENABLE_W0);
582
583
- spi_ctrl_start_user();
584
- writeb(ASPEED_FLASH_BASE, RDSR);
585
- r = readb(ASPEED_FLASH_BASE);
586
- spi_ctrl_stop_user();
587
+ spi_ctrl_start_user(test_data);
588
+ flash_writeb(test_data, 0, RDSR);
589
+ r = flash_readb(test_data, 0);
590
+ spi_ctrl_stop_user(test_data);
591
592
g_assert_cmphex(r & SR_WEL, ==, 0);
593
g_assert(!qtest_qom_get_bool
594
- (global_qtest, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
595
+ (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
596
597
- spi_ctrl_start_user();
598
- writeb(ASPEED_FLASH_BASE, WREN);
599
- writeb(ASPEED_FLASH_BASE, RDSR);
600
- r = readb(ASPEED_FLASH_BASE);
601
- spi_ctrl_stop_user();
602
+ spi_ctrl_start_user(test_data);
603
+ flash_writeb(test_data, 0, WREN);
604
+ flash_writeb(test_data, 0, RDSR);
605
+ r = flash_readb(test_data, 0);
606
+ spi_ctrl_stop_user(test_data);
607
608
g_assert_cmphex(r & SR_WEL, ==, SR_WEL);
609
g_assert(qtest_qom_get_bool
610
- (global_qtest, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
611
+ (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
612
613
- spi_ctrl_start_user();
614
- writeb(ASPEED_FLASH_BASE, WRDI);
615
- writeb(ASPEED_FLASH_BASE, RDSR);
616
- r = readb(ASPEED_FLASH_BASE);
617
- spi_ctrl_stop_user();
618
+ spi_ctrl_start_user(test_data);
619
+ flash_writeb(test_data, 0, WRDI);
620
+ flash_writeb(test_data, 0, RDSR);
621
+ r = flash_readb(test_data, 0);
622
+ spi_ctrl_stop_user(test_data);
623
624
g_assert_cmphex(r & SR_WEL, ==, 0);
625
g_assert(!qtest_qom_get_bool
626
- (global_qtest, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
627
+ (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
628
629
- flash_reset();
630
+ flash_reset(test_data);
631
}
632
633
-static void test_status_reg_write_protection(void)
634
+static void test_status_reg_write_protection(const void *data)
635
{
636
+ const TestData *test_data = (const TestData *)data;
637
uint8_t r;
638
639
- spi_conf(CONF_ENABLE_W0);
640
+ spi_conf(test_data, CONF_ENABLE_W0);
641
642
/* default case: WP# is high and SRWD is low -> status register writable */
643
- spi_ctrl_start_user();
644
- writeb(ASPEED_FLASH_BASE, WREN);
645
+ spi_ctrl_start_user(test_data);
646
+ flash_writeb(test_data, 0, WREN);
647
/* test ability to write SRWD */
648
- writeb(ASPEED_FLASH_BASE, WRSR);
649
- writeb(ASPEED_FLASH_BASE, SRWD);
650
- writeb(ASPEED_FLASH_BASE, RDSR);
651
- r = readb(ASPEED_FLASH_BASE);
652
- spi_ctrl_stop_user();
653
+ flash_writeb(test_data, 0, WRSR);
654
+ flash_writeb(test_data, 0, SRWD);
655
+ flash_writeb(test_data, 0, RDSR);
656
+ r = flash_readb(test_data, 0);
657
+ spi_ctrl_stop_user(test_data);
658
g_assert_cmphex(r & SRWD, ==, SRWD);
659
660
/* WP# high and SRWD high -> status register writable */
661
- spi_ctrl_start_user();
662
- writeb(ASPEED_FLASH_BASE, WREN);
663
+ spi_ctrl_start_user(test_data);
664
+ flash_writeb(test_data, 0, WREN);
665
/* test ability to write SRWD */
666
- writeb(ASPEED_FLASH_BASE, WRSR);
667
- writeb(ASPEED_FLASH_BASE, 0);
668
- writeb(ASPEED_FLASH_BASE, RDSR);
669
- r = readb(ASPEED_FLASH_BASE);
670
- spi_ctrl_stop_user();
671
+ flash_writeb(test_data, 0, WRSR);
672
+ flash_writeb(test_data, 0, 0);
673
+ flash_writeb(test_data, 0, RDSR);
674
+ r = flash_readb(test_data, 0);
675
+ spi_ctrl_stop_user(test_data);
676
g_assert_cmphex(r & SRWD, ==, 0);
677
678
/* WP# low and SRWD low -> status register writable */
679
- qtest_set_irq_in(global_qtest,
680
+ qtest_set_irq_in(test_data->s,
681
"/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 0);
682
- spi_ctrl_start_user();
683
- writeb(ASPEED_FLASH_BASE, WREN);
684
+ spi_ctrl_start_user(test_data);
685
+ flash_writeb(test_data, 0, WREN);
686
/* test ability to write SRWD */
687
- writeb(ASPEED_FLASH_BASE, WRSR);
688
- writeb(ASPEED_FLASH_BASE, SRWD);
689
- writeb(ASPEED_FLASH_BASE, RDSR);
690
- r = readb(ASPEED_FLASH_BASE);
691
- spi_ctrl_stop_user();
692
+ flash_writeb(test_data, 0, WRSR);
693
+ flash_writeb(test_data, 0, SRWD);
694
+ flash_writeb(test_data, 0, RDSR);
695
+ r = flash_readb(test_data, 0);
696
+ spi_ctrl_stop_user(test_data);
697
g_assert_cmphex(r & SRWD, ==, SRWD);
698
699
/* WP# low and SRWD high -> status register NOT writable */
700
- spi_ctrl_start_user();
701
- writeb(ASPEED_FLASH_BASE, WREN);
702
+ spi_ctrl_start_user(test_data);
703
+ flash_writeb(test_data, 0 , WREN);
704
/* test ability to write SRWD */
705
- writeb(ASPEED_FLASH_BASE, WRSR);
706
- writeb(ASPEED_FLASH_BASE, 0);
707
- writeb(ASPEED_FLASH_BASE, RDSR);
708
- r = readb(ASPEED_FLASH_BASE);
709
- spi_ctrl_stop_user();
710
+ flash_writeb(test_data, 0, WRSR);
711
+ flash_writeb(test_data, 0, 0);
712
+ flash_writeb(test_data, 0, RDSR);
713
+ r = flash_readb(test_data, 0);
714
+ spi_ctrl_stop_user(test_data);
715
/* write is not successful */
716
g_assert_cmphex(r & SRWD, ==, SRWD);
717
718
- qtest_set_irq_in(global_qtest,
719
+ qtest_set_irq_in(test_data->s,
720
"/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 1);
721
- flash_reset();
722
+ flash_reset(test_data);
723
}
724
725
-static void test_write_block_protect(void)
726
+static void test_write_block_protect(const void *data)
727
{
728
+ const TestData *test_data = (const TestData *)data;
729
uint32_t sector_size = 65536;
730
uint32_t n_sectors = 512;
731
732
- spi_ce_ctrl(1 << CRTL_EXTENDED0);
733
- spi_conf(CONF_ENABLE_W0);
734
+ spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0);
735
+ spi_conf(test_data, CONF_ENABLE_W0);
736
737
uint32_t bp_bits = 0b0;
738
739
for (int i = 0; i < 16; i++) {
740
bp_bits = ((i & 0b1000) << 3) | ((i & 0b0111) << 2);
741
742
- spi_ctrl_start_user();
743
- writeb(ASPEED_FLASH_BASE, WREN);
744
- writeb(ASPEED_FLASH_BASE, BULK_ERASE);
745
- writeb(ASPEED_FLASH_BASE, WREN);
746
- writeb(ASPEED_FLASH_BASE, WRSR);
747
- writeb(ASPEED_FLASH_BASE, bp_bits);
748
- writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
749
- writeb(ASPEED_FLASH_BASE, WREN);
750
- spi_ctrl_stop_user();
751
+ spi_ctrl_start_user(test_data);
752
+ flash_writeb(test_data, 0, WREN);
753
+ flash_writeb(test_data, 0, BULK_ERASE);
754
+ flash_writeb(test_data, 0, WREN);
755
+ flash_writeb(test_data, 0, WRSR);
756
+ flash_writeb(test_data, 0, bp_bits);
757
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
758
+ flash_writeb(test_data, 0, WREN);
759
+ spi_ctrl_stop_user(test_data);
760
761
uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0;
762
uint32_t protection_start = n_sectors - num_protected_sectors;
763
@@ -XXX,XX +XXX,XX @@ static void test_write_block_protect(void)
764
for (int sector = 0; sector < n_sectors; sector++) {
765
uint32_t addr = sector * sector_size;
766
767
- assert_page_mem(addr, 0xffffffff);
768
- write_page_mem(addr, make_be32(0xabcdef12));
769
+ assert_page_mem(test_data, addr, 0xffffffff);
770
+ write_page_mem(test_data, addr, make_be32(0xabcdef12));
771
772
uint32_t expected_value = protection_start <= sector
773
&& sector < protection_end
774
? 0xffffffff : 0xabcdef12;
775
776
- assert_page_mem(addr, expected_value);
777
+ assert_page_mem(test_data, addr, expected_value);
778
}
779
}
780
781
- flash_reset();
782
+ flash_reset(test_data);
783
}
784
785
-static void test_write_block_protect_bottom_bit(void)
786
+static void test_write_block_protect_bottom_bit(const void *data)
787
{
788
+ const TestData *test_data = (const TestData *)data;
789
uint32_t sector_size = 65536;
790
uint32_t n_sectors = 512;
791
792
- spi_ce_ctrl(1 << CRTL_EXTENDED0);
793
- spi_conf(CONF_ENABLE_W0);
794
+ spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0);
795
+ spi_conf(test_data, CONF_ENABLE_W0);
796
797
/* top bottom bit is enabled */
798
uint32_t bp_bits = 0b00100 << 3;
799
@@ -XXX,XX +XXX,XX @@ static void test_write_block_protect_bottom_bit(void)
800
for (int i = 0; i < 16; i++) {
801
bp_bits = (((i & 0b1000) | 0b0100) << 3) | ((i & 0b0111) << 2);
802
803
- spi_ctrl_start_user();
804
- writeb(ASPEED_FLASH_BASE, WREN);
805
- writeb(ASPEED_FLASH_BASE, BULK_ERASE);
806
- writeb(ASPEED_FLASH_BASE, WREN);
807
- writeb(ASPEED_FLASH_BASE, WRSR);
808
- writeb(ASPEED_FLASH_BASE, bp_bits);
809
- writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
810
- writeb(ASPEED_FLASH_BASE, WREN);
811
- spi_ctrl_stop_user();
812
+ spi_ctrl_start_user(test_data);
813
+ flash_writeb(test_data, 0, WREN);
814
+ flash_writeb(test_data, 0, BULK_ERASE);
815
+ flash_writeb(test_data, 0, WREN);
816
+ flash_writeb(test_data, 0, WRSR);
817
+ flash_writeb(test_data, 0, bp_bits);
818
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
819
+ flash_writeb(test_data, 0, WREN);
820
+ spi_ctrl_stop_user(test_data);
821
822
uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0;
823
uint32_t protection_start = 0;
824
@@ -XXX,XX +XXX,XX @@ static void test_write_block_protect_bottom_bit(void)
825
for (int sector = 0; sector < n_sectors; sector++) {
826
uint32_t addr = sector * sector_size;
827
828
- assert_page_mem(addr, 0xffffffff);
829
- write_page_mem(addr, make_be32(0xabcdef12));
830
+ assert_page_mem(test_data, addr, 0xffffffff);
831
+ write_page_mem(test_data, addr, make_be32(0xabcdef12));
832
833
uint32_t expected_value = protection_start <= sector
834
&& sector < protection_end
835
? 0xffffffff : 0xabcdef12;
836
837
- assert_page_mem(addr, expected_value);
838
+ assert_page_mem(test_data, addr, expected_value);
839
}
840
}
841
842
- flash_reset();
843
+ flash_reset(test_data);
844
}
845
846
-static int test_palmetto_bmc(void)
847
+static void test_palmetto_bmc(TestData *data)
848
{
849
- g_autofree char *tmp_path = NULL;
850
int ret;
851
int fd;
852
853
- fd = g_file_open_tmp("qtest.m25p80.XXXXXX", &tmp_path, NULL);
854
+ fd = g_file_open_tmp("qtest.m25p80.n25q256a.XXXXXX", &data->tmp_path, NULL);
855
g_assert(fd >= 0);
856
- ret = ftruncate(fd, FLASH_SIZE);
857
+ ret = ftruncate(fd, 32 * 1024 * 1024);
858
g_assert(ret == 0);
859
close(fd);
860
861
- global_qtest = qtest_initf("-m 256 -machine palmetto-bmc "
862
- "-drive file=%s,format=raw,if=mtd",
863
- tmp_path);
864
-
865
- qtest_add_func("/ast2400/smc/read_jedec", test_read_jedec);
866
- qtest_add_func("/ast2400/smc/erase_sector", test_erase_sector);
867
- qtest_add_func("/ast2400/smc/erase_all", test_erase_all);
868
- qtest_add_func("/ast2400/smc/write_page", test_write_page);
869
- qtest_add_func("/ast2400/smc/read_page_mem", test_read_page_mem);
870
- qtest_add_func("/ast2400/smc/write_page_mem", test_write_page_mem);
871
- qtest_add_func("/ast2400/smc/read_status_reg", test_read_status_reg);
872
- qtest_add_func("/ast2400/smc/status_reg_write_protection",
873
- test_status_reg_write_protection);
874
- qtest_add_func("/ast2400/smc/write_block_protect",
875
- test_write_block_protect);
876
- qtest_add_func("/ast2400/smc/write_block_protect_bottom_bit",
877
- test_write_block_protect_bottom_bit);
878
-
879
- flash_reset();
880
- ret = g_test_run();
881
- qtest_quit(global_qtest);
882
- unlink(tmp_path);
883
-
884
- return ret;
885
+ data->s = qtest_initf("-m 256 -machine palmetto-bmc "
886
+ "-drive file=%s,format=raw,if=mtd",
887
+ data->tmp_path);
888
+
889
+ /* fmc cs0 with n25q256a flash */
890
+ data->flash_base = 0x20000000;
891
+ data->spi_base = 0x1E620000;
892
+ data->jedec_id = 0x20ba19;
893
+
894
+ qtest_add_data_func("/ast2400/smc/read_jedec", data, test_read_jedec);
895
+ qtest_add_data_func("/ast2400/smc/erase_sector", data, test_erase_sector);
896
+ qtest_add_data_func("/ast2400/smc/erase_all", data, test_erase_all);
897
+ qtest_add_data_func("/ast2400/smc/write_page", data, test_write_page);
898
+ qtest_add_data_func("/ast2400/smc/read_page_mem",
899
+ data, test_read_page_mem);
900
+ qtest_add_data_func("/ast2400/smc/write_page_mem",
901
+ data, test_write_page_mem);
902
+ qtest_add_data_func("/ast2400/smc/read_status_reg",
903
+ data, test_read_status_reg);
904
+ qtest_add_data_func("/ast2400/smc/status_reg_write_protection",
905
+ data, test_status_reg_write_protection);
906
+ qtest_add_data_func("/ast2400/smc/write_block_protect",
907
+ data, test_write_block_protect);
908
+ qtest_add_data_func("/ast2400/smc/write_block_protect_bottom_bit",
909
+ data, test_write_block_protect_bottom_bit);
910
}
911
912
int main(int argc, char **argv)
913
{
914
+ TestData palmetto_data;
915
int ret;
916
917
g_test_init(&argc, &argv, NULL);
918
- ret = test_palmetto_bmc();
919
920
+ test_palmetto_bmc(&palmetto_data);
921
+ ret = g_test_run();
922
+
923
+ qtest_quit(palmetto_data.s);
924
+ unlink(palmetto_data.tmp_path);
925
return ret;
926
}
205
--
927
--
206
2.31.1
928
2.47.1
207
929
208
930
diff view generated by jsdifflib
New patch
1
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
3
Currently, these test cases only support to test CE0. To test all CE pins,
4
introduces new ce and node members in TestData structure. The ce member is used
5
for saving the ce index and node member is used for saving the node path,
6
respectively.
7
8
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
9
Reviewed-by: Cédric Le Goater <clg@redhat.com>
10
Link: https://lore.kernel.org/r/20241127091543.1243114-4-jamin_lin@aspeedtech.com
11
Signed-off-by: Cédric Le Goater <clg@redhat.com>
12
---
13
tests/qtest/aspeed_smc-test.c | 77 ++++++++++++++++++-----------------
14
1 file changed, 40 insertions(+), 37 deletions(-)
15
16
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qtest/aspeed_smc-test.c
19
+++ b/tests/qtest/aspeed_smc-test.c
20
@@ -XXX,XX +XXX,XX @@
21
* ASPEED SPI Controller registers
22
*/
23
#define R_CONF 0x00
24
-#define CONF_ENABLE_W0 (1 << 16)
25
+#define CONF_ENABLE_W0 16
26
#define R_CE_CTRL 0x04
27
#define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */
28
#define R_CTRL0 0x10
29
-#define CTRL_CE_STOP_ACTIVE (1 << 2)
30
+#define CTRL_CE_STOP_ACTIVE BIT(2)
31
#define CTRL_READMODE 0x0
32
#define CTRL_FREADMODE 0x1
33
#define CTRL_WRITEMODE 0x2
34
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
35
uint64_t flash_base;
36
uint32_t jedec_id;
37
char *tmp_path;
38
+ uint8_t cs;
39
+ const char *node;
40
} TestData;
41
42
/*
43
@@ -XXX,XX +XXX,XX @@ static void spi_ce_ctrl(const TestData *data, uint32_t value)
44
45
static void spi_ctrl_setmode(const TestData *data, uint8_t mode, uint8_t cmd)
46
{
47
- uint32_t ctrl = spi_readl(data, R_CTRL0);
48
+ uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
49
+ uint32_t ctrl = spi_readl(data, ctrl_reg);
50
ctrl &= ~(CTRL_USERMODE | 0xff << 16);
51
ctrl |= mode | (cmd << 16);
52
- spi_writel(data, R_CTRL0, ctrl);
53
+ spi_writel(data, ctrl_reg, ctrl);
54
}
55
56
static void spi_ctrl_start_user(const TestData *data)
57
{
58
- uint32_t ctrl = spi_readl(data, R_CTRL0);
59
+ uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
60
+ uint32_t ctrl = spi_readl(data, ctrl_reg);
61
62
ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
63
- spi_writel(data, R_CTRL0, ctrl);
64
+ spi_writel(data, ctrl_reg, ctrl);
65
66
ctrl &= ~CTRL_CE_STOP_ACTIVE;
67
- spi_writel(data, R_CTRL0, ctrl);
68
+ spi_writel(data, ctrl_reg, ctrl);
69
}
70
71
static void spi_ctrl_stop_user(const TestData *data)
72
{
73
- uint32_t ctrl = spi_readl(data, R_CTRL0);
74
+ uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
75
+ uint32_t ctrl = spi_readl(data, ctrl_reg);
76
77
ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
78
- spi_writel(data, R_CTRL0, ctrl);
79
+ spi_writel(data, ctrl_reg, ctrl);
80
}
81
82
static void flash_reset(const TestData *data)
83
{
84
- spi_conf(data, CONF_ENABLE_W0);
85
+ spi_conf(data, 1 << (CONF_ENABLE_W0 + data->cs));
86
87
spi_ctrl_start_user(data);
88
flash_writeb(data, 0, RESET_ENABLE);
89
@@ -XXX,XX +XXX,XX @@ static void flash_reset(const TestData *data)
90
flash_writeb(data, 0, WRDI);
91
spi_ctrl_stop_user(data);
92
93
- spi_conf_remove(data, CONF_ENABLE_W0);
94
+ spi_conf_remove(data, 1 << (CONF_ENABLE_W0 + data->cs));
95
}
96
97
static void test_read_jedec(const void *data)
98
@@ -XXX,XX +XXX,XX @@ static void test_read_jedec(const void *data)
99
const TestData *test_data = (const TestData *)data;
100
uint32_t jedec = 0x0;
101
102
- spi_conf(test_data, CONF_ENABLE_W0);
103
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
104
105
spi_ctrl_start_user(test_data);
106
flash_writeb(test_data, 0, JEDEC_READ);
107
@@ -XXX,XX +XXX,XX @@ static void test_erase_sector(const void *data)
108
uint32_t page[FLASH_PAGE_SIZE / 4];
109
int i;
110
111
- spi_conf(test_data, CONF_ENABLE_W0);
112
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
113
114
/*
115
* Previous page should be full of 0xffs after backend is
116
@@ -XXX,XX +XXX,XX @@ static void test_erase_all(const void *data)
117
uint32_t page[FLASH_PAGE_SIZE / 4];
118
int i;
119
120
- spi_conf(test_data, CONF_ENABLE_W0);
121
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
122
123
/*
124
* Previous page should be full of 0xffs after backend is
125
@@ -XXX,XX +XXX,XX @@ static void test_write_page(const void *data)
126
uint32_t page[FLASH_PAGE_SIZE / 4];
127
int i;
128
129
- spi_conf(test_data, CONF_ENABLE_W0);
130
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
131
132
spi_ctrl_start_user(test_data);
133
flash_writeb(test_data, 0, EN_4BYTE_ADDR);
134
@@ -XXX,XX +XXX,XX @@ static void test_read_page_mem(const void *data)
135
int i;
136
137
/*
138
- * Enable 4BYTE mode for controller. This is should be strapped by
139
- * HW for CE0 anyhow.
140
+ * Enable 4BYTE mode for controller.
141
*/
142
- spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0);
143
+ spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
144
145
/* Enable 4BYTE mode for flash. */
146
- spi_conf(test_data, CONF_ENABLE_W0);
147
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
148
spi_ctrl_start_user(test_data);
149
flash_writeb(test_data, 0, EN_4BYTE_ADDR);
150
flash_writeb(test_data, 0, WREN);
151
@@ -XXX,XX +XXX,XX @@ static void test_read_page_mem(const void *data)
152
flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
153
}
154
spi_ctrl_stop_user(test_data);
155
- spi_conf_remove(test_data, CONF_ENABLE_W0);
156
+ spi_conf_remove(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
157
158
/* Check what was written */
159
read_page_mem(test_data, my_page_addr, page);
160
@@ -XXX,XX +XXX,XX @@ static void test_write_page_mem(const void *data)
161
int i;
162
163
/*
164
- * Enable 4BYTE mode for controller. This is should be strapped by
165
- * HW for CE0 anyhow.
166
+ * Enable 4BYTE mode for controller.
167
*/
168
- spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0);
169
+ spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
170
171
/* Enable 4BYTE mode for flash. */
172
- spi_conf(test_data, CONF_ENABLE_W0);
173
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
174
spi_ctrl_start_user(test_data);
175
flash_writeb(test_data, 0, EN_4BYTE_ADDR);
176
flash_writeb(test_data, 0, WREN);
177
@@ -XXX,XX +XXX,XX @@ static void test_read_status_reg(const void *data)
178
const TestData *test_data = (const TestData *)data;
179
uint8_t r;
180
181
- spi_conf(test_data, CONF_ENABLE_W0);
182
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
183
184
spi_ctrl_start_user(test_data);
185
flash_writeb(test_data, 0, RDSR);
186
@@ -XXX,XX +XXX,XX @@ static void test_read_status_reg(const void *data)
187
188
g_assert_cmphex(r & SR_WEL, ==, 0);
189
g_assert(!qtest_qom_get_bool
190
- (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
191
+ (test_data->s, test_data->node, "write-enable"));
192
193
spi_ctrl_start_user(test_data);
194
flash_writeb(test_data, 0, WREN);
195
@@ -XXX,XX +XXX,XX @@ static void test_read_status_reg(const void *data)
196
197
g_assert_cmphex(r & SR_WEL, ==, SR_WEL);
198
g_assert(qtest_qom_get_bool
199
- (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
200
+ (test_data->s, test_data->node, "write-enable"));
201
202
spi_ctrl_start_user(test_data);
203
flash_writeb(test_data, 0, WRDI);
204
@@ -XXX,XX +XXX,XX @@ static void test_read_status_reg(const void *data)
205
206
g_assert_cmphex(r & SR_WEL, ==, 0);
207
g_assert(!qtest_qom_get_bool
208
- (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable"));
209
+ (test_data->s, test_data->node, "write-enable"));
210
211
flash_reset(test_data);
212
}
213
@@ -XXX,XX +XXX,XX @@ static void test_status_reg_write_protection(const void *data)
214
const TestData *test_data = (const TestData *)data;
215
uint8_t r;
216
217
- spi_conf(test_data, CONF_ENABLE_W0);
218
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
219
220
/* default case: WP# is high and SRWD is low -> status register writable */
221
spi_ctrl_start_user(test_data);
222
@@ -XXX,XX +XXX,XX @@ static void test_status_reg_write_protection(const void *data)
223
g_assert_cmphex(r & SRWD, ==, 0);
224
225
/* WP# low and SRWD low -> status register writable */
226
- qtest_set_irq_in(test_data->s,
227
- "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 0);
228
+ qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 0);
229
spi_ctrl_start_user(test_data);
230
flash_writeb(test_data, 0, WREN);
231
/* test ability to write SRWD */
232
@@ -XXX,XX +XXX,XX @@ static void test_status_reg_write_protection(const void *data)
233
/* write is not successful */
234
g_assert_cmphex(r & SRWD, ==, SRWD);
235
236
- qtest_set_irq_in(test_data->s,
237
- "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 1);
238
+ qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 1);
239
flash_reset(test_data);
240
}
241
242
@@ -XXX,XX +XXX,XX @@ static void test_write_block_protect(const void *data)
243
uint32_t sector_size = 65536;
244
uint32_t n_sectors = 512;
245
246
- spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0);
247
- spi_conf(test_data, CONF_ENABLE_W0);
248
+ spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
249
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
250
251
uint32_t bp_bits = 0b0;
252
253
@@ -XXX,XX +XXX,XX @@ static void test_write_block_protect_bottom_bit(const void *data)
254
uint32_t sector_size = 65536;
255
uint32_t n_sectors = 512;
256
257
- spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0);
258
- spi_conf(test_data, CONF_ENABLE_W0);
259
+ spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
260
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
261
262
/* top bottom bit is enabled */
263
uint32_t bp_bits = 0b00100 << 3;
264
@@ -XXX,XX +XXX,XX @@ static void test_palmetto_bmc(TestData *data)
265
data->flash_base = 0x20000000;
266
data->spi_base = 0x1E620000;
267
data->jedec_id = 0x20ba19;
268
+ data->cs = 0;
269
+ data->node = "/machine/soc/fmc/ssi.0/child[0]";
270
271
qtest_add_data_func("/ast2400/smc/read_jedec", data, test_read_jedec);
272
qtest_add_data_func("/ast2400/smc/erase_sector", data, test_erase_sector);
273
--
274
2.47.1
275
276
diff view generated by jsdifflib
1
This simplifies the reset handler and has the benefit to remove some
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
"bad" use of the segments array as an identifier of the controller model.
3
2
4
Signed-off-by: Cédric Le Goater <clg@kaod.org>
3
Currently, these test cases used the hardcode offset 0x1400000 (0x14000 * 256)
4
which was beyond the 16MB flash size for flash page read/write command testing.
5
However, the default fmc flash model of ast1030-a1 EVB is "w25q80bl" whose size
6
is 1MB. To test SoC flash models, introduces a new page_addr member in TestData
7
structure, so users can set the offset for flash page read/write command
8
testing.
9
10
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
11
Reviewed-by: Cédric Le Goater <clg@redhat.com>
12
Link: https://lore.kernel.org/r/20241127091543.1243114-5-jamin_lin@aspeedtech.com
13
Signed-off-by: Cédric Le Goater <clg@redhat.com>
5
---
14
---
6
include/hw/ssi/aspeed_smc.h | 1 +
15
tests/qtest/aspeed_smc-test.c | 17 ++++++++++-------
7
hw/ssi/aspeed_smc.c | 52 +++++++++++++++++++------------------
16
1 file changed, 10 insertions(+), 7 deletions(-)
8
2 files changed, 28 insertions(+), 25 deletions(-)
9
17
10
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
18
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
11
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
12
--- a/include/hw/ssi/aspeed_smc.h
20
--- a/tests/qtest/aspeed_smc-test.c
13
+++ b/include/hw/ssi/aspeed_smc.h
21
+++ b/tests/qtest/aspeed_smc-test.c
14
@@ -XXX,XX +XXX,XX @@ struct AspeedSMCClass {
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
15
uint8_t nregs_timings;
23
char *tmp_path;
16
uint8_t conf_enable_w0;
24
uint8_t cs;
17
uint8_t max_peripherals;
25
const char *node;
18
+ const uint32_t *resets;
26
+ uint32_t page_addr;
19
const AspeedSegments *segments;
27
} TestData;
20
hwaddr flash_window_base;
28
21
uint32_t flash_window_size;
29
/*
22
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
30
@@ -XXX,XX +XXX,XX @@ static void assert_page_mem(const TestData *data, uint32_t addr,
23
index XXXXXXX..XXXXXXX 100644
31
static void test_erase_sector(const void *data)
24
--- a/hw/ssi/aspeed_smc.c
32
{
25
+++ b/hw/ssi/aspeed_smc.c
33
const TestData *test_data = (const TestData *)data;
26
@@ -XXX,XX +XXX,XX @@
34
- uint32_t some_page_addr = 0x600 * FLASH_PAGE_SIZE;
27
* controller. These can be changed when board is initialized with the
35
+ uint32_t some_page_addr = test_data->page_addr;
28
* Segment Address Registers.
36
uint32_t page[FLASH_PAGE_SIZE / 4];
29
*/
30
-static const AspeedSegments aspeed_2400_fmc_segments[];
31
static const AspeedSegments aspeed_2400_spi1_segments[];
32
-static const AspeedSegments aspeed_2500_fmc_segments[];
33
static const AspeedSegments aspeed_2500_spi1_segments[];
34
static const AspeedSegments aspeed_2500_spi2_segments[];
35
-static const AspeedSegments aspeed_2600_fmc_segments[];
36
37
#define ASPEED_SMC_FEATURE_DMA 0x1
38
#define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
39
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
40
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
41
int i;
37
int i;
42
38
43
- memset(s->regs, 0, sizeof s->regs);
39
@@ -XXX,XX +XXX,XX @@ static void test_erase_sector(const void *data)
44
+ if (asc->resets) {
40
static void test_erase_all(const void *data)
45
+ memcpy(s->regs, asc->resets, sizeof s->regs);
41
{
46
+ } else {
42
const TestData *test_data = (const TestData *)data;
47
+ memset(s->regs, 0, sizeof s->regs);
43
- uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE;
48
+ }
44
+ uint32_t some_page_addr = test_data->page_addr;
49
45
uint32_t page[FLASH_PAGE_SIZE / 4];
50
/* Unselect all peripherals */
46
int i;
51
for (i = 0; i < s->num_cs; ++i) {
47
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
48
@@ -XXX,XX +XXX,XX @@ static void test_erase_all(const void *data)
53
asc->segment_to_reg(s, &asc->segments[i]));
49
static void test_write_page(const void *data)
54
}
50
{
55
51
const TestData *test_data = (const TestData *)data;
56
- /* HW strapping flash type for the AST2600 controllers */
52
- uint32_t my_page_addr = 0x14000 * FLASH_PAGE_SIZE; /* beyond 16MB */
57
- if (asc->segments == aspeed_2600_fmc_segments) {
53
- uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE;
58
- /* flash type is fixed to SPI for all */
54
+ uint32_t my_page_addr = test_data->page_addr;
59
- s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
55
+ uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
60
- s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1);
56
uint32_t page[FLASH_PAGE_SIZE / 4];
61
- s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE2);
57
int i;
62
- }
58
63
-
59
@@ -XXX,XX +XXX,XX @@ static void test_write_page(const void *data)
64
- /* HW strapping flash type for FMC controllers */
60
static void test_read_page_mem(const void *data)
65
- if (asc->segments == aspeed_2500_fmc_segments) {
61
{
66
- /* flash type is fixed to SPI for CE0 and CE1 */
62
const TestData *test_data = (const TestData *)data;
67
- s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
63
- uint32_t my_page_addr = 0x14000 * FLASH_PAGE_SIZE; /* beyond 16MB */
68
- s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1);
64
- uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE;
69
- }
65
+ uint32_t my_page_addr = test_data->page_addr;
70
-
66
+ uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
71
- /* HW strapping for AST2400 FMC controllers (SCU70). Let's use the
67
uint32_t page[FLASH_PAGE_SIZE / 4];
72
- * configuration of the palmetto-bmc machine */
68
int i;
73
- if (asc->segments == aspeed_2400_fmc_segments) {
69
74
- s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
70
@@ -XXX,XX +XXX,XX @@ static void test_read_page_mem(const void *data)
75
- }
71
static void test_write_page_mem(const void *data)
76
-
72
{
77
s->snoop_index = SNOOP_OFF;
73
const TestData *test_data = (const TestData *)data;
78
s->snoop_dummies = 0;
74
- uint32_t my_page_addr = 0x15000 * FLASH_PAGE_SIZE;
79
}
75
+ uint32_t my_page_addr = test_data->page_addr;
80
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_2400_smc_info = {
76
uint32_t page[FLASH_PAGE_SIZE / 4];
81
.class_init = aspeed_2400_smc_class_init,
77
int i;
82
};
78
83
79
@@ -XXX,XX +XXX,XX @@ static void test_palmetto_bmc(TestData *data)
84
+static const uint32_t aspeed_2400_fmc_resets[ASPEED_SMC_R_MAX] = {
80
data->jedec_id = 0x20ba19;
85
+ /*
81
data->cs = 0;
86
+ * CE0 and CE1 types are HW strapped in SCU70. Do it here to
82
data->node = "/machine/soc/fmc/ssi.0/child[0]";
87
+ * simplify the model.
83
+ /* beyond 16MB */
88
+ */
84
+ data->page_addr = 0x14000 * FLASH_PAGE_SIZE;
89
+ [R_CONF] = CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0,
85
90
+};
86
qtest_add_data_func("/ast2400/smc/read_jedec", data, test_read_jedec);
91
+
87
qtest_add_data_func("/ast2400/smc/erase_sector", data, test_erase_sector);
92
static const AspeedSegments aspeed_2400_fmc_segments[] = {
93
{ 0x20000000, 64 * MiB }, /* start address is readonly */
94
{ 0x24000000, 32 * MiB },
95
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_fmc_class_init(ObjectClass *klass, void *data)
96
asc->conf_enable_w0 = CONF_ENABLE_W0;
97
asc->max_peripherals = 5;
98
asc->segments = aspeed_2400_fmc_segments;
99
+ asc->resets = aspeed_2400_fmc_resets;
100
asc->flash_window_base = 0x20000000;
101
asc->flash_window_size = 0x10000000;
102
asc->features = ASPEED_SMC_FEATURE_DMA;
103
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_2400_spi1_info = {
104
.class_init = aspeed_2400_spi1_class_init,
105
};
106
107
+static const uint32_t aspeed_2500_fmc_resets[ASPEED_SMC_R_MAX] = {
108
+ [R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
109
+ CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
110
+};
111
+
112
static const AspeedSegments aspeed_2500_fmc_segments[] = {
113
{ 0x20000000, 128 * MiB }, /* start address is readonly */
114
{ 0x28000000, 32 * MiB },
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_fmc_class_init(ObjectClass *klass, void *data)
116
asc->conf_enable_w0 = CONF_ENABLE_W0;
117
asc->max_peripherals = 3;
118
asc->segments = aspeed_2500_fmc_segments;
119
+ asc->resets = aspeed_2500_fmc_resets;
120
asc->flash_window_base = 0x20000000;
121
asc->flash_window_size = 0x10000000;
122
asc->features = ASPEED_SMC_FEATURE_DMA;
123
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
124
}
125
}
126
127
+static const uint32_t aspeed_2600_fmc_resets[ASPEED_SMC_R_MAX] = {
128
+ [R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
129
+ CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1 |
130
+ CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE2),
131
+};
132
+
133
static const AspeedSegments aspeed_2600_fmc_segments[] = {
134
{ 0x0, 128 * MiB }, /* start address is readonly */
135
{ 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
136
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_fmc_class_init(ObjectClass *klass, void *data)
137
asc->conf_enable_w0 = CONF_ENABLE_W0;
138
asc->max_peripherals = 3;
139
asc->segments = aspeed_2600_fmc_segments;
140
+ asc->resets = aspeed_2600_fmc_resets;
141
asc->flash_window_base = 0x20000000;
142
asc->flash_window_size = 0x10000000;
143
asc->features = ASPEED_SMC_FEATURE_DMA |
144
--
88
--
145
2.31.1
89
2.47.1
146
90
147
91
diff view generated by jsdifflib
1
'cs' is a more appropriate name to index SPI flash devices.
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Add test_ast2500_evb function and reused testcases for AST2500 testing.
4
Signed-off-by: Cédric Le Goater <clg@kaod.org>
4
The spi base address, flash base address and ce index of fmc_cs0 are
5
0x1E620000, 0x20000000 and 0, respectively.
6
The default flash model of fmc_cs0 is "mx25l25635e" whose size is 32MB,
7
so set jedec_id 0xc22019.
8
9
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
10
Reviewed-by: Cédric Le Goater <clg@redhat.com>
11
Link: https://lore.kernel.org/r/20241127091543.1243114-6-jamin_lin@aspeedtech.com
12
Signed-off-by: Cédric Le Goater <clg@redhat.com>
5
---
13
---
6
include/hw/ssi/aspeed_smc.h | 2 +-
14
tests/qtest/aspeed_smc-test.c | 40 +++++++++++++++++++++++++++++++++++
7
hw/ssi/aspeed_smc.c | 30 +++++++++++++++---------------
15
1 file changed, 40 insertions(+)
8
2 files changed, 16 insertions(+), 16 deletions(-)
9
16
10
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
17
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
11
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
12
--- a/include/hw/ssi/aspeed_smc.h
19
--- a/tests/qtest/aspeed_smc-test.c
13
+++ b/include/hw/ssi/aspeed_smc.h
20
+++ b/tests/qtest/aspeed_smc-test.c
14
@@ -XXX,XX +XXX,XX @@ struct AspeedSMCState;
21
@@ -XXX,XX +XXX,XX @@ static void test_palmetto_bmc(TestData *data)
15
typedef struct AspeedSMCFlash {
22
data, test_write_block_protect_bottom_bit);
16
struct AspeedSMCState *controller;
23
}
17
24
18
- uint8_t id;
25
+static void test_ast2500_evb(TestData *data)
19
+ uint8_t cs;
26
+{
20
27
+ int ret;
21
MemoryRegion mmio;
28
+ int fd;
22
} AspeedSMCFlash;
29
+
23
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
30
+ fd = g_file_open_tmp("qtest.m25p80.mx25l25635e.XXXXXX",
24
index XXXXXXX..XXXXXXX 100644
31
+ &data->tmp_path, NULL);
25
--- a/hw/ssi/aspeed_smc.c
32
+ g_assert(fd >= 0);
26
+++ b/hw/ssi/aspeed_smc.c
33
+ ret = ftruncate(fd, 32 * 1024 * 1024);
27
@@ -XXX,XX +XXX,XX @@ static inline int aspeed_smc_flash_mode(const AspeedSMCFlash *fl)
34
+ g_assert(ret == 0);
35
+ close(fd);
36
+
37
+ data->s = qtest_initf("-machine ast2500-evb "
38
+ "-drive file=%s,format=raw,if=mtd",
39
+ data->tmp_path);
40
+
41
+ /* fmc cs0 with mx25l25635e flash */
42
+ data->flash_base = 0x20000000;
43
+ data->spi_base = 0x1E620000;
44
+ data->jedec_id = 0xc22019;
45
+ data->cs = 0;
46
+ data->node = "/machine/soc/fmc/ssi.0/child[0]";
47
+ /* beyond 16MB */
48
+ data->page_addr = 0x14000 * FLASH_PAGE_SIZE;
49
+
50
+ qtest_add_data_func("/ast2500/smc/read_jedec", data, test_read_jedec);
51
+ qtest_add_data_func("/ast2500/smc/erase_sector", data, test_erase_sector);
52
+ qtest_add_data_func("/ast2500/smc/erase_all", data, test_erase_all);
53
+ qtest_add_data_func("/ast2500/smc/write_page", data, test_write_page);
54
+ qtest_add_data_func("/ast2500/smc/read_page_mem",
55
+ data, test_read_page_mem);
56
+ qtest_add_data_func("/ast2500/smc/write_page_mem",
57
+ data, test_write_page_mem);
58
+ qtest_add_data_func("/ast2500/smc/read_status_reg",
59
+ data, test_read_status_reg);
60
+}
61
int main(int argc, char **argv)
28
{
62
{
29
const AspeedSMCState *s = fl->controller;
63
TestData palmetto_data;
30
64
+ TestData ast2500_evb_data;
31
- return s->regs[s->r_ctrl0 + fl->id] & CTRL_CMD_MODE_MASK;
65
int ret;
32
+ return s->regs[s->r_ctrl0 + fl->cs] & CTRL_CMD_MODE_MASK;
66
33
}
67
g_test_init(&argc, &argv, NULL);
34
68
35
static inline bool aspeed_smc_is_writable(const AspeedSMCFlash *fl)
69
test_palmetto_bmc(&palmetto_data);
36
{
70
+ test_ast2500_evb(&ast2500_evb_data);
37
const AspeedSMCState *s = fl->controller;
71
ret = g_test_run();
38
72
39
- return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->id));
73
qtest_quit(palmetto_data.s);
40
+ return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->cs));
74
+ qtest_quit(ast2500_evb_data.s);
41
}
75
unlink(palmetto_data.tmp_path);
42
76
+ unlink(ast2500_evb_data.tmp_path);
43
static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
44
{
45
const AspeedSMCState *s = fl->controller;
46
- int cmd = (s->regs[s->r_ctrl0 + fl->id] >> CTRL_CMD_SHIFT) & CTRL_CMD_MASK;
47
+ int cmd = (s->regs[s->r_ctrl0 + fl->cs] >> CTRL_CMD_SHIFT) & CTRL_CMD_MASK;
48
49
/*
50
* In read mode, the default SPI command is READ (0x3). In other
51
@@ -XXX,XX +XXX,XX @@ static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl)
52
if (asc->segments == aspeed_2400_spi1_segments) {
53
return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
54
} else {
55
- return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->id));
56
+ return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->cs));
57
}
58
}
59
60
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_do_select(AspeedSMCFlash *fl, bool unselect)
61
{
62
AspeedSMCState *s = fl->controller;
63
64
- trace_aspeed_smc_flash_select(fl->id, unselect ? "un" : "");
65
+ trace_aspeed_smc_flash_select(fl->cs, unselect ? "un" : "");
66
67
- qemu_set_irq(s->cs_lines[fl->id], unselect);
68
+ qemu_set_irq(s->cs_lines[fl->cs], unselect);
69
}
70
71
static void aspeed_smc_flash_select(AspeedSMCFlash *fl)
72
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
73
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
74
AspeedSegments seg;
75
76
- asc->reg_to_segment(s, s->regs[R_SEG_ADDR0 + fl->id], &seg);
77
+ asc->reg_to_segment(s, s->regs[R_SEG_ADDR0 + fl->cs], &seg);
78
if ((addr % seg.size) != addr) {
79
aspeed_smc_error("invalid address 0x%08x for CS%d segment : "
80
"[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
81
- addr, fl->id, seg.addr, seg.addr + seg.size);
82
+ addr, fl->cs, seg.addr, seg.addr + seg.size);
83
addr %= seg.size;
84
}
85
86
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
87
static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
88
{
89
const AspeedSMCState *s = fl->controller;
90
- uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->id];
91
+ uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->cs];
92
uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
93
uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
94
uint32_t dummies = ((dummy_high << 2) | dummy_low) * 8;
95
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
96
aspeed_smc_error("invalid flash mode %d", aspeed_smc_flash_mode(fl));
97
}
98
99
- trace_aspeed_smc_flash_read(fl->id, addr, size, ret,
100
+ trace_aspeed_smc_flash_read(fl->cs, addr, size, ret,
101
aspeed_smc_flash_mode(fl));
102
return ret;
77
return ret;
103
}
78
}
104
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_do_snoop(AspeedSMCFlash *fl, uint64_t data,
105
AspeedSMCState *s = fl->controller;
106
uint8_t addr_width = aspeed_smc_flash_is_4byte(fl) ? 4 : 3;
107
108
- trace_aspeed_smc_do_snoop(fl->id, s->snoop_index, s->snoop_dummies,
109
+ trace_aspeed_smc_do_snoop(fl->cs, s->snoop_index, s->snoop_dummies,
110
(uint8_t) data & 0xff);
111
112
if (s->snoop_index == SNOOP_OFF) {
113
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
114
AspeedSMCState *s = fl->controller;
115
int i;
116
117
- trace_aspeed_smc_flash_write(fl->id, addr, size, data,
118
+ trace_aspeed_smc_flash_write(fl->cs, addr, size, data,
119
aspeed_smc_flash_mode(fl));
120
121
if (!aspeed_smc_is_writable(fl)) {
122
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_update_ctrl(AspeedSMCFlash *fl, uint32_t value)
123
unselect = (value & CTRL_CMD_MODE_MASK) != CTRL_USERMODE;
124
125
/* A change of CTRL_CE_STOP_ACTIVE from 0 to 1, unselects the CS */
126
- if (!(s->regs[s->r_ctrl0 + fl->id] & CTRL_CE_STOP_ACTIVE) &&
127
+ if (!(s->regs[s->r_ctrl0 + fl->cs] & CTRL_CE_STOP_ACTIVE) &&
128
value & CTRL_CE_STOP_ACTIVE) {
129
unselect = true;
130
}
131
132
- s->regs[s->r_ctrl0 + fl->id] = value;
133
+ s->regs[s->r_ctrl0 + fl->cs] = value;
134
135
s->snoop_index = unselect ? SNOOP_OFF : SNOOP_START;
136
137
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
138
139
snprintf(name, sizeof(name), TYPE_ASPEED_SMC ".flash.%d", i);
140
141
- fl->id = i;
142
+ fl->cs = i;
143
fl->controller = s;
144
memory_region_init_io(&fl->mmio, OBJECT(s), &aspeed_smc_flash_ops,
145
fl, name, asc->segments[i].size);
146
--
79
--
147
2.31.1
80
2.47.1
148
81
149
82
diff view generated by jsdifflib
1
There is no need to keep a reference of the flash qdev in the AspeedSMCFlash
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
state: the SPI bus takes ownership and will release its resources. Remove
3
AspeedSMCFlash::flash.
4
2
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Add test_ast2600_evb function and reused testcases for AST2600 testing.
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
4
The spi base address, flash base address and ce index of fmc_cs0 are
5
0x1E620000, 0x20000000 and 0, respectively.
6
The default flash model of fmc_cs0 is "mx66u51235f" whose size is 64MB,
7
so set jedec_id 0xc2253a.
8
9
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
10
Reviewed-by: Cédric Le Goater <clg@redhat.com>
11
Link: https://lore.kernel.org/r/20241127091543.1243114-7-jamin_lin@aspeedtech.com
12
Signed-off-by: Cédric Le Goater <clg@redhat.com>
7
---
13
---
8
include/hw/ssi/aspeed_smc.h | 1 -
14
tests/qtest/aspeed_smc-test.c | 41 +++++++++++++++++++++++++++++++++++
9
hw/arm/aspeed.c | 11 +++++------
15
1 file changed, 41 insertions(+)
10
2 files changed, 5 insertions(+), 7 deletions(-)
11
16
12
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
17
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/ssi/aspeed_smc.h
19
--- a/tests/qtest/aspeed_smc-test.c
15
+++ b/include/hw/ssi/aspeed_smc.h
20
+++ b/tests/qtest/aspeed_smc-test.c
16
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCFlash {
21
@@ -XXX,XX +XXX,XX @@ static void test_ast2500_evb(TestData *data)
17
uint32_t size;
22
qtest_add_data_func("/ast2500/smc/read_status_reg",
18
23
data, test_read_status_reg);
19
MemoryRegion mmio;
24
}
20
- DeviceState *flash;
25
+
21
} AspeedSMCFlash;
26
+static void test_ast2600_evb(TestData *data)
22
27
+{
23
#define TYPE_ASPEED_SMC "aspeed.smc"
28
+ int ret;
24
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
29
+ int fd;
25
index XXXXXXX..XXXXXXX 100644
30
+
26
--- a/hw/arm/aspeed.c
31
+ fd = g_file_open_tmp("qtest.m25p80.mx66u51235f.XXXXXX",
27
+++ b/hw/arm/aspeed.c
32
+ &data->tmp_path, NULL);
28
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init_flashes(AspeedSMCState *s,
33
+ g_assert(fd >= 0);
29
int i ;
34
+ ret = ftruncate(fd, 64 * 1024 * 1024);
30
35
+ g_assert(ret == 0);
31
for (i = 0; i < s->num_cs; ++i) {
36
+ close(fd);
32
- AspeedSMCFlash *fl = &s->flashes[i];
37
+
33
DriveInfo *dinfo = drive_get_next(IF_MTD);
38
+ data->s = qtest_initf("-machine ast2600-evb "
34
qemu_irq cs_line;
39
+ "-drive file=%s,format=raw,if=mtd",
35
+ DeviceState *dev;
40
+ data->tmp_path);
36
41
+
37
- fl->flash = qdev_new(flashtype);
42
+ /* fmc cs0 with mx66u51235f flash */
38
+ dev = qdev_new(flashtype);
43
+ data->flash_base = 0x20000000;
39
if (dinfo) {
44
+ data->spi_base = 0x1E620000;
40
- qdev_prop_set_drive(fl->flash, "drive",
45
+ data->jedec_id = 0xc2253a;
41
- blk_by_legacy_dinfo(dinfo));
46
+ data->cs = 0;
42
+ qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
47
+ data->node = "/machine/soc/fmc/ssi.0/child[0]";
43
}
48
+ /* beyond 16MB */
44
- qdev_realize_and_unref(fl->flash, BUS(s->spi), &error_fatal);
49
+ data->page_addr = 0x14000 * FLASH_PAGE_SIZE;
45
+ qdev_realize_and_unref(dev, BUS(s->spi), &error_fatal);
50
+
46
51
+ qtest_add_data_func("/ast2600/smc/read_jedec", data, test_read_jedec);
47
- cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0);
52
+ qtest_add_data_func("/ast2600/smc/erase_sector", data, test_erase_sector);
48
+ cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
53
+ qtest_add_data_func("/ast2600/smc/erase_all", data, test_erase_all);
49
sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
54
+ qtest_add_data_func("/ast2600/smc/write_page", data, test_write_page);
50
}
55
+ qtest_add_data_func("/ast2600/smc/read_page_mem",
56
+ data, test_read_page_mem);
57
+ qtest_add_data_func("/ast2600/smc/write_page_mem",
58
+ data, test_write_page_mem);
59
+ qtest_add_data_func("/ast2600/smc/read_status_reg",
60
+ data, test_read_status_reg);
61
+}
62
int main(int argc, char **argv)
63
{
64
TestData palmetto_data;
65
TestData ast2500_evb_data;
66
+ TestData ast2600_evb_data;
67
int ret;
68
69
g_test_init(&argc, &argv, NULL);
70
71
test_palmetto_bmc(&palmetto_data);
72
test_ast2500_evb(&ast2500_evb_data);
73
+ test_ast2600_evb(&ast2600_evb_data);
74
ret = g_test_run();
75
76
qtest_quit(palmetto_data.s);
77
qtest_quit(ast2500_evb_data.s);
78
+ qtest_quit(ast2600_evb_data.s);
79
unlink(palmetto_data.tmp_path);
80
unlink(ast2500_evb_data.tmp_path);
81
+ unlink(ast2600_evb_data.tmp_path);
82
return ret;
51
}
83
}
52
--
84
--
53
2.31.1
85
2.47.1
54
86
55
87
diff view generated by jsdifflib
1
The Aspeed SoCs have a dual boot function for firmware fail-over
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
recovery. The system auto-reboots from the second flash if the main
3
flash does not boot successfully within a certain amount of time. This
4
function is called alternate boot (ABR) in the FMC controllers.
5
2
6
On AST2400/AST2500, ABR is enabled by hardware strapping in SCU70 to
3
Add test_ast1030_evb function and reused testcases for AST1030 testing.
7
enable the 2nd watchdog timer, on AST2600, through register SCU510.
4
The base address, flash base address and ce index of fmc_cs0 are
8
If the boot on the the main flash succeeds, the firmware should
5
0x7E620000, 0x80000000 and 0, respectively.
9
disable the 2nd watchdog timer. If not, the BMC is reset and the CE0
6
The default flash model of fmc_cs0 is "w25q80bl" whose size is 1MB,
10
and CE1 mappings are swapped to restart the BMC from the 2nd flash.
7
so set jedec_id 0xef4014.
11
8
12
On the AST2600, the ABR registers controlling the 2nd watchdog timer
9
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
13
were moved from the watchdog register to the FMC controller and the
10
Reviewed-by: Cédric Le Goater <clg@redhat.com>
14
FMC model should be able to control WDT2 through its own register set.
11
Link: https://lore.kernel.org/r/20241127091543.1243114-8-jamin_lin@aspeedtech.com
15
This requires more work. For now, add dummy read/write handlers to let
12
Signed-off-by: Cédric Le Goater <clg@redhat.com>
16
the FW disable the 2nd watchdog without error.
13
---
14
tests/qtest/aspeed_smc-test.c | 42 +++++++++++++++++++++++++++++++++++
15
1 file changed, 42 insertions(+)
17
16
18
Reviewed-by: Peter Delevoryas <pdel@fb.com>
17
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
19
Reported-by: Peter Delevoryas <pdel@fb.com>
20
Signed-off-by: Cédric Le Goater <clg@kaod.org>
21
---
22
hw/ssi/aspeed_smc.c | 19 ++++++++++++++++++-
23
1 file changed, 18 insertions(+), 1 deletion(-)
24
25
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
26
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/ssi/aspeed_smc.c
19
--- a/tests/qtest/aspeed_smc-test.c
28
+++ b/hw/ssi/aspeed_smc.c
20
+++ b/tests/qtest/aspeed_smc-test.c
29
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void test_ast2600_evb(TestData *data)
30
/* SPI dummy cycle data */
22
qtest_add_data_func("/ast2600/smc/read_status_reg",
31
#define R_DUMMY_DATA (0x54 / 4)
23
data, test_read_status_reg);
32
24
}
33
+/* FMC_WDT2 Control/Status Register for Alternate Boot (AST2600) */
34
+#define R_FMC_WDT2_CTRL (0x64 / 4)
35
+#define FMC_WDT2_CTRL_ALT_BOOT_MODE BIT(6) /* O: 2 chips 1: 1 chip */
36
+#define FMC_WDT2_CTRL_SINGLE_BOOT_MODE BIT(5)
37
+#define FMC_WDT2_CTRL_BOOT_SOURCE BIT(4) /* O: primary 1: alternate */
38
+#define FMC_WDT2_CTRL_EN BIT(0)
39
+
25
+
40
/* DMA Control/Status Register */
26
+static void test_ast1030_evb(TestData *data)
41
#define R_DMA_CTRL (0x80 / 4)
42
#define DMA_CTRL_REQUEST (1 << 31)
43
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_dma_ctrl(AspeedSMCState *s, uint32_t value);
44
45
#define ASPEED_SMC_FEATURE_DMA 0x1
46
#define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
47
+#define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
48
49
static inline bool aspeed_smc_has_dma(const AspeedSMCState *s)
50
{
51
return !!(s->ctrl->features & ASPEED_SMC_FEATURE_DMA);
52
}
53
54
+static inline bool aspeed_smc_has_wdt_control(const AspeedSMCState *s)
55
+{
27
+{
56
+ return !!(s->ctrl->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
28
+ int ret;
29
+ int fd;
30
+
31
+ fd = g_file_open_tmp("qtest.m25p80.w25q80bl.XXXXXX",
32
+ &data->tmp_path, NULL);
33
+ g_assert(fd >= 0);
34
+ ret = ftruncate(fd, 1 * 1024 * 1024);
35
+ g_assert(ret == 0);
36
+ close(fd);
37
+
38
+ data->s = qtest_initf("-machine ast1030-evb "
39
+ "-drive file=%s,format=raw,if=mtd",
40
+ data->tmp_path);
41
+
42
+ /* fmc cs0 with w25q80bl flash */
43
+ data->flash_base = 0x80000000;
44
+ data->spi_base = 0x7E620000;
45
+ data->jedec_id = 0xef4014;
46
+ data->cs = 0;
47
+ data->node = "/machine/soc/fmc/ssi.0/child[0]";
48
+ /* beyond 512KB */
49
+ data->page_addr = 0x800 * FLASH_PAGE_SIZE;
50
+
51
+ qtest_add_data_func("/ast1030/smc/read_jedec", data, test_read_jedec);
52
+ qtest_add_data_func("/ast1030/smc/erase_sector", data, test_erase_sector);
53
+ qtest_add_data_func("/ast1030/smc/erase_all", data, test_erase_all);
54
+ qtest_add_data_func("/ast1030/smc/write_page", data, test_write_page);
55
+ qtest_add_data_func("/ast1030/smc/read_page_mem",
56
+ data, test_read_page_mem);
57
+ qtest_add_data_func("/ast1030/smc/write_page_mem",
58
+ data, test_write_page_mem);
59
+ qtest_add_data_func("/ast1030/smc/read_status_reg",
60
+ data, test_read_status_reg);
57
+}
61
+}
58
+
62
+
59
static const AspeedSMCController controllers[] = {
63
int main(int argc, char **argv)
60
{
64
{
61
.name = "aspeed.smc-ast2400",
65
TestData palmetto_data;
62
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
66
TestData ast2500_evb_data;
63
.segments = aspeed_segments_ast2600_fmc,
67
TestData ast2600_evb_data;
64
.flash_window_base = ASPEED26_SOC_FMC_FLASH_BASE,
68
+ TestData ast1030_evb_data;
65
.flash_window_size = 0x10000000,
69
int ret;
66
- .features = ASPEED_SMC_FEATURE_DMA,
70
67
+ .features = ASPEED_SMC_FEATURE_DMA |
71
g_test_init(&argc, &argv, NULL);
68
+ ASPEED_SMC_FEATURE_WDT_CONTROL,
72
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
69
.dma_flash_mask = 0x0FFFFFFC,
73
test_palmetto_bmc(&palmetto_data);
70
.dma_dram_mask = 0x3FFFFFFC,
74
test_ast2500_evb(&ast2500_evb_data);
71
.nregs = ASPEED_SMC_R_MAX,
75
test_ast2600_evb(&ast2600_evb_data);
72
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
76
+ test_ast1030_evb(&ast1030_evb_data);
73
addr == R_CE_CMD_CTRL ||
77
ret = g_test_run();
74
addr == R_INTR_CTRL ||
78
75
addr == R_DUMMY_DATA ||
79
qtest_quit(palmetto_data.s);
76
+ (aspeed_smc_has_wdt_control(s) && addr == R_FMC_WDT2_CTRL) ||
80
qtest_quit(ast2500_evb_data.s);
77
(aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) ||
81
qtest_quit(ast2600_evb_data.s);
78
(aspeed_smc_has_dma(s) && addr == R_DMA_FLASH_ADDR) ||
82
+ qtest_quit(ast1030_evb_data.s);
79
(aspeed_smc_has_dma(s) && addr == R_DMA_DRAM_ADDR) ||
83
unlink(palmetto_data.tmp_path);
80
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
84
unlink(ast2500_evb_data.tmp_path);
81
s->regs[addr] = value & 0xff;
85
unlink(ast2600_evb_data.tmp_path);
82
} else if (addr == R_DUMMY_DATA) {
86
+ unlink(ast1030_evb_data.tmp_path);
83
s->regs[addr] = value & 0xff;
87
return ret;
84
+ } else if (aspeed_smc_has_wdt_control(s) && addr == R_FMC_WDT2_CTRL) {
88
}
85
+ s->regs[addr] = value & FMC_WDT2_CTRL_EN;
86
} else if (addr == R_INTR_CTRL) {
87
s->regs[addr] = value;
88
} else if (aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) {
89
--
89
--
90
2.31.1
90
2.47.1
91
91
92
92
diff view generated by jsdifflib
1
From: Peter Delevoryas <pdel@fb.com>
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
2
3
The gpio array is declared as a dense array:
3
Add a new testcase for write page command with QPI mode testing.
4
Currently, only run this testcase for AST2500, AST2600 and AST1030.
4
5
5
qemu_irq gpios[ASPEED_GPIO_NR_PINS];
6
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
7
Reviewed-by: Cédric Le Goater <clg@redhat.com>
8
Link: https://lore.kernel.org/r/20241127091543.1243114-9-jamin_lin@aspeedtech.com
9
Signed-off-by: Cédric Le Goater <clg@redhat.com>
10
---
11
tests/qtest/aspeed_smc-test.c | 74 +++++++++++++++++++++++++++++++++++
12
1 file changed, 74 insertions(+)
6
13
7
(AST2500 has 228, AST2400 has 216, AST2600 has 208)
14
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
8
9
However, this array is used like a matrix of GPIO sets
10
(e.g. gpio[NR_SETS][NR_PINS_PER_SET] = gpio[8][32])
11
12
size_t offset = set * GPIOS_PER_SET + gpio;
13
qemu_set_irq(s->gpios[offset], !!(new & mask));
14
15
This can result in an out-of-bounds access to "s->gpios" because the
16
gpio sets do _not_ have the same length. Some of the groups (e.g.
17
GPIOAB) only have 4 pins. 228 != 8 * 32 == 256.
18
19
To fix this, I converted the gpio array from dense to sparse, to that
20
match both the hardware layout and this existing indexing code.
21
22
Fixes: 4b7f956862dc2db4c5c ("hw/gpio: Add basic Aspeed GPIO model for AST2400 and AST2500")
23
Signed-off-by: Peter Delevoryas <pdel@fb.com>
24
Message-Id: <20211008033501.934729-2-pdel@fb.com>
25
Signed-off-by: Cédric Le Goater <clg@kaod.org>
26
---
27
include/hw/gpio/aspeed_gpio.h | 5 +--
28
hw/gpio/aspeed_gpio.c | 80 +++++++++++++++--------------------
29
2 files changed, 35 insertions(+), 50 deletions(-)
30
31
diff --git a/include/hw/gpio/aspeed_gpio.h b/include/hw/gpio/aspeed_gpio.h
32
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/gpio/aspeed_gpio.h
16
--- a/tests/qtest/aspeed_smc-test.c
34
+++ b/include/hw/gpio/aspeed_gpio.h
17
+++ b/tests/qtest/aspeed_smc-test.c
35
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
36
OBJECT_DECLARE_TYPE(AspeedGPIOState, AspeedGPIOClass, ASPEED_GPIO)
19
#define R_CE_CTRL 0x04
37
20
#define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */
38
#define ASPEED_GPIO_MAX_NR_SETS 8
21
#define R_CTRL0 0x10
39
+#define ASPEED_GPIOS_PER_SET 32
22
+#define CTRL_IO_QUAD_IO BIT(31)
40
#define ASPEED_REGS_PER_BANK 14
23
#define CTRL_CE_STOP_ACTIVE BIT(2)
41
#define ASPEED_GPIO_MAX_NR_REGS (ASPEED_REGS_PER_BANK * ASPEED_GPIO_MAX_NR_SETS)
24
#define CTRL_READMODE 0x0
42
-#define ASPEED_GPIO_NR_PINS 228
25
#define CTRL_FREADMODE 0x1
43
#define ASPEED_GROUPS_PER_SET 4
26
@@ -XXX,XX +XXX,XX @@ enum {
44
#define ASPEED_GPIO_NR_DEBOUNCE_REGS 3
27
ERASE_SECTOR = 0xd8,
45
#define ASPEED_CHARS_PER_GROUP_LABEL 4
46
@@ -XXX,XX +XXX,XX @@ struct AspeedGPIOClass {
47
const GPIOSetProperties *props;
48
uint32_t nr_gpio_pins;
49
uint32_t nr_gpio_sets;
50
- uint32_t gap;
51
const AspeedGPIOReg *reg_table;
52
};
28
};
53
29
54
@@ -XXX,XX +XXX,XX @@ struct AspeedGPIOState {
30
+#define CTRL_IO_MODE_MASK (BIT(31) | BIT(30) | BIT(29) | BIT(28))
55
MemoryRegion iomem;
31
#define FLASH_PAGE_SIZE 256
56
int pending;
32
57
qemu_irq irq;
33
typedef struct TestData {
58
- qemu_irq gpios[ASPEED_GPIO_NR_PINS];
34
@@ -XXX,XX +XXX,XX @@ static void spi_ctrl_stop_user(const TestData *data)
59
+ qemu_irq gpios[ASPEED_GPIO_MAX_NR_SETS][ASPEED_GPIOS_PER_SET];
35
spi_writel(data, ctrl_reg, ctrl);
60
61
/* Parallel GPIO Registers */
62
uint32_t debounce_regs[ASPEED_GPIO_NR_DEBOUNCE_REGS];
63
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/gpio/aspeed_gpio.c
66
+++ b/hw/gpio/aspeed_gpio.c
67
@@ -XXX,XX +XXX,XX @@
68
#include "hw/irq.h"
69
#include "migration/vmstate.h"
70
71
-#define GPIOS_PER_REG 32
72
-#define GPIOS_PER_SET GPIOS_PER_REG
73
-#define GPIO_PIN_GAP_SIZE 4
74
#define GPIOS_PER_GROUP 8
75
-#define GPIO_GROUP_SHIFT 3
76
77
/* GPIO Source Types */
78
#define ASPEED_CMD_SRC_MASK 0x01010101
79
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
80
81
diff = old ^ new;
82
if (diff) {
83
- for (gpio = 0; gpio < GPIOS_PER_REG; gpio++) {
84
+ for (gpio = 0; gpio < ASPEED_GPIOS_PER_SET; gpio++) {
85
uint32_t mask = 1 << gpio;
86
87
/* If the gpio needs to be updated... */
88
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
89
if (direction & mask) {
90
/* ...trigger the line-state IRQ */
91
ptrdiff_t set = aspeed_gpio_set_idx(s, regs);
92
- size_t offset = set * GPIOS_PER_SET + gpio;
93
- qemu_set_irq(s->gpios[offset], !!(new & mask));
94
+ qemu_set_irq(s->gpios[set][gpio], !!(new & mask));
95
} else {
96
/* ...otherwise if we meet the line's current IRQ policy... */
97
if (aspeed_evaluate_irq(regs, old & mask, gpio)) {
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
99
qemu_set_irq(s->irq, !!(s->pending));
100
}
36
}
101
37
102
-static uint32_t aspeed_adjust_pin(AspeedGPIOState *s, uint32_t pin)
38
+static void spi_ctrl_set_io_mode(const TestData *data, uint32_t value)
103
-{
39
+{
104
- AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
40
+ uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
105
- /*
41
+ uint32_t ctrl = spi_readl(data, ctrl_reg);
106
- * The 2500 has a 4 pin gap in group AB and the 2400 has a 4 pin
42
+ uint32_t mode;
107
- * gap in group Y (and only four pins in AB but this is the last group so
43
+
108
- * it doesn't matter).
44
+ mode = value & CTRL_IO_MODE_MASK;
109
- */
45
+ ctrl &= ~CTRL_IO_MODE_MASK;
110
- if (agc->gap && pin >= agc->gap) {
46
+ ctrl |= mode;
111
- pin += GPIO_PIN_GAP_SIZE;
47
+ spi_writel(data, ctrl_reg, ctrl);
112
- }
48
+}
113
-
49
+
114
- return pin;
50
static void flash_reset(const TestData *data)
115
-}
116
-
117
static bool aspeed_gpio_get_pin_level(AspeedGPIOState *s, uint32_t set_idx,
118
uint32_t pin)
119
{
51
{
120
@@ -XXX,XX +XXX,XX @@ static uint32_t update_value_control_source(GPIOSets *regs, uint32_t old_value,
52
spi_conf(data, 1 << (CONF_ENABLE_W0 + data->cs));
121
uint32_t new_value = 0;
53
@@ -XXX,XX +XXX,XX @@ static void test_write_block_protect_bottom_bit(const void *data)
122
54
flash_reset(test_data);
123
/* for each group in set */
124
- for (i = 0; i < GPIOS_PER_REG; i += GPIOS_PER_GROUP) {
125
+ for (i = 0; i < ASPEED_GPIOS_PER_SET; i += GPIOS_PER_GROUP) {
126
cmd_source = extract32(regs->cmd_source_0, i, 1)
127
| (extract32(regs->cmd_source_1, i, 1) << 1);
128
129
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
130
* bidirectional | 1 | 1 | data
131
* input only | 1 | 0 | 0
132
* output only | 0 | 1 | 1
133
- * no pin / gap | 0 | 0 | 0
134
+ * no pin | 0 | 0 | 0
135
*
136
* which is captured by:
137
* data = ( data | ~input) & output;
138
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
139
}
55
}
140
56
141
/****************** Setup functions ******************/
57
+static void test_write_page_qpi(const void *data)
142
-static const GPIOSetProperties ast2400_set_props[] = {
58
+{
143
+static const GPIOSetProperties ast2400_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
59
+ const TestData *test_data = (const TestData *)data;
144
[0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
60
+ uint32_t my_page_addr = test_data->page_addr;
145
[1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
61
+ uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
146
[2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
62
+ uint32_t page[FLASH_PAGE_SIZE / 4];
147
@@ -XXX,XX +XXX,XX @@ static const GPIOSetProperties ast2400_set_props[] = {
63
+ uint32_t page_pattern[] = {
148
[6] = {0x0000000f, 0x0fffff0f, {"Y", "Z", "AA", "AB"} },
64
+ 0xebd8c134, 0x5da196bc, 0xae15e729, 0x5085ccdf
149
};
65
+ };
150
66
+ int i;
151
-static const GPIOSetProperties ast2500_set_props[] = {
67
+
152
+static const GPIOSetProperties ast2500_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
68
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
153
[0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
69
+
154
[1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
70
+ spi_ctrl_start_user(test_data);
155
[2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
71
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
156
@@ -XXX,XX +XXX,XX @@ static const GPIOSetProperties ast2500_set_props[] = {
72
+ flash_writeb(test_data, 0, WREN);
157
[7] = {0x000000ff, 0x000000ff, {"AC"} },
73
+ flash_writeb(test_data, 0, PP);
158
};
74
+ flash_writel(test_data, 0, make_be32(my_page_addr));
159
75
+
160
-static GPIOSetProperties ast2600_3_3v_set_props[] = {
76
+ /* Set QPI mode */
161
+static GPIOSetProperties ast2600_3_3v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
77
+ spi_ctrl_set_io_mode(test_data, CTRL_IO_QUAD_IO);
162
[0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
78
+
163
[1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
79
+ /* Fill the page pattern */
164
[2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
80
+ for (i = 0; i < ARRAY_SIZE(page_pattern); i++) {
165
@@ -XXX,XX +XXX,XX @@ static GPIOSetProperties ast2600_3_3v_set_props[] = {
81
+ flash_writel(test_data, 0, make_be32(page_pattern[i]));
166
[6] = {0x0000ffff, 0x0000ffff, {"Y", "Z"} },
82
+ }
167
};
83
+
168
84
+ /* Fill the page with its own addresses */
169
-static GPIOSetProperties ast2600_1_8v_set_props[] = {
85
+ for (; i < FLASH_PAGE_SIZE / 4; i++) {
170
+static GPIOSetProperties ast2600_1_8v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
86
+ flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
171
[0] = {0xffffffff, 0xffffffff, {"18A", "18B", "18C", "18D"} },
87
+ }
172
[1] = {0x0000000f, 0x0000000f, {"18E"} },
88
+
173
};
89
+ /* Restore io mode */
174
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_realize(DeviceState *dev, Error **errp)
90
+ spi_ctrl_set_io_mode(test_data, 0);
175
AspeedGPIOState *s = ASPEED_GPIO(dev);
91
+ spi_ctrl_stop_user(test_data);
176
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
92
+
177
AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
93
+ /* Check what was written */
178
- int pin;
94
+ read_page(test_data, my_page_addr, page);
179
95
+ for (i = 0; i < ARRAY_SIZE(page_pattern); i++) {
180
/* Interrupt parent line */
96
+ g_assert_cmphex(page[i], ==, page_pattern[i]);
181
sysbus_init_irq(sbd, &s->irq);
97
+ }
182
98
+ for (; i < FLASH_PAGE_SIZE / 4; i++) {
183
/* Individual GPIOs */
99
+ g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
184
- for (pin = 0; pin < agc->nr_gpio_pins; pin++) {
100
+ }
185
- sysbus_init_irq(sbd, &s->gpios[pin]);
101
+
186
+ for (int i = 0; i < ASPEED_GPIO_MAX_NR_SETS; i++) {
102
+ /* Check some other page. It should be full of 0xff */
187
+ const GPIOSetProperties *props = &agc->props[i];
103
+ read_page(test_data, some_page_addr, page);
188
+ uint32_t skip = ~(props->input | props->output);
104
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
189
+ for (int j = 0; j < ASPEED_GPIOS_PER_SET; j++) {
105
+ g_assert_cmphex(page[i], ==, 0xffffffff);
190
+ if (skip >> j & 1) {
106
+ }
191
+ continue;
107
+
192
+ }
108
+ flash_reset(test_data);
193
+ sysbus_init_irq(sbd, &s->gpios[i][j]);
109
+}
194
+ }
110
+
195
}
111
static void test_palmetto_bmc(TestData *data)
196
197
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_gpio_ops, s,
198
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_init(Object *obj)
199
{
112
{
200
AspeedGPIOState *s = ASPEED_GPIO(obj);
113
int ret;
201
AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
114
@@ -XXX,XX +XXX,XX @@ static void test_ast2500_evb(TestData *data)
202
- int pin;
115
data, test_write_page_mem);
203
-
116
qtest_add_data_func("/ast2500/smc/read_status_reg",
204
- for (pin = 0; pin < agc->nr_gpio_pins; pin++) {
117
data, test_read_status_reg);
205
- char *name;
118
+ qtest_add_data_func("/ast2500/smc/write_page_qpi",
206
- int set_idx = pin / GPIOS_PER_SET;
119
+ data, test_write_page_qpi);
207
- int pin_idx = aspeed_adjust_pin(s, pin) - (set_idx * GPIOS_PER_SET);
208
- int group_idx = pin_idx >> GPIO_GROUP_SHIFT;
209
- const GPIOSetProperties *props = &agc->props[set_idx];
210
-
211
- name = g_strdup_printf("gpio%s%d", props->group_label[group_idx],
212
- pin_idx % GPIOS_PER_GROUP);
213
- object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
214
- aspeed_gpio_set_pin, NULL, NULL);
215
- g_free(name);
216
+
217
+ for (int i = 0; i < ASPEED_GPIO_MAX_NR_SETS; i++) {
218
+ const GPIOSetProperties *props = &agc->props[i];
219
+ uint32_t skip = ~(props->input | props->output);
220
+ for (int j = 0; j < ASPEED_GPIOS_PER_SET; j++) {
221
+ if (skip >> j & 1) {
222
+ continue;
223
+ }
224
+ int group_idx = j / GPIOS_PER_GROUP;
225
+ int pin_idx = j % GPIOS_PER_GROUP;
226
+ const char *group = &props->group_label[group_idx][0];
227
+ char *name = g_strdup_printf("gpio%s%d", group, pin_idx);
228
+ object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
229
+ aspeed_gpio_set_pin, NULL, NULL);
230
+ g_free(name);
231
+ }
232
}
233
}
120
}
234
121
235
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data)
122
static void test_ast2600_evb(TestData *data)
236
agc->props = ast2400_set_props;
123
@@ -XXX,XX +XXX,XX @@ static void test_ast2600_evb(TestData *data)
237
agc->nr_gpio_pins = 216;
124
data, test_write_page_mem);
238
agc->nr_gpio_sets = 7;
125
qtest_add_data_func("/ast2600/smc/read_status_reg",
239
- agc->gap = 196;
126
data, test_read_status_reg);
240
agc->reg_table = aspeed_3_3v_gpios;
127
+ qtest_add_data_func("/ast2600/smc/write_page_qpi",
128
+ data, test_write_page_qpi);
241
}
129
}
242
130
243
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data)
131
static void test_ast1030_evb(TestData *data)
244
agc->props = ast2500_set_props;
132
@@ -XXX,XX +XXX,XX @@ static void test_ast1030_evb(TestData *data)
245
agc->nr_gpio_pins = 228;
133
data, test_write_page_mem);
246
agc->nr_gpio_sets = 8;
134
qtest_add_data_func("/ast1030/smc/read_status_reg",
247
- agc->gap = 220;
135
data, test_read_status_reg);
248
agc->reg_table = aspeed_3_3v_gpios;
136
+ qtest_add_data_func("/ast1030/smc/write_page_qpi",
137
+ data, test_write_page_qpi);
249
}
138
}
250
139
140
int main(int argc, char **argv)
251
--
141
--
252
2.31.1
142
2.47.1
253
143
254
144
diff view generated by jsdifflib
1
It unifies the errors reported by the Aspeed SMC model and also
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
removes some use of ctrl->name which will help us for the next
3
patches.
4
2
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
3
The testcases for ASPEED SMC model were placed in aspeed_smc-test.c.
4
However, this test file only supports for ARM32. To support all ASPEED SOCs
5
such as AST2700 whose CPU architecture is aarch64, introduces a new
6
aspeed-smc-utils source file and move all common APIs and testcases
7
from aspeed_smc-test.c to aspeed-smc-utils.c.
8
9
Finally, users are able to re-used these testcase for AST2700 and future
10
ASPEED SOCs testing.
11
12
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
13
Reviewed-by: Cédric Le Goater <clg@redhat.com>
14
Link: https://lore.kernel.org/r/20241127091543.1243114-10-jamin_lin@aspeedtech.com
15
Signed-off-by: Cédric Le Goater <clg@redhat.com>
6
---
16
---
7
hw/ssi/aspeed_smc.c | 97 +++++++++++++++++++++------------------------
17
tests/qtest/aspeed-smc-utils.h | 95 ++++
8
1 file changed, 45 insertions(+), 52 deletions(-)
18
tests/qtest/aspeed-smc-utils.c | 686 ++++++++++++++++++++++++++++
19
tests/qtest/aspeed_smc-test.c | 800 +++------------------------------
20
tests/qtest/meson.build | 1 +
21
4 files changed, 841 insertions(+), 741 deletions(-)
22
create mode 100644 tests/qtest/aspeed-smc-utils.h
23
create mode 100644 tests/qtest/aspeed-smc-utils.c
9
24
10
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
25
diff --git a/tests/qtest/aspeed-smc-utils.h b/tests/qtest/aspeed-smc-utils.h
26
new file mode 100644
27
index XXXXXXX..XXXXXXX
28
--- /dev/null
29
+++ b/tests/qtest/aspeed-smc-utils.h
30
@@ -XXX,XX +XXX,XX @@
31
+/*
32
+ * QTest testcase for the M25P80 Flash (Using the Aspeed SPI
33
+ * Controller)
34
+ *
35
+ * Copyright (C) 2016 IBM Corp.
36
+ *
37
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
38
+ * of this software and associated documentation files (the "Software"), to deal
39
+ * in the Software without restriction, including without limitation the rights
40
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
41
+ * copies of the Software, and to permit persons to whom the Software is
42
+ * furnished to do so, subject to the following conditions:
43
+ *
44
+ * The above copyright notice and this permission notice shall be included in
45
+ * all copies or substantial portions of the Software.
46
+ *
47
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
50
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53
+ * THE SOFTWARE.
54
+ */
55
+
56
+#ifndef TESTS_ASPEED_SMC_UTILS_H
57
+#define TESTS_ASPEED_SMC_UTILS_H
58
+
59
+#include "qemu/osdep.h"
60
+#include "qemu/bswap.h"
61
+#include "libqtest-single.h"
62
+#include "qemu/bitops.h"
63
+
64
+/*
65
+ * ASPEED SPI Controller registers
66
+ */
67
+#define R_CONF 0x00
68
+#define CONF_ENABLE_W0 16
69
+#define R_CE_CTRL 0x04
70
+#define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */
71
+#define R_CTRL0 0x10
72
+#define CTRL_IO_QUAD_IO BIT(31)
73
+#define CTRL_CE_STOP_ACTIVE BIT(2)
74
+#define CTRL_READMODE 0x0
75
+#define CTRL_FREADMODE 0x1
76
+#define CTRL_WRITEMODE 0x2
77
+#define CTRL_USERMODE 0x3
78
+#define SR_WEL BIT(1)
79
+
80
+/*
81
+ * Flash commands
82
+ */
83
+enum {
84
+ JEDEC_READ = 0x9f,
85
+ RDSR = 0x5,
86
+ WRDI = 0x4,
87
+ BULK_ERASE = 0xc7,
88
+ READ = 0x03,
89
+ PP = 0x02,
90
+ WRSR = 0x1,
91
+ WREN = 0x6,
92
+ SRWD = 0x80,
93
+ RESET_ENABLE = 0x66,
94
+ RESET_MEMORY = 0x99,
95
+ EN_4BYTE_ADDR = 0xB7,
96
+ ERASE_SECTOR = 0xd8,
97
+};
98
+
99
+#define CTRL_IO_MODE_MASK (BIT(31) | BIT(30) | BIT(29) | BIT(28))
100
+#define FLASH_PAGE_SIZE 256
101
+
102
+typedef struct AspeedSMCTestData {
103
+ QTestState *s;
104
+ uint64_t spi_base;
105
+ uint64_t flash_base;
106
+ uint32_t jedec_id;
107
+ char *tmp_path;
108
+ uint8_t cs;
109
+ const char *node;
110
+ uint32_t page_addr;
111
+} AspeedSMCTestData;
112
+
113
+void aspeed_smc_test_read_jedec(const void *data);
114
+void aspeed_smc_test_erase_sector(const void *data);
115
+void aspeed_smc_test_erase_all(const void *data);
116
+void aspeed_smc_test_write_page(const void *data);
117
+void aspeed_smc_test_read_page_mem(const void *data);
118
+void aspeed_smc_test_write_page_mem(const void *data);
119
+void aspeed_smc_test_read_status_reg(const void *data);
120
+void aspeed_smc_test_status_reg_write_protection(const void *data);
121
+void aspeed_smc_test_write_block_protect(const void *data);
122
+void aspeed_smc_test_write_block_protect_bottom_bit(const void *data);
123
+void aspeed_smc_test_write_page_qpi(const void *data);
124
+
125
+#endif /* TESTS_ASPEED_SMC_UTILS_H */
126
diff --git a/tests/qtest/aspeed-smc-utils.c b/tests/qtest/aspeed-smc-utils.c
127
new file mode 100644
128
index XXXXXXX..XXXXXXX
129
--- /dev/null
130
+++ b/tests/qtest/aspeed-smc-utils.c
131
@@ -XXX,XX +XXX,XX @@
132
+/*
133
+ * QTest testcase for the M25P80 Flash (Using the Aspeed SPI
134
+ * Controller)
135
+ *
136
+ * Copyright (C) 2016 IBM Corp.
137
+ *
138
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
139
+ * of this software and associated documentation files (the "Software"), to deal
140
+ * in the Software without restriction, including without limitation the rights
141
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
142
+ * copies of the Software, and to permit persons to whom the Software is
143
+ * furnished to do so, subject to the following conditions:
144
+ *
145
+ * The above copyright notice and this permission notice shall be included in
146
+ * all copies or substantial portions of the Software.
147
+ *
148
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
149
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
150
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
151
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
152
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
153
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
154
+ * THE SOFTWARE.
155
+ */
156
+
157
+#include "qemu/osdep.h"
158
+#include "qemu/bswap.h"
159
+#include "libqtest-single.h"
160
+#include "qemu/bitops.h"
161
+#include "aspeed-smc-utils.h"
162
+
163
+/*
164
+ * Use an explicit bswap for the values read/wrote to the flash region
165
+ * as they are BE and the Aspeed CPU is LE.
166
+ */
167
+static inline uint32_t make_be32(uint32_t data)
168
+{
169
+ return bswap32(data);
170
+}
171
+
172
+static inline void spi_writel(const AspeedSMCTestData *data, uint64_t offset,
173
+ uint32_t value)
174
+{
175
+ qtest_writel(data->s, data->spi_base + offset, value);
176
+}
177
+
178
+static inline uint32_t spi_readl(const AspeedSMCTestData *data, uint64_t offset)
179
+{
180
+ return qtest_readl(data->s, data->spi_base + offset);
181
+}
182
+
183
+static inline void flash_writeb(const AspeedSMCTestData *data, uint64_t offset,
184
+ uint8_t value)
185
+{
186
+ qtest_writeb(data->s, data->flash_base + offset, value);
187
+}
188
+
189
+static inline void flash_writel(const AspeedSMCTestData *data, uint64_t offset,
190
+ uint32_t value)
191
+{
192
+ qtest_writel(data->s, data->flash_base + offset, value);
193
+}
194
+
195
+static inline uint8_t flash_readb(const AspeedSMCTestData *data,
196
+ uint64_t offset)
197
+{
198
+ return qtest_readb(data->s, data->flash_base + offset);
199
+}
200
+
201
+static inline uint32_t flash_readl(const AspeedSMCTestData *data,
202
+ uint64_t offset)
203
+{
204
+ return qtest_readl(data->s, data->flash_base + offset);
205
+}
206
+
207
+static void spi_conf(const AspeedSMCTestData *data, uint32_t value)
208
+{
209
+ uint32_t conf = spi_readl(data, R_CONF);
210
+
211
+ conf |= value;
212
+ spi_writel(data, R_CONF, conf);
213
+}
214
+
215
+static void spi_conf_remove(const AspeedSMCTestData *data, uint32_t value)
216
+{
217
+ uint32_t conf = spi_readl(data, R_CONF);
218
+
219
+ conf &= ~value;
220
+ spi_writel(data, R_CONF, conf);
221
+}
222
+
223
+static void spi_ce_ctrl(const AspeedSMCTestData *data, uint32_t value)
224
+{
225
+ uint32_t conf = spi_readl(data, R_CE_CTRL);
226
+
227
+ conf |= value;
228
+ spi_writel(data, R_CE_CTRL, conf);
229
+}
230
+
231
+static void spi_ctrl_setmode(const AspeedSMCTestData *data, uint8_t mode,
232
+ uint8_t cmd)
233
+{
234
+ uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
235
+ uint32_t ctrl = spi_readl(data, ctrl_reg);
236
+ ctrl &= ~(CTRL_USERMODE | 0xff << 16);
237
+ ctrl |= mode | (cmd << 16);
238
+ spi_writel(data, ctrl_reg, ctrl);
239
+}
240
+
241
+static void spi_ctrl_start_user(const AspeedSMCTestData *data)
242
+{
243
+ uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
244
+ uint32_t ctrl = spi_readl(data, ctrl_reg);
245
+
246
+ ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
247
+ spi_writel(data, ctrl_reg, ctrl);
248
+
249
+ ctrl &= ~CTRL_CE_STOP_ACTIVE;
250
+ spi_writel(data, ctrl_reg, ctrl);
251
+}
252
+
253
+static void spi_ctrl_stop_user(const AspeedSMCTestData *data)
254
+{
255
+ uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
256
+ uint32_t ctrl = spi_readl(data, ctrl_reg);
257
+
258
+ ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
259
+ spi_writel(data, ctrl_reg, ctrl);
260
+}
261
+
262
+static void spi_ctrl_set_io_mode(const AspeedSMCTestData *data, uint32_t value)
263
+{
264
+ uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
265
+ uint32_t ctrl = spi_readl(data, ctrl_reg);
266
+ uint32_t mode;
267
+
268
+ mode = value & CTRL_IO_MODE_MASK;
269
+ ctrl &= ~CTRL_IO_MODE_MASK;
270
+ ctrl |= mode;
271
+ spi_writel(data, ctrl_reg, ctrl);
272
+}
273
+
274
+static void flash_reset(const AspeedSMCTestData *data)
275
+{
276
+ spi_conf(data, 1 << (CONF_ENABLE_W0 + data->cs));
277
+
278
+ spi_ctrl_start_user(data);
279
+ flash_writeb(data, 0, RESET_ENABLE);
280
+ flash_writeb(data, 0, RESET_MEMORY);
281
+ flash_writeb(data, 0, WREN);
282
+ flash_writeb(data, 0, BULK_ERASE);
283
+ flash_writeb(data, 0, WRDI);
284
+ spi_ctrl_stop_user(data);
285
+
286
+ spi_conf_remove(data, 1 << (CONF_ENABLE_W0 + data->cs));
287
+}
288
+
289
+static void read_page(const AspeedSMCTestData *data, uint32_t addr,
290
+ uint32_t *page)
291
+{
292
+ int i;
293
+
294
+ spi_ctrl_start_user(data);
295
+
296
+ flash_writeb(data, 0, EN_4BYTE_ADDR);
297
+ flash_writeb(data, 0, READ);
298
+ flash_writel(data, 0, make_be32(addr));
299
+
300
+ /* Continuous read are supported */
301
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
302
+ page[i] = make_be32(flash_readl(data, 0));
303
+ }
304
+ spi_ctrl_stop_user(data);
305
+}
306
+
307
+static void read_page_mem(const AspeedSMCTestData *data, uint32_t addr,
308
+ uint32_t *page)
309
+{
310
+ int i;
311
+
312
+ /* move out USER mode to use direct reads from the AHB bus */
313
+ spi_ctrl_setmode(data, CTRL_READMODE, READ);
314
+
315
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
316
+ page[i] = make_be32(flash_readl(data, addr + i * 4));
317
+ }
318
+}
319
+
320
+static void write_page_mem(const AspeedSMCTestData *data, uint32_t addr,
321
+ uint32_t write_value)
322
+{
323
+ spi_ctrl_setmode(data, CTRL_WRITEMODE, PP);
324
+
325
+ for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
326
+ flash_writel(data, addr + i * 4, write_value);
327
+ }
328
+}
329
+
330
+static void assert_page_mem(const AspeedSMCTestData *data, uint32_t addr,
331
+ uint32_t expected_value)
332
+{
333
+ uint32_t page[FLASH_PAGE_SIZE / 4];
334
+ read_page_mem(data, addr, page);
335
+ for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
336
+ g_assert_cmphex(page[i], ==, expected_value);
337
+ }
338
+}
339
+
340
+void aspeed_smc_test_read_jedec(const void *data)
341
+{
342
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
343
+ uint32_t jedec = 0x0;
344
+
345
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
346
+
347
+ spi_ctrl_start_user(test_data);
348
+ flash_writeb(test_data, 0, JEDEC_READ);
349
+ jedec |= flash_readb(test_data, 0) << 16;
350
+ jedec |= flash_readb(test_data, 0) << 8;
351
+ jedec |= flash_readb(test_data, 0);
352
+ spi_ctrl_stop_user(test_data);
353
+
354
+ flash_reset(test_data);
355
+
356
+ g_assert_cmphex(jedec, ==, test_data->jedec_id);
357
+}
358
+
359
+void aspeed_smc_test_erase_sector(const void *data)
360
+{
361
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
362
+ uint32_t some_page_addr = test_data->page_addr;
363
+ uint32_t page[FLASH_PAGE_SIZE / 4];
364
+ int i;
365
+
366
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
367
+
368
+ /*
369
+ * Previous page should be full of 0xffs after backend is
370
+ * initialized
371
+ */
372
+ read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page);
373
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
374
+ g_assert_cmphex(page[i], ==, 0xffffffff);
375
+ }
376
+
377
+ spi_ctrl_start_user(test_data);
378
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
379
+ flash_writeb(test_data, 0, WREN);
380
+ flash_writeb(test_data, 0, PP);
381
+ flash_writel(test_data, 0, make_be32(some_page_addr));
382
+
383
+ /* Fill the page with its own addresses */
384
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
385
+ flash_writel(test_data, 0, make_be32(some_page_addr + i * 4));
386
+ }
387
+ spi_ctrl_stop_user(test_data);
388
+
389
+ /* Check the page is correctly written */
390
+ read_page(test_data, some_page_addr, page);
391
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
392
+ g_assert_cmphex(page[i], ==, some_page_addr + i * 4);
393
+ }
394
+
395
+ spi_ctrl_start_user(test_data);
396
+ flash_writeb(test_data, 0, WREN);
397
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
398
+ flash_writeb(test_data, 0, ERASE_SECTOR);
399
+ flash_writel(test_data, 0, make_be32(some_page_addr));
400
+ spi_ctrl_stop_user(test_data);
401
+
402
+ /* Check the page is erased */
403
+ read_page(test_data, some_page_addr, page);
404
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
405
+ g_assert_cmphex(page[i], ==, 0xffffffff);
406
+ }
407
+
408
+ flash_reset(test_data);
409
+}
410
+
411
+void aspeed_smc_test_erase_all(const void *data)
412
+{
413
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
414
+ uint32_t some_page_addr = test_data->page_addr;
415
+ uint32_t page[FLASH_PAGE_SIZE / 4];
416
+ int i;
417
+
418
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
419
+
420
+ /*
421
+ * Previous page should be full of 0xffs after backend is
422
+ * initialized
423
+ */
424
+ read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page);
425
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
426
+ g_assert_cmphex(page[i], ==, 0xffffffff);
427
+ }
428
+
429
+ spi_ctrl_start_user(test_data);
430
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
431
+ flash_writeb(test_data, 0, WREN);
432
+ flash_writeb(test_data, 0, PP);
433
+ flash_writel(test_data, 0, make_be32(some_page_addr));
434
+
435
+ /* Fill the page with its own addresses */
436
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
437
+ flash_writel(test_data, 0, make_be32(some_page_addr + i * 4));
438
+ }
439
+ spi_ctrl_stop_user(test_data);
440
+
441
+ /* Check the page is correctly written */
442
+ read_page(test_data, some_page_addr, page);
443
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
444
+ g_assert_cmphex(page[i], ==, some_page_addr + i * 4);
445
+ }
446
+
447
+ spi_ctrl_start_user(test_data);
448
+ flash_writeb(test_data, 0, WREN);
449
+ flash_writeb(test_data, 0, BULK_ERASE);
450
+ spi_ctrl_stop_user(test_data);
451
+
452
+ /* Check the page is erased */
453
+ read_page(test_data, some_page_addr, page);
454
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
455
+ g_assert_cmphex(page[i], ==, 0xffffffff);
456
+ }
457
+
458
+ flash_reset(test_data);
459
+}
460
+
461
+void aspeed_smc_test_write_page(const void *data)
462
+{
463
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
464
+ uint32_t my_page_addr = test_data->page_addr;
465
+ uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
466
+ uint32_t page[FLASH_PAGE_SIZE / 4];
467
+ int i;
468
+
469
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
470
+
471
+ spi_ctrl_start_user(test_data);
472
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
473
+ flash_writeb(test_data, 0, WREN);
474
+ flash_writeb(test_data, 0, PP);
475
+ flash_writel(test_data, 0, make_be32(my_page_addr));
476
+
477
+ /* Fill the page with its own addresses */
478
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
479
+ flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
480
+ }
481
+ spi_ctrl_stop_user(test_data);
482
+
483
+ /* Check what was written */
484
+ read_page(test_data, my_page_addr, page);
485
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
486
+ g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
487
+ }
488
+
489
+ /* Check some other page. It should be full of 0xff */
490
+ read_page(test_data, some_page_addr, page);
491
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
492
+ g_assert_cmphex(page[i], ==, 0xffffffff);
493
+ }
494
+
495
+ flash_reset(test_data);
496
+}
497
+
498
+void aspeed_smc_test_read_page_mem(const void *data)
499
+{
500
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
501
+ uint32_t my_page_addr = test_data->page_addr;
502
+ uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
503
+ uint32_t page[FLASH_PAGE_SIZE / 4];
504
+ int i;
505
+
506
+ /*
507
+ * Enable 4BYTE mode for controller.
508
+ */
509
+ spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
510
+
511
+ /* Enable 4BYTE mode for flash. */
512
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
513
+ spi_ctrl_start_user(test_data);
514
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
515
+ flash_writeb(test_data, 0, WREN);
516
+ flash_writeb(test_data, 0, PP);
517
+ flash_writel(test_data, 0, make_be32(my_page_addr));
518
+
519
+ /* Fill the page with its own addresses */
520
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
521
+ flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
522
+ }
523
+ spi_ctrl_stop_user(test_data);
524
+ spi_conf_remove(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
525
+
526
+ /* Check what was written */
527
+ read_page_mem(test_data, my_page_addr, page);
528
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
529
+ g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
530
+ }
531
+
532
+ /* Check some other page. It should be full of 0xff */
533
+ read_page_mem(test_data, some_page_addr, page);
534
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
535
+ g_assert_cmphex(page[i], ==, 0xffffffff);
536
+ }
537
+
538
+ flash_reset(test_data);
539
+}
540
+
541
+void aspeed_smc_test_write_page_mem(const void *data)
542
+{
543
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
544
+ uint32_t my_page_addr = test_data->page_addr;
545
+ uint32_t page[FLASH_PAGE_SIZE / 4];
546
+ int i;
547
+
548
+ /*
549
+ * Enable 4BYTE mode for controller.
550
+ */
551
+ spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
552
+
553
+ /* Enable 4BYTE mode for flash. */
554
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
555
+ spi_ctrl_start_user(test_data);
556
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
557
+ flash_writeb(test_data, 0, WREN);
558
+ spi_ctrl_stop_user(test_data);
559
+
560
+ /* move out USER mode to use direct writes to the AHB bus */
561
+ spi_ctrl_setmode(test_data, CTRL_WRITEMODE, PP);
562
+
563
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
564
+ flash_writel(test_data, my_page_addr + i * 4,
565
+ make_be32(my_page_addr + i * 4));
566
+ }
567
+
568
+ /* Check what was written */
569
+ read_page_mem(test_data, my_page_addr, page);
570
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
571
+ g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
572
+ }
573
+
574
+ flash_reset(test_data);
575
+}
576
+
577
+void aspeed_smc_test_read_status_reg(const void *data)
578
+{
579
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
580
+ uint8_t r;
581
+
582
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
583
+
584
+ spi_ctrl_start_user(test_data);
585
+ flash_writeb(test_data, 0, RDSR);
586
+ r = flash_readb(test_data, 0);
587
+ spi_ctrl_stop_user(test_data);
588
+
589
+ g_assert_cmphex(r & SR_WEL, ==, 0);
590
+ g_assert(!qtest_qom_get_bool
591
+ (test_data->s, test_data->node, "write-enable"));
592
+
593
+ spi_ctrl_start_user(test_data);
594
+ flash_writeb(test_data, 0, WREN);
595
+ flash_writeb(test_data, 0, RDSR);
596
+ r = flash_readb(test_data, 0);
597
+ spi_ctrl_stop_user(test_data);
598
+
599
+ g_assert_cmphex(r & SR_WEL, ==, SR_WEL);
600
+ g_assert(qtest_qom_get_bool
601
+ (test_data->s, test_data->node, "write-enable"));
602
+
603
+ spi_ctrl_start_user(test_data);
604
+ flash_writeb(test_data, 0, WRDI);
605
+ flash_writeb(test_data, 0, RDSR);
606
+ r = flash_readb(test_data, 0);
607
+ spi_ctrl_stop_user(test_data);
608
+
609
+ g_assert_cmphex(r & SR_WEL, ==, 0);
610
+ g_assert(!qtest_qom_get_bool
611
+ (test_data->s, test_data->node, "write-enable"));
612
+
613
+ flash_reset(test_data);
614
+}
615
+
616
+void aspeed_smc_test_status_reg_write_protection(const void *data)
617
+{
618
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
619
+ uint8_t r;
620
+
621
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
622
+
623
+ /* default case: WP# is high and SRWD is low -> status register writable */
624
+ spi_ctrl_start_user(test_data);
625
+ flash_writeb(test_data, 0, WREN);
626
+ /* test ability to write SRWD */
627
+ flash_writeb(test_data, 0, WRSR);
628
+ flash_writeb(test_data, 0, SRWD);
629
+ flash_writeb(test_data, 0, RDSR);
630
+ r = flash_readb(test_data, 0);
631
+ spi_ctrl_stop_user(test_data);
632
+ g_assert_cmphex(r & SRWD, ==, SRWD);
633
+
634
+ /* WP# high and SRWD high -> status register writable */
635
+ spi_ctrl_start_user(test_data);
636
+ flash_writeb(test_data, 0, WREN);
637
+ /* test ability to write SRWD */
638
+ flash_writeb(test_data, 0, WRSR);
639
+ flash_writeb(test_data, 0, 0);
640
+ flash_writeb(test_data, 0, RDSR);
641
+ r = flash_readb(test_data, 0);
642
+ spi_ctrl_stop_user(test_data);
643
+ g_assert_cmphex(r & SRWD, ==, 0);
644
+
645
+ /* WP# low and SRWD low -> status register writable */
646
+ qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 0);
647
+ spi_ctrl_start_user(test_data);
648
+ flash_writeb(test_data, 0, WREN);
649
+ /* test ability to write SRWD */
650
+ flash_writeb(test_data, 0, WRSR);
651
+ flash_writeb(test_data, 0, SRWD);
652
+ flash_writeb(test_data, 0, RDSR);
653
+ r = flash_readb(test_data, 0);
654
+ spi_ctrl_stop_user(test_data);
655
+ g_assert_cmphex(r & SRWD, ==, SRWD);
656
+
657
+ /* WP# low and SRWD high -> status register NOT writable */
658
+ spi_ctrl_start_user(test_data);
659
+ flash_writeb(test_data, 0 , WREN);
660
+ /* test ability to write SRWD */
661
+ flash_writeb(test_data, 0, WRSR);
662
+ flash_writeb(test_data, 0, 0);
663
+ flash_writeb(test_data, 0, RDSR);
664
+ r = flash_readb(test_data, 0);
665
+ spi_ctrl_stop_user(test_data);
666
+ /* write is not successful */
667
+ g_assert_cmphex(r & SRWD, ==, SRWD);
668
+
669
+ qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 1);
670
+ flash_reset(test_data);
671
+}
672
+
673
+void aspeed_smc_test_write_block_protect(const void *data)
674
+{
675
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
676
+ uint32_t sector_size = 65536;
677
+ uint32_t n_sectors = 512;
678
+
679
+ spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
680
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
681
+
682
+ uint32_t bp_bits = 0b0;
683
+
684
+ for (int i = 0; i < 16; i++) {
685
+ bp_bits = ((i & 0b1000) << 3) | ((i & 0b0111) << 2);
686
+
687
+ spi_ctrl_start_user(test_data);
688
+ flash_writeb(test_data, 0, WREN);
689
+ flash_writeb(test_data, 0, BULK_ERASE);
690
+ flash_writeb(test_data, 0, WREN);
691
+ flash_writeb(test_data, 0, WRSR);
692
+ flash_writeb(test_data, 0, bp_bits);
693
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
694
+ flash_writeb(test_data, 0, WREN);
695
+ spi_ctrl_stop_user(test_data);
696
+
697
+ uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0;
698
+ uint32_t protection_start = n_sectors - num_protected_sectors;
699
+ uint32_t protection_end = n_sectors;
700
+
701
+ for (int sector = 0; sector < n_sectors; sector++) {
702
+ uint32_t addr = sector * sector_size;
703
+
704
+ assert_page_mem(test_data, addr, 0xffffffff);
705
+ write_page_mem(test_data, addr, make_be32(0xabcdef12));
706
+
707
+ uint32_t expected_value = protection_start <= sector
708
+ && sector < protection_end
709
+ ? 0xffffffff : 0xabcdef12;
710
+
711
+ assert_page_mem(test_data, addr, expected_value);
712
+ }
713
+ }
714
+
715
+ flash_reset(test_data);
716
+}
717
+
718
+void aspeed_smc_test_write_block_protect_bottom_bit(const void *data)
719
+{
720
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
721
+ uint32_t sector_size = 65536;
722
+ uint32_t n_sectors = 512;
723
+
724
+ spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
725
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
726
+
727
+ /* top bottom bit is enabled */
728
+ uint32_t bp_bits = 0b00100 << 3;
729
+
730
+ for (int i = 0; i < 16; i++) {
731
+ bp_bits = (((i & 0b1000) | 0b0100) << 3) | ((i & 0b0111) << 2);
732
+
733
+ spi_ctrl_start_user(test_data);
734
+ flash_writeb(test_data, 0, WREN);
735
+ flash_writeb(test_data, 0, BULK_ERASE);
736
+ flash_writeb(test_data, 0, WREN);
737
+ flash_writeb(test_data, 0, WRSR);
738
+ flash_writeb(test_data, 0, bp_bits);
739
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
740
+ flash_writeb(test_data, 0, WREN);
741
+ spi_ctrl_stop_user(test_data);
742
+
743
+ uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0;
744
+ uint32_t protection_start = 0;
745
+ uint32_t protection_end = num_protected_sectors;
746
+
747
+ for (int sector = 0; sector < n_sectors; sector++) {
748
+ uint32_t addr = sector * sector_size;
749
+
750
+ assert_page_mem(test_data, addr, 0xffffffff);
751
+ write_page_mem(test_data, addr, make_be32(0xabcdef12));
752
+
753
+ uint32_t expected_value = protection_start <= sector
754
+ && sector < protection_end
755
+ ? 0xffffffff : 0xabcdef12;
756
+
757
+ assert_page_mem(test_data, addr, expected_value);
758
+ }
759
+ }
760
+
761
+ flash_reset(test_data);
762
+}
763
+
764
+void aspeed_smc_test_write_page_qpi(const void *data)
765
+{
766
+ const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data;
767
+ uint32_t my_page_addr = test_data->page_addr;
768
+ uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
769
+ uint32_t page[FLASH_PAGE_SIZE / 4];
770
+ uint32_t page_pattern[] = {
771
+ 0xebd8c134, 0x5da196bc, 0xae15e729, 0x5085ccdf
772
+ };
773
+ int i;
774
+
775
+ spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
776
+
777
+ spi_ctrl_start_user(test_data);
778
+ flash_writeb(test_data, 0, EN_4BYTE_ADDR);
779
+ flash_writeb(test_data, 0, WREN);
780
+ flash_writeb(test_data, 0, PP);
781
+ flash_writel(test_data, 0, make_be32(my_page_addr));
782
+
783
+ /* Set QPI mode */
784
+ spi_ctrl_set_io_mode(test_data, CTRL_IO_QUAD_IO);
785
+
786
+ /* Fill the page pattern */
787
+ for (i = 0; i < ARRAY_SIZE(page_pattern); i++) {
788
+ flash_writel(test_data, 0, make_be32(page_pattern[i]));
789
+ }
790
+
791
+ /* Fill the page with its own addresses */
792
+ for (; i < FLASH_PAGE_SIZE / 4; i++) {
793
+ flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
794
+ }
795
+
796
+ /* Restore io mode */
797
+ spi_ctrl_set_io_mode(test_data, 0);
798
+ spi_ctrl_stop_user(test_data);
799
+
800
+ /* Check what was written */
801
+ read_page(test_data, my_page_addr, page);
802
+ for (i = 0; i < ARRAY_SIZE(page_pattern); i++) {
803
+ g_assert_cmphex(page[i], ==, page_pattern[i]);
804
+ }
805
+ for (; i < FLASH_PAGE_SIZE / 4; i++) {
806
+ g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
807
+ }
808
+
809
+ /* Check some other page. It should be full of 0xff */
810
+ read_page(test_data, some_page_addr, page);
811
+ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
812
+ g_assert_cmphex(page[i], ==, 0xffffffff);
813
+ }
814
+
815
+ flash_reset(test_data);
816
+}
817
+
818
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
11
index XXXXXXX..XXXXXXX 100644
819
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/ssi/aspeed_smc.c
820
--- a/tests/qtest/aspeed_smc-test.c
13
+++ b/hw/ssi/aspeed_smc.c
821
+++ b/tests/qtest/aspeed_smc-test.c
14
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
822
@@ -XXX,XX +XXX,XX @@
15
}
823
#include "qemu/bswap.h"
824
#include "libqtest-single.h"
825
#include "qemu/bitops.h"
826
+#include "aspeed-smc-utils.h"
827
828
-/*
829
- * ASPEED SPI Controller registers
830
- */
831
-#define R_CONF 0x00
832
-#define CONF_ENABLE_W0 16
833
-#define R_CE_CTRL 0x04
834
-#define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */
835
-#define R_CTRL0 0x10
836
-#define CTRL_IO_QUAD_IO BIT(31)
837
-#define CTRL_CE_STOP_ACTIVE BIT(2)
838
-#define CTRL_READMODE 0x0
839
-#define CTRL_FREADMODE 0x1
840
-#define CTRL_WRITEMODE 0x2
841
-#define CTRL_USERMODE 0x3
842
-#define SR_WEL BIT(1)
843
-
844
-/*
845
- * Flash commands
846
- */
847
-enum {
848
- JEDEC_READ = 0x9f,
849
- RDSR = 0x5,
850
- WRDI = 0x4,
851
- BULK_ERASE = 0xc7,
852
- READ = 0x03,
853
- PP = 0x02,
854
- WRSR = 0x1,
855
- WREN = 0x6,
856
- SRWD = 0x80,
857
- RESET_ENABLE = 0x66,
858
- RESET_MEMORY = 0x99,
859
- EN_4BYTE_ADDR = 0xB7,
860
- ERASE_SECTOR = 0xd8,
861
-};
862
-
863
-#define CTRL_IO_MODE_MASK (BIT(31) | BIT(30) | BIT(29) | BIT(28))
864
-#define FLASH_PAGE_SIZE 256
865
-
866
-typedef struct TestData {
867
- QTestState *s;
868
- uint64_t spi_base;
869
- uint64_t flash_base;
870
- uint32_t jedec_id;
871
- char *tmp_path;
872
- uint8_t cs;
873
- const char *node;
874
- uint32_t page_addr;
875
-} TestData;
876
-
877
-/*
878
- * Use an explicit bswap for the values read/wrote to the flash region
879
- * as they are BE and the Aspeed CPU is LE.
880
- */
881
-static inline uint32_t make_be32(uint32_t data)
882
-{
883
- return bswap32(data);
884
-}
885
-
886
-static inline void spi_writel(const TestData *data, uint64_t offset,
887
- uint32_t value)
888
-{
889
- qtest_writel(data->s, data->spi_base + offset, value);
890
-}
891
-
892
-static inline uint32_t spi_readl(const TestData *data, uint64_t offset)
893
-{
894
- return qtest_readl(data->s, data->spi_base + offset);
895
-}
896
-
897
-static inline void flash_writeb(const TestData *data, uint64_t offset,
898
- uint8_t value)
899
-{
900
- qtest_writeb(data->s, data->flash_base + offset, value);
901
-}
902
-
903
-static inline void flash_writel(const TestData *data, uint64_t offset,
904
- uint32_t value)
905
-{
906
- qtest_writel(data->s, data->flash_base + offset, value);
907
-}
908
-
909
-static inline uint8_t flash_readb(const TestData *data, uint64_t offset)
910
-{
911
- return qtest_readb(data->s, data->flash_base + offset);
912
-}
913
-
914
-static inline uint32_t flash_readl(const TestData *data, uint64_t offset)
915
-{
916
- return qtest_readl(data->s, data->flash_base + offset);
917
-}
918
-
919
-static void spi_conf(const TestData *data, uint32_t value)
920
-{
921
- uint32_t conf = spi_readl(data, R_CONF);
922
-
923
- conf |= value;
924
- spi_writel(data, R_CONF, conf);
925
-}
926
-
927
-static void spi_conf_remove(const TestData *data, uint32_t value)
928
-{
929
- uint32_t conf = spi_readl(data, R_CONF);
930
-
931
- conf &= ~value;
932
- spi_writel(data, R_CONF, conf);
933
-}
934
-
935
-static void spi_ce_ctrl(const TestData *data, uint32_t value)
936
-{
937
- uint32_t conf = spi_readl(data, R_CE_CTRL);
938
-
939
- conf |= value;
940
- spi_writel(data, R_CE_CTRL, conf);
941
-}
942
-
943
-static void spi_ctrl_setmode(const TestData *data, uint8_t mode, uint8_t cmd)
944
-{
945
- uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
946
- uint32_t ctrl = spi_readl(data, ctrl_reg);
947
- ctrl &= ~(CTRL_USERMODE | 0xff << 16);
948
- ctrl |= mode | (cmd << 16);
949
- spi_writel(data, ctrl_reg, ctrl);
950
-}
951
-
952
-static void spi_ctrl_start_user(const TestData *data)
953
-{
954
- uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
955
- uint32_t ctrl = spi_readl(data, ctrl_reg);
956
-
957
- ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
958
- spi_writel(data, ctrl_reg, ctrl);
959
-
960
- ctrl &= ~CTRL_CE_STOP_ACTIVE;
961
- spi_writel(data, ctrl_reg, ctrl);
962
-}
963
-
964
-static void spi_ctrl_stop_user(const TestData *data)
965
-{
966
- uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
967
- uint32_t ctrl = spi_readl(data, ctrl_reg);
968
-
969
- ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
970
- spi_writel(data, ctrl_reg, ctrl);
971
-}
972
-
973
-static void spi_ctrl_set_io_mode(const TestData *data, uint32_t value)
974
-{
975
- uint32_t ctrl_reg = R_CTRL0 + data->cs * 4;
976
- uint32_t ctrl = spi_readl(data, ctrl_reg);
977
- uint32_t mode;
978
-
979
- mode = value & CTRL_IO_MODE_MASK;
980
- ctrl &= ~CTRL_IO_MODE_MASK;
981
- ctrl |= mode;
982
- spi_writel(data, ctrl_reg, ctrl);
983
-}
984
-
985
-static void flash_reset(const TestData *data)
986
-{
987
- spi_conf(data, 1 << (CONF_ENABLE_W0 + data->cs));
988
-
989
- spi_ctrl_start_user(data);
990
- flash_writeb(data, 0, RESET_ENABLE);
991
- flash_writeb(data, 0, RESET_MEMORY);
992
- flash_writeb(data, 0, WREN);
993
- flash_writeb(data, 0, BULK_ERASE);
994
- flash_writeb(data, 0, WRDI);
995
- spi_ctrl_stop_user(data);
996
-
997
- spi_conf_remove(data, 1 << (CONF_ENABLE_W0 + data->cs));
998
-}
999
-
1000
-static void test_read_jedec(const void *data)
1001
-{
1002
- const TestData *test_data = (const TestData *)data;
1003
- uint32_t jedec = 0x0;
1004
-
1005
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1006
-
1007
- spi_ctrl_start_user(test_data);
1008
- flash_writeb(test_data, 0, JEDEC_READ);
1009
- jedec |= flash_readb(test_data, 0) << 16;
1010
- jedec |= flash_readb(test_data, 0) << 8;
1011
- jedec |= flash_readb(test_data, 0);
1012
- spi_ctrl_stop_user(test_data);
1013
-
1014
- flash_reset(test_data);
1015
-
1016
- g_assert_cmphex(jedec, ==, test_data->jedec_id);
1017
-}
1018
-
1019
-static void read_page(const TestData *data, uint32_t addr, uint32_t *page)
1020
-{
1021
- int i;
1022
-
1023
- spi_ctrl_start_user(data);
1024
-
1025
- flash_writeb(data, 0, EN_4BYTE_ADDR);
1026
- flash_writeb(data, 0, READ);
1027
- flash_writel(data, 0, make_be32(addr));
1028
-
1029
- /* Continuous read are supported */
1030
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1031
- page[i] = make_be32(flash_readl(data, 0));
1032
- }
1033
- spi_ctrl_stop_user(data);
1034
-}
1035
-
1036
-static void read_page_mem(const TestData *data, uint32_t addr, uint32_t *page)
1037
-{
1038
- int i;
1039
-
1040
- /* move out USER mode to use direct reads from the AHB bus */
1041
- spi_ctrl_setmode(data, CTRL_READMODE, READ);
1042
-
1043
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1044
- page[i] = make_be32(flash_readl(data, addr + i * 4));
1045
- }
1046
-}
1047
-
1048
-static void write_page_mem(const TestData *data, uint32_t addr,
1049
- uint32_t write_value)
1050
-{
1051
- spi_ctrl_setmode(data, CTRL_WRITEMODE, PP);
1052
-
1053
- for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1054
- flash_writel(data, addr + i * 4, write_value);
1055
- }
1056
-}
1057
-
1058
-static void assert_page_mem(const TestData *data, uint32_t addr,
1059
- uint32_t expected_value)
1060
-{
1061
- uint32_t page[FLASH_PAGE_SIZE / 4];
1062
- read_page_mem(data, addr, page);
1063
- for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1064
- g_assert_cmphex(page[i], ==, expected_value);
1065
- }
1066
-}
1067
-
1068
-static void test_erase_sector(const void *data)
1069
-{
1070
- const TestData *test_data = (const TestData *)data;
1071
- uint32_t some_page_addr = test_data->page_addr;
1072
- uint32_t page[FLASH_PAGE_SIZE / 4];
1073
- int i;
1074
-
1075
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1076
-
1077
- /*
1078
- * Previous page should be full of 0xffs after backend is
1079
- * initialized
1080
- */
1081
- read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page);
1082
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1083
- g_assert_cmphex(page[i], ==, 0xffffffff);
1084
- }
1085
-
1086
- spi_ctrl_start_user(test_data);
1087
- flash_writeb(test_data, 0, EN_4BYTE_ADDR);
1088
- flash_writeb(test_data, 0, WREN);
1089
- flash_writeb(test_data, 0, PP);
1090
- flash_writel(test_data, 0, make_be32(some_page_addr));
1091
-
1092
- /* Fill the page with its own addresses */
1093
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1094
- flash_writel(test_data, 0, make_be32(some_page_addr + i * 4));
1095
- }
1096
- spi_ctrl_stop_user(test_data);
1097
-
1098
- /* Check the page is correctly written */
1099
- read_page(test_data, some_page_addr, page);
1100
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1101
- g_assert_cmphex(page[i], ==, some_page_addr + i * 4);
1102
- }
1103
-
1104
- spi_ctrl_start_user(test_data);
1105
- flash_writeb(test_data, 0, WREN);
1106
- flash_writeb(test_data, 0, EN_4BYTE_ADDR);
1107
- flash_writeb(test_data, 0, ERASE_SECTOR);
1108
- flash_writel(test_data, 0, make_be32(some_page_addr));
1109
- spi_ctrl_stop_user(test_data);
1110
-
1111
- /* Check the page is erased */
1112
- read_page(test_data, some_page_addr, page);
1113
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1114
- g_assert_cmphex(page[i], ==, 0xffffffff);
1115
- }
1116
-
1117
- flash_reset(test_data);
1118
-}
1119
-
1120
-static void test_erase_all(const void *data)
1121
-{
1122
- const TestData *test_data = (const TestData *)data;
1123
- uint32_t some_page_addr = test_data->page_addr;
1124
- uint32_t page[FLASH_PAGE_SIZE / 4];
1125
- int i;
1126
-
1127
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1128
-
1129
- /*
1130
- * Previous page should be full of 0xffs after backend is
1131
- * initialized
1132
- */
1133
- read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page);
1134
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1135
- g_assert_cmphex(page[i], ==, 0xffffffff);
1136
- }
1137
-
1138
- spi_ctrl_start_user(test_data);
1139
- flash_writeb(test_data, 0, EN_4BYTE_ADDR);
1140
- flash_writeb(test_data, 0, WREN);
1141
- flash_writeb(test_data, 0, PP);
1142
- flash_writel(test_data, 0, make_be32(some_page_addr));
1143
-
1144
- /* Fill the page with its own addresses */
1145
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1146
- flash_writel(test_data, 0, make_be32(some_page_addr + i * 4));
1147
- }
1148
- spi_ctrl_stop_user(test_data);
1149
-
1150
- /* Check the page is correctly written */
1151
- read_page(test_data, some_page_addr, page);
1152
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1153
- g_assert_cmphex(page[i], ==, some_page_addr + i * 4);
1154
- }
1155
-
1156
- spi_ctrl_start_user(test_data);
1157
- flash_writeb(test_data, 0, WREN);
1158
- flash_writeb(test_data, 0, BULK_ERASE);
1159
- spi_ctrl_stop_user(test_data);
1160
-
1161
- /* Check the page is erased */
1162
- read_page(test_data, some_page_addr, page);
1163
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1164
- g_assert_cmphex(page[i], ==, 0xffffffff);
1165
- }
1166
-
1167
- flash_reset(test_data);
1168
-}
1169
-
1170
-static void test_write_page(const void *data)
1171
-{
1172
- const TestData *test_data = (const TestData *)data;
1173
- uint32_t my_page_addr = test_data->page_addr;
1174
- uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
1175
- uint32_t page[FLASH_PAGE_SIZE / 4];
1176
- int i;
1177
-
1178
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1179
-
1180
- spi_ctrl_start_user(test_data);
1181
- flash_writeb(test_data, 0, EN_4BYTE_ADDR);
1182
- flash_writeb(test_data, 0, WREN);
1183
- flash_writeb(test_data, 0, PP);
1184
- flash_writel(test_data, 0, make_be32(my_page_addr));
1185
-
1186
- /* Fill the page with its own addresses */
1187
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1188
- flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
1189
- }
1190
- spi_ctrl_stop_user(test_data);
1191
-
1192
- /* Check what was written */
1193
- read_page(test_data, my_page_addr, page);
1194
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1195
- g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
1196
- }
1197
-
1198
- /* Check some other page. It should be full of 0xff */
1199
- read_page(test_data, some_page_addr, page);
1200
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1201
- g_assert_cmphex(page[i], ==, 0xffffffff);
1202
- }
1203
-
1204
- flash_reset(test_data);
1205
-}
1206
-
1207
-static void test_read_page_mem(const void *data)
1208
-{
1209
- const TestData *test_data = (const TestData *)data;
1210
- uint32_t my_page_addr = test_data->page_addr;
1211
- uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
1212
- uint32_t page[FLASH_PAGE_SIZE / 4];
1213
- int i;
1214
-
1215
- /*
1216
- * Enable 4BYTE mode for controller.
1217
- */
1218
- spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
1219
-
1220
- /* Enable 4BYTE mode for flash. */
1221
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1222
- spi_ctrl_start_user(test_data);
1223
- flash_writeb(test_data, 0, EN_4BYTE_ADDR);
1224
- flash_writeb(test_data, 0, WREN);
1225
- flash_writeb(test_data, 0, PP);
1226
- flash_writel(test_data, 0, make_be32(my_page_addr));
1227
-
1228
- /* Fill the page with its own addresses */
1229
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1230
- flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
1231
- }
1232
- spi_ctrl_stop_user(test_data);
1233
- spi_conf_remove(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1234
-
1235
- /* Check what was written */
1236
- read_page_mem(test_data, my_page_addr, page);
1237
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1238
- g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
1239
- }
1240
-
1241
- /* Check some other page. It should be full of 0xff */
1242
- read_page_mem(test_data, some_page_addr, page);
1243
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1244
- g_assert_cmphex(page[i], ==, 0xffffffff);
1245
- }
1246
-
1247
- flash_reset(test_data);
1248
-}
1249
-
1250
-static void test_write_page_mem(const void *data)
1251
-{
1252
- const TestData *test_data = (const TestData *)data;
1253
- uint32_t my_page_addr = test_data->page_addr;
1254
- uint32_t page[FLASH_PAGE_SIZE / 4];
1255
- int i;
1256
-
1257
- /*
1258
- * Enable 4BYTE mode for controller.
1259
- */
1260
- spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
1261
-
1262
- /* Enable 4BYTE mode for flash. */
1263
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1264
- spi_ctrl_start_user(test_data);
1265
- flash_writeb(test_data, 0, EN_4BYTE_ADDR);
1266
- flash_writeb(test_data, 0, WREN);
1267
- spi_ctrl_stop_user(test_data);
1268
-
1269
- /* move out USER mode to use direct writes to the AHB bus */
1270
- spi_ctrl_setmode(test_data, CTRL_WRITEMODE, PP);
1271
-
1272
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1273
- flash_writel(test_data, my_page_addr + i * 4,
1274
- make_be32(my_page_addr + i * 4));
1275
- }
1276
-
1277
- /* Check what was written */
1278
- read_page_mem(test_data, my_page_addr, page);
1279
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1280
- g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
1281
- }
1282
-
1283
- flash_reset(test_data);
1284
-}
1285
-
1286
-static void test_read_status_reg(const void *data)
1287
-{
1288
- const TestData *test_data = (const TestData *)data;
1289
- uint8_t r;
1290
-
1291
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1292
-
1293
- spi_ctrl_start_user(test_data);
1294
- flash_writeb(test_data, 0, RDSR);
1295
- r = flash_readb(test_data, 0);
1296
- spi_ctrl_stop_user(test_data);
1297
-
1298
- g_assert_cmphex(r & SR_WEL, ==, 0);
1299
- g_assert(!qtest_qom_get_bool
1300
- (test_data->s, test_data->node, "write-enable"));
1301
-
1302
- spi_ctrl_start_user(test_data);
1303
- flash_writeb(test_data, 0, WREN);
1304
- flash_writeb(test_data, 0, RDSR);
1305
- r = flash_readb(test_data, 0);
1306
- spi_ctrl_stop_user(test_data);
1307
-
1308
- g_assert_cmphex(r & SR_WEL, ==, SR_WEL);
1309
- g_assert(qtest_qom_get_bool
1310
- (test_data->s, test_data->node, "write-enable"));
1311
-
1312
- spi_ctrl_start_user(test_data);
1313
- flash_writeb(test_data, 0, WRDI);
1314
- flash_writeb(test_data, 0, RDSR);
1315
- r = flash_readb(test_data, 0);
1316
- spi_ctrl_stop_user(test_data);
1317
-
1318
- g_assert_cmphex(r & SR_WEL, ==, 0);
1319
- g_assert(!qtest_qom_get_bool
1320
- (test_data->s, test_data->node, "write-enable"));
1321
-
1322
- flash_reset(test_data);
1323
-}
1324
-
1325
-static void test_status_reg_write_protection(const void *data)
1326
-{
1327
- const TestData *test_data = (const TestData *)data;
1328
- uint8_t r;
1329
-
1330
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1331
-
1332
- /* default case: WP# is high and SRWD is low -> status register writable */
1333
- spi_ctrl_start_user(test_data);
1334
- flash_writeb(test_data, 0, WREN);
1335
- /* test ability to write SRWD */
1336
- flash_writeb(test_data, 0, WRSR);
1337
- flash_writeb(test_data, 0, SRWD);
1338
- flash_writeb(test_data, 0, RDSR);
1339
- r = flash_readb(test_data, 0);
1340
- spi_ctrl_stop_user(test_data);
1341
- g_assert_cmphex(r & SRWD, ==, SRWD);
1342
-
1343
- /* WP# high and SRWD high -> status register writable */
1344
- spi_ctrl_start_user(test_data);
1345
- flash_writeb(test_data, 0, WREN);
1346
- /* test ability to write SRWD */
1347
- flash_writeb(test_data, 0, WRSR);
1348
- flash_writeb(test_data, 0, 0);
1349
- flash_writeb(test_data, 0, RDSR);
1350
- r = flash_readb(test_data, 0);
1351
- spi_ctrl_stop_user(test_data);
1352
- g_assert_cmphex(r & SRWD, ==, 0);
1353
-
1354
- /* WP# low and SRWD low -> status register writable */
1355
- qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 0);
1356
- spi_ctrl_start_user(test_data);
1357
- flash_writeb(test_data, 0, WREN);
1358
- /* test ability to write SRWD */
1359
- flash_writeb(test_data, 0, WRSR);
1360
- flash_writeb(test_data, 0, SRWD);
1361
- flash_writeb(test_data, 0, RDSR);
1362
- r = flash_readb(test_data, 0);
1363
- spi_ctrl_stop_user(test_data);
1364
- g_assert_cmphex(r & SRWD, ==, SRWD);
1365
-
1366
- /* WP# low and SRWD high -> status register NOT writable */
1367
- spi_ctrl_start_user(test_data);
1368
- flash_writeb(test_data, 0 , WREN);
1369
- /* test ability to write SRWD */
1370
- flash_writeb(test_data, 0, WRSR);
1371
- flash_writeb(test_data, 0, 0);
1372
- flash_writeb(test_data, 0, RDSR);
1373
- r = flash_readb(test_data, 0);
1374
- spi_ctrl_stop_user(test_data);
1375
- /* write is not successful */
1376
- g_assert_cmphex(r & SRWD, ==, SRWD);
1377
-
1378
- qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 1);
1379
- flash_reset(test_data);
1380
-}
1381
-
1382
-static void test_write_block_protect(const void *data)
1383
-{
1384
- const TestData *test_data = (const TestData *)data;
1385
- uint32_t sector_size = 65536;
1386
- uint32_t n_sectors = 512;
1387
-
1388
- spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
1389
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1390
-
1391
- uint32_t bp_bits = 0b0;
1392
-
1393
- for (int i = 0; i < 16; i++) {
1394
- bp_bits = ((i & 0b1000) << 3) | ((i & 0b0111) << 2);
1395
-
1396
- spi_ctrl_start_user(test_data);
1397
- flash_writeb(test_data, 0, WREN);
1398
- flash_writeb(test_data, 0, BULK_ERASE);
1399
- flash_writeb(test_data, 0, WREN);
1400
- flash_writeb(test_data, 0, WRSR);
1401
- flash_writeb(test_data, 0, bp_bits);
1402
- flash_writeb(test_data, 0, EN_4BYTE_ADDR);
1403
- flash_writeb(test_data, 0, WREN);
1404
- spi_ctrl_stop_user(test_data);
1405
-
1406
- uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0;
1407
- uint32_t protection_start = n_sectors - num_protected_sectors;
1408
- uint32_t protection_end = n_sectors;
1409
-
1410
- for (int sector = 0; sector < n_sectors; sector++) {
1411
- uint32_t addr = sector * sector_size;
1412
-
1413
- assert_page_mem(test_data, addr, 0xffffffff);
1414
- write_page_mem(test_data, addr, make_be32(0xabcdef12));
1415
-
1416
- uint32_t expected_value = protection_start <= sector
1417
- && sector < protection_end
1418
- ? 0xffffffff : 0xabcdef12;
1419
-
1420
- assert_page_mem(test_data, addr, expected_value);
1421
- }
1422
- }
1423
-
1424
- flash_reset(test_data);
1425
-}
1426
-
1427
-static void test_write_block_protect_bottom_bit(const void *data)
1428
-{
1429
- const TestData *test_data = (const TestData *)data;
1430
- uint32_t sector_size = 65536;
1431
- uint32_t n_sectors = 512;
1432
-
1433
- spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs));
1434
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1435
-
1436
- /* top bottom bit is enabled */
1437
- uint32_t bp_bits = 0b00100 << 3;
1438
-
1439
- for (int i = 0; i < 16; i++) {
1440
- bp_bits = (((i & 0b1000) | 0b0100) << 3) | ((i & 0b0111) << 2);
1441
-
1442
- spi_ctrl_start_user(test_data);
1443
- flash_writeb(test_data, 0, WREN);
1444
- flash_writeb(test_data, 0, BULK_ERASE);
1445
- flash_writeb(test_data, 0, WREN);
1446
- flash_writeb(test_data, 0, WRSR);
1447
- flash_writeb(test_data, 0, bp_bits);
1448
- flash_writeb(test_data, 0, EN_4BYTE_ADDR);
1449
- flash_writeb(test_data, 0, WREN);
1450
- spi_ctrl_stop_user(test_data);
1451
-
1452
- uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0;
1453
- uint32_t protection_start = 0;
1454
- uint32_t protection_end = num_protected_sectors;
1455
-
1456
- for (int sector = 0; sector < n_sectors; sector++) {
1457
- uint32_t addr = sector * sector_size;
1458
-
1459
- assert_page_mem(test_data, addr, 0xffffffff);
1460
- write_page_mem(test_data, addr, make_be32(0xabcdef12));
1461
-
1462
- uint32_t expected_value = protection_start <= sector
1463
- && sector < protection_end
1464
- ? 0xffffffff : 0xabcdef12;
1465
-
1466
- assert_page_mem(test_data, addr, expected_value);
1467
- }
1468
- }
1469
-
1470
- flash_reset(test_data);
1471
-}
1472
-
1473
-static void test_write_page_qpi(const void *data)
1474
-{
1475
- const TestData *test_data = (const TestData *)data;
1476
- uint32_t my_page_addr = test_data->page_addr;
1477
- uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE;
1478
- uint32_t page[FLASH_PAGE_SIZE / 4];
1479
- uint32_t page_pattern[] = {
1480
- 0xebd8c134, 0x5da196bc, 0xae15e729, 0x5085ccdf
1481
- };
1482
- int i;
1483
-
1484
- spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs));
1485
-
1486
- spi_ctrl_start_user(test_data);
1487
- flash_writeb(test_data, 0, EN_4BYTE_ADDR);
1488
- flash_writeb(test_data, 0, WREN);
1489
- flash_writeb(test_data, 0, PP);
1490
- flash_writel(test_data, 0, make_be32(my_page_addr));
1491
-
1492
- /* Set QPI mode */
1493
- spi_ctrl_set_io_mode(test_data, CTRL_IO_QUAD_IO);
1494
-
1495
- /* Fill the page pattern */
1496
- for (i = 0; i < ARRAY_SIZE(page_pattern); i++) {
1497
- flash_writel(test_data, 0, make_be32(page_pattern[i]));
1498
- }
1499
-
1500
- /* Fill the page with its own addresses */
1501
- for (; i < FLASH_PAGE_SIZE / 4; i++) {
1502
- flash_writel(test_data, 0, make_be32(my_page_addr + i * 4));
1503
- }
1504
-
1505
- /* Restore io mode */
1506
- spi_ctrl_set_io_mode(test_data, 0);
1507
- spi_ctrl_stop_user(test_data);
1508
-
1509
- /* Check what was written */
1510
- read_page(test_data, my_page_addr, page);
1511
- for (i = 0; i < ARRAY_SIZE(page_pattern); i++) {
1512
- g_assert_cmphex(page[i], ==, page_pattern[i]);
1513
- }
1514
- for (; i < FLASH_PAGE_SIZE / 4; i++) {
1515
- g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
1516
- }
1517
-
1518
- /* Check some other page. It should be full of 0xff */
1519
- read_page(test_data, some_page_addr, page);
1520
- for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) {
1521
- g_assert_cmphex(page[i], ==, 0xffffffff);
1522
- }
1523
-
1524
- flash_reset(test_data);
1525
-}
1526
-
1527
-static void test_palmetto_bmc(TestData *data)
1528
+static void test_palmetto_bmc(AspeedSMCTestData *data)
1529
{
1530
int ret;
1531
int fd;
1532
@@ -XXX,XX +XXX,XX @@ static void test_palmetto_bmc(TestData *data)
1533
/* beyond 16MB */
1534
data->page_addr = 0x14000 * FLASH_PAGE_SIZE;
1535
1536
- qtest_add_data_func("/ast2400/smc/read_jedec", data, test_read_jedec);
1537
- qtest_add_data_func("/ast2400/smc/erase_sector", data, test_erase_sector);
1538
- qtest_add_data_func("/ast2400/smc/erase_all", data, test_erase_all);
1539
- qtest_add_data_func("/ast2400/smc/write_page", data, test_write_page);
1540
+ qtest_add_data_func("/ast2400/smc/read_jedec",
1541
+ data, aspeed_smc_test_read_jedec);
1542
+ qtest_add_data_func("/ast2400/smc/erase_sector",
1543
+ data, aspeed_smc_test_erase_sector);
1544
+ qtest_add_data_func("/ast2400/smc/erase_all",
1545
+ data, aspeed_smc_test_erase_all);
1546
+ qtest_add_data_func("/ast2400/smc/write_page",
1547
+ data, aspeed_smc_test_write_page);
1548
qtest_add_data_func("/ast2400/smc/read_page_mem",
1549
- data, test_read_page_mem);
1550
+ data, aspeed_smc_test_read_page_mem);
1551
qtest_add_data_func("/ast2400/smc/write_page_mem",
1552
- data, test_write_page_mem);
1553
+ data, aspeed_smc_test_write_page_mem);
1554
qtest_add_data_func("/ast2400/smc/read_status_reg",
1555
- data, test_read_status_reg);
1556
+ data, aspeed_smc_test_read_status_reg);
1557
qtest_add_data_func("/ast2400/smc/status_reg_write_protection",
1558
- data, test_status_reg_write_protection);
1559
+ data, aspeed_smc_test_status_reg_write_protection);
1560
qtest_add_data_func("/ast2400/smc/write_block_protect",
1561
- data, test_write_block_protect);
1562
+ data, aspeed_smc_test_write_block_protect);
1563
qtest_add_data_func("/ast2400/smc/write_block_protect_bottom_bit",
1564
- data, test_write_block_protect_bottom_bit);
1565
+ data, aspeed_smc_test_write_block_protect_bottom_bit);
16
}
1566
}
17
1567
18
+#define aspeed_smc_error(fmt, ...) \
1568
-static void test_ast2500_evb(TestData *data)
19
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__)
1569
+static void test_ast2500_evb(AspeedSMCTestData *data)
20
+
21
static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
22
const AspeedSegments *new,
23
int cs)
24
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
25
26
if (new->addr + new->size > seg.addr &&
27
new->addr < seg.addr + seg.size) {
28
- qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment CS%d [ 0x%"
29
- HWADDR_PRIx" - 0x%"HWADDR_PRIx" ] overlaps with "
30
- "CS%d [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
31
- s->ctrl->name, cs, new->addr, new->addr + new->size,
32
- i, seg.addr, seg.addr + seg.size);
33
+ aspeed_smc_error("new segment CS%d [ 0x%"
34
+ HWADDR_PRIx" - 0x%"HWADDR_PRIx" ] overlaps with "
35
+ "CS%d [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
36
+ cs, new->addr, new->addr + new->size,
37
+ i, seg.addr, seg.addr + seg.size);
38
return true;
39
}
40
}
41
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
42
43
/* The start address of CS0 is read-only */
44
if (cs == 0 && seg.addr != s->ctrl->flash_window_base) {
45
- qemu_log_mask(LOG_GUEST_ERROR,
46
- "%s: Tried to change CS0 start address to 0x%"
47
- HWADDR_PRIx "\n", s->ctrl->name, seg.addr);
48
+ aspeed_smc_error("Tried to change CS0 start address to 0x%"
49
+ HWADDR_PRIx, seg.addr);
50
seg.addr = s->ctrl->flash_window_base;
51
new = s->ctrl->segment_to_reg(s, &seg);
52
}
53
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
54
cs == s->ctrl->max_peripherals &&
55
seg.addr + seg.size != s->ctrl->segments[cs].addr +
56
s->ctrl->segments[cs].size) {
57
- qemu_log_mask(LOG_GUEST_ERROR,
58
- "%s: Tried to change CS%d end address to 0x%"
59
- HWADDR_PRIx "\n", s->ctrl->name, cs, seg.addr + seg.size);
60
+ aspeed_smc_error("Tried to change CS%d end address to 0x%"
61
+ HWADDR_PRIx, cs, seg.addr + seg.size);
62
seg.size = s->ctrl->segments[cs].addr + s->ctrl->segments[cs].size -
63
seg.addr;
64
new = s->ctrl->segment_to_reg(s, &seg);
65
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
66
if (seg.size &&
67
(seg.addr + seg.size <= s->ctrl->flash_window_base ||
68
seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size)) {
69
- qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
70
- "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
71
- s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
72
+ aspeed_smc_error("new segment for CS%d is invalid : "
73
+ "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
74
+ cs, seg.addr, seg.addr + seg.size);
75
return;
76
}
77
78
/* Check start address vs. alignment */
79
if (seg.size && !QEMU_IS_ALIGNED(seg.addr, seg.size)) {
80
- qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is not "
81
- "aligned : [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
82
- s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
83
+ aspeed_smc_error("new segment for CS%d is not "
84
+ "aligned : [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
85
+ cs, seg.addr, seg.addr + seg.size);
86
}
87
88
/* And segments should not overlap (in the specs) */
89
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
90
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
91
unsigned size)
92
{
1570
{
93
- qemu_log_mask(LOG_GUEST_ERROR, "%s: To 0x%" HWADDR_PRIx " of size %u"
1571
int ret;
94
- PRIx64 "\n", __func__, addr, size);
1572
int fd;
95
+ aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u" PRIx64, addr, size);
1573
@@ -XXX,XX +XXX,XX @@ static void test_ast2500_evb(TestData *data)
96
return 0;
1574
/* beyond 16MB */
1575
data->page_addr = 0x14000 * FLASH_PAGE_SIZE;
1576
1577
- qtest_add_data_func("/ast2500/smc/read_jedec", data, test_read_jedec);
1578
- qtest_add_data_func("/ast2500/smc/erase_sector", data, test_erase_sector);
1579
- qtest_add_data_func("/ast2500/smc/erase_all", data, test_erase_all);
1580
- qtest_add_data_func("/ast2500/smc/write_page", data, test_write_page);
1581
+ qtest_add_data_func("/ast2500/smc/read_jedec",
1582
+ data, aspeed_smc_test_read_jedec);
1583
+ qtest_add_data_func("/ast2500/smc/erase_sector",
1584
+ data, aspeed_smc_test_erase_sector);
1585
+ qtest_add_data_func("/ast2500/smc/erase_all",
1586
+ data, aspeed_smc_test_erase_all);
1587
+ qtest_add_data_func("/ast2500/smc/write_page",
1588
+ data, aspeed_smc_test_write_page);
1589
qtest_add_data_func("/ast2500/smc/read_page_mem",
1590
- data, test_read_page_mem);
1591
+ data, aspeed_smc_test_read_page_mem);
1592
qtest_add_data_func("/ast2500/smc/write_page_mem",
1593
- data, test_write_page_mem);
1594
+ data, aspeed_smc_test_write_page_mem);
1595
qtest_add_data_func("/ast2500/smc/read_status_reg",
1596
- data, test_read_status_reg);
1597
+ data, aspeed_smc_test_read_status_reg);
1598
qtest_add_data_func("/ast2500/smc/write_page_qpi",
1599
- data, test_write_page_qpi);
1600
+ data, aspeed_smc_test_write_page_qpi);
97
}
1601
}
98
1602
99
static void aspeed_smc_flash_default_write(void *opaque, hwaddr addr,
1603
-static void test_ast2600_evb(TestData *data)
100
uint64_t data, unsigned size)
1604
+static void test_ast2600_evb(AspeedSMCTestData *data)
101
{
1605
{
102
- qemu_log_mask(LOG_GUEST_ERROR, "%s: To 0x%" HWADDR_PRIx " of size %u: 0x%"
1606
int ret;
103
- PRIx64 "\n", __func__, addr, size, data);
1607
int fd;
104
+ aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u: 0x%" PRIx64,
1608
@@ -XXX,XX +XXX,XX @@ static void test_ast2600_evb(TestData *data)
105
+ addr, size, data);
1609
/* beyond 16MB */
1610
data->page_addr = 0x14000 * FLASH_PAGE_SIZE;
1611
1612
- qtest_add_data_func("/ast2600/smc/read_jedec", data, test_read_jedec);
1613
- qtest_add_data_func("/ast2600/smc/erase_sector", data, test_erase_sector);
1614
- qtest_add_data_func("/ast2600/smc/erase_all", data, test_erase_all);
1615
- qtest_add_data_func("/ast2600/smc/write_page", data, test_write_page);
1616
+ qtest_add_data_func("/ast2600/smc/read_jedec",
1617
+ data, aspeed_smc_test_read_jedec);
1618
+ qtest_add_data_func("/ast2600/smc/erase_sector",
1619
+ data, aspeed_smc_test_erase_sector);
1620
+ qtest_add_data_func("/ast2600/smc/erase_all",
1621
+ data, aspeed_smc_test_erase_all);
1622
+ qtest_add_data_func("/ast2600/smc/write_page",
1623
+ data, aspeed_smc_test_write_page);
1624
qtest_add_data_func("/ast2600/smc/read_page_mem",
1625
- data, test_read_page_mem);
1626
+ data, aspeed_smc_test_read_page_mem);
1627
qtest_add_data_func("/ast2600/smc/write_page_mem",
1628
- data, test_write_page_mem);
1629
+ data, aspeed_smc_test_write_page_mem);
1630
qtest_add_data_func("/ast2600/smc/read_status_reg",
1631
- data, test_read_status_reg);
1632
+ data, aspeed_smc_test_read_status_reg);
1633
qtest_add_data_func("/ast2600/smc/write_page_qpi",
1634
- data, test_write_page_qpi);
1635
+ data, aspeed_smc_test_write_page_qpi);
106
}
1636
}
107
1637
108
static const MemoryRegionOps aspeed_smc_flash_default_ops = {
1638
-static void test_ast1030_evb(TestData *data)
109
@@ -XXX,XX +XXX,XX @@ static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
1639
+static void test_ast1030_evb(AspeedSMCTestData *data)
110
}
1640
{
111
1641
int ret;
112
if (!cmd) {
1642
int fd;
113
- qemu_log_mask(LOG_GUEST_ERROR, "%s: no command defined for mode %d\n",
1643
@@ -XXX,XX +XXX,XX @@ static void test_ast1030_evb(TestData *data)
114
- __func__, aspeed_smc_flash_mode(fl));
1644
/* beyond 512KB */
115
+ aspeed_smc_error("no command defined for mode %d",
1645
data->page_addr = 0x800 * FLASH_PAGE_SIZE;
116
+ aspeed_smc_flash_mode(fl));
1646
117
}
1647
- qtest_add_data_func("/ast1030/smc/read_jedec", data, test_read_jedec);
118
1648
- qtest_add_data_func("/ast1030/smc/erase_sector", data, test_erase_sector);
119
return cmd;
1649
- qtest_add_data_func("/ast1030/smc/erase_all", data, test_erase_all);
120
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
1650
- qtest_add_data_func("/ast1030/smc/write_page", data, test_write_page);
121
1651
+ qtest_add_data_func("/ast1030/smc/read_jedec",
122
s->ctrl->reg_to_segment(s, s->regs[R_SEG_ADDR0 + fl->id], &seg);
1652
+ data, aspeed_smc_test_read_jedec);
123
if ((addr % seg.size) != addr) {
1653
+ qtest_add_data_func("/ast1030/smc/erase_sector",
124
- qemu_log_mask(LOG_GUEST_ERROR,
1654
+ data, aspeed_smc_test_erase_sector);
125
- "%s: invalid address 0x%08x for CS%d segment : "
1655
+ qtest_add_data_func("/ast1030/smc/erase_all",
126
- "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
1656
+ data, aspeed_smc_test_erase_all);
127
- s->ctrl->name, addr, fl->id, seg.addr,
1657
+ qtest_add_data_func("/ast1030/smc/write_page",
128
- seg.addr + seg.size);
1658
+ data, aspeed_smc_test_write_page);
129
+ aspeed_smc_error("invalid address 0x%08x for CS%d segment : "
1659
qtest_add_data_func("/ast1030/smc/read_page_mem",
130
+ "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
1660
- data, test_read_page_mem);
131
+ addr, fl->id, seg.addr, seg.addr + seg.size);
1661
+ data, aspeed_smc_test_read_page_mem);
132
addr %= seg.size;
1662
qtest_add_data_func("/ast1030/smc/write_page_mem",
133
}
1663
- data, test_write_page_mem);
134
1664
+ data, aspeed_smc_test_write_page_mem);
135
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
1665
qtest_add_data_func("/ast1030/smc/read_status_reg",
136
aspeed_smc_flash_unselect(fl);
1666
- data, test_read_status_reg);
137
break;
1667
+ data, aspeed_smc_test_read_status_reg);
138
default:
1668
qtest_add_data_func("/ast1030/smc/write_page_qpi",
139
- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid flash mode %d\n",
1669
- data, test_write_page_qpi);
140
- __func__, aspeed_smc_flash_mode(fl));
1670
+ data, aspeed_smc_test_write_page_qpi);
141
+ aspeed_smc_error("invalid flash mode %d", aspeed_smc_flash_mode(fl));
142
}
143
144
trace_aspeed_smc_flash_read(fl->id, addr, size, ret,
145
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
146
aspeed_smc_flash_mode(fl));
147
148
if (!aspeed_smc_is_writable(fl)) {
149
- qemu_log_mask(LOG_GUEST_ERROR, "%s: flash is not writable at 0x%"
150
- HWADDR_PRIx "\n", __func__, addr);
151
+ aspeed_smc_error("flash is not writable at 0x%" HWADDR_PRIx, addr);
152
return;
153
}
154
155
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
156
aspeed_smc_flash_unselect(fl);
157
break;
158
default:
159
- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid flash mode %d\n",
160
- __func__, aspeed_smc_flash_mode(fl));
161
+ aspeed_smc_error("invalid flash mode %d", aspeed_smc_flash_mode(fl));
162
}
163
}
1671
}
164
1672
165
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_smc_hclk_divisor(uint8_t hclk_mask)
1673
int main(int argc, char **argv)
166
}
1674
{
167
}
1675
- TestData palmetto_data;
168
1676
- TestData ast2500_evb_data;
169
- qemu_log_mask(LOG_GUEST_ERROR, "invalid HCLK mask %x", hclk_mask);
1677
- TestData ast2600_evb_data;
170
+ aspeed_smc_error("invalid HCLK mask %x", hclk_mask);
1678
- TestData ast1030_evb_data;
171
return 0;
1679
+ AspeedSMCTestData palmetto_data;
1680
+ AspeedSMCTestData ast2500_evb_data;
1681
+ AspeedSMCTestData ast2600_evb_data;
1682
+ AspeedSMCTestData ast1030_evb_data;
1683
int ret;
1684
1685
g_test_init(&argc, &argv, NULL);
1686
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
1687
index XXXXXXX..XXXXXXX 100644
1688
--- a/tests/qtest/meson.build
1689
+++ b/tests/qtest/meson.build
1690
@@ -XXX,XX +XXX,XX @@ qtests = {
1691
'virtio-net-failover': files('migration-helpers.c'),
1692
'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'),
1693
'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
1694
+ 'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'),
172
}
1695
}
173
1696
174
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
1697
if vnc.found()
175
uint32_t data;
176
177
if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
178
- qemu_log_mask(LOG_GUEST_ERROR,
179
- "%s: invalid direction for DMA checksum\n", __func__);
180
+ aspeed_smc_error("invalid direction for DMA checksum");
181
return;
182
}
183
184
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
185
data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
186
MEMTXATTRS_UNSPECIFIED, &result);
187
if (result != MEMTX_OK) {
188
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash read failed @%08x\n",
189
- __func__, s->regs[R_DMA_FLASH_ADDR]);
190
+ aspeed_smc_error("Flash read failed @%08x",
191
+ s->regs[R_DMA_FLASH_ADDR]);
192
return;
193
}
194
trace_aspeed_smc_dma_checksum(s->regs[R_DMA_FLASH_ADDR], data);
195
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
196
data = address_space_ldl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
197
MEMTXATTRS_UNSPECIFIED, &result);
198
if (result != MEMTX_OK) {
199
- qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n",
200
- __func__, s->regs[R_DMA_DRAM_ADDR]);
201
+ aspeed_smc_error("DRAM read failed @%08x",
202
+ s->regs[R_DMA_DRAM_ADDR]);
203
return;
204
}
205
206
address_space_stl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
207
data, MEMTXATTRS_UNSPECIFIED, &result);
208
if (result != MEMTX_OK) {
209
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash write failed @%08x\n",
210
- __func__, s->regs[R_DMA_FLASH_ADDR]);
211
+ aspeed_smc_error("Flash write failed @%08x",
212
+ s->regs[R_DMA_FLASH_ADDR]);
213
return;
214
}
215
} else {
216
data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
217
MEMTXATTRS_UNSPECIFIED, &result);
218
if (result != MEMTX_OK) {
219
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash read failed @%08x\n",
220
- __func__, s->regs[R_DMA_FLASH_ADDR]);
221
+ aspeed_smc_error("Flash read failed @%08x",
222
+ s->regs[R_DMA_FLASH_ADDR]);
223
return;
224
}
225
226
address_space_stl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
227
data, MEMTXATTRS_UNSPECIFIED, &result);
228
if (result != MEMTX_OK) {
229
- qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
230
- __func__, s->regs[R_DMA_DRAM_ADDR]);
231
+ aspeed_smc_error("DRAM write failed @%08x",
232
+ s->regs[R_DMA_DRAM_ADDR]);
233
return;
234
}
235
}
236
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint32_t dma_ctrl)
237
}
238
239
if (aspeed_smc_dma_in_progress(s)) {
240
- qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA in progress\n", __func__);
241
+ aspeed_smc_error("DMA in progress !");
242
return;
243
}
244
245
@@ -XXX,XX +XXX,XX @@ static inline bool aspeed_smc_dma_granted(AspeedSMCState *s)
246
}
247
248
if (!(s->regs[R_DMA_CTRL] & DMA_CTRL_GRANT)) {
249
- qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA not granted\n", __func__);
250
+ aspeed_smc_error("DMA not granted");
251
return false;
252
}
253
254
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_dma_ctrl(AspeedSMCState *s, uint32_t dma_ctrl)
255
}
256
257
if (!aspeed_smc_dma_granted(s)) {
258
- qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA not granted\n", __func__);
259
+ aspeed_smc_error("DMA not granted");
260
return;
261
}
262
263
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
264
265
/* Enforce some real HW limits */
266
if (s->num_cs > s->ctrl->max_peripherals) {
267
- qemu_log_mask(LOG_GUEST_ERROR, "%s: num_cs cannot exceed: %d\n",
268
- __func__, s->ctrl->max_peripherals);
269
+ aspeed_smc_error("num_cs cannot exceed: %d", s->ctrl->max_peripherals);
270
s->num_cs = s->ctrl->max_peripherals;
271
}
272
273
--
1698
--
274
2.31.1
1699
2.47.1
275
1700
276
1701
diff view generated by jsdifflib
1
From: Andrew Jeffery <andrew@aj.id.au>
1
From: Jamin Lin <jamin_lin@aspeedtech.com>
2
2
3
This model implements enough behaviour to do basic functionality tests
3
Add test_ast2700_evb function and reused testcases which are from
4
such as device initialisation and read out of dummy sample values. The
4
aspeed_smc-test.c for AST2700 testing. The base address, flash base address
5
sample value generation strategy is similar to the STM ADC already in
5
and ce index of fmc_cs0 are 0x14000000, 0x100000000 and 0, respectively.
6
the tree.
6
The default flash model of fmc_cs0 is "w25q01jvq" whose size is 128MB,
7
so set jedec_id 0xef4021.
7
8
8
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
9
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
9
[clg : support for multiple engines (AST2600) ]
10
Reviewed-by: Cédric Le Goater <clg@redhat.com>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Link: https://lore.kernel.org/r/20241127091543.1243114-11-jamin_lin@aspeedtech.com
11
[pdel : refactored engine register struct fields to regs[] array field]
12
Signed-off-by: Cédric Le Goater <clg@redhat.com>
12
[pdel : added guest-error checking for upper-8 channel regs in AST2600]
13
[pdel : allow 16-bit reads of the channel data registers]
14
Signed-off-by: Peter Delevoryas <pdel@fb.com>
15
Message-Id: <20211005052604.1674891-2-pdel@fb.com>
16
Signed-off-by: Cédric Le Goater <clg@kaod.org>
17
---
13
---
18
include/hw/adc/aspeed_adc.h | 55 +++++
14
tests/qtest/ast2700-smc-test.c | 71 ++++++++++++++++++++++++++++++++++
19
hw/adc/aspeed_adc.c | 427 ++++++++++++++++++++++++++++++++++++
15
tests/qtest/meson.build | 4 +-
20
hw/adc/meson.build | 1 +
16
2 files changed, 74 insertions(+), 1 deletion(-)
21
hw/adc/trace-events | 3 +
17
create mode 100644 tests/qtest/ast2700-smc-test.c
22
4 files changed, 486 insertions(+)
23
create mode 100644 include/hw/adc/aspeed_adc.h
24
create mode 100644 hw/adc/aspeed_adc.c
25
18
26
diff --git a/include/hw/adc/aspeed_adc.h b/include/hw/adc/aspeed_adc.h
19
diff --git a/tests/qtest/ast2700-smc-test.c b/tests/qtest/ast2700-smc-test.c
27
new file mode 100644
20
new file mode 100644
28
index XXXXXXX..XXXXXXX
21
index XXXXXXX..XXXXXXX
29
--- /dev/null
22
--- /dev/null
30
+++ b/include/hw/adc/aspeed_adc.h
23
+++ b/tests/qtest/ast2700-smc-test.c
31
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
32
+/*
25
+/*
33
+ * Aspeed ADC
26
+ * QTest testcase for the M25P80 Flash using the ASPEED SPI Controller since
34
+ *
27
+ * AST2700.
35
+ * Copyright 2017-2021 IBM Corp.
36
+ *
37
+ * Andrew Jeffery <andrew@aj.id.au>
38
+ *
28
+ *
39
+ * SPDX-License-Identifier: GPL-2.0-or-later
29
+ * SPDX-License-Identifier: GPL-2.0-or-later
40
+ */
30
+ * Copyright (C) 2024 ASPEED Technology Inc.
41
+
42
+#ifndef HW_ADC_ASPEED_ADC_H
43
+#define HW_ADC_ASPEED_ADC_H
44
+
45
+#include "hw/sysbus.h"
46
+
47
+#define TYPE_ASPEED_ADC "aspeed.adc"
48
+#define TYPE_ASPEED_2400_ADC TYPE_ASPEED_ADC "-ast2400"
49
+#define TYPE_ASPEED_2500_ADC TYPE_ASPEED_ADC "-ast2500"
50
+#define TYPE_ASPEED_2600_ADC TYPE_ASPEED_ADC "-ast2600"
51
+OBJECT_DECLARE_TYPE(AspeedADCState, AspeedADCClass, ASPEED_ADC)
52
+
53
+#define TYPE_ASPEED_ADC_ENGINE "aspeed.adc.engine"
54
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedADCEngineState, ASPEED_ADC_ENGINE)
55
+
56
+#define ASPEED_ADC_NR_CHANNELS 16
57
+#define ASPEED_ADC_NR_REGS (0xD0 >> 2)
58
+
59
+struct AspeedADCEngineState {
60
+ /* <private> */
61
+ SysBusDevice parent;
62
+
63
+ MemoryRegion mmio;
64
+ qemu_irq irq;
65
+ uint32_t engine_id;
66
+ uint32_t nr_channels;
67
+ uint32_t regs[ASPEED_ADC_NR_REGS];
68
+};
69
+
70
+struct AspeedADCState {
71
+ /* <private> */
72
+ SysBusDevice parent;
73
+
74
+ MemoryRegion mmio;
75
+ qemu_irq irq;
76
+
77
+ AspeedADCEngineState engines[2];
78
+};
79
+
80
+struct AspeedADCClass {
81
+ SysBusDeviceClass parent_class;
82
+
83
+ uint32_t nr_engines;
84
+};
85
+
86
+#endif /* HW_ADC_ASPEED_ADC_H */
87
diff --git a/hw/adc/aspeed_adc.c b/hw/adc/aspeed_adc.c
88
new file mode 100644
89
index XXXXXXX..XXXXXXX
90
--- /dev/null
91
+++ b/hw/adc/aspeed_adc.c
92
@@ -XXX,XX +XXX,XX @@
93
+/*
94
+ * Aspeed ADC
95
+ *
96
+ * Copyright 2017-2021 IBM Corp.
97
+ *
98
+ * Andrew Jeffery <andrew@aj.id.au>
99
+ *
100
+ * SPDX-License-Identifier: GPL-2.0-or-later
101
+ */
31
+ */
102
+
32
+
103
+#include "qemu/osdep.h"
33
+#include "qemu/osdep.h"
104
+#include "qapi/error.h"
34
+#include "qemu/bswap.h"
105
+#include "qemu/log.h"
35
+#include "libqtest-single.h"
106
+#include "hw/irq.h"
36
+#include "qemu/bitops.h"
107
+#include "hw/qdev-properties.h"
37
+#include "aspeed-smc-utils.h"
108
+#include "migration/vmstate.h"
109
+#include "hw/adc/aspeed_adc.h"
110
+#include "trace.h"
111
+
38
+
112
+#define ASPEED_ADC_MEMORY_REGION_SIZE 0x1000
39
+static void test_ast2700_evb(AspeedSMCTestData *data)
113
+#define ASPEED_ADC_ENGINE_MEMORY_REGION_SIZE 0x100
40
+{
114
+#define ASPEED_ADC_ENGINE_CH_EN_MASK 0xffff0000
41
+ int ret;
115
+#define ASPEED_ADC_ENGINE_CH_EN(x) ((BIT(x)) << 16)
42
+ int fd;
116
+#define ASPEED_ADC_ENGINE_INIT BIT(8)
117
+#define ASPEED_ADC_ENGINE_AUTO_COMP BIT(5)
118
+#define ASPEED_ADC_ENGINE_COMP BIT(4)
119
+#define ASPEED_ADC_ENGINE_MODE_MASK 0x0000000e
120
+#define ASPEED_ADC_ENGINE_MODE_OFF (0b000 << 1)
121
+#define ASPEED_ADC_ENGINE_MODE_STANDBY (0b001 << 1)
122
+#define ASPEED_ADC_ENGINE_MODE_NORMAL (0b111 << 1)
123
+#define ASPEED_ADC_ENGINE_EN BIT(0)
124
+#define ASPEED_ADC_HYST_EN BIT(31)
125
+
43
+
126
+#define ASPEED_ADC_L_MASK ((1 << 10) - 1)
44
+ fd = g_file_open_tmp("qtest.m25p80.w25q01jvq.XXXXXX",
127
+#define ASPEED_ADC_L(x) ((x) & ASPEED_ADC_L_MASK)
45
+ &data->tmp_path, NULL);
128
+#define ASPEED_ADC_H(x) (((x) >> 16) & ASPEED_ADC_L_MASK)
46
+ g_assert(fd >= 0);
129
+#define ASPEED_ADC_LH_MASK (ASPEED_ADC_L_MASK << 16 | ASPEED_ADC_L_MASK)
47
+ ret = ftruncate(fd, 128 * 1024 * 1024);
130
+#define LOWER_CHANNEL_MASK ((1 << 10) - 1)
48
+ g_assert(ret == 0);
131
+#define LOWER_CHANNEL_DATA(x) ((x) & LOWER_CHANNEL_MASK)
49
+ close(fd);
132
+#define UPPER_CHANNEL_DATA(x) (((x) >> 16) & LOWER_CHANNEL_MASK)
133
+
50
+
134
+#define TO_REG(addr) (addr >> 2)
51
+ data->s = qtest_initf("-machine ast2700-evb "
52
+ "-drive file=%s,format=raw,if=mtd",
53
+ data->tmp_path);
135
+
54
+
136
+#define ENGINE_CONTROL TO_REG(0x00)
55
+ /* fmc cs0 with w25q01jvq flash */
137
+#define INTERRUPT_CONTROL TO_REG(0x04)
56
+ data->flash_base = 0x100000000;
138
+#define VGA_DETECT_CONTROL TO_REG(0x08)
57
+ data->spi_base = 0x14000000;
139
+#define CLOCK_CONTROL TO_REG(0x0C)
58
+ data->jedec_id = 0xef4021;
140
+#define DATA_CHANNEL_1_AND_0 TO_REG(0x10)
59
+ data->cs = 0;
141
+#define DATA_CHANNEL_7_AND_6 TO_REG(0x1C)
60
+ data->node = "/machine/soc/fmc/ssi.0/child[0]";
142
+#define DATA_CHANNEL_9_AND_8 TO_REG(0x20)
61
+ /* beyond 64MB */
143
+#define DATA_CHANNEL_15_AND_14 TO_REG(0x2C)
62
+ data->page_addr = 0x40000 * FLASH_PAGE_SIZE;
144
+#define BOUNDS_CHANNEL_0 TO_REG(0x30)
145
+#define BOUNDS_CHANNEL_7 TO_REG(0x4C)
146
+#define BOUNDS_CHANNEL_8 TO_REG(0x50)
147
+#define BOUNDS_CHANNEL_15 TO_REG(0x6C)
148
+#define HYSTERESIS_CHANNEL_0 TO_REG(0x70)
149
+#define HYSTERESIS_CHANNEL_7 TO_REG(0x8C)
150
+#define HYSTERESIS_CHANNEL_8 TO_REG(0x90)
151
+#define HYSTERESIS_CHANNEL_15 TO_REG(0xAC)
152
+#define INTERRUPT_SOURCE TO_REG(0xC0)
153
+#define COMPENSATING_AND_TRIMMING TO_REG(0xC4)
154
+
63
+
155
+static inline uint32_t update_channels(uint32_t current)
64
+ qtest_add_data_func("/ast2700/smc/read_jedec",
156
+{
65
+ data, aspeed_smc_test_read_jedec);
157
+ return ((((current >> 16) & ASPEED_ADC_L_MASK) + 7) << 16) |
66
+ qtest_add_data_func("/ast2700/smc/erase_sector",
158
+ ((current + 5) & ASPEED_ADC_L_MASK);
67
+ data, aspeed_smc_test_erase_sector);
68
+ qtest_add_data_func("/ast2700/smc/erase_all",
69
+ data, aspeed_smc_test_erase_all);
70
+ qtest_add_data_func("/ast2700/smc/write_page",
71
+ data, aspeed_smc_test_write_page);
72
+ qtest_add_data_func("/ast2700/smc/read_page_mem",
73
+ data, aspeed_smc_test_read_page_mem);
74
+ qtest_add_data_func("/ast2700/smc/write_page_mem",
75
+ data, aspeed_smc_test_write_page_mem);
76
+ qtest_add_data_func("/ast2700/smc/read_status_reg",
77
+ data, aspeed_smc_test_read_status_reg);
78
+ qtest_add_data_func("/ast2700/smc/write_page_qpi",
79
+ data, aspeed_smc_test_write_page_qpi);
159
+}
80
+}
160
+
81
+
161
+static bool breaks_threshold(AspeedADCEngineState *s, int reg)
82
+int main(int argc, char **argv)
162
+{
83
+{
163
+ assert(reg >= DATA_CHANNEL_1_AND_0 &&
84
+ AspeedSMCTestData ast2700_evb_data;
164
+ reg < DATA_CHANNEL_1_AND_0 + s->nr_channels / 2);
85
+ int ret;
165
+
86
+
166
+ int a_bounds_reg = BOUNDS_CHANNEL_0 + (reg - DATA_CHANNEL_1_AND_0) * 2;
87
+ g_test_init(&argc, &argv, NULL);
167
+ int b_bounds_reg = a_bounds_reg + 1;
168
+ uint32_t a_and_b = s->regs[reg];
169
+ uint32_t a_bounds = s->regs[a_bounds_reg];
170
+ uint32_t b_bounds = s->regs[b_bounds_reg];
171
+ uint32_t a = ASPEED_ADC_L(a_and_b);
172
+ uint32_t b = ASPEED_ADC_H(a_and_b);
173
+ uint32_t a_lower = ASPEED_ADC_L(a_bounds);
174
+ uint32_t a_upper = ASPEED_ADC_H(a_bounds);
175
+ uint32_t b_lower = ASPEED_ADC_L(b_bounds);
176
+ uint32_t b_upper = ASPEED_ADC_H(b_bounds);
177
+
88
+
178
+ return (a < a_lower || a > a_upper) ||
89
+ test_ast2700_evb(&ast2700_evb_data);
179
+ (b < b_lower || b > b_upper);
90
+ ret = g_test_run();
91
+
92
+ qtest_quit(ast2700_evb_data.s);
93
+ unlink(ast2700_evb_data.tmp_path);
94
+ return ret;
180
+}
95
+}
181
+
96
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
182
+static uint32_t read_channel_sample(AspeedADCEngineState *s, int reg)
183
+{
184
+ assert(reg >= DATA_CHANNEL_1_AND_0 &&
185
+ reg < DATA_CHANNEL_1_AND_0 + s->nr_channels / 2);
186
+
187
+ /* Poor man's sampling */
188
+ uint32_t value = s->regs[reg];
189
+ s->regs[reg] = update_channels(s->regs[reg]);
190
+
191
+ if (breaks_threshold(s, reg)) {
192
+ s->regs[INTERRUPT_CONTROL] |= BIT(reg - DATA_CHANNEL_1_AND_0);
193
+ qemu_irq_raise(s->irq);
194
+ }
195
+
196
+ return value;
197
+}
198
+
199
+static uint64_t aspeed_adc_engine_read(void *opaque, hwaddr addr,
200
+ unsigned int size)
201
+{
202
+ AspeedADCEngineState *s = ASPEED_ADC_ENGINE(opaque);
203
+ int reg = TO_REG(addr);
204
+ uint32_t value = 0;
205
+
206
+ switch (reg) {
207
+ case BOUNDS_CHANNEL_8 ... BOUNDS_CHANNEL_15:
208
+ if (s->nr_channels <= 8) {
209
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: engine[%u]: "
210
+ "bounds register %u invalid, only 0...7 valid\n",
211
+ __func__, s->engine_id, reg - BOUNDS_CHANNEL_0);
212
+ break;
213
+ }
214
+ /* fallthrough */
215
+ case HYSTERESIS_CHANNEL_8 ... HYSTERESIS_CHANNEL_15:
216
+ if (s->nr_channels <= 8) {
217
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: engine[%u]: "
218
+ "hysteresis register %u invalid, only 0...7 valid\n",
219
+ __func__, s->engine_id, reg - HYSTERESIS_CHANNEL_0);
220
+ break;
221
+ }
222
+ /* fallthrough */
223
+ case BOUNDS_CHANNEL_0 ... BOUNDS_CHANNEL_7:
224
+ case HYSTERESIS_CHANNEL_0 ... HYSTERESIS_CHANNEL_7:
225
+ case ENGINE_CONTROL:
226
+ case INTERRUPT_CONTROL:
227
+ case VGA_DETECT_CONTROL:
228
+ case CLOCK_CONTROL:
229
+ case INTERRUPT_SOURCE:
230
+ case COMPENSATING_AND_TRIMMING:
231
+ value = s->regs[reg];
232
+ break;
233
+ case DATA_CHANNEL_9_AND_8 ... DATA_CHANNEL_15_AND_14:
234
+ if (s->nr_channels <= 8) {
235
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: engine[%u]: "
236
+ "data register %u invalid, only 0...3 valid\n",
237
+ __func__, s->engine_id, reg - DATA_CHANNEL_1_AND_0);
238
+ break;
239
+ }
240
+ /* fallthrough */
241
+ case DATA_CHANNEL_1_AND_0 ... DATA_CHANNEL_7_AND_6:
242
+ value = read_channel_sample(s, reg);
243
+ /* Allow 16-bit reads of the data registers */
244
+ if (addr & 0x2) {
245
+ assert(size == 2);
246
+ value >>= 16;
247
+ }
248
+ break;
249
+ default:
250
+ qemu_log_mask(LOG_UNIMP, "%s: engine[%u]: 0x%" HWADDR_PRIx "\n",
251
+ __func__, s->engine_id, addr);
252
+ break;
253
+ }
254
+
255
+ trace_aspeed_adc_engine_read(s->engine_id, addr, value);
256
+ return value;
257
+}
258
+
259
+static void aspeed_adc_engine_write(void *opaque, hwaddr addr, uint64_t value,
260
+ unsigned int size)
261
+{
262
+ AspeedADCEngineState *s = ASPEED_ADC_ENGINE(opaque);
263
+ int reg = TO_REG(addr);
264
+ uint32_t init = 0;
265
+
266
+ trace_aspeed_adc_engine_write(s->engine_id, addr, value);
267
+
268
+ switch (reg) {
269
+ case ENGINE_CONTROL:
270
+ init = !!(value & ASPEED_ADC_ENGINE_EN);
271
+ init *= ASPEED_ADC_ENGINE_INIT;
272
+
273
+ value &= ~ASPEED_ADC_ENGINE_INIT;
274
+ value |= init;
275
+
276
+ value &= ~ASPEED_ADC_ENGINE_AUTO_COMP;
277
+ break;
278
+ case INTERRUPT_CONTROL:
279
+ case VGA_DETECT_CONTROL:
280
+ case CLOCK_CONTROL:
281
+ break;
282
+ case DATA_CHANNEL_9_AND_8 ... DATA_CHANNEL_15_AND_14:
283
+ if (s->nr_channels <= 8) {
284
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: engine[%u]: "
285
+ "data register %u invalid, only 0...3 valid\n",
286
+ __func__, s->engine_id, reg - DATA_CHANNEL_1_AND_0);
287
+ return;
288
+ }
289
+ /* fallthrough */
290
+ case BOUNDS_CHANNEL_8 ... BOUNDS_CHANNEL_15:
291
+ if (s->nr_channels <= 8) {
292
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: engine[%u]: "
293
+ "bounds register %u invalid, only 0...7 valid\n",
294
+ __func__, s->engine_id, reg - BOUNDS_CHANNEL_0);
295
+ return;
296
+ }
297
+ /* fallthrough */
298
+ case DATA_CHANNEL_1_AND_0 ... DATA_CHANNEL_7_AND_6:
299
+ case BOUNDS_CHANNEL_0 ... BOUNDS_CHANNEL_7:
300
+ value &= ASPEED_ADC_LH_MASK;
301
+ break;
302
+ case HYSTERESIS_CHANNEL_8 ... HYSTERESIS_CHANNEL_15:
303
+ if (s->nr_channels <= 8) {
304
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: engine[%u]: "
305
+ "hysteresis register %u invalid, only 0...7 valid\n",
306
+ __func__, s->engine_id, reg - HYSTERESIS_CHANNEL_0);
307
+ return;
308
+ }
309
+ /* fallthrough */
310
+ case HYSTERESIS_CHANNEL_0 ... HYSTERESIS_CHANNEL_7:
311
+ value &= (ASPEED_ADC_HYST_EN | ASPEED_ADC_LH_MASK);
312
+ break;
313
+ case INTERRUPT_SOURCE:
314
+ value &= 0xffff;
315
+ break;
316
+ case COMPENSATING_AND_TRIMMING:
317
+ value &= 0xf;
318
+ break;
319
+ default:
320
+ qemu_log_mask(LOG_UNIMP, "%s: engine[%u]: "
321
+ "0x%" HWADDR_PRIx " 0x%" PRIx64 "\n",
322
+ __func__, s->engine_id, addr, value);
323
+ break;
324
+ }
325
+
326
+ s->regs[reg] = value;
327
+}
328
+
329
+static const MemoryRegionOps aspeed_adc_engine_ops = {
330
+ .read = aspeed_adc_engine_read,
331
+ .write = aspeed_adc_engine_write,
332
+ .endianness = DEVICE_LITTLE_ENDIAN,
333
+ .valid = {
334
+ .min_access_size = 2,
335
+ .max_access_size = 4,
336
+ .unaligned = false,
337
+ },
338
+};
339
+
340
+static const uint32_t aspeed_adc_resets[ASPEED_ADC_NR_REGS] = {
341
+ [ENGINE_CONTROL] = 0x00000000,
342
+ [INTERRUPT_CONTROL] = 0x00000000,
343
+ [VGA_DETECT_CONTROL] = 0x0000000f,
344
+ [CLOCK_CONTROL] = 0x0000000f,
345
+};
346
+
347
+static void aspeed_adc_engine_reset(DeviceState *dev)
348
+{
349
+ AspeedADCEngineState *s = ASPEED_ADC_ENGINE(dev);
350
+
351
+ memcpy(s->regs, aspeed_adc_resets, sizeof(aspeed_adc_resets));
352
+}
353
+
354
+static void aspeed_adc_engine_realize(DeviceState *dev, Error **errp)
355
+{
356
+ AspeedADCEngineState *s = ASPEED_ADC_ENGINE(dev);
357
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
358
+ g_autofree char *name = g_strdup_printf(TYPE_ASPEED_ADC_ENGINE ".%d",
359
+ s->engine_id);
360
+
361
+ assert(s->engine_id < 2);
362
+
363
+ sysbus_init_irq(sbd, &s->irq);
364
+
365
+ memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_adc_engine_ops, s, name,
366
+ ASPEED_ADC_ENGINE_MEMORY_REGION_SIZE);
367
+
368
+ sysbus_init_mmio(sbd, &s->mmio);
369
+}
370
+
371
+static const VMStateDescription vmstate_aspeed_adc_engine = {
372
+ .name = TYPE_ASPEED_ADC,
373
+ .version_id = 1,
374
+ .minimum_version_id = 1,
375
+ .fields = (VMStateField[]) {
376
+ VMSTATE_UINT32_ARRAY(regs, AspeedADCEngineState, ASPEED_ADC_NR_REGS),
377
+ VMSTATE_END_OF_LIST(),
378
+ }
379
+};
380
+
381
+static Property aspeed_adc_engine_properties[] = {
382
+ DEFINE_PROP_UINT32("engine-id", AspeedADCEngineState, engine_id, 0),
383
+ DEFINE_PROP_UINT32("nr-channels", AspeedADCEngineState, nr_channels, 0),
384
+ DEFINE_PROP_END_OF_LIST(),
385
+};
386
+
387
+static void aspeed_adc_engine_class_init(ObjectClass *klass, void *data)
388
+{
389
+ DeviceClass *dc = DEVICE_CLASS(klass);
390
+
391
+ dc->realize = aspeed_adc_engine_realize;
392
+ dc->reset = aspeed_adc_engine_reset;
393
+ device_class_set_props(dc, aspeed_adc_engine_properties);
394
+ dc->desc = "Aspeed Analog-to-Digital Engine";
395
+ dc->vmsd = &vmstate_aspeed_adc_engine;
396
+}
397
+
398
+static const TypeInfo aspeed_adc_engine_info = {
399
+ .name = TYPE_ASPEED_ADC_ENGINE,
400
+ .parent = TYPE_SYS_BUS_DEVICE,
401
+ .instance_size = sizeof(AspeedADCEngineState),
402
+ .class_init = aspeed_adc_engine_class_init,
403
+};
404
+
405
+static void aspeed_adc_instance_init(Object *obj)
406
+{
407
+ AspeedADCState *s = ASPEED_ADC(obj);
408
+ AspeedADCClass *aac = ASPEED_ADC_GET_CLASS(obj);
409
+ uint32_t nr_channels = ASPEED_ADC_NR_CHANNELS / aac->nr_engines;
410
+
411
+ for (int i = 0; i < aac->nr_engines; i++) {
412
+ AspeedADCEngineState *engine = &s->engines[i];
413
+ object_initialize_child(obj, "engine[*]", engine,
414
+ TYPE_ASPEED_ADC_ENGINE);
415
+ qdev_prop_set_uint32(DEVICE(engine), "engine-id", i);
416
+ qdev_prop_set_uint32(DEVICE(engine), "nr-channels", nr_channels);
417
+ }
418
+}
419
+
420
+static void aspeed_adc_set_irq(void *opaque, int n, int level)
421
+{
422
+ AspeedADCState *s = opaque;
423
+ AspeedADCClass *aac = ASPEED_ADC_GET_CLASS(s);
424
+ uint32_t pending = 0;
425
+
426
+ /* TODO: update Global IRQ status register on AST2600 (Need specs) */
427
+ for (int i = 0; i < aac->nr_engines; i++) {
428
+ uint32_t irq_status = s->engines[i].regs[INTERRUPT_CONTROL] & 0xFF;
429
+ pending |= irq_status << (i * 8);
430
+ }
431
+
432
+ qemu_set_irq(s->irq, !!pending);
433
+}
434
+
435
+static void aspeed_adc_realize(DeviceState *dev, Error **errp)
436
+{
437
+ AspeedADCState *s = ASPEED_ADC(dev);
438
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
439
+ AspeedADCClass *aac = ASPEED_ADC_GET_CLASS(dev);
440
+
441
+ qdev_init_gpio_in_named_with_opaque(DEVICE(sbd), aspeed_adc_set_irq,
442
+ s, NULL, aac->nr_engines);
443
+
444
+ sysbus_init_irq(sbd, &s->irq);
445
+
446
+ memory_region_init(&s->mmio, OBJECT(s), TYPE_ASPEED_ADC,
447
+ ASPEED_ADC_MEMORY_REGION_SIZE);
448
+
449
+ sysbus_init_mmio(sbd, &s->mmio);
450
+
451
+ for (int i = 0; i < aac->nr_engines; i++) {
452
+ Object *eng = OBJECT(&s->engines[i]);
453
+
454
+ if (!sysbus_realize(SYS_BUS_DEVICE(eng), errp)) {
455
+ return;
456
+ }
457
+ sysbus_connect_irq(SYS_BUS_DEVICE(eng), 0,
458
+ qdev_get_gpio_in(DEVICE(sbd), i));
459
+ memory_region_add_subregion(&s->mmio,
460
+ i * ASPEED_ADC_ENGINE_MEMORY_REGION_SIZE,
461
+ &s->engines[i].mmio);
462
+ }
463
+}
464
+
465
+static void aspeed_adc_class_init(ObjectClass *klass, void *data)
466
+{
467
+ DeviceClass *dc = DEVICE_CLASS(klass);
468
+ AspeedADCClass *aac = ASPEED_ADC_CLASS(klass);
469
+
470
+ dc->realize = aspeed_adc_realize;
471
+ dc->desc = "Aspeed Analog-to-Digital Converter";
472
+ aac->nr_engines = 1;
473
+}
474
+
475
+static void aspeed_2600_adc_class_init(ObjectClass *klass, void *data)
476
+{
477
+ DeviceClass *dc = DEVICE_CLASS(klass);
478
+ AspeedADCClass *aac = ASPEED_ADC_CLASS(klass);
479
+
480
+ dc->desc = "ASPEED 2600 ADC Controller";
481
+ aac->nr_engines = 2;
482
+}
483
+
484
+static const TypeInfo aspeed_adc_info = {
485
+ .name = TYPE_ASPEED_ADC,
486
+ .parent = TYPE_SYS_BUS_DEVICE,
487
+ .instance_init = aspeed_adc_instance_init,
488
+ .instance_size = sizeof(AspeedADCState),
489
+ .class_init = aspeed_adc_class_init,
490
+ .class_size = sizeof(AspeedADCClass),
491
+ .abstract = true,
492
+};
493
+
494
+static const TypeInfo aspeed_2400_adc_info = {
495
+ .name = TYPE_ASPEED_2400_ADC,
496
+ .parent = TYPE_ASPEED_ADC,
497
+};
498
+
499
+static const TypeInfo aspeed_2500_adc_info = {
500
+ .name = TYPE_ASPEED_2500_ADC,
501
+ .parent = TYPE_ASPEED_ADC,
502
+};
503
+
504
+static const TypeInfo aspeed_2600_adc_info = {
505
+ .name = TYPE_ASPEED_2600_ADC,
506
+ .parent = TYPE_ASPEED_ADC,
507
+ .class_init = aspeed_2600_adc_class_init,
508
+};
509
+
510
+static void aspeed_adc_register_types(void)
511
+{
512
+ type_register_static(&aspeed_adc_engine_info);
513
+ type_register_static(&aspeed_adc_info);
514
+ type_register_static(&aspeed_2400_adc_info);
515
+ type_register_static(&aspeed_2500_adc_info);
516
+ type_register_static(&aspeed_2600_adc_info);
517
+}
518
+
519
+type_init(aspeed_adc_register_types);
520
diff --git a/hw/adc/meson.build b/hw/adc/meson.build
521
index XXXXXXX..XXXXXXX 100644
97
index XXXXXXX..XXXXXXX 100644
522
--- a/hw/adc/meson.build
98
--- a/tests/qtest/meson.build
523
+++ b/hw/adc/meson.build
99
+++ b/tests/qtest/meson.build
524
@@ -XXX,XX +XXX,XX @@
100
@@ -XXX,XX +XXX,XX @@ qtests_aspeed = \
525
softmmu_ss.add(when: 'CONFIG_STM32F2XX_ADC', if_true: files('stm32f2xx_adc.c'))
101
'aspeed_smc-test',
526
+softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_adc.c'))
102
'aspeed_gpio-test']
527
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_adc.c'))
103
qtests_aspeed64 = \
528
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq-xadc.c'))
104
- ['ast2700-gpio-test']
529
softmmu_ss.add(when: 'CONFIG_MAX111X', if_true: files('max111x.c'))
105
+ ['ast2700-gpio-test',
530
diff --git a/hw/adc/trace-events b/hw/adc/trace-events
106
+ 'ast2700-smc-test']
531
index XXXXXXX..XXXXXXX 100644
107
532
--- a/hw/adc/trace-events
108
qtests_stm32l4x5 = \
533
+++ b/hw/adc/trace-events
109
['stm32l4x5_exti-test',
534
@@ -XXX,XX +XXX,XX @@
110
@@ -XXX,XX +XXX,XX @@ qtests = {
535
# npcm7xx_adc.c
111
'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'),
536
npcm7xx_adc_read(const char *id, uint64_t offset, uint32_t value) " %s offset: 0x%04" PRIx64 " value 0x%04" PRIx32
112
'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
537
npcm7xx_adc_write(const char *id, uint64_t offset, uint32_t value) "%s offset: 0x%04" PRIx64 " value 0x%04" PRIx32
113
'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'),
538
+
114
+ 'ast2700-smc-test': files('aspeed-smc-utils.c', 'ast2700-smc-test.c'),
539
+aspeed_adc_engine_read(uint32_t engine_id, uint64_t addr, uint64_t value) "engine[%u] 0x%" PRIx64 " 0x%" PRIx64
115
}
540
+aspeed_adc_engine_write(uint32_t engine_id, uint64_t addr, uint64_t value) "engine[%u] 0x%" PRIx64 " 0x%" PRIx64
116
117
if vnc.found()
541
--
118
--
542
2.31.1
119
2.47.1
543
120
544
121
diff view generated by jsdifflib