cpu.c 2.5 KB
Newer Older
B
bigmagic 已提交
1
/*
mysterywolf's avatar
mysterywolf 已提交
2
 * Copyright (c) 2006-2021, RT-Thread Development Team
B
bigmagic 已提交
3 4 5 6 7 8 9
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2011-09-15     Bernard      first version
 * 2019-07-28     zdzn         add smp support
10
 * 2021-12-21     GuEe-GUI     set tpidr_el1 as multiprocessor id instead of mpidr_el1
G
GuEe-GUI 已提交
11
 * 2021-12-28     GuEe-GUI     add spinlock for aarch64
B
bigmagic 已提交
12 13 14 15
 */

#include <rthw.h>
#include <rtthread.h>
G
GuEe-GUI 已提交
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
#include <cpuport.h>

#ifdef RT_USING_SMP
/* The more common mpidr_el1 table, redefine it in BSP if it is in other cases */
RT_WEAK rt_uint64_t rt_cpu_mpidr_early[] =
{
    [0] = 0x80000000,
    [1] = 0x80000001,
    [2] = 0x80000002,
    [3] = 0x80000003,
    [4] = 0x80000004,
    [5] = 0x80000005,
    [6] = 0x80000006,
    [7] = 0x80000007,
    [RT_CPUS_NR] = 0
};
#endif
B
bigmagic 已提交
33 34 35 36 37

int rt_hw_cpu_id(void)
{
    rt_base_t value;

G
GuEe-GUI 已提交
38 39 40 41
    __asm__ volatile ("mrs %0, tpidr_el1":"=r"(value));

    return value;
}
B
bigmagic 已提交
42 43 44 45 46 47 48 49 50

#ifdef RT_USING_SMP
void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock)
{
    lock->slock = 0;
}

void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
{
G
GuEe-GUI 已提交
51 52
    rt_hw_spinlock_t lock_val, new_lockval;
    unsigned int tmp;
B
bigmagic 已提交
53

G
GuEe-GUI 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
    __asm__ volatile (
        /* Increment the next ticket. */
        "   prfm    pstl1strm, %3\n"
        "1: ldaxr   %w0, %3\n"
        "   add %w1, %w0, %w5\n"
        "   stxr    %w2, %w1, %3\n"
        "   cbnz    %w2, 1b\n"
        /* Check wether we get the lock */
        "   eor     %w1, %w0, %w0, ror #16\n"
        "   cbz     %w1, 3f\n"
        /*
         * Didn't get lock and spin on the owner.
         * Should send a local event to avoid missing an
         * unlock before the exclusive load.
         */
        "   sevl\n"
        "2: wfe\n"
        "   ldaxrh  %w2, %4\n"
        "   eor     %w1, %w2, %w0, lsr #16\n"
        "   cbnz    %w1, 2b\n"
        /* got the lock. */
        "3:"
        : "=&r" (lock_val), "=&r" (new_lockval), "=&r" (tmp), "+Q" (*lock)
        : "Q" (lock->tickets.owner), "I" (1 << 16)
        : "memory");
B
bigmagic 已提交
79 80 81 82 83 84
    __DMB();
}

void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
{
    __DMB();
G
GuEe-GUI 已提交
85 86 87 88 89
    __asm__ volatile (
        "stlrh   %w1, %0\n"
        : "=Q" (lock->tickets.owner)
        : "r" (lock->tickets.owner + 1)
        : "memory");
B
bigmagic 已提交
90 91 92 93 94 95 96 97 98
}
#endif /*RT_USING_SMP*/

/**
 * @addtogroup ARM CPU
 */
/*@{*/

/** shutdown CPU */
99
RT_WEAK void rt_hw_cpu_shutdown()
B
bigmagic 已提交
100
{
101
    register rt_int32_t level;
B
bigmagic 已提交
102 103 104 105 106 107 108 109 110 111
    rt_kprintf("shutdown...\n");

    level = rt_hw_interrupt_disable();
    while (level)
    {
        RT_ASSERT(0);
    }
}

/*@}*/