Official STM32CubeL4 drivers use and require support for 16-bit writes to
UART registers for proper function despite datasheet claims.
Signed-off-by: Jacob Whitaker Abrams <satur9nine@gmail.com>
---
v3:
- Add suggested comment and set only valid.min_access_size to 4
v2:
- Remove all changes other than supporting 16-bit writes UART regs
hw/char/stm32l4x5_usart.c | 7 ++++++-
tests/qtest/stm32l4x5_usart-test.c | 22 +++++++++++++++++++++-
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c
index 0b02dde1f8..c4ffc0d6ce 100644
--- a/hw/char/stm32l4x5_usart.c
+++ b/hw/char/stm32l4x5_usart.c
@@ -522,7 +522,12 @@ static const MemoryRegionOps stm32l4x5_usart_base_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.max_access_size = 4,
- .min_access_size = 4,
+ /*
+ * Official STM32CubeL4 drivers use and require support for 16-bit
+ * writes to UART registers for proper function despite datasheet
+ * claims.
+ */
+ .min_access_size = 2,
.unaligned = false
},
.impl = {
diff --git a/tests/qtest/stm32l4x5_usart-test.c b/tests/qtest/stm32l4x5_usart-test.c
index a72c5a685d..3c6437e75d 100644
--- a/tests/qtest/stm32l4x5_usart-test.c
+++ b/tests/qtest/stm32l4x5_usart-test.c
@@ -332,6 +332,26 @@ static void test_ack(void)
qtest_quit(qts);
}
+static void test_16bit_access(void)
+{
+ QTestState *qts = qtest_init("-M b-l475e-iot01a");
+
+ /* GTPR is declared uint16_t in the official STM driver. */
+ qtest_writew(qts, USART1_BASE_ADDR + A_GTPR, 0xABCD);
+ uint16_t gtpr16 = qtest_readw(qts, USART1_BASE_ADDR + A_GTPR);
+ g_assert_cmpuint(gtpr16, ==, 0xABCD);
+
+ /* TDR is uint16_t and r/w, register is 9-bits */
+ qtest_writew(qts, USART1_BASE_ADDR + A_TDR, 0x01CD);
+ uint16_t tdr16 = qtest_readw(qts, USART1_BASE_ADDR + A_TDR);
+ g_assert_cmpuint(tdr16, ==, 0x01CD);
+
+ /* RDR is uint16_t and read only, register is 9-bits */
+ qtest_writew(qts, USART1_BASE_ADDR + A_RDR, 0x01FA);
+
+ qtest_quit(qts);
+}
+
static void check_clock(QTestState *qts, const char *path, uint32_t rcc_reg,
uint32_t reg_offset)
{
@@ -370,6 +390,6 @@ int main(int argc, char **argv)
qtest_add_func("stm32l4x5/usart/send_str", test_send_str);
qtest_add_func("stm32l4x5/usart/ack", test_ack);
qtest_add_func("stm32l4x5/usart/clock_enable", test_clock_enable);
+ qtest_add_func("stm32l4x5/usart/16bit_access", test_16bit_access);
return g_test_run();
}
-
--
2.43.0