diff mbox series

[5/5] hw/char/avr_usart: Trace baudrate changes

Message ID 20200814163924.11662-6-f4bug@amsat.org
State New
Headers show
Series hw/avr: Start using the Clock API | expand

Commit Message

Philippe Mathieu-Daudé Aug. 14, 2020, 4:39 p.m. UTC
Add a trace event to track baudrate changes.

Example when running the FreeRTOS acceptance test [1]:

  $ qemu-system-avr -machine arduino-mega-2560-v3 -bios demo.elf -trace avr\*
  2546@1597415281.399619:avr_usart_update_baudrate baudrate 0x0019 (38461 bauds)
  2546@1597415281.400029:avr_usart_update_baudrate baudrate 0x0019 (38461 bauds)

Which confirm the definition from the test [2]:

  #define mainCOM_TEST_BAUD_RATE        ( ( unsigned long ) 38400 )

[1] tests/acceptance/machine_avr6.py
[2] https://github.com/seharris/qemu-avr-tests/blob/9c0c24da1b1/free-rtos/Demo/AVR_ATMega2560_GCC/main.c#L80

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/char/avr_usart.c  | 13 +++++++++++++
 hw/char/trace-events |  3 +++
 2 files changed, 16 insertions(+)
diff mbox series

Patch

diff --git a/hw/char/avr_usart.c b/hw/char/avr_usart.c
index 4a43492082..176158a96b 100644
--- a/hw/char/avr_usart.c
+++ b/hw/char/avr_usart.c
@@ -25,6 +25,7 @@ 
 #include "hw/irq.h"
 #include "hw/qdev-clock.h"
 #include "hw/qdev-properties.h"
+#include "trace.h"
 
 /* Offsets of registers. */
 #define USART_DR   0x06
@@ -56,6 +57,8 @@ 
 #define USART_CSRC_CSZ1   (1 << 2)
 #define USART_CSRC_CSZ0   (1 << 1)
 
+#define USART_CLOCK_DIVISOR  16      /* baudrate is input clock / 16 */
+
 static int avr_usart_can_receive(void *opaque)
 {
     AVRUsartState *usart = opaque;
@@ -120,6 +123,14 @@  static void update_char_mask(AVRUsartState *usart)
     }
 }
 
+static void avr_usart_update_baudrate(AVRUsartState *s)
+{
+    unsigned baudrate = (clock_get_hz(s->clkin) / USART_CLOCK_DIVISOR)
+                        / (((s->brrh << 8) | s->brrl) + 1);
+
+    trace_avr_usart_update_baudrate((s->brrh << 8) | s->brrl, baudrate);
+}
+
 static void avr_usart_reset(DeviceState *dev)
 {
     AVRUsartState *usart = AVR_USART(dev);
@@ -269,9 +280,11 @@  static void avr_usart_write(void *opaque, hwaddr addr, uint64_t value,
         break;
     case USART_BRRL:
         usart->brrl = value;
+        avr_usart_update_baudrate(usart);
         break;
     case USART_BRRH:
         usart->brrh = value & 0b00001111;
+        avr_usart_update_baudrate(usart);
         break;
     default:
         qemu_log_mask(
diff --git a/hw/char/trace-events b/hw/char/trace-events
index d20eafd56f..b92cecbfaa 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -100,3 +100,6 @@  exynos_uart_rx_timeout(uint32_t channel, uint32_t stat, uint32_t intsp) "UART%d:
 
 # hw/char/cadence_uart.c
 cadence_uart_baudrate(unsigned baudrate) "baudrate %u"
+
+# avr_usart.c
+avr_usart_update_baudrate(uint16_t regval, unsigned baudrate) "baudrate 0x%04x (%u bauds)"