@@ -106,6 +106,16 @@ REG32(TIMEOUT_CTRL, 0x30u)
106106 INTR_RX_OVERFLOW_MASK | INTR_RX_FRAME_ERR_MASK | INTR_RX_BREAK_ERR_MASK | \
107107 INTR_RX_TIMEOUT_MASK | INTR_RX_PARITY_ERR_MASK | INTR_TX_EMPTY_MASK)
108108
109+ /*
110+ * Status-type interrupts (tx_watermark, rx_watermark, tx_empty per uart.hjson).
111+ * Unlike event-type interrupts, their INTR_STATE bits are read-only (ro): the
112+ * hardware drives them from the live FIFO condition every cycle rather than
113+ * latching, so INTR_STATE writes do not affect them and they de-assert
114+ * automatically once the condition clears (prim_intr_hw.sv, IntrT="Status").
115+ */
116+ #define INTR_STATUS_MASK \
117+ (INTR_TX_WATERMARK_MASK | INTR_RX_WATERMARK_MASK | INTR_TX_EMPTY_MASK)
118+
109119#define CTRL_MASK \
110120 (R_CTRL_TX_MASK | R_CTRL_RX_MASK | R_CTRL_NF_MASK | R_CTRL_SLPBK_MASK | \
111121 R_CTRL_LLPBK_MASK | R_CTRL_PARITY_EN_MASK | R_CTRL_PARITY_ODD_MASK | \
@@ -114,9 +124,10 @@ REG32(TIMEOUT_CTRL, 0x30u)
114124#define CTRL_SUP_MASK \
115125 (R_CTRL_RX_MASK | R_CTRL_TX_MASK | R_CTRL_SLPBK_MASK | R_CTRL_NCO_MASK)
116126
127+ /* FIFO depths match uart_reg_pkg.sv (TxFifoDepth=32, RxFifoDepth=64). */
117128#define OT_UART_NCO_BITS 16u
118- #define OT_UART_TX_FIFO_SIZE 128u
119- #define OT_UART_RX_FIFO_SIZE 128u
129+ #define OT_UART_TX_FIFO_SIZE 32u
130+ #define OT_UART_RX_FIFO_SIZE 64u
120131#define OT_UART_IRQ_NUM 9u
121132
122133#define R32_OFF (_r_ ) ((_r_) / sizeof(uint32_t))
@@ -157,7 +168,6 @@ struct OtUARTState {
157168
158169 Fifo8 tx_fifo ;
159170 Fifo8 rx_fifo ;
160- uint32_t tx_watermark_level ;
161171 bool in_break ;
162172 guint watch_tag ;
163173 unsigned pclk ; /* Current input clock */
@@ -181,23 +191,81 @@ static uint32_t ot_uart_get_tx_watermark_level(const OtUARTState *s)
181191 uint32_t tx_ilvl = (s -> regs [R_FIFO_CTRL ] & R_FIFO_CTRL_TXILVL_MASK ) >>
182192 R_FIFO_CTRL_TXILVL_SHIFT ;
183193
184- return tx_ilvl < 7u ? (1u << tx_ilvl ) : 64u ;
194+ /*
195+ * Power-of-two thresholds, matching uart_core.sv. TxFifoDepthW == 6 for a
196+ * 32-entry FIFO, so the threshold saturates at half the FIFO depth (16)
197+ * once txilvl >= TxFifoDepthW - 2 == 4.
198+ */
199+ if (tx_ilvl >= 4u ) {
200+ return OT_UART_TX_FIFO_SIZE / 2u ;
201+ }
202+ return 1u << tx_ilvl ;
185203}
186204
187205static uint32_t ot_uart_get_rx_watermark_level (const OtUARTState * s )
188206{
189207 uint32_t rx_ilvl = (s -> regs [R_FIFO_CTRL ] & R_FIFO_CTRL_RXILVL_MASK ) >>
190208 R_FIFO_CTRL_RXILVL_SHIFT ;
191209
192- return rx_ilvl < 7u ? (1u << rx_ilvl ) : 126u ;
210+ /*
211+ * Power-of-two thresholds, matching uart_core.sv. RxFifoDepthW == 7 for a
212+ * 64-entry FIFO: rxilvl 6 saturates at RxFifoDepth - 2 (62), and rxilvl 7
213+ * selects a threshold the FIFO can never reach (2*RxFifoDepth - 1), which
214+ * disables the interrupt.
215+ */
216+ if (rx_ilvl > 6u ) {
217+ return OT_UART_RX_FIFO_SIZE * 2u - 1u ;
218+ }
219+ if (rx_ilvl == 6u ) {
220+ return OT_UART_RX_FIFO_SIZE - 2u ;
221+ }
222+ return 1u << rx_ilvl ;
223+ }
224+
225+ /*
226+ * Compute the live values of the status-type interrupt conditions from the
227+ * current FIFO state. These bits are not stored in regs[R_INTR_STATE]; they are
228+ * recomputed on every INTR_STATE read and IRQ update so that the interrupt
229+ * tracks the hardware condition (matching prim_intr_hw IntrT="Status").
230+ */
231+ static uint32_t ot_uart_status_intr_bits (OtUARTState * s )
232+ {
233+ uint32_t bits = 0 ;
234+
235+ /* rx_watermark: asserted while RX FIFO fill level >= threshold. */
236+ if ((uint32_t )fifo8_num_used (& s -> rx_fifo ) >=
237+ ot_uart_get_rx_watermark_level (s )) {
238+ bits |= INTR_RX_WATERMARK_MASK ;
239+ }
240+ /* tx_watermark: asserted while TX FIFO has drained below the threshold. */
241+ if ((uint32_t )fifo8_num_used (& s -> tx_fifo ) <
242+ ot_uart_get_tx_watermark_level (s )) {
243+ bits |= INTR_TX_WATERMARK_MASK ;
244+ }
245+ /* tx_empty: asserted while the TX FIFO is empty. */
246+ if (fifo8_is_empty (& s -> tx_fifo )) {
247+ bits |= INTR_TX_EMPTY_MASK ;
248+ }
249+
250+ return bits ;
251+ }
252+
253+ /*
254+ * The architectural INTR_STATE value: latched event-type bits (held in
255+ * regs[R_INTR_STATE]) combined with the live status-type bits.
256+ */
257+ static uint32_t ot_uart_intr_state (OtUARTState * s )
258+ {
259+ return (s -> regs [R_INTR_STATE ] & ~INTR_STATUS_MASK ) |
260+ ot_uart_status_intr_bits (s );
193261}
194262
195263static void ot_uart_update_irqs (OtUARTState * s )
196264{
197- uint32_t state_masked = s -> regs [R_INTR_STATE ] & s -> regs [R_INTR_ENABLE ];
265+ uint32_t state = ot_uart_intr_state (s );
266+ uint32_t state_masked = state & s -> regs [R_INTR_ENABLE ];
198267
199- trace_ot_uart_irqs (s -> ot_id , s -> regs [R_INTR_STATE ], s -> regs [R_INTR_ENABLE ],
200- state_masked );
268+ trace_ot_uart_irqs (s -> ot_id , state , s -> regs [R_INTR_ENABLE ], state_masked );
201269
202270 for (int index = 0 ; index < OT_UART_IRQ_NUM ; index ++ ) {
203271 bool level = (state_masked & (1U << index )) != 0 ;
@@ -256,27 +324,23 @@ static int ot_uart_can_receive(void *opaque)
256324static void ot_uart_receive (void * opaque , const uint8_t * buf , int size )
257325{
258326 OtUARTState * s = opaque ;
259- uint32_t rx_watermark_level ;
260327 size_t count = MIN (fifo8_num_free (& s -> rx_fifo ), (size_t )size );
261328
262329 if (size && !s -> toggle_break ) {
263330 /* no longer breaking, so emulate idle in oversampled VAL register */
264331 s -> in_break = false;
265332 }
266333
267- for (int index = 0 ; index < size ; index ++ ) {
334+ for (size_t index = 0 ; index < count ; index ++ ) {
268335 fifo8_push (& s -> rx_fifo , buf [index ]);
269336 }
270337
271- /* update INTR_STATE */
272- if (count != size ) {
338+ /* rx_overflow is event-type: latch it if the FIFO could not absorb all. */
339+ if (count != ( size_t ) size ) {
273340 s -> regs [R_INTR_STATE ] |= INTR_RX_OVERFLOW_MASK ;
274341 }
275- rx_watermark_level = ot_uart_get_rx_watermark_level (s );
276- if (rx_watermark_level && size >= rx_watermark_level ) {
277- s -> regs [R_INTR_STATE ] |= INTR_RX_WATERMARK_MASK ;
278- }
279342
343+ /* rx_watermark is status-type: computed live in ot_uart_update_irqs(). */
280344 ot_uart_update_irqs (s );
281345}
282346
@@ -312,6 +376,12 @@ static uint8_t ot_uart_read_rx_fifo(OtUARTState *s)
312376
313377 val = fifo8_pop (& s -> rx_fifo );
314378
379+ /*
380+ * rx_watermark is status-type: draining the FIFO may drop it below the
381+ * threshold, which must de-assert the interrupt line immediately.
382+ */
383+ ot_uart_update_irqs (s );
384+
315385 if (ot_uart_is_rx_enabled (s ) && !ot_uart_is_sys_loopack_enabled (s )) {
316386 qemu_chr_fe_accept_input (& s -> chr );
317387 }
@@ -322,12 +392,11 @@ static uint8_t ot_uart_read_rx_fifo(OtUARTState *s)
322392static void ot_uart_reset_tx_fifo (OtUARTState * s )
323393{
324394 fifo8_reset (& s -> tx_fifo );
325- s -> regs [R_INTR_STATE ] |= INTR_TX_EMPTY_MASK ;
395+ /*
396+ * tx_done is event-type and latched here; tx_empty and tx_watermark are
397+ * status-type and follow the (now empty) FIFO live via ot_uart_update_irqs.
398+ */
326399 s -> regs [R_INTR_STATE ] |= INTR_TX_DONE_MASK ;
327- if (s -> tx_watermark_level ) {
328- s -> regs [R_INTR_STATE ] |= INTR_TX_WATERMARK_MASK ;
329- s -> tx_watermark_level = 0 ;
330- }
331400}
332401
333402static void ot_uart_xmit (OtUARTState * s )
@@ -373,16 +442,11 @@ static void ot_uart_xmit(OtUARTState *s)
373442 }
374443 }
375444
376- /* update INTR_STATE */
445+ /* update INTR_STATE: tx_done is event-type and latched on drain.
446+ * tx_empty/tx_watermark are status-type and tracked live in update_irqs. */
377447 if (fifo8_is_empty (& s -> tx_fifo )) {
378- s -> regs [R_INTR_STATE ] |= INTR_TX_EMPTY_MASK ;
379448 s -> regs [R_INTR_STATE ] |= INTR_TX_DONE_MASK ;
380449 }
381- if (s -> tx_watermark_level &&
382- fifo8_num_used (& s -> tx_fifo ) < s -> tx_watermark_level ) {
383- s -> regs [R_INTR_STATE ] |= INTR_TX_WATERMARK_MASK ;
384- s -> tx_watermark_level = 0 ;
385- }
386450
387451 ot_uart_update_irqs (s );
388452}
@@ -409,18 +473,11 @@ static void uart_write_tx_fifo(OtUARTState *s, uint8_t val)
409473
410474 fifo8_push (& s -> tx_fifo , val );
411475
412- s -> tx_watermark_level = ot_uart_get_tx_watermark_level (s );
413- if (fifo8_num_used (& s -> tx_fifo ) < s -> tx_watermark_level ) {
414- /*
415- * TX watermark interrupt is raised when FIFO depth goes from above
416- * watermark to below. If we haven't reached watermark, reset cached
417- * watermark level
418- */
419- s -> tx_watermark_level = 0 ;
420- }
421-
422476 if (ot_uart_is_tx_enabled (s )) {
423477 ot_uart_xmit (s );
478+ } else {
479+ /* tx_watermark/tx_empty are status-type: refresh from the new level. */
480+ ot_uart_update_irqs (s );
424481 }
425482}
426483
@@ -445,6 +502,9 @@ static uint64_t ot_uart_read(void *opaque, hwaddr addr, unsigned size)
445502 hwaddr reg = R32_OFF (addr );
446503 switch (reg ) {
447504 case R_INTR_STATE :
505+ /* Status-type bits reflect the live FIFO condition, not a latch. */
506+ val32 = ot_uart_intr_state (s );
507+ break ;
448508 case R_INTR_ENABLE :
449509 case R_CTRL :
450510 case R_FIFO_CTRL :
@@ -553,8 +613,14 @@ static void ot_uart_write(void *opaque, hwaddr addr, uint64_t val64,
553613
554614 switch (reg ) {
555615 case R_INTR_STATE :
556- val32 &= INTR_MASK ;
557- s -> regs [R_INTR_STATE ] &= ~val32 ; /* RW1C */
616+ /*
617+ * Only the event-type bits are RW1C; the status-type bits are ro and
618+ * are never stored in regs[R_INTR_STATE] (they are recomputed live), so
619+ * mask them out here and leave regs[R_INTR_STATE] holding event bits
620+ * only.
621+ */
622+ val32 &= INTR_MASK & ~INTR_STATUS_MASK ;
623+ s -> regs [R_INTR_STATE ] &= ~val32 ; /* RW1C (event-type bits only) */
558624 ot_uart_update_irqs (s );
559625 break ;
560626 case R_INTR_ENABLE :
@@ -601,12 +667,15 @@ static void ot_uart_write(void *opaque, hwaddr addr, uint64_t val64,
601667 val32 & (R_FIFO_CTRL_RXILVL_MASK | R_FIFO_CTRL_TXILVL_MASK );
602668 if (val32 & R_FIFO_CTRL_RXRST_MASK ) {
603669 ot_uart_reset_rx_fifo (s );
604- ot_uart_update_irqs (s );
605670 }
606671 if (val32 & R_FIFO_CTRL_TXRST_MASK ) {
607672 ot_uart_reset_tx_fifo (s );
608- ot_uart_update_irqs (s );
609673 }
674+ /*
675+ * Changing RXILVL/TXILVL moves the status-type watermark thresholds, so
676+ * re-evaluate the interrupt lines unconditionally.
677+ */
678+ ot_uart_update_irqs (s );
610679 break ;
611680 case R_OVRD :
612681 if (val32 & R_OVRD_TXEN_MASK ) {
@@ -680,7 +749,6 @@ static void ot_uart_reset_enter(Object *obj, ResetType type)
680749
681750 memset (& s -> regs [0 ], 0 , sizeof (s -> regs ));
682751
683- s -> tx_watermark_level = 0 ;
684752 for (unsigned index = 0 ; index < ARRAY_SIZE (s -> irqs ); index ++ ) {
685753 ibex_irq_set (& s -> irqs [index ], 0 );
686754 }
0 commit comments