/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2011-09-15 Bernard first version * 2018-11-22 Jesven add rt_hw_cpu_id() */ #include #include #include #ifdef RT_USING_SMP int rt_hw_cpu_id(void) { int cpu_id; __asm__ volatile ( "mrc p15, 0, %0, c0, c0, 5" :"=r"(cpu_id) ); cpu_id &= 0xf; return cpu_id; }; void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock) { lock->slock = 0; } void rt_hw_spin_lock(rt_hw_spinlock_t *lock) { unsigned long tmp; unsigned long newval; rt_hw_spinlock_t lockval; __asm__ __volatile__( "pld [%0]" ::"r"(&lock->slock) ); __asm__ __volatile__( "1: ldrex %0, [%3]\n" " add %1, %0, %4\n" " strex %2, %1, [%3]\n" " teq %2, #0\n" " bne 1b" : "=&r" (lockval), "=&r" (newval), "=&r" (tmp) : "r" (&lock->slock), "I" (1 << 16) : "cc"); while (lockval.tickets.next != lockval.tickets.owner) { __asm__ __volatile__("wfe":::"memory"); lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner); } __asm__ volatile ("dmb":::"memory"); } void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) { __asm__ volatile ("dmb":::"memory"); lock->tickets.owner++; __asm__ volatile ("dsb ishst\nsev":::"memory"); } #endif /*RT_USING_SMP*/ /** * @addtogroup ARM CPU */ /*@{*/ /** shutdown CPU */ RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); level = rt_hw_interrupt_disable(); while (level) { RT_ASSERT(0); } } /*@}*/