Skip to content

Commit a763f2b

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

9 files changed

+53
-8
lines changed

asm-v7.s

+37
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

+16-8
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,15 @@ 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): The asm routine manages exclusive access to the SCB
340+
// registers and applies the proper barriers; it is technically safe on
341+
// its own, and is only `unsafe` here because it's `extern "C"`.
342+
unsafe { __enable_icache(); }
339343
}
340344

341345
/// Disables I-cache if currently enabled.
@@ -400,11 +404,15 @@ impl SCB {
400404
unsafe { self.invalidate_dcache(cpuid) };
401405

402406
// 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) };
407+
extern "C" {
408+
// see asm-v7m.s
409+
fn __enable_dcache();
410+
}
405411

406-
crate::asm::dsb();
407-
crate::asm::isb();
412+
// NOTE(unsafe): The asm routine manages exclusive access to the SCB
413+
// registers and applies the proper barriers; it is technically safe on
414+
// its own, and is only `unsafe` here because it's `extern "C"`.
415+
unsafe { __enable_dcache(); }
408416
}
409417

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

0 commit comments

Comments
 (0)