Skip to content

Commit b846fb7

Browse files
committed
use unchecked functions, improve safety docs
1 parent 01e39c0 commit b846fb7

1 file changed

Lines changed: 36 additions & 47 deletions

File tree

cortex-m/src/peripheral/nvic.rs

Lines changed: 36 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,10 @@ impl NVIC {
122122
I: InterruptNumber,
123123
{
124124
let nr = interrupt.number();
125-
// NOTE(unsafe) this is a write to a stateless register
125+
// SAFETY: this is a write to a stateless register.
126126
let mut nvic = unsafe { Self::steal() };
127-
nvic.write_icer(usize::from(nr / 32), 1 << (nr % 32))
128-
.expect("invalid interrupt number");
127+
// SAFETY: InterruptNumber is an unsafe trait, we can assume correct implementation.
128+
unsafe { nvic.write_icer_unchecked(usize::from(nr / 32), 1 << (nr % 32)) }
129129
}
130130

131131
/// Enables `interrupt`
@@ -137,10 +137,10 @@ impl NVIC {
137137
I: InterruptNumber,
138138
{
139139
let nr = interrupt.number();
140-
// NOTE(ptr) this is a write to a stateless register
140+
// SAFETY: this is a write to a stateless register,
141141
let mut nvic = unsafe { Self::steal() };
142-
nvic.write_iser(usize::from(nr / 32), 1 << (nr % 32))
143-
.expect("invalid interrupt number");
142+
// SAFETY: InterruptNumber is an unsafe trait, we can assume correct implementation.
143+
unsafe { nvic.write_iser_unchecked(usize::from(nr / 32), 1 << (nr % 32)) }
144144
}
145145

146146
/// Returns the NVIC priority of `interrupt`
@@ -156,24 +156,21 @@ impl NVIC {
156156
#[cfg(not(armv6m))]
157157
{
158158
let nr = interrupt.number();
159-
// note(unsafe) atomic read with no side effects
159+
// SAFETY: atomic read with no side effects
160160
let nvic = unsafe { Self::steal() };
161161
let ipr_ptr = nvic.pointer_to_ipr_start() as *const u8;
162-
// This should never happen for correct `InterruptNumber` implementations.
163-
if nr >= 124 {
164-
panic!("unexpected interrupt number");
165-
}
166-
// note(unsafe) atomic read with no side effects
162+
// SAFETY:
163+
// - atomic read with no side effects
164+
// - InterruptNumber is an unsafe trait, we can assume correct implementation.
167165
unsafe { core::ptr::read_volatile(ipr_ptr.offset(nr as isize)) }
168166
}
169167

170168
#[cfg(armv6m)]
171169
{
172-
// note(unsafe) atomic read with no side effects
170+
// SAFETY: atomic read with no side effects
173171
let nvic = unsafe { Self::steal() };
174-
let ipr_n = nvic
175-
.read_ipr(Self::ipr_index(interrupt))
176-
.expect("unexpected interrupt number");
172+
// SAFETY: InterruptNumber is an unsafe trait, we can assume correct implementation.
173+
let ipr_n = unsafe { nvic.read_ipr_unchecked(Self::ipr_index(interrupt)) };
177174
((ipr_n >> Self::ipr_shift(interrupt)) & 0x0000_00ff) as u8
178175
}
179176
}
@@ -188,12 +185,10 @@ impl NVIC {
188185
let nr = interrupt.number();
189186
let mask = 1 << (nr % 32);
190187

191-
// note(unsafe) atomic read with no side effects
188+
// SAFETY: atomic read with no side effects
192189
let nvic = unsafe { Self::steal() };
193-
nvic.read_iabr(usize::from(nr / 32))
194-
.expect("unexpected interrupt number")
195-
& mask
196-
== mask
190+
// SAFETY: InterruptNumber is an unsafe trait, we can assume correct implementation.
191+
unsafe { nvic.read_iabr_unchecked(usize::from(nr / 32)) & mask == mask }
197192
}
198193

199194
/// Checks if `interrupt` is enabled
@@ -205,12 +200,10 @@ impl NVIC {
205200
let nr = interrupt.number();
206201
let mask = 1 << (nr % 32);
207202

208-
// note(unsafe) atomic read with no side effects
203+
// SAFETY: atomic read with no side effects
209204
let nvic = unsafe { Self::steal() };
210-
nvic.read_iser(usize::from(nr / 32))
211-
.expect("unexpected interrupt number")
212-
& mask
213-
== mask
205+
// SAFETY: InterruptNumber is an unsafe trait, we can assume correct implementation.
206+
unsafe { nvic.read_iser_unchecked(usize::from(nr / 32)) & mask == mask }
214207
}
215208

216209
/// Checks if `interrupt` is pending
@@ -222,12 +215,10 @@ impl NVIC {
222215
let nr = interrupt.number();
223216
let mask = 1 << (nr % 32);
224217

225-
// note(unsafe) atomic read with no side effects
218+
// SAFETY: atomic read with no side effects
226219
let nvic = unsafe { Self::steal() };
227-
nvic.read_ispr(usize::from(nr / 32))
228-
.expect("unexpected interrupt number")
229-
& mask
230-
== mask
220+
// SAFETY: InterruptNumber is an unsafe trait, we can assume correct implementation.
221+
unsafe { nvic.read_ispr_unchecked(usize::from(nr / 32)) & mask == mask }
231222
}
232223

233224
/// Forces `interrupt` into pending state
@@ -238,10 +229,10 @@ impl NVIC {
238229
{
239230
let nr = interrupt.number();
240231

241-
// NOTE(unsafe) atomic stateless write; ICPR doesn't store any state
232+
// SAFETY: atomic stateless write; ICPR doesn't store any state
242233
let mut nvic = unsafe { Self::steal() };
243-
nvic.write_ispr(usize::from(nr / 32), 1 << (nr % 32))
244-
.expect("unexpected interrupt number")
234+
// SAFETY: InterruptNumber is an unsafe trait, we can assume correct implementation.
235+
unsafe { nvic.write_ispr_unchecked(usize::from(nr / 32), 1 << (nr % 32)) }
245236
}
246237

247238
/// Sets the "priority" of `interrupt` to `prio`
@@ -264,28 +255,26 @@ impl NVIC {
264255
#[cfg(not(armv6m))]
265256
{
266257
let nr = interrupt.number();
267-
// NOTE(unsafe) atomic stateless write; IPR doesn't store any state
258+
// SAFETY: atomic stateless write; IPR doesn't store any state
268259
let nvic = unsafe { Self::steal() };
269260
let ipr_ptr = nvic.pointer_to_ipr_start() as *mut u8;
270-
// This should never happen for correct `InterruptNumber` implementations.
271-
if nr >= 124 {
272-
panic!("unexpected interrupt number");
273-
}
274-
// NOTE(unsafe) atomic stateless write; IPR doesn't store any state
261+
// SAFETY:
262+
// - atomic stateless write; IPR doesn't store any state
263+
// - InterruptNumber is an unsafe trait, we can assume correct implementation.
275264
unsafe { core::ptr::write_volatile(ipr_ptr.offset(nr as isize), prio) }
276265
}
277266

278267
#[cfg(armv6m)]
279268
{
280-
// NOTE(unsafe) atomic stateless write; IPR doesn't store any state
269+
// SAFETY: atomic stateless write; IPR doesn't store any state
281270
let mut nvic = unsafe { Self::steal() };
282-
nvic.modify_ipr(Self::ipr_index(interrupt), |mut value| {
271+
// SAFETY: InterruptNumber is an unsafe trait, we can assume correct implementation.
272+
nvic.modify_ipr_unchecked(Self::ipr_index(interrupt), |mut value| {
283273
let mask = 0x0000_00ff << Self::ipr_shift(interrupt);
284274
let prio = u32::from(prio) << Self::ipr_shift(interrupt);
285275

286276
(value & !mask) | prio
287-
})
288-
.expect("unexpected interrupt number");
277+
});
289278
}
290279
}
291280

@@ -297,10 +286,10 @@ impl NVIC {
297286
{
298287
let nr = interrupt.number();
299288

300-
// NOTE(unsafe) atomic stateless write; ICPR doesn't store any state
289+
// SAFETY: atomic stateless write; ICPR doesn't store any state
301290
let mut nvic = unsafe { Self::steal() };
302-
nvic.write_icpr(usize::from(nr / 32), 1 << (nr % 32))
303-
.expect("unexpected interrupt number")
291+
// SAFETY: InterruptNumber is an unsafe trait, we can assume correct implementation.
292+
unsafe { nvic.write_icpr_unchecked(usize::from(nr / 32), 1 << (nr % 32)) }
304293
}
305294

306295
#[cfg(armv6m)]

0 commit comments

Comments
 (0)