| ////////////////////////////////////////////////////////////////////////////// |
| // SPDX-FileCopyrightText: 2021, Dinesh Annayya //// |
| // //// |
| // Licensed under the Apache License, Version 2.0 (the "License"); //// |
| // you may not use this file except in compliance with the License. //// |
| // You may obtain a copy of the License at //// |
| // //// |
| // http://www.apache.org/licenses/LICENSE-2.0 //// |
| // //// |
| // Unless required by applicable law or agreed to in writing, software //// |
| // distributed under the License is distributed on an "AS IS" BASIS, //// |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied./// |
| // See the License for the specific language governing permissions and //// |
| // limitations under the License. //// |
| // SPDX-License-Identifier: Apache-2.0 //// |
| // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org> //// |
| ////////////////////////////////////////////////////////////////////////////// |
| /// Architecture specific CSR's defs and inlines |
| |
| #ifndef YCR_CSR_H |
| #define YCR_CSR_H |
| |
| #include <stdint.h> |
| #include <stdbool.h> |
| |
| #define __xstringify(s) __stringify(s) |
| #define __stringify(s) #s |
| |
| #ifdef read_csr |
| #undef read_csr |
| #endif |
| |
| #ifdef write_csr |
| #undef write_csr |
| #endif |
| |
| #ifdef swap_csr |
| #undef swap_csr |
| #endif |
| |
| #ifdef set_csr |
| #undef set_csr |
| #endif |
| |
| #ifdef clear_csr |
| #undef clear_csr |
| #endif |
| |
| #ifdef rdtime |
| #undef rdtime |
| #endif |
| |
| #ifdef rdcycle |
| #undef rdcycle |
| #endif |
| |
| #ifdef rdinstret |
| #undef rdinstret |
| #endif |
| |
| #define read_csr(reg) \ |
| ({ \ |
| unsigned long __tmp; \ |
| asm volatile ("csrr %0, " __xstringify(reg) : "=r"(__tmp)); \ |
| __tmp; \ |
| }) |
| |
| #define write_csr(reg, val) \ |
| do { \ |
| if (__builtin_constant_p(val) && (val) == 0) \ |
| asm volatile ("csrw " __xstringify(reg) ", zero" ::); \ |
| else if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ |
| asm volatile ("csrw " __xstringify(reg) ", %0" :: "i"(val)); \ |
| else \ |
| asm volatile ("csrw " __xstringify(reg) ", %0" :: "r"(val)); \ |
| } while (0) |
| |
| #define swap_csr(reg, val) \ |
| ({ \ |
| unsigned long __tmp; \ |
| if (__builtin_constant_p(val) && (val) == 0) \ |
| asm volatile ("csrrw %0, " __xstringify(reg) ", zero" : "=r"(__tmp) :); \ |
| else if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ |
| asm volatile ("csrrw %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(val)); \ |
| else \ |
| asm volatile ("csrrw %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(val)); \ |
| __tmp; \ |
| }) |
| |
| #define set_csr(reg, bit) \ |
| ({ \ |
| unsigned long __tmp; \ |
| if (__builtin_constant_p(bit) && (bit) < 32) \ |
| asm volatile ("csrrs %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(bit)); \ |
| else \ |
| asm volatile ("csrrs %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(bit)); \ |
| __tmp; \ |
| }) |
| |
| #define clear_csr(reg, bit) \ |
| ({ \ |
| unsigned long __tmp; \ |
| if (__builtin_constant_p(bit) && (bit) < 32) \ |
| asm volatile ("csrrc %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(bit)); \ |
| else \ |
| asm volatile ("csrrc %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(bit)); \ |
| __tmp; \ |
| }) |
| |
| #define rdtime() read_csr(time) |
| #define rdcycle() read_csr(cycle) |
| #define rdinstret() read_csr(instret) |
| |
| static inline unsigned long __attribute__((const)) cpuid() |
| { |
| unsigned long res; |
| asm ("csrr %0, mcpuid" : "=r"(res)); |
| return res; |
| } |
| |
| static inline unsigned long __attribute__((const)) impid() |
| { |
| unsigned long res; |
| asm ("csrr %0, mimpid" : "=r"(res)); |
| return res; |
| } |
| |
| #endif // YCR_CSR_H |