1 /*
2  * Copyright (c) 2021 Sun Amar
3  * Copyright (c) 2021 Yonatan Schachter
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <em_system.h>
9 #include <em_rmu.h>
10 #include <zephyr/drivers/hwinfo.h>
11 #include <string.h>
12 #include <zephyr/sys/byteorder.h>
13 
14 #if defined(RMU_RSTCAUSE_BODUNREGRST) || defined(RMU_RSTCAUSE_BODREGRST) || \
15     defined(RMU_RSTCAUSE_AVDDBOD) || defined(RMU_RSTCAUSE_DVDDBOD) || \
16     defined(RMU_RSTCAUSE_DECBOD) || defined(RMU_RSTCAUSE_BODAVDD0) || \
17     defined(RMU_RSTCAUSE_BODAVDD1) || \
18     (defined(BU_PRESENT) && defined(_SILICON_LABS_32B_SERIES_0))
19 #define HAS_BROWNOUT 1
20 #endif
21 
z_impl_hwinfo_get_device_id(uint8_t * buffer,size_t length)22 ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length)
23 {
24 	uint64_t unique_id = sys_cpu_to_be64(SYSTEM_GetUnique());
25 
26 	if (length > sizeof(unique_id)) {
27 		length = sizeof(unique_id);
28 	}
29 
30 	memcpy(buffer, &unique_id, length);
31 
32 	return length;
33 }
34 
z_impl_hwinfo_get_reset_cause(uint32_t * cause)35 int z_impl_hwinfo_get_reset_cause(uint32_t *cause)
36 {
37 	uint32_t flags = 0;
38 	uint32_t __maybe_unused rmu_flags = RMU_ResetCauseGet();
39 
40 #ifdef RMU_RSTCAUSE_PORST
41 	if (rmu_flags & RMU_RSTCAUSE_PORST) {
42 		flags |= RESET_POR;
43 	}
44 #endif /* RMU_RSTCAUSE_PORST */
45 
46 #ifdef RMU_RSTCAUSE_EXTRST
47 	if (rmu_flags & RMU_RSTCAUSE_EXTRST) {
48 		flags |= RESET_PIN;
49 	}
50 #endif /* RMU_RSTCAUSE_EXTRST */
51 
52 #ifdef RMU_RSTCAUSE_SYSREQRST
53 	if (rmu_flags & RMU_RSTCAUSE_SYSREQRST) {
54 		flags |= RESET_SOFTWARE;
55 	}
56 #endif /* RMU_RSTCAUSE_SYSREQRST */
57 
58 #ifdef RMU_RSTCAUSE_LOCKUPRST
59 	if (rmu_flags & RMU_RSTCAUSE_LOCKUPRST) {
60 		flags |= RESET_CPU_LOCKUP;
61 	}
62 #endif /* RMU_RSTCAUSE_LOCKUPRST */
63 
64 #ifdef RMU_RSTCAUSE_WDOGRST
65 	if (rmu_flags & RMU_RSTCAUSE_WDOGRST) {
66 		flags |= RESET_WATCHDOG;
67 	}
68 #endif /* RMU_RSTCAUSE_WDOGRST */
69 
70 #ifdef RMU_RSTCAUSE_EM4WURST
71 	if (rmu_flags & RMU_RSTCAUSE_EM4WURST) {
72 		flags |= RESET_LOW_POWER_WAKE;
73 	}
74 #endif /* RMU_RSTCAUSE_EM4WURST */
75 
76 #ifdef RMU_RSTCAUSE_EM4RST
77 	if (rmu_flags & RMU_RSTCAUSE_EM4RST) {
78 		flags |= RESET_LOW_POWER_WAKE;
79 	}
80 #endif /* RMU_RSTCAUSE_EM4RST */
81 
82 #ifdef RMU_RSTCAUSE_BODUNREGRST
83 	if (rmu_flags & RMU_RSTCAUSE_BODUNREGRST) {
84 		flags |= RESET_BROWNOUT;
85 	}
86 #endif /* RMU_RSTCAUSE_BODUNREGRST */
87 
88 #ifdef RMU_RSTCAUSE_BODREGRST
89 	if (rmu_flags & RMU_RSTCAUSE_BODREGRST) {
90 		flags |= RESET_BROWNOUT;
91 	}
92 #endif /* RMU_RSTCAUSE_BODREGRST */
93 
94 #ifdef RMU_RSTCAUSE_AVDDBOD
95 	if (rmu_flags & RMU_RSTCAUSE_AVDDBOD) {
96 		flags |= RESET_BROWNOUT;
97 	}
98 #endif /* RMU_RSTCAUSE_AVDDBOD */
99 
100 #ifdef RMU_RSTCAUSE_DVDDBOD
101 	if (rmu_flags & RMU_RSTCAUSE_DVDDBOD) {
102 		flags |= RESET_BROWNOUT;
103 	}
104 #endif /* RMU_RSTCAUSE_DVDDBOD */
105 
106 #ifdef RMU_RSTCAUSE_DECBOD
107 	if (rmu_flags & RMU_RSTCAUSE_DECBOD) {
108 		flags |= RESET_BROWNOUT;
109 	}
110 #endif /* RMU_RSTCAUSE_DECBOD */
111 
112 #ifdef RMU_RSTCAUSE_BODAVDD0
113 	if (rmu_flags & RMU_RSTCAUSE_BODAVDD0) {
114 		flags |= RESET_BROWNOUT;
115 	}
116 #endif /* RMU_RSTCAUSE_BODAVDD0 */
117 
118 #ifdef RMU_RSTCAUSE_BODAVDD1
119 	if (rmu_flags & RMU_RSTCAUSE_BODAVDD1) {
120 		flags |= RESET_BROWNOUT;
121 	}
122 #endif /* RMU_RSTCAUSE_BODAVDD1 */
123 
124 #if defined(BU_PRESENT) && defined(_SILICON_LABS_32B_SERIES_0)
125 	if (rmu_flags & RMU_RSTCAUSE_BUBODVDDDREG) {
126 		flags |= RESET_BROWNOUT;
127 	}
128 
129 	if (rmu_flags & RMU_RSTCAUSE_BUBODBUVIN) {
130 		flags |= RESET_BROWNOUT;
131 	}
132 
133 	if (rmu_flags & RMU_RSTCAUSE_BUBODUNREG) {
134 		flags |= RESET_BROWNOUT;
135 	}
136 
137 	if (rmu_flags & RMU_RSTCAUSE_BUBODREG) {
138 		flags |= RESET_BROWNOUT;
139 	}
140 
141 	if (rmu_flags & RMU_RSTCAUSE_BUMODERST) {
142 		flags |= RESET_BROWNOUT;
143 	}
144 
145 #elif defined(RMU_RSTCAUSE_BUMODERST)
146 	if (rmu_flags & RMU_RSTCAUSE_BUMODERST) {
147 		flags |= RESET_BROWNOUT;
148 	}
149 
150 #endif /* defined(BU_PRESENT) && defined(_SILICON_LABS_32B_SERIES_0) */
151 
152 	*cause = flags;
153 	return 0;
154 }
155 
z_impl_hwinfo_clear_reset_cause(void)156 int z_impl_hwinfo_clear_reset_cause(void)
157 {
158 	RMU_ResetCauseClear();
159 
160 	return 0;
161 }
162 
z_impl_hwinfo_get_supported_reset_cause(uint32_t * supported)163 int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported)
164 {
165 	*supported = RESET_PIN
166 			| RESET_SOFTWARE
167 			| RESET_POR
168 			| RESET_WATCHDOG
169 			| RESET_CPU_LOCKUP
170 #if defined(RMU_RSTCAUSE_EM4WURST) || defined(RMU_RSTCAUSE_EM4RST)
171 			| RESET_LOW_POWER_WAKE
172 #endif /* defined(RMU_RSTCAUSE_EM4WURST) || defined(RMU_RSTCAUSE_EM4RST) */
173 #if HAS_BROWNOUT
174 			| RESET_BROWNOUT
175 #endif /* HAS_BROWNOUT */
176 			;
177 	return 0;
178 }
179