From c6dc2d83c96505b22bfd6ee0a4d1738b292fd19a Mon Sep 17 00:00:00 2001 From: MacRsh Date: Sun, 11 May 2025 23:55:58 +0800 Subject: [PATCH] fix(string): Fix the logical errors of the "mr_ffs32" and "mr_ffs64" series interfaces. 1.Fix the incorrect result caused by the fls numerical conversion error. 2.Remove the ack mechanism in irq. --- include/kernel/mr_irq.h | 1 - include/libc/mr_string.h | 22 ++++++++++++++++++++-- kernel/irq.c | 12 ++---------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/include/kernel/mr_irq.h b/include/kernel/mr_irq.h index 76fb9d0..af468a1 100644 --- a/include/kernel/mr_irq.h +++ b/include/kernel/mr_irq.h @@ -47,7 +47,6 @@ typedef struct mr_irq_ops { void (*unmask)(mr_uint32_t irq, void *args); void (*disable)(mr_uint32_t irq, void *args); void (*mask)(mr_uint32_t irq, void *args); - void (*ack)(mr_uint32_t irq, void *args); } mr_irq_ops_t; /* Irq type */ diff --git a/include/libc/mr_string.h b/include/libc/mr_string.h index 7c74590..9df2b54 100644 --- a/include/libc/mr_string.h +++ b/include/libc/mr_string.h @@ -199,7 +199,16 @@ MR_INLINE int mr_ffs64(mr_uint64_t x) { * @return The index of the last set bit. */ MR_INLINE int mr_fls32(mr_uint32_t x) { - return mr_ffs32(x & (-x)); + /* Higher order bits */ + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x -= x >> 1; + + /* Find last set bit */ + return mr_ffs32(x); } /** @@ -209,7 +218,16 @@ MR_INLINE int mr_fls32(mr_uint32_t x) { * @return The index of the last set bit. */ MR_INLINE int mr_fls64(mr_uint64_t x) { - return mr_ffs64(x & (-x)); + /* Higher order bits */ + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + x -= x >> 1; + + return mr_ffs64(x); } /** @} */ diff --git a/kernel/irq.c b/kernel/irq.c index c45fe7c..1a98994 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -631,12 +631,8 @@ mr_irq_return_t mr_irq_handle(mr_uint32_t irq) { /* Get irq run-time */ mr_irq_get(desc->irq); - /* Shield irq mask */ + /* Mask irq */ desc->irq->ops->mask(irq, desc->irq->args); - if (desc->flags & MR_IRQ_EDGE_BOTH) { - /* First ack if irq mode is edge */ - desc->irq->ops->ack(irq, desc->irq->args); - } /* Handle irq action */ for (action = desc->action; action; action = action->next) { @@ -700,12 +696,8 @@ mr_irq_return_t mr_irq_handle(mr_uint32_t irq) { } } - /* Unmask irq mask */ + /* Unmask irq if irq action is enabled */ if (mr_atomic_load(&desc->depth) == 0) { - if (desc->flags & (MR_IRQ_LEVEL_HIGH | MR_IRQ_LEVEL_LOW)) { - /* Then ack if irq mode is level */ - desc->irq->ops->ack(irq, desc->irq->args); - } desc->irq->ops->unmask(irq, desc->irq->args); }