[v851]add spi interface for v851/v853

This commit is contained in:
JianjunJiang 2023-05-19 17:13:26 +08:00
parent ca7319bbe5
commit 30494aa4b6
17 changed files with 1116 additions and 6 deletions

View File

@ -1449,12 +1449,148 @@ static int chip_ddr(struct xfel_ctx_t * ctx, const char * type)
static int chip_spi_init(struct xfel_ctx_t * ctx, uint32_t * swapbuf, uint32_t * swaplen, uint32_t * cmdlen)
{
return 0;
static const uint8_t payload[] = {
0x00, 0x00, 0xa0, 0xe3, 0x17, 0x0f, 0x08, 0xee, 0x15, 0x0f, 0x07, 0xee,
0xd5, 0x0f, 0x07, 0xee, 0x9a, 0x0f, 0x07, 0xee, 0x95, 0x0f, 0x07, 0xee,
0xff, 0xff, 0xff, 0xea, 0x5c, 0x00, 0x9f, 0xe5, 0x00, 0xd0, 0x80, 0xe5,
0x04, 0xe0, 0x80, 0xe5, 0x00, 0xe0, 0x0f, 0xe1, 0x08, 0xe0, 0x80, 0xe5,
0x10, 0xef, 0x11, 0xee, 0x0c, 0xe0, 0x80, 0xe5, 0x10, 0xef, 0x1c, 0xee,
0x10, 0xe0, 0x80, 0xe5, 0x10, 0xef, 0x11, 0xee, 0x14, 0xe0, 0x80, 0xe5,
0x29, 0x0a, 0xa0, 0xe3, 0x77, 0x00, 0x00, 0xeb, 0x28, 0x00, 0x9f, 0xe5,
0x00, 0xd0, 0x90, 0xe5, 0x04, 0xe0, 0x90, 0xe5, 0x14, 0x10, 0x90, 0xe5,
0x10, 0x1f, 0x01, 0xee, 0x10, 0x10, 0x90, 0xe5, 0x10, 0x1f, 0x0c, 0xee,
0x0c, 0x10, 0x90, 0xe5, 0x10, 0x1f, 0x01, 0xee, 0x08, 0x10, 0x90, 0xe5,
0x01, 0xf0, 0x29, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0xe0, 0x0f, 0x04, 0x00,
0xf0, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0x51, 0xe2, 0xf0, 0x80, 0xbd, 0x08,
0x05, 0xea, 0xa0, 0xe3, 0x52, 0x6c, 0xa0, 0xe3, 0x02, 0xe4, 0x40, 0xe3,
0x53, 0x4c, 0xa0, 0xe3, 0x02, 0x64, 0x40, 0xe3, 0x00, 0x70, 0xe0, 0xe3,
0x02, 0x44, 0x40, 0xe3, 0x40, 0x00, 0x55, 0xe3, 0x00, 0x30, 0xa0, 0xe3,
0x07, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0x31, 0x40, 0x20, 0xa0, 0x23,
0x30, 0x20, 0x8e, 0xe5, 0x34, 0x20, 0x8e, 0xe5, 0x38, 0x20, 0x8e, 0xe5,
0x00, 0x10, 0xc6, 0xe5, 0x01, 0x30, 0x83, 0xe2, 0x03, 0x00, 0x52, 0xe1,
0xfb, 0xff, 0xff, 0xca, 0x08, 0x30, 0x9e, 0xe5, 0x02, 0x31, 0x83, 0xe3,
0x08, 0x30, 0x8e, 0xe5, 0x1c, 0x30, 0x9e, 0xe5, 0x73, 0x30, 0xef, 0xe6,
0x03, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x8a, 0x00, 0x30, 0xa0, 0xe3,
0x00, 0xc0, 0xd4, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x00, 0x10, 0xa0, 0xe1,
0x01, 0x30, 0x83, 0xe2, 0x7c, 0xc0, 0xef, 0xe6, 0x06, 0x00, 0x00, 0x0a,
0x03, 0x00, 0x52, 0xe1, 0x01, 0xc0, 0xc1, 0xe4, 0x01, 0x00, 0xa0, 0xe1,
0xf5, 0xff, 0xff, 0xca, 0x02, 0x50, 0x55, 0xe0, 0xdf, 0xff, 0xff, 0x1a,
0xf0, 0x80, 0xbd, 0xe8, 0x03, 0x00, 0x52, 0xe1, 0x01, 0x10, 0x83, 0xe2,
0x02, 0x30, 0x83, 0xe2, 0xf8, 0xff, 0xff, 0xda, 0x01, 0x00, 0x52, 0xe1,
0x00, 0x10, 0xd4, 0xe5, 0xf5, 0xff, 0xff, 0xda, 0x03, 0x00, 0x52, 0xe1,
0x00, 0x10, 0xd4, 0xe5, 0x01, 0x10, 0x83, 0xe2, 0x02, 0x30, 0x83, 0xe2,
0xf7, 0xff, 0xff, 0xca, 0x02, 0x50, 0x55, 0xe0, 0xd0, 0xff, 0xff, 0x1a,
0xf0, 0x80, 0xbd, 0xe8, 0xf0, 0x40, 0x2d, 0xe9, 0x00, 0x60, 0x51, 0xe2,
0xf0, 0x80, 0xbd, 0x08, 0x05, 0x1a, 0xa0, 0xe3, 0x52, 0x5c, 0xa0, 0xe3,
0x02, 0x14, 0x40, 0xe3, 0x53, 0x4c, 0xa0, 0xe3, 0x02, 0x54, 0x40, 0xe3,
0x00, 0x70, 0xe0, 0xe3, 0x02, 0x44, 0x40, 0xe3, 0x40, 0x00, 0x56, 0xe3,
0x06, 0x20, 0xa0, 0x31, 0x40, 0x20, 0xa0, 0x23, 0x30, 0x20, 0x81, 0xe5,
0x00, 0x00, 0x50, 0xe3, 0x34, 0x20, 0x81, 0xe5, 0x38, 0x20, 0x81, 0xe5,
0x17, 0x00, 0x00, 0x0a, 0x00, 0xc0, 0xa0, 0xe1, 0x00, 0x30, 0xa0, 0xe3,
0x01, 0xe0, 0xdc, 0xe4, 0x01, 0x30, 0x83, 0xe2, 0x03, 0x00, 0x52, 0xe1,
0x00, 0xe0, 0xc5, 0xe5, 0xfa, 0xff, 0xff, 0xca, 0x08, 0x30, 0x91, 0xe5,
0x02, 0x31, 0x83, 0xe3, 0x08, 0x30, 0x81, 0xe5, 0x1c, 0x30, 0x91, 0xe5,
0x73, 0x30, 0xef, 0xe6, 0x03, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x8a,
0x00, 0x30, 0xa0, 0xe3, 0x00, 0xc0, 0xd4, 0xe5, 0x01, 0x30, 0x83, 0xe2,
0x03, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0xca, 0x00, 0x00, 0x50, 0xe3,
0x02, 0x00, 0x80, 0x10, 0x02, 0x60, 0x56, 0xe0, 0xe0, 0xff, 0xff, 0x1a,
0xf0, 0x80, 0xbd, 0xe8, 0x00, 0x30, 0xa0, 0xe1, 0x07, 0xc0, 0xa0, 0xe1,
0x00, 0xc0, 0xc5, 0xe5, 0x01, 0x30, 0x83, 0xe2, 0x03, 0x00, 0x52, 0xe1,
0xfb, 0xff, 0xff, 0xca, 0xe7, 0xff, 0xff, 0xea, 0xf0, 0x43, 0x2d, 0xe9,
0x0f, 0x80, 0x0c, 0xe3, 0xff, 0x8f, 0x4f, 0xe3, 0x05, 0x5a, 0xa0, 0xe3,
0x02, 0x54, 0x40, 0xe3, 0x01, 0x7a, 0xa0, 0xe3, 0x00, 0x72, 0x40, 0xe3,
0x14, 0xd0, 0x4d, 0xe2, 0x00, 0x60, 0xa0, 0xe1, 0x06, 0x40, 0xa0, 0xe1,
0x01, 0x30, 0xd4, 0xe4, 0x01, 0x00, 0x53, 0xe3, 0x1e, 0x00, 0x00, 0x0a,
0x02, 0x00, 0x53, 0xe3, 0x5c, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x53, 0xe3,
0x5f, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x53, 0xe3, 0x63, 0x00, 0x00, 0x0a,
0x05, 0x00, 0x53, 0xe3, 0x68, 0x00, 0x00, 0x0a, 0x06, 0x00, 0x53, 0xe3,
0x77, 0x00, 0x00, 0x0a, 0x07, 0x00, 0x53, 0xe3, 0x86, 0x00, 0x00, 0x0a,
0x08, 0x00, 0x53, 0xe3, 0x93, 0x00, 0x00, 0x1a, 0xb0, 0x80, 0xcd, 0xe1,
0x0d, 0x90, 0xa0, 0xe1, 0x08, 0x60, 0x8d, 0xe2, 0x02, 0x10, 0xa0, 0xe3,
0x09, 0x00, 0xa0, 0xe1, 0xad, 0xff, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3,
0x06, 0x00, 0xa0, 0xe1, 0x70, 0xff, 0xff, 0xeb, 0x08, 0x30, 0xdd, 0xe5,
0x01, 0x00, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x1a, 0x04, 0x60, 0xa0, 0xe1,
0x06, 0x40, 0xa0, 0xe1, 0x01, 0x30, 0xd4, 0xe4, 0x01, 0x00, 0x53, 0xe3,
0xe0, 0xff, 0xff, 0x1a, 0x02, 0x34, 0xa0, 0xe3, 0x01, 0x1a, 0xa0, 0xe3,
0x60, 0x20, 0x93, 0xe5, 0x0f, 0x20, 0xc2, 0xe3, 0x04, 0x20, 0x82, 0xe3,
0x60, 0x20, 0x83, 0xe5, 0x60, 0x20, 0x93, 0xe5, 0xf0, 0x20, 0xc2, 0xe3,
0x40, 0x20, 0x82, 0xe3, 0x60, 0x20, 0x83, 0xe5, 0x60, 0x20, 0x93, 0xe5,
0x0f, 0x2c, 0xc2, 0xe3, 0x01, 0x2b, 0x82, 0xe3, 0x60, 0x20, 0x83, 0xe5,
0x60, 0x20, 0x93, 0xe5, 0x0f, 0x2a, 0xc2, 0xe3, 0x01, 0x29, 0x82, 0xe3,
0x60, 0x20, 0x83, 0xe5, 0x60, 0x20, 0x93, 0xe5, 0x0f, 0x28, 0xc2, 0xe3,
0x01, 0x27, 0x82, 0xe3, 0x60, 0x20, 0x83, 0xe5, 0x60, 0x20, 0x93, 0xe5,
0x0f, 0x26, 0xc2, 0xe3, 0x01, 0x25, 0x82, 0xe3, 0x60, 0x20, 0x83, 0xe5,
0x6c, 0x39, 0x97, 0xe5, 0x01, 0x38, 0x83, 0xe3, 0x6c, 0x39, 0x87, 0xe5,
0x40, 0x39, 0x97, 0xe5, 0x02, 0x31, 0x83, 0xe3, 0x40, 0x39, 0x87, 0xe5,
0x6c, 0x39, 0x97, 0xe5, 0x01, 0x30, 0x83, 0xe3, 0x6c, 0x39, 0x87, 0xe5,
0x40, 0x39, 0x97, 0xe5, 0x03, 0x34, 0xc3, 0xe3, 0x01, 0x34, 0x83, 0xe3,
0x40, 0x39, 0x87, 0xe5, 0x40, 0x39, 0x97, 0xe5, 0x03, 0x3c, 0xc3, 0xe3,
0x40, 0x39, 0x87, 0xe5, 0x40, 0x39, 0x97, 0xe5, 0x0f, 0x30, 0xc3, 0xe3,
0x05, 0x30, 0x83, 0xe3, 0x40, 0x39, 0x87, 0xe5, 0x24, 0x10, 0x85, 0xe5,
0x04, 0x30, 0x95, 0xe5, 0x02, 0x31, 0x83, 0xe3, 0x83, 0x30, 0x83, 0xe3,
0x04, 0x30, 0x85, 0xe5, 0x04, 0x30, 0x95, 0xe5, 0x00, 0x00, 0x53, 0xe3,
0xfc, 0xff, 0xff, 0xba, 0x08, 0x30, 0x95, 0xe5, 0x04, 0x60, 0xa0, 0xe1,
0x03, 0x30, 0xc3, 0xe3, 0x44, 0x30, 0x83, 0xe3, 0x08, 0x30, 0x85, 0xe5,
0x18, 0x30, 0x95, 0xe5, 0x02, 0x31, 0x83, 0xe3, 0x02, 0x39, 0x83, 0xe3,
0x18, 0x30, 0x85, 0xe5, 0x9c, 0xff, 0xff, 0xea, 0x08, 0x30, 0x95, 0xe5,
0x04, 0x60, 0xa0, 0xe1, 0xb0, 0x30, 0xc3, 0xe3, 0x08, 0x30, 0x85, 0xe5,
0x97, 0xff, 0xff, 0xea, 0x08, 0x30, 0x95, 0xe5, 0x04, 0x60, 0xa0, 0xe1,
0xb0, 0x30, 0xc3, 0xe3, 0x80, 0x30, 0x83, 0xe3, 0x08, 0x30, 0x85, 0xe5,
0x91, 0xff, 0xff, 0xea, 0x01, 0x90, 0xd6, 0xe5, 0x02, 0x00, 0x86, 0xe2,
0x09, 0x10, 0xa0, 0xe1, 0x01, 0x60, 0x89, 0xe2, 0x06, 0x60, 0x84, 0xe0,
0x51, 0xff, 0xff, 0xeb, 0x8a, 0xff, 0xff, 0xea, 0x06, 0x10, 0xd6, 0xe5,
0x09, 0x60, 0x86, 0xe2, 0x07, 0x00, 0x56, 0xe5, 0x04, 0x20, 0x56, 0xe5,
0x08, 0x30, 0x56, 0xe5, 0x02, 0xe0, 0x56, 0xe5, 0x06, 0xc0, 0x56, 0xe5,
0x01, 0x24, 0x82, 0xe1, 0x00, 0x34, 0x83, 0xe1, 0x01, 0x10, 0x56, 0xe5,
0x05, 0x00, 0x56, 0xe5, 0x0e, 0x28, 0x82, 0xe1, 0x0c, 0x38, 0x83, 0xe1,
0x01, 0x1c, 0x82, 0xe1, 0x00, 0x0c, 0x83, 0xe1, 0x40, 0xff, 0xff, 0xeb,
0x79, 0xff, 0xff, 0xea, 0x06, 0x10, 0xd6, 0xe5, 0x09, 0x60, 0x86, 0xe2,
0x07, 0x00, 0x56, 0xe5, 0x04, 0x20, 0x56, 0xe5, 0x08, 0x30, 0x56, 0xe5,
0x02, 0xe0, 0x56, 0xe5, 0x06, 0xc0, 0x56, 0xe5, 0x01, 0x24, 0x82, 0xe1,
0x00, 0x34, 0x83, 0xe1, 0x01, 0x10, 0x56, 0xe5, 0x05, 0x00, 0x56, 0xe5,
0x0e, 0x28, 0x82, 0xe1, 0x0c, 0x38, 0x83, 0xe1, 0x01, 0x1c, 0x82, 0xe1,
0x00, 0x0c, 0x83, 0xe1, 0xf5, 0xfe, 0xff, 0xeb, 0x68, 0xff, 0xff, 0xea,
0x0d, 0x90, 0xa0, 0xe1, 0x08, 0x60, 0x8d, 0xe2, 0x05, 0x30, 0xa0, 0xe3,
0x00, 0x30, 0xcd, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x09, 0x00, 0xa0, 0xe1,
0x27, 0xff, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x06, 0x00, 0xa0, 0xe1,
0xea, 0xfe, 0xff, 0xeb, 0x08, 0x30, 0xdd, 0xe5, 0x01, 0x00, 0x13, 0xe3,
0xf6, 0xff, 0xff, 0x1a, 0x04, 0x60, 0xa0, 0xe1, 0x78, 0xff, 0xff, 0xea,
0x14, 0xd0, 0x8d, 0xe2, 0xf0, 0x83, 0xbd, 0xe8, 0x04, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x4e, 0x55, 0x00,
0x51, 0x5f, 0x35, 0x3c, 0x4a, 0x75, 0x7e, 0xc7, 0x3a, 0x29, 0x61, 0xd7,
0xc7, 0x74, 0x86, 0x5b, 0xb8, 0x72, 0x8f, 0x5a, 0x2f, 0x6c, 0x69, 0x62,
0x2f, 0x6c, 0x64, 0x2d, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x2d, 0x61, 0x72,
0x6d, 0x68, 0x66, 0x2e, 0x73, 0x6f, 0x2e, 0x33, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xfe, 0xff, 0x6f,
0x48, 0x85, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x44, 0x85, 0x02, 0x00,
0x06, 0x00, 0x00, 0x00, 0x34, 0x85, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0xfb, 0xff, 0xff, 0x6f, 0x01, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x60, 0x85, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
fel_write(ctx, 0x00028000, (void *)&payload[0], sizeof(payload));
if(swapbuf)
*swapbuf = 0x0002a000;
if(swaplen)
*swaplen = 65536;
if(cmdlen)
*cmdlen = 4096;
return 1;
}
static int chip_spi_run(struct xfel_ctx_t * ctx, uint8_t * cbuf, uint32_t clen)
{
return 0;
fel_write(ctx, 0x00029000, (void *)cbuf, clen);
fel_exec(ctx, 0x00028000);
return 1;
}
static int chip_extra(struct xfel_ctx_t * ctx, int argc, char * argv[])

View File

@ -80,8 +80,8 @@ usage:
| S3 | Single-core Cortex-A7 | 0x00168100 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| V536 | Dual-Core Cortex-A7 | 0x00181600 | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| V831 | Single-core Cortex-A7 800Mhz | 0x00181700 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| V851 | Single-core Cortex-A7 1Ghz + E907 RISC-V | 0x00188600 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| V853 | Single-core Cortex-A7 1Ghz + E907 RISC-V | 0x00188600 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| V851 | Single-core Cortex-A7 1Ghz + E907 RISC-V | 0x00188600 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| V853 | Single-core Cortex-A7 1Ghz + E907 RISC-V | 0x00188600 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
# Build from source

View File

@ -81,8 +81,8 @@ usage:
| S3 | Single-core Cortex-A7 | 0x00168100 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| V536 | Dual-Core Cortex-A7 | 0x00181600 | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| V831 | Single-core Cortex-A7 800Mhz | 0x00181700 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| V851 | Single-core Cortex-A7 1Ghz + E907 RISC-V | 0x00188600 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| V853 | Single-core Cortex-A7 1Ghz + E907 RISC-V | 0x00188600 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| V851 | Single-core Cortex-A7 1Ghz + E907 RISC-V | 0x00188600 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| V853 | Single-core Cortex-A7 1Ghz + E907 RISC-V | 0x00188600 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
# 编译安装

10
payloads/v851_v853/spi/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
#
# Normal rules
#
*~
#
# Generated files
#
/.obj
/output

View File

@ -0,0 +1,120 @@
#
# Top makefile
#
CROSS ?= arm-linux-gnueabihf-
NAME := spi
#
# System environment variable.
#
ifeq ($(OS), Windows_NT)
HOSTOS := windows
else
ifneq (,$(findstring Linux, $(shell uname -a)))
HOSTOS := linux
endif
endif
#
# Load default variables.
#
ASFLAGS := -g -ggdb -Wall -O3
CFLAGS := -g -ggdb -Wall -O3
CXXFLAGS := -g -ggdb -Wall -O3
LDFLAGS := -T link.ld -nostdlib
ARFLAGS := -rcs
OCFLAGS := -v -O binary
ODFLAGS :=
MCFLAGS := -march=armv7-a -mtune=cortex-a7 -mfpu=vfpv4 -mfloat-abi=hard -marm -mno-thumb-interwork -mno-unaligned-access -fno-stack-protector
LIBDIRS :=
LIBS :=
INCDIRS :=
SRCDIRS :=
#
# Add external library
#
INCDIRS += include \
include/external
SRCDIRS += source \
source/external
#
# You shouldn't need to change anything below this point.
#
AS := $(CROSS)gcc -x assembler-with-cpp
CC := $(CROSS)gcc
CXX := $(CROSS)g++
LD := $(CROSS)ld
AR := $(CROSS)ar
OC := $(CROSS)objcopy
OD := $(CROSS)objdump
MKDIR := mkdir -p
CP := cp -af
RM := rm -fr
CD := cd
FIND := find
#
# X variables
#
X_ASFLAGS := $(MCFLAGS) $(ASFLAGS)
X_CFLAGS := $(MCFLAGS) $(CFLAGS)
X_CXXFLAGS := $(MCFLAGS) $(CXXFLAGS)
X_LDFLAGS := $(LDFLAGS)
X_OCFLAGS := $(OCFLAGS)
X_LIBDIRS := $(LIBDIRS)
X_LIBS := $(LIBS) -lgcc
X_OUT := output
X_NAME := $(patsubst %, $(X_OUT)/%, $(NAME))
X_INCDIRS := $(patsubst %, -I %, $(INCDIRS))
X_SRCDIRS := $(patsubst %, %, $(SRCDIRS))
X_OBJDIRS := $(patsubst %, .obj/%, $(X_SRCDIRS))
X_SFILES := $(foreach dir, $(X_SRCDIRS), $(wildcard $(dir)/*.S))
X_CFILES := $(foreach dir, $(X_SRCDIRS), $(wildcard $(dir)/*.c))
X_CPPFILES := $(foreach dir, $(X_SRCDIRS), $(wildcard $(dir)/*.cpp))
X_SDEPS := $(patsubst %, .obj/%, $(X_SFILES:.S=.o.d))
X_CDEPS := $(patsubst %, .obj/%, $(X_CFILES:.c=.o.d))
X_CPPDEPS := $(patsubst %, .obj/%, $(X_CPPFILES:.cpp=.o.d))
X_DEPS := $(X_SDEPS) $(X_CDEPS) $(X_CPPDEPS)
X_SOBJS := $(patsubst %, .obj/%, $(X_SFILES:.S=.o))
X_COBJS := $(patsubst %, .obj/%, $(X_CFILES:.c=.o))
X_CPPOBJS := $(patsubst %, .obj/%, $(X_CPPFILES:.cpp=.o))
X_OBJS := $(X_SOBJS) $(X_COBJS) $(X_CPPOBJS)
VPATH := $(X_OBJDIRS)
.PHONY: all clean
all : $(X_NAME)
$(X_NAME) : $(X_OBJS)
@echo [LD] Linking $@.elf
@$(CC) $(X_LDFLAGS) $(X_LIBDIRS) -Wl,--cref,-Map=$@.map $^ -o $@.elf $(X_LIBS)
@echo [OC] Objcopying $@.bin
@$(OC) $(X_OCFLAGS) $@.elf $@.bin
$(X_SOBJS) : .obj/%.o : %.S
@echo [AS] $<
@$(AS) $(X_ASFLAGS) -MD -MP -MF $@.d $(X_INCDIRS) -c $< -o $@
$(X_COBJS) : .obj/%.o : %.c
@echo [CC] $<
@$(CC) $(X_CFLAGS) -MD -MP -MF $@.d $(X_INCDIRS) -c $< -o $@
$(X_CPPOBJS) : .obj/%.o : %.cpp
@echo [CXX] $<
@$(CXX) $(X_CXXFLAGS) -MD -MP -MF $@.d $(X_INCDIRS) -c $< -o $@
clean:
@$(RM) .obj $(X_OUT)
#
# Include the dependency files, should be place the last of makefile
#
sinclude $(shell $(MKDIR) $(X_OBJDIRS) $(X_OUT)) $(X_DEPS)

View File

@ -0,0 +1,83 @@
#ifndef __BYTEORDER_H__
#define __BYTEORDER_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <types.h>
static inline u16_t __swab16(u16_t x)
{
return ( (x<<8) | (x>>8) );
}
static inline u32_t __swab32(u32_t x)
{
return ( (x<<24) | (x>>24) | \
((x & (u32_t)0x0000ff00UL)<<8) | \
((x & (u32_t)0x00ff0000UL)>>8) );
}
static inline u64_t __swab64(u64_t x)
{
return ( (x<<56) | (x>>56) | \
((x & (u64_t)0x000000000000ff00ULL)<<40) | \
((x & (u64_t)0x0000000000ff0000ULL)<<24) | \
((x & (u64_t)0x00000000ff000000ULL)<< 8) | \
((x & (u64_t)0x000000ff00000000ULL)>> 8) | \
((x & (u64_t)0x0000ff0000000000ULL)>>24) | \
((x & (u64_t)0x00ff000000000000ULL)>>40) );
}
/*
* swap bytes bizarrely.
* swahw32 - swap 16-bit half-words in a 32-bit word
*/
static inline u32_t __swahw32(u32_t x)
{
return ( ((x & (u32_t)0x0000ffffUL)<<16) | ((x & (u32_t)0xffff0000UL)>>16) );
}
/*
* swap bytes bizarrely.
* swahb32 - swap 8-bit halves of each 16-bit half-word in a 32-bit word
*/
static inline u32_t __swahb32(u32_t x)
{
return ( ((x & (u32_t)0x00ff00ffUL)<<8) | ((x & (u32_t)0xff00ff00UL)>>8) );
}
#if (BYTE_ORDER == BIG_ENDIAN)
#define cpu_to_le64(x) (__swab64((u64_t)(x)))
#define le64_to_cpu(x) (__swab64((u64_t)(x)))
#define cpu_to_le32(x) (__swab32((u32_t)(x)))
#define le32_to_cpu(x) (__swab32((u32_t)(x)))
#define cpu_to_le16(x) (__swab16((u16_t)(x)))
#define le16_to_cpu(x) (__swab16((u16_t)(x)))
#define cpu_to_be64(x) ((u64_t)(x))
#define be64_to_cpu(x) ((u64_t)(x))
#define cpu_to_be32(x) ((u32_t)(x))
#define be32_to_cpu(x) ((u32_t)(x))
#define cpu_to_be16(x) ((u16_t)(x))
#define be16_to_cpu(x) ((u16_t)(x))
#else
#define cpu_to_le64(x) ((u64_t)(x))
#define le64_to_cpu(x) ((u64_t)(x))
#define cpu_to_le32(x) ((u32_t)(x))
#define le32_to_cpu(x) ((u32_t)(x))
#define cpu_to_le16(x) ((u16_t)(x))
#define le16_to_cpu(x) ((u16_t)(x))
#define cpu_to_be64(x) (__swab64((u64_t)(x)))
#define be64_to_cpu(x) (__swab64((u64_t)(x)))
#define cpu_to_be32(x) (__swab32((u32_t)(x)))
#define be32_to_cpu(x) (__swab32((u32_t)(x)))
#define cpu_to_be16(x) (__swab16((u16_t)(x)))
#define be16_to_cpu(x) (__swab16((u16_t)(x)))
#endif
#ifdef __cplusplus
}
#endif
#endif /* __BYTEORDER_H__ */

View File

@ -0,0 +1,27 @@
#ifndef __ARM32_ENDIAN_H__
#define __ARM32_ENDIAN_H__
#ifdef __cplusplus
extern "C" {
#endif
#define LITTLE_ENDIAN (0x1234)
#define BIG_ENDIAN (0x4321)
#if ( !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN) )
#define __LITTLE_ENDIAN
#endif
#if defined(__LITTLE_ENDIAN)
#define BYTE_ORDER LITTLE_ENDIAN
#elif defined(__BIG_ENDIAN)
#define BYTE_ORDER BIG_ENDIAN
#else
#error "Unknown byte order!"
#endif
#ifdef __cplusplus
}
#endif
#endif /* __ARM32_ENDIAN_H__ */

View File

@ -0,0 +1,54 @@
#ifndef __IO_H__
#define __IO_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <types.h>
static inline u8_t read8(virtual_addr_t addr)
{
return( *((volatile u8_t *)(addr)) );
}
static inline u16_t read16(virtual_addr_t addr)
{
return( *((volatile u16_t *)(addr)) );
}
static inline u32_t read32(virtual_addr_t addr)
{
return( *((volatile u32_t *)(addr)) );
}
static inline u64_t read64(virtual_addr_t addr)
{
return( *((volatile u64_t *)(addr)) );
}
static inline void write8(virtual_addr_t addr, u8_t value)
{
*((volatile u8_t *)(addr)) = value;
}
static inline void write16(virtual_addr_t addr, u16_t value)
{
*((volatile u16_t *)(addr)) = value;
}
static inline void write32(virtual_addr_t addr, u32_t value)
{
*((volatile u32_t *)(addr)) = value;
}
static inline void write64(virtual_addr_t addr, u64_t value)
{
*((volatile u64_t *)(addr)) = value;
}
#ifdef __cplusplus
}
#endif
#endif /* __IO_H__ */

View File

@ -0,0 +1,34 @@
#ifndef __STDARG_H__
#define __STDARG_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef __builtin_va_list va_list;
/*
* prepare to access variable args
*/
#define va_start(v, l) __builtin_va_start(v, l)
/*
* the caller will get the value of current argument
*/
#define va_arg(v, l) __builtin_va_arg(v, l)
/*
* end for variable args
*/
#define va_end(v) __builtin_va_end(v)
/*
* copy variable args
*/
#define va_copy(d, s) __builtin_va_copy(d, s)
#ifdef __cplusplus
}
#endif
#endif /* __STDARG_H__ */

View File

@ -0,0 +1,49 @@
#ifndef __STDDEF_H__
#define __STDDEF_H__
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__cplusplus)
#define NULL (0)
#else
#define NULL ((void *)0)
#endif
#if (defined(__GNUC__) && (__GNUC__ >= 4))
#define offsetof(type, member) __builtin_offsetof(type, member)
#else
#define offsetof(type, field) ((size_t)(&((type *)0)->field))
#endif
#define container_of(ptr, type, member) ({const typeof(((type *)0)->member) *__mptr = (ptr); (type *)((char *)__mptr - offsetof(type,member));})
#if (defined(__GNUC__) && (__GNUC__ >= 3))
#define likely(expr) (__builtin_expect(!!(expr), 1))
#define unlikely(expr) (__builtin_expect(!!(expr), 0))
#else
#define likely(expr) (!!(expr))
#define unlikely(expr) (!!(expr))
#endif
#define min(a, b) ({typeof(a) _amin = (a); typeof(b) _bmin = (b); (void)(&_amin == &_bmin); _amin < _bmin ? _amin : _bmin;})
#define max(a, b) ({typeof(a) _amax = (a); typeof(b) _bmax = (b); (void)(&_amax == &_bmax); _amax > _bmax ? _amax : _bmax;})
#define clamp(v, a, b) min(max(a, v), b)
#define ifloor(x) ((x) > 0 ? (int)(x) : (int)((x) - 0.9999999999))
#define iround(x) ((x) > 0 ? (int)((x) + 0.5) : (int)((x) - 0.5))
#define iceil(x) ((x) > 0 ? (int)((x) + 0.9999999999) : (int)(x))
#define idiv255(x) ((((int)(x) + 1) * 257) >> 16)
#define X(...) ("" #__VA_ARGS__ "")
enum {
FALSE = 0,
TRUE = 1,
};
#ifdef __cplusplus
}
#endif
#endif /* __STDDEF_H__ */

View File

@ -0,0 +1,31 @@
#ifndef __STDINT_H__
#define __STDINT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <types.h>
typedef s8_t int8_t;
typedef u8_t uint8_t;
typedef s16_t int16_t;
typedef u16_t uint16_t;
typedef s32_t int32_t;
typedef u32_t uint32_t;
typedef s64_t int64_t;
typedef u64_t uint64_t;
#define UINT8_MAX (0xff)
#define UINT16_MAX (0xffff)
#define UINT32_MAX (0xffffffff)
#define UINT64_MAX (0xffffffffffffffffULL)
#ifdef __cplusplus
}
#endif
#endif /* __STDINT_H__ */

View File

@ -0,0 +1,17 @@
#ifndef __STRING_H__
#define __STRING_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <types.h>
void * memset(void * s, int c, size_t n);
void * memcpy(void * dest, const void * src, size_t len);
#ifdef __cplusplus
}
#endif
#endif /* __STRING_H__ */

View File

@ -0,0 +1,53 @@
#ifndef __ARM32_TYPES_H__
#define __ARM32_TYPES_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef signed char s8_t;
typedef unsigned char u8_t;
typedef signed short s16_t;
typedef unsigned short u16_t;
typedef signed int s32_t;
typedef unsigned int u32_t;
typedef signed long long s64_t;
typedef unsigned long long u64_t;
typedef signed long long intmax_t;
typedef unsigned long long uintmax_t;
typedef signed int ptrdiff_t;
typedef signed int intptr_t;
typedef unsigned int uintptr_t;
typedef unsigned int size_t;
typedef signed int ssize_t;
typedef signed int off_t;
typedef signed long long loff_t;
typedef signed int bool_t;
typedef unsigned int irq_flags_t;
typedef unsigned int virtual_addr_t;
typedef unsigned int virtual_size_t;
typedef unsigned int physical_addr_t;
typedef unsigned int physical_size_t;
typedef struct {
volatile int counter;
} atomic_t;
typedef struct {
volatile int lock;
} spinlock_t;
#ifdef __cplusplus
}
#endif
#endif /* __ARM32_TYPES_H__ */

View File

@ -0,0 +1,21 @@
#ifndef __XBOOT_H__
#define __XBOOT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <types.h>
#include <io.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <endian.h>
#include <byteorder.h>
#ifdef __cplusplus
}
#endif
#endif /* __XBOOT_H__ */

View File

@ -0,0 +1,122 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
STACK_UND_SIZE = 0x010;
STACK_ABT_SIZE = 0x010;
STACK_IRQ_SIZE = 0x010;
STACK_FIQ_SIZE = 0x010;
STACK_SRV_SIZE = 0x100;
MEMORY
{
ram : org = 0x00028000, len = 0x00001000 /* 4 KB */
}
SECTIONS
{
.text :
{
PROVIDE(__image_start = .);
PROVIDE(__text_start = .);
.obj/source/start.o (.text)
.obj/source/sys-spi.o (.text)
*(.text*)
*(.glue*)
*(.note.gnu.build-id)
PROVIDE(__text_end = .);
} > ram
.ARM.exidx ALIGN(8) :
{
PROVIDE (__exidx_start = .);
*(.ARM.exidx*)
PROVIDE (__exidx_end = .);
} > ram
.ARM.extab ALIGN(8) :
{
PROVIDE (__extab_start = .);
*(.ARM.extab*)
PROVIDE (__extab_end = .);
} > ram
.ksymtab ALIGN(16) :
{
PROVIDE(__ksymtab_start = .);
KEEP(*(.ksymtab.text))
PROVIDE(__ksymtab_end = .);
} > ram
.romdisk ALIGN(8) :
{
PROVIDE(__romdisk_start = .);
KEEP(*(.romdisk))
PROVIDE(__romdisk_end = .);
} > ram
.rodata ALIGN(8) :
{
PROVIDE(__rodata_start = .);
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
PROVIDE(__rodata_end = .);
} > ram
.data ALIGN(8) :
{
PROVIDE(__data_start = .);
*(.data*)
. = ALIGN(8);
PROVIDE(__data_end = .);
PROVIDE(__image_end = .);
} > ram
.bss ALIGN(8) (NOLOAD) :
{
PROVIDE(__bss_start = .);
*(.bss*)
*(.sbss*)
*(COMMON)
. = ALIGN(8);
PROVIDE(__bss_end = .);
} > ram
.stack ALIGN(8) (NOLOAD) :
{
PROVIDE(__stack_start = .);
PROVIDE(__stack_und_start = .);
. += STACK_UND_SIZE;
PROVIDE(__stack_und_end = .);
. = ALIGN(8);
PROVIDE(__stack_abt_start = .);
. += STACK_ABT_SIZE;
PROVIDE(__stack_abt_end = .);
. = ALIGN(8);
PROVIDE(__stack_irq_start = .);
. += STACK_IRQ_SIZE;
PROVIDE(__stack_irq_end = .);
. = ALIGN(8);
PROVIDE(__stack_fiq_start = .);
. += STACK_FIQ_SIZE;
PROVIDE(__stack_fiq_end = .);
. = ALIGN(8);
PROVIDE(__stack_srv_start = .);
. += STACK_SRV_SIZE;
PROVIDE(__stack_srv_end = .);
. = ALIGN(8);
PROVIDE(__stack_end = .);
} > ram
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
}

View File

@ -0,0 +1,66 @@
/*
* start.S
*
* Copyright(c) 2007-2021 Jianjun Jiang <8192542@qq.com>
* Official site: http://xboot.org
* Mobile phone: +86-18665388956
* QQ: 8192542
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
.global _start
_start:
mov r0, #0
mcr p15, 0, r0, c8, c7, 0
mcr p15, 0, r0, c7, c5, 0
mcr p15, 0, r0, c7, c5, 6
mcr p15, 0, r0, c7, c10, 4
mcr p15, 0, r0, c7, c5, 4
b reset
reset:
ldr r0, =0x00040fe0
str sp, [r0, #0]
str lr, [r0, #4]
mrs lr, cpsr
str lr, [r0, #8]
mrc p15, 0, lr, c1, c0, 0
str lr, [r0, #12]
mrc p15, 0, lr, c12, c0, 0
str lr, [r0, #16]
mrc p15, 0, lr, c1, c0, 0
str lr, [r0, #20]
ldr r0, =0x00029000
bl sys_spi_run
ldr r0, =0x00040fe0
ldr sp, [r0, #0]
ldr lr, [r0, #4]
ldr r1, [r0, #20]
mcr p15, 0, r1, c1, c0, 0
ldr r1, [r0, #16]
mcr p15, 0, r1, c12, c0, 0
ldr r1, [r0, #12]
mcr p15, 0, r1, c1, c0, 0
ldr r1, [r0, #8]
msr cpsr, r1
bx lr

View File

@ -0,0 +1,287 @@
/*
* sys-spi.c
*
* Copyright(c) 2007-2021 Jianjun Jiang <8192542@qq.com>
* Official site: http://xboot.org
* Mobile phone: +86-18665388956
* QQ: 8192542
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#include <xboot.h>
enum {
SPI_GCR = 0x04,
SPI_TCR = 0x08,
SPI_IER = 0x10,
SPI_ISR = 0x14,
SPI_FCR = 0x18,
SPI_FSR = 0x1c,
SPI_WCR = 0x20,
SPI_CCR = 0x24,
SPI_MBC = 0x30,
SPI_MTC = 0x34,
SPI_BCC = 0x38,
SPI_TXD = 0x200,
SPI_RXD = 0x300,
};
static void sys_spi_init(void)
{
virtual_addr_t addr;
u32_t val;
/* Config GPIOC0, GPIOC1, GPIOC2, GPIOC3, GPIOC4 and GPIOC5 */
addr = 0x02000060 + 0x00;
val = read32(addr);
val &= ~(0xf << ((0 & 0x7) << 2));
val |= ((0x4 & 0xf) << ((0 & 0x7) << 2));
write32(addr, val);
val = read32(addr);
val &= ~(0xf << ((1 & 0x7) << 2));
val |= ((0x4 & 0xf) << ((1 & 0x7) << 2));
write32(addr, val);
val = read32(addr);
val &= ~(0xf << ((2 & 0x7) << 2));
val |= ((0x4 & 0xf) << ((2 & 0x7) << 2));
write32(addr, val);
val = read32(addr);
val &= ~(0xf << ((3 & 0x7) << 2));
val |= ((0x4 & 0xf) << ((3 & 0x7) << 2));
write32(addr, val);
val = read32(addr);
val &= ~(0xf << ((4 & 0x7) << 2));
val |= ((0x4 & 0xf) << ((4 & 0x7) << 2));
write32(addr, val);
val = read32(addr);
val &= ~(0xf << ((5 & 0x7) << 2));
val |= ((0x4 & 0xf) << ((5 & 0x7) << 2));
write32(addr, val);
/* Deassert spi0 reset */
addr = 0x0200196c;
val = read32(addr);
val |= (1 << 16);
write32(addr, val);
/* Open the spi0 gate */
addr = 0x02001940;
val = read32(addr);
val |= (1 << 31);
write32(addr, val);
/* Open the spi0 bus gate */
addr = 0x0200196c;
val = read32(addr);
val |= (1 << 0);
write32(addr, val);
/* Select pll-periph0 for spi0 clk */
addr = 0x02001940;
val = read32(addr);
val &= ~(0x3 << 24);
val |= 0x1 << 24;
write32(addr, val);
/* Set clock pre divide ratio, divided by 1 */
addr = 0x02001940;
val = read32(addr);
val &= ~(0x3 << 8);
val |= 0x0 << 8;
write32(addr, val);
/* Set clock divide ratio, divided by 6 */
addr = 0x02001940;
val = read32(addr);
val &= ~(0xf << 0);
val |= (6 - 1) << 0;
write32(addr, val);
/* Set spi clock rate control register, divided by 2 */
addr = 0x04025000;
write32(addr + SPI_CCR, 0x1000);
/* Enable spi0 and do a soft reset */
addr = 0x04025000;
val = read32(addr + SPI_GCR);
val |= (1 << 31) | (1 << 7) | (1 << 1) | (1 << 0);
write32(addr + SPI_GCR, val);
while(read32(addr + SPI_GCR) & (1 << 31));
val = read32(addr + SPI_TCR);
val &= ~(0x3 << 0);
val |= (1 << 6) | (1 << 2);
write32(addr + SPI_TCR, val);
val = read32(addr + SPI_FCR);
val |= (1 << 31) | (1 << 15);
write32(addr + SPI_FCR, val);
}
static void sys_spi_select(void)
{
virtual_addr_t addr = 0x04025000;
u32_t val;
val = read32(addr + SPI_TCR);
val &= ~((0x3 << 4) | (0x1 << 7));
val |= ((0 & 0x3) << 4) | (0x0 << 7);
write32(addr + SPI_TCR, val);
}
static void sys_spi_deselect(void)
{
virtual_addr_t addr = 0x04025000;
u32_t val;
val = read32(addr + SPI_TCR);
val &= ~((0x3 << 4) | (0x1 << 7));
val |= ((0 & 0x3) << 4) | (0x1 << 7);
write32(addr + SPI_TCR, val);
}
static inline void sys_spi_write_txbuf(u8_t * buf, int len)
{
virtual_addr_t addr = 0x04025000;
int i;
write32(addr + SPI_MTC, len & 0xffffff);
write32(addr + SPI_BCC, len & 0xffffff);
if(buf)
{
for(i = 0; i < len; i++)
write8(addr + SPI_TXD, *buf++);
}
else
{
for(i = 0; i < len; i++)
write8(addr + SPI_TXD, 0xff);
}
}
static void sys_spi_transfer(void * txbuf, void * rxbuf, u32_t len)
{
virtual_addr_t addr = 0x04025000;
u8_t * tx = txbuf;
u8_t * rx = rxbuf;
u8_t val;
int n, i;
while(len > 0)
{
n = (len <= 64) ? len : 64;
write32(addr + SPI_MBC, n);
sys_spi_write_txbuf(tx, n);
write32(addr + SPI_TCR, read32(addr + SPI_TCR) | (1 << 31));
while((read32(addr + SPI_FSR) & 0xff) < n);
for(i = 0; i < n; i++)
{
val = read8(addr + SPI_RXD);
if(rx)
*rx++ = val;
}
if(tx)
tx += n;
len -= n;
}
}
enum {
SPI_CMD_END = 0x00,
SPI_CMD_INIT = 0x01,
SPI_CMD_SELECT = 0x02,
SPI_CMD_DESELECT = 0x03,
SPI_CMD_FAST = 0x04,
SPI_CMD_TXBUF = 0x05,
SPI_CMD_RXBUF = 0x06,
SPI_CMD_SPINOR_WAIT = 0x07,
SPI_CMD_SPINAND_WAIT = 0x08,
};
void sys_spi_run(void * cbuf)
{
uint8_t tx[8], rx[8];
u8_t c, * p = cbuf;
u32_t addr, len;
while(1)
{
c = *p++;
if(c == SPI_CMD_INIT)
{
sys_spi_init();
}
else if(c == SPI_CMD_SELECT)
{
sys_spi_select();
}
else if(c == SPI_CMD_DESELECT)
{
sys_spi_deselect();
}
else if(c == SPI_CMD_FAST)
{
len = p[0];
sys_spi_transfer((void *)&p[1], NULL, len);
p += (len + 1);
}
else if(c == SPI_CMD_TXBUF)
{
addr = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
len = (p[4] << 0) | (p[5] << 8) | (p[6] << 16) | (p[7] << 24);
sys_spi_transfer((void *)((unsigned long)addr), NULL, len);
p += 8;
}
else if(c == SPI_CMD_RXBUF)
{
addr = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
len = (p[4] << 0) | (p[5] << 8) | (p[6] << 16) | (p[7] << 24);
sys_spi_transfer(NULL, (void *)((unsigned long)addr), len);
p += 8;
}
else if(c == SPI_CMD_SPINOR_WAIT)
{
tx[0] = 0x05;
do {
sys_spi_transfer((void *)&tx[0], NULL, 1);
sys_spi_transfer(NULL, (void *)&rx[0], 1);
} while((rx[0] & 0x1) == 0x1);
}
else if(c == SPI_CMD_SPINAND_WAIT)
{
tx[0] = 0x0f;
tx[1] = 0xc0;
do {
sys_spi_transfer((void *)&tx[0], NULL, 2);
sys_spi_transfer(NULL, (void *)&rx[0], 1);
} while((rx[0] & 0x1) == 0x1);
}
else
{
return;
}
}
}