Skip to content

Commit 63bf19c

Browse files
committed
Use assembly sequences to enable caches.
See rust-embedded#232, which this partially fixes -- there's still the question of taking an interrupt in the midst of these sequences.
1 parent b70c25a commit 63bf19c

9 files changed

+57
-8
lines changed

asm-v7.s

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.syntax unified
12
.cfi_sections .debug_frame
23

34
.section .text.__basepri_max
@@ -39,3 +40,39 @@ __faultmask:
3940
bx lr
4041
.cfi_endproc
4142
.size __faultmask, . - __faultmask
43+
44+
.section .text.__enable_icache
45+
.global __enable_icache
46+
.thumb_func
47+
.cfi_startproc
48+
__enable_icache:
49+
ldr r0, =0xE000ED14 @ CCR
50+
mrs r2, PRIMASK @ save critical nesting info
51+
cpsid i @ mask interrupts
52+
ldr r1, [r0] @ read CCR
53+
orr.w r1, r1, #(1 << 17) @ Set bit 17, IC
54+
str r1, [r0] @ write it back
55+
dsb @ ensure store completes
56+
isb @ synchronize pipeline
57+
msr PRIMASK, r2 @ unnest critical section
58+
bx lr
59+
.cfi_endproc
60+
.size __enable_icache, . - __enable_icache
61+
62+
.section .text.__enable_dcache
63+
.global __enable_dcache
64+
.thumb_func
65+
.cfi_startproc
66+
__enable_dcache:
67+
ldr r0, =0xE000ED14 @ CCR
68+
mrs r2, PRIMASK @ save critical nesting info
69+
cpsid i @ mask interrupts
70+
ldr r1, [r0] @ read CCR
71+
orr.w r1, r1, #(1 << 16) @ Set bit 16, DC
72+
str r1, [r0] @ write it back
73+
dsb @ ensure store completes
74+
isb @ synchronize pipeline
75+
msr PRIMASK, r2 @ unnest critical section
76+
bx lr
77+
.cfi_endproc
78+
.size __enable_dcache, . - __enable_dcache

bin/thumbv6m-none-eabi.a

8 Bytes
Binary file not shown.

bin/thumbv7em-none-eabi.a

672 Bytes
Binary file not shown.

bin/thumbv7em-none-eabihf.a

672 Bytes
Binary file not shown.

bin/thumbv7m-none-eabi.a

664 Bytes
Binary file not shown.

bin/thumbv8m.base-none-eabi.a

16 Bytes
Binary file not shown.

bin/thumbv8m.main-none-eabi.a

680 Bytes
Binary file not shown.

bin/thumbv8m.main-none-eabihf.a

684 Bytes
Binary file not shown.

src/peripheral/scb.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,17 @@ impl SCB {
331331
cbp.iciallu();
332332

333333
// Enable I-cache
334-
// NOTE(unsafe): We have synchronised access by &mut self
335-
unsafe { self.ccr.modify(|r| r | SCB_CCR_IC_MASK) };
334+
extern "C" {
335+
// see asm-v7m.s
336+
fn __enable_icache();
337+
}
336338

337-
crate::asm::dsb();
338-
crate::asm::isb();
339+
// NOTE(unsafe): Having &mut self means no ISR, for example, is going to
340+
// try to alter this register at the same time.
341+
unsafe { __enable_icache(); }
342+
343+
// The asm routine covers both the critical section and barriers we
344+
// need.
339345
}
340346

341347
/// Disables I-cache if currently enabled.
@@ -400,11 +406,17 @@ impl SCB {
400406
unsafe { self.invalidate_dcache(cpuid) };
401407

402408
// Now turn on the D-cache
403-
// NOTE(unsafe): We have synchronised access by &mut self
404-
unsafe { self.ccr.modify(|r| r | SCB_CCR_DC_MASK) };
409+
extern "C" {
410+
// see asm-v7m.s
411+
fn __enable_dcache();
412+
}
405413

406-
crate::asm::dsb();
407-
crate::asm::isb();
414+
// NOTE(unsafe): Having &mut self means no ISR, for example, is going to
415+
// try to alter this register at the same time.
416+
unsafe { __enable_dcache(); }
417+
418+
// The asm routine covers both the critical section and barriers we
419+
// need.
408420
}
409421

410422
/// Disables D-cache if currently enabled.

0 commit comments

Comments
 (0)