/* 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."); }