Anonymous Coward (1001664) has uploaded this change for review. ( https://review.coreboot.org/27351
Change subject: riscv: add spin lock support, modify the directory structure ......................................................................
riscv: add spin lock support, modify the directory structure
Add spin lock support for riscv. replicate directory layout from x86 for SMP.
Change-Id: Ia53b358be46efefe9dca0c8216693c73533c32d7 Signed-off-by: Xiang Wang wxjstz@126.com --- A src/arch/riscv/include/arch/smp/atomic.h A src/arch/riscv/include/arch/smp/smp.h A src/arch/riscv/include/arch/smp/spinlock.h D src/arch/riscv/include/atomic.h 4 files changed, 150 insertions(+), 67 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/51/27351/1
diff --git a/src/arch/riscv/include/arch/smp/atomic.h b/src/arch/riscv/include/arch/smp/atomic.h new file mode 100644 index 0000000..81999ac --- /dev/null +++ b/src/arch/riscv/include/arch/smp/atomic.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013, The Regents of the University of California (Regents). + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Regents nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef _RISCV_ATOMIC_H +#define _RISCV_ATOMIC_H + +#include <arch/encoding.h> + +#define disable_irqsave() clear_csr(mstatus, MSTATUS_MIE) +#define enable_irqrestore(flags) set_csr(mstatus, (flags) & MSTATUS_MIE) + +#define atomic_set(ptr, val) (*(volatile typeof(*(ptr)) *)(ptr) = val) +#define atomic_read(ptr) (*(volatile typeof(*(ptr)) *)(ptr)) + +#ifdef __riscv_atomic +# define atomic_or(ptr, inc) __sync_fetch_and_or(ptr, inc) +# define atomic_add(ptr, inc) __sync_fetch_and_add(ptr, inc) +# define atomic_swap(ptr, swp) __sync_lock_test_and_set(ptr, swp) +# define atomic_cas(ptr, cmp, swp) __sync_val_compare_and_swap(ptr, cmp, swp) +#else +# define atomic_or(ptr, inc) ({ \ +long flags = disable_irqsave(); \ +typeof(ptr) res = *(volatile typeof(ptr))(ptr); \ +*(volatile typeof(ptr))(ptr) = res | (inc); \ +enable_irqrestore(flags); \ +res; }) +# define atomic_add(ptr, inc) ({ \ +long flags = disable_irqsave(); \ +typeof(ptr) res = *(volatile typeof(ptr))(ptr); \ +*(volatile typeof(ptr))(ptr) = res + (inc); \ +enable_irqrestore(flags); \ +res; }) +# define atomic_swap(ptr, swp) ({ \ +long flags = disable_irqsave(); \ +typeof(*ptr) res = *(volatile typeof(ptr))(ptr); \ +*(volatile typeof(ptr))(ptr) = (swp); \ +enable_irqrestore(flags); \ +res; }) +# define atomic_cas(ptr, cmp, swp) ({ \ +long flags = disable_irqsave(); \ +typeof(ptr) res = *(volatile typeof(ptr))(ptr); \ +*(volatile typeof(ptr))(ptr) = (res == (cmp) ? swp : res); \ +enable_irqrestore(flags); \ +res; }) +#endif + +#endif diff --git a/src/arch/riscv/include/arch/smp/smp.h b/src/arch/riscv/include/arch/smp/smp.h new file mode 100644 index 0000000..4d227e2 --- /dev/null +++ b/src/arch/riscv/include/arch/smp/smp.h @@ -0,0 +1,43 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 HardenedLinux + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SMP_H +#define _SMP_H + +#include <arch/encoding.h> +#include <arch/smp/atomic.h> + +/* + * If your code needs to temporarily block multiple-threads, do this: + * if(RUNNING_ON_HART(active)) // `active` is hartid of working thread + * { + * ... single-threaded work ... + * } + * SMP_SYNC(); + * // `SMP_SYNC` is not required, if other hart not need to wait for + * // the single-threaded work to complete. + * ... multi-threaded work ... + */ + + +#define RUNNING_ON_HART(active) ((active) == read_csr(mhartid)) + +#define SMP_SYNC() do {\ +static int counter;\ +atomic_add(&counter, 1);\ +do { barrier(); } while (counter < CONFIG_HART_NUM);\ +} while (0) + +#endif //_SMP_H diff --git a/src/arch/riscv/include/arch/smp/spinlock.h b/src/arch/riscv/include/arch/smp/spinlock.h new file mode 100644 index 0000000..724e7a9 --- /dev/null +++ b/src/arch/riscv/include/arch/smp/spinlock.h @@ -0,0 +1,36 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 HardenedLinux + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + #include <arch/encoding.h> + #include <arch/smp/atomic.h> + +#define barrier() { asm volatile ("fence" ::: "memory"); } + +typedef struct { + volatile unsigned int lock; +} spinlock_t; + +static inline void spinlock_lock(spinlock_t *lock) +{ + do { + } while (atomic_cas(&lock->lock, 0, -1)); + barrier(); +} + +static inline void spinlock_unlock(spinlock_t *lock) +{ + barrier(); + atomic_set(&lock->lock, 0); +} diff --git a/src/arch/riscv/include/atomic.h b/src/arch/riscv/include/atomic.h deleted file mode 100644 index bc739fb..0000000 --- a/src/arch/riscv/include/atomic.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2013, The Regents of the University of California (Regents). - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Regents nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, - * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING - * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS - * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED - * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#ifndef _RISCV_ATOMIC_H -#define _RISCV_ATOMIC_H - -#include <arch/encoding.h> - -#define disable_irqsave() clear_csr(mstatus, MSTATUS_MIE) -#define enable_irqrestore(flags) set_csr(mstatus, (flags) & MSTATUS_MIE) - -typedef struct { int lock; } spinlock_t; -#define SPINLOCK_INIT {0} - -#define atomic_set(ptr, val) (*(volatile typeof(*(ptr)) *)(ptr) = val) -#define atomic_read(ptr) (*(volatile typeof(*(ptr)) *)(ptr)) - -#ifdef PK_ENABLE_ATOMICS -# define atomic_add(ptr, inc) __sync_fetch_and_add(ptr, inc) -# define atomic_swap(ptr, swp) __sync_lock_test_and_set(ptr, swp) -# define atomic_cas(ptr, cmp, swp) __sync_val_compare_and_swap(ptr, cmp, swp) -#else -# define atomic_add(ptr, inc) ({ \ - long flags = disable_irqsave(); \ - typeof(ptr) res = *(volatile typeof(ptr))(ptr); \ - *(volatile typeof(ptr))(ptr) = res + (inc); \ - enable_irqrestore(flags); \ - res; }) -# define atomic_swap(ptr, swp) ({ \ - long flags = disable_irqsave(); \ - typeof(*ptr) res = *(volatile typeof(ptr))(ptr); \ - *(volatile typeof(ptr))(ptr) = (swp); \ - enable_irqrestore(flags); \ - res; }) -# define atomic_cas(ptr, cmp, swp) ({ \ - long flags = disable_irqsave(); \ - typeof(ptr) res = *(volatile typeof(ptr))(ptr); \ - if (res == (cmp)) *(volatile typeof(ptr))(ptr) = (swp); \ - enable_irqrestore(flags); \ - res; }) -#endif - -#endif