• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <stdint.h>
18 #include <stdbool.h>
19 #include "soc/cpu.h"
20 #include "soc/soc_memory_layout.h"
21 
22 #if __XTENSA__
23 #include "xtensa/xtruntime.h"
24 #endif
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
compare_and_set_native(volatile uint32_t * addr,uint32_t compare,uint32_t * set)30 static inline void __attribute__((always_inline)) compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
31 {
32 #if (XCHAL_HAVE_S32C1I > 0)
33     __asm__ __volatile__ (
34         "WSR 	    %2,SCOMPARE1 \n"
35         "S32C1I     %0, %1, 0	 \n"
36         :"=r"(*set)
37         :"r"(addr), "r"(compare), "0"(*set)
38     );
39 #else
40     uint32_t old_value;
41 
42 #ifdef __XTENSA__
43     // No S32C1I, so do this by disabling and re-enabling interrupts (slower)
44     uint32_t intlevel;
45     __asm__ __volatile__ ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) "\n"
46                           : "=r"(intlevel));
47 #else
48     unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
49 #endif
50 
51     old_value = *addr;
52     if (old_value == compare) {
53         *addr = *set;
54     }
55 
56 #ifdef __XTENSA__
57     __asm__ __volatile__ ("memw \n"
58                           "wsr %0, ps\n"
59                           :: "r"(intlevel));
60 
61 #else
62     RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
63 #endif
64 
65     *set = old_value;
66 #endif
67 }
68 
69 
70 void compare_and_set_extram(volatile uint32_t *addr, uint32_t compare, uint32_t *set);
71 
72 #ifdef __cplusplus
73 }
74 #endif
75