1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
/* Test Cortex-M3/M4 bitbanding */
#include "armv7m.h"
#include "testme.h"
/* The underlying RAM is at 0x20000000-0x200fffff, and the bitbanding
* region is at 0x22000000-0x23ffffff.
* Each 32-bit word in the bitbanding region corresponds to one bit
* in the underlying RAM.
*/
#define BB_RAM ((uint8_t*)0x20000000)
#define BB_BASE ((uint8_t*)0x22000000)
void test_reads(int offset, uint32_t value, int access)
{
/* Read 32 words from the bitbanding region at the location
* corresponding to offset bytes into the underlying RAM, and
* check they match the value required.
* Use bitband region accesses of the specified size.
*/
int i;
out32(BB_RAM + offset, value);
for (i = 0; i < 32; i++) {
uint32_t v;
switch (access) {
case 1:
v = in8(BB_BASE + offset * 32 + i * 4);
break;
case 2:
v = in16(BB_BASE + offset * 32 + i * 4);
break;
case 4:
v = in32(BB_BASE + offset * 32 + i * 4);
break;
default:
abort();
}
testEqI(v, (value >> i) & 1,
"bitbanding region offset %x access width %x",
offset + i, access);
}
}
void test_writes(int offset, uint32_t value, int access)
{
/* Write 32 words into the bitbanding region as required for
* the value to appear at offset bytes into the underlying RAM.
*/
int i;
uint32_t v;
for (i = 0; i < 32; i++) {
switch (access) {
case 1:
out8(BB_BASE + offset * 32 + i * 4, (value >> i) & 1);
break;
case 2:
out16(BB_BASE + offset * 32 + i * 4, (value >> i) & 1);
break;
case 4:
out32(BB_BASE + offset * 32 + i * 4, (value >> i) & 1);
break;
default:
abort();
}
}
v = in32(BB_RAM + offset);
testEqI(v, value,
"read RAM written via bitbanding (access width %x)", access);
}
void test_writes_byte(int offset, uint32_t value)
{
/* Write 32 words into the bitbanding region as required for
* the value to appear at offset bytes into the underlying RAM.
*/
int i;
for (i = 0; i < 32; i++) {
out8(BB_BASE + offset * 32 + i * 4, (value >> i) & 1);
}
}
void main(void)
{
uint32_t v;
testInit(100);
testDiag("Test SRAM bitbanding region");
/* This is just to check that there's really RAM at this address */
out32(BB_RAM, 0x89ABCDEF);
v = in32(BB_RAM);
testEqI(v, 0x89ABCDEF, "simple read of RAM");
test_reads(8, 0x89ABCDEF, 4);
test_writes(24, 0x12345678, 4);
/* Byte and halfword accesses work too. They work the same as
* word accesses but perform byte or halfword accesses to the
* underlying device, which we can't detect for RAM.
*/
test_reads(6400, 0x12874928, 1);
test_writes(3200, 0xf8364386, 1);
test_reads(16000, 0x18273823, 2);
test_writes(32000, 0xab82646, 2);
testDiag("Done.");
}
|