Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/arch/arm/src/amebasmart, os/board/rtl8730e: Update critical zone API usage for SMP #6079

Merged
merged 3 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion os/arch/arm/src/amebasmart/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ ifeq ($(CONFIG_ARCH_FPU),y)
endif

ifeq ($(CONFIG_SMP),y)
CMN_CSRCS += arm_cpuindex.c arm_cpustart.c arm_cpupause.c arm_cpuidlestack.c arm_cpuflash.c
CMN_CSRCS += arm_cpuindex.c arm_cpustart.c arm_cpupause.c arm_cpuidlestack.c arm_cpugating.c
CMN_CSRCS += arm_scu.c
endif

Expand Down
12 changes: 6 additions & 6 deletions os/arch/arm/src/amebasmart/amebasmart_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ static inline int amebasmart_i2c_sem_waitdone(FAR struct amebasmart_i2c_priv_s *
irqstate_t flags;
int ret;

flags = irqsave();
flags = enter_critical_section();

/* Enable I2C interrupts */
up_enable_irq(priv->config->irq);
Expand Down Expand Up @@ -533,7 +533,7 @@ static inline int amebasmart_i2c_sem_waitdone(FAR struct amebasmart_i2c_priv_s *

up_disable_irq(priv->config->irq);

irqrestore(flags);
leave_critical_section(flags);
return ret;
}
#else
Expand Down Expand Up @@ -1156,14 +1156,14 @@ FAR struct i2c_dev_s *up_i2cinitialize(int port)
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
*/
flags = irqsave();
flags = enter_critical_section();

if ((volatile int)priv->refs++ == 0) {
amebasmart_i2c_sem_init(priv);
amebasmart_i2c_init(priv);
}

irqrestore(flags);
leave_critical_section(flags);

return (struct i2c_dev_s *)priv;
}
Expand All @@ -1189,14 +1189,14 @@ int up_i2cuninitialize(FAR struct i2c_dev_s *dev)
return ERROR;
}

flags = irqsave();
flags = enter_critical_section();

if (--priv->refs > 0) {
irqrestore(flags);
return OK;
}

irqrestore(flags);
leave_critical_section(flags);

/* Disable power and other HW resource (GPIO's) */

Expand Down
64 changes: 32 additions & 32 deletions os/arch/arm/src/amebasmart/amebasmart_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,14 +435,14 @@ static int i2s_tx_start(struct amebasmart_i2s_s *priv)
return OK;
}

flags = irqsave();
flags = enter_critical_section();

/* Remove the pending TX transfer at the head of the TX pending queue. */
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->tx.pend);

/* Start first transfer */
amebasmart_i2s_tx(priv, bfcontainer);
irqrestore(flags);
leave_critical_section(flags);

/* Start a watchdog to catch DMA timeouts */
if (bfcontainer->timeout > 0) {
Expand Down Expand Up @@ -488,9 +488,9 @@ static void i2s_tx_worker(void *arg)
* also modified from the interrupt level.
*/

flags = irqsave();
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->tx.done);
irqrestore(flags);
leave_critical_section(flags);
/* Perform the TX transfer done callback */

DEBUGASSERT(bfcontainer && bfcontainer->callback);
Expand Down Expand Up @@ -668,9 +668,9 @@ static int i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, i2s_callback
bfcontainer->apb = apb;
bfcontainer->result = -EBUSY;

flags = irqsave();
flags = enter_critical_section();
sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.pend);
irqrestore(flags);
leave_critical_section(flags);

ret = i2s_tx_start(priv);

Expand Down Expand Up @@ -788,7 +788,7 @@ static int i2s_rx_start(struct amebasmart_i2s_s *priv)
return OK;
}

flags = irqsave();
flags = enter_critical_section();
/* Remove the pending RX transfer at the head of the RX pending queue. */
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->rx.pend);

Expand All @@ -799,7 +799,7 @@ static int i2s_rx_start(struct amebasmart_i2s_s *priv)

i2s_recv_page(&priv->i2s_object);
}
irqrestore(flags);
leave_critical_section(flags);

/* Start a watchdog to catch DMA timeouts */
if (bfcontainer->timeout > 0) {
Expand Down Expand Up @@ -844,9 +844,9 @@ static void i2s_rx_worker(void *arg)
* interrupts must be disabled to do this because the rx.done queue is
* also modified from the interrupt level.
*/
flags = irqsave();
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->rx.done);
irqrestore(flags);
leave_critical_section(flags);

/* Perform the RX transfer done callback */
DEBUGASSERT(bfcontainer && bfcontainer->apb && bfcontainer->callback);
Expand Down Expand Up @@ -1027,9 +1027,9 @@ static int i2s_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, i2s_callb
/* Prepare DMA microcode */
i2s_rxdma_prep(priv, bfcontainer);

flags = irqsave();
flags = enter_critical_section();
sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.pend);
irqrestore(flags);
leave_critical_section(flags);
i2sinfo("i2s_rx_start\n");
/* Start transfer */
ret = i2s_rx_start(priv);
Expand Down Expand Up @@ -1121,13 +1121,13 @@ static struct amebasmart_buffer_s *i2s_buf_rx_allocate(struct amebasmart_i2s_s *
i2s_bufsem_rx_take(priv);

/* Get the buffer from the head of the free list */
flags = irqsave();
flags = enter_critical_section();
bfcontainer = priv->freelist_rx;
ASSERT(bfcontainer);

/* Unlink the buffer from the freelist */
priv->freelist_rx = bfcontainer->flink;
irqrestore(flags);
leave_critical_section(flags);

return bfcontainer;
}
Expand All @@ -1154,10 +1154,10 @@ static void i2s_buf_rx_free(struct amebasmart_i2s_s *priv, struct amebasmart_buf
irqstate_t flags;

/* Put the buffer container back on the free list */
flags = irqsave();
flags = enter_critical_section();
bfcontainer->flink = priv->freelist_rx;
priv->freelist_rx = bfcontainer;
irqrestore(flags);
leave_critical_section(flags);

/* Wake up any threads waiting for a buffer container */
i2s_bufsem_rx_give(priv);
Expand Down Expand Up @@ -1252,13 +1252,13 @@ static struct amebasmart_buffer_s *i2s_buf_tx_allocate(struct amebasmart_i2s_s *
i2s_bufsem_tx_take(priv);

/* Get the buffer from the head of the free list */
flags = irqsave();
flags = enter_critical_section();
bfcontainer = priv->freelist_tx;
ASSERT(bfcontainer);

/* Unlink the buffer from the freelist */
priv->freelist_tx = bfcontainer->flink;
irqrestore(flags);
leave_critical_section(flags);

return bfcontainer;
}
Expand All @@ -1285,10 +1285,10 @@ static void i2s_buf_tx_free(struct amebasmart_i2s_s *priv, struct amebasmart_buf
irqstate_t flags;

/* Put the buffer container back on the free list */
flags = irqsave();
flags = enter_critical_section();
bfcontainer->flink = priv->freelist_tx;
priv->freelist_tx = bfcontainer;
irqrestore(flags);
leave_critical_section(flags);

/* Wake up any threads waiting for a buffer container */
i2s_bufsem_tx_give(priv);
Expand Down Expand Up @@ -1469,25 +1469,25 @@ static int i2s_stop(struct i2s_dev_s *dev, i2s_ch_dir_t dir)
if (dir == I2S_TX) {
i2s_disable(&priv->i2s_object);
while (sq_peek(&priv->tx.pend) != NULL) {
flags = irqsave();
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->tx.pend);
irqrestore(flags);
leave_critical_section(flags);
apb_free(bfcontainer->apb);
i2s_buf_tx_free(priv, bfcontainer);
}

while (sq_peek(&priv->tx.act) != NULL) {
flags = irqsave();
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->tx.act);
irqrestore(flags);
leave_critical_section(flags);
apb_free(bfcontainer->apb);
i2s_buf_tx_free(priv, bfcontainer);
}

while (sq_peek(&priv->tx.done) != NULL) {
flags = irqsave();
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->tx.done);
irqrestore(flags);
leave_critical_section(flags);
i2s_buf_tx_free(priv, bfcontainer);
}
}
Expand All @@ -1497,25 +1497,25 @@ static int i2s_stop(struct i2s_dev_s *dev, i2s_ch_dir_t dir)
if (dir == I2S_RX) {
i2s_disable(&priv->i2s_object);
while (sq_peek(&priv->rx.pend) != NULL) {
flags = irqsave();
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->rx.pend);
irqrestore(flags);
leave_critical_section(flags);
apb_free(bfcontainer->apb);
i2s_buf_rx_free(priv, bfcontainer);
}

while (sq_peek(&priv->rx.act) != NULL) {
flags = irqsave();
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->rx.act);
irqrestore(flags);
leave_critical_section(flags);
apb_free(bfcontainer->apb);
i2s_buf_rx_free(priv, bfcontainer);
}

while (sq_peek(&priv->rx.done) != NULL) {
flags = irqsave();
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->rx.done);
irqrestore(flags);
leave_critical_section(flags);
i2s_buf_rx_free(priv, bfcontainer);
}
}
Expand Down
41 changes: 30 additions & 11 deletions os/arch/arm/src/amebasmart/amebasmart_smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#endif

#ifdef CONFIG_PLATFORM_TIZENRT_OS
#ifdef CONFIG_CPU_GATING
extern volatile uint32_t ulFlashPG_Flag;
#endif
extern void __cpu1_start(void);
#else
extern void _boot(void);
Expand Down Expand Up @@ -71,31 +73,48 @@ void rtk_core1_power_off(void)
HAL_WRITE32(SYSTEM_CTRL_BASE_HP, REG_HSYS_HP_PWC, val);
}

void vPortGateOtherCore(void)
bool vPortGateOtherCore(void)
{
#if ( defined(CONFIG_SMP) && CONFIG_SMP_NCPUS > 1 )
ulFlashPG_Flag = 1;
ARM_DSB();
ARM_ISB();

BaseType_t ulCoreID = up_cpu_index();
ulCoreID = (ulCoreID + 1) % CONFIG_SMP_NCPUS;
CA32_TypeDef *ca32 = CA32_BASE;
/* ulFlashPG_Flag should be checked here, it should only exists under 3 states:
0: No flash operation / Just completed a flash operation
1: A gating request has been sent out to another core, further checking shall be done at the while condition below
2: The target core is already in gating state, proceed for flash operation
*/
if (!ulFlashPG_Flag) {
ulFlashPG_Flag = 1;
ARM_DSB();

#ifndef CONFIG_PLATFORM_TIZENRT_OS
arm_gic_raise_softirq(ulCoreID, IPI_FLASHPG_IRQ);
arm_gic_raise_softirq(ulCoreID, IPI_FLASHPG_IRQ);
#else
arm_cpu_sgi(GIC_IRQ_SGI3, (1 << ulCoreID));
arm_cpu_sgi(GIC_IRQ_SGI3, (1 << ulCoreID));
#endif

CA32_TypeDef *ca32 = CA32_BASE;
while (CA32_GET_STANDBYWFE(ca32->CA32_C0_CPU_STATUS) != BIT(ulCoreID));
}
/* We already initiated a gating request previously, skip sending duplicated request */
/* Before gating the other CPU, we have to check for pending pause request, as the target core
* might have entered spinlock to wait for current core to pause itself. And currently
* we are in a interrupt disabled status here, thus we should exit and handle
* pause request first, before we proceed to gate another cpu for executing
* flash operation
*/
while ((ulFlashPG_Flag == 1) || CA32_GET_STANDBYWFE(ca32->CA32_C0_CPU_STATUS) != BIT(ulCoreID)) {
/* If there is a pause request, we should handle it first */
if (up_cpu_pausereq(up_cpu_index())) {
return false;
}
}
return true;
#endif
}

void vPortWakeOtherCore(void)
{
ulFlashPG_Flag = 0;
ARM_DSB();
ARM_ISB();
__asm__ __volatile__ ("sev" : : : "memory");
}

Expand Down
8 changes: 4 additions & 4 deletions os/arch/arm/src/amebasmart/amebasmart_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1390,7 +1390,7 @@ FAR struct spi_dev_s *amebasmart_spibus_initialize(int bus)
{
FAR struct amebasmart_spidev_s *priv = NULL;

irqstate_t flags = irqsave();
irqstate_t flags = enter_critical_section();

if (bus == 0) {
/* Select SPI0 */
Expand Down Expand Up @@ -1424,7 +1424,7 @@ FAR struct spi_dev_s *amebasmart_spibus_initialize(int bus)
return NULL;
}

irqrestore(flags);
leave_critical_section(flags);

return (FAR struct spi_dev_s *)priv;
}
Expand Down Expand Up @@ -1605,7 +1605,7 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
{
FAR struct amebasmart_spidev_s *priv = NULL;

irqstate_t flags = irqsave();
irqstate_t flags = enter_critical_section();

if (port == 0) {
/* Select SPI0 */
Expand Down Expand Up @@ -1638,7 +1638,7 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
return NULL;
}

irqrestore(flags);
leave_critical_section(flags);

return (FAR struct spi_dev_s *)priv;
}
Expand Down
4 changes: 2 additions & 2 deletions os/arch/arm/src/amebasmart/amebasmart_timer_lowerhalf.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ static void amebasmart_gpt_setcallback(struct timer_lowerhalf_s *lower, tccb_t c
struct amebasmart_gpt_lowerhalf_s *priv = (struct amebasmart_gpt_lowerhalf_s *)lower;
DEBUGASSERT(priv);
if (priv) {
irqstate_t flags = irqsave();
irqstate_t flags = enter_critical_section();

/* Save the new callback */
priv->callback = callback;
Expand All @@ -363,7 +363,7 @@ static void amebasmart_gpt_setcallback(struct timer_lowerhalf_s *lower, tccb_t c
priv->obj.hid = 0;
}

irqrestore(flags);
leave_critical_section(flags);
}
}

Expand Down
Loading