Merge commit '4b1ea8511a7da9d7201df40302e3341c6e97ffdd' into from_upstream

Change-Id: I59366e08a4ac7e443e426b5fd6727c649f1ac9d5
This commit is contained in:
Tim Newsome 2023-11-27 10:04:09 -08:00
commit 84bcf9aa8b
60 changed files with 1508 additions and 285 deletions

View File

@ -1,60 +1,70 @@
/* Autogenerated with ../../../../src/helper/bin2char.sh */ /* Autogenerated with ../../../../src/helper/bin2char.sh */
0x08,0xb5,0xdf,0xf8,0x08,0xd0,0x00,0xf0,0x2f,0xf9,0x00,0x00,0x48,0x15,0x0c,0x20, 0x08,0xb5,0xdf,0xf8,0x08,0xd0,0x00,0xf0,0x95,0xf9,0x00,0x00,0xec,0x15,0x0c,0x20,
0x03,0x4b,0x18,0x70,0x19,0x72,0x08,0x33,0x1a,0x78,0xd2,0x09,0xfc,0xd1,0x70,0x47, 0x03,0x4b,0x18,0x70,0x08,0x33,0x19,0x70,0x1a,0x78,0xd2,0x09,0xfc,0xd1,0x70,0x47,
0x16,0x00,0x02,0x40,0x70,0xb5,0x11,0x4c,0x23,0x78,0x03,0xf0,0xfd,0x03,0x23,0x70, 0x16,0x00,0x02,0x40,0x13,0x4b,0x14,0x49,0x1a,0x68,0xea,0xb1,0x1a,0x68,0x01,0x2a,
0xc0,0x21,0x05,0x20,0xff,0xf7,0xec,0xff,0x0d,0x4a,0x0e,0x49,0x6f,0xf0,0x7f,0x43, 0x1e,0xd0,0x1b,0x68,0x02,0x2b,0x1b,0xd1,0x10,0x4b,0x1a,0x78,0x50,0xb1,0x02,0xf0,
0x6f,0xf0,0x2e,0x05,0x10,0x46,0x15,0x70,0x06,0x78,0xf6,0x09,0xfc,0xd1,0x0e,0x78, 0xf7,0x02,0x1a,0x70,0x01,0x22,0x08,0x78,0x01,0x23,0x93,0x40,0x03,0x43,0xdb,0xb2,
0xf6,0x07,0x01,0xd5,0x01,0x3b,0xf6,0xd1,0x22,0x78,0x42,0xf0,0x02,0x02,0x00,0x2b, 0x0b,0x70,0x70,0x47,0x42,0xf0,0x08,0x02,0x1a,0x70,0x01,0x22,0x08,0x78,0x01,0x23,
0x22,0x70,0x0c,0xbf,0x03,0x20,0x00,0x20,0x70,0xbd,0x00,0xbf,0x1f,0x00,0x02,0x40, 0x93,0x40,0x20,0xea,0x03,0x03,0xf3,0xe7,0x01,0x22,0x00,0x28,0xf6,0xd0,0xea,0xe7,
0x00,0x22,0xfa,0xe7,0x00,0x00,0x0c,0x20,0x1f,0x00,0x02,0x40,0x43,0x00,0x02,0x40,
0x73,0xb5,0x04,0x46,0x00,0x20,0x15,0x46,0x0e,0x46,0xff,0xf7,0xcb,0xff,0x0f,0x4b,
0x01,0x94,0xc4,0xf3,0x07,0x44,0x1c,0x70,0x9d,0xf8,0x05,0x20,0x5a,0x70,0x9d,0xf8,
0x04,0x20,0x9a,0x70,0xf3,0x21,0x02,0x20,0xff,0xf7,0xb2,0xff,0x2c,0x46,0x63,0x1b,
0xb3,0x42,0x05,0xd3,0x01,0x20,0x02,0xb0,0xbd,0xe8,0x70,0x40,0xff,0xf7,0xb2,0xbf,
0xe0,0x21,0x14,0xf8,0x01,0x0b,0xff,0xf7,0xa3,0xff,0xf0,0xe7,0x1a,0x00,0x02,0x40,
0x08,0x4b,0x1b,0x68,0x02,0x2b,0x08,0x4b,0x07,0xd1,0x08,0x4a,0x80,0x21,0x11,0x70,
0xc0,0x22,0x1a,0x70,0x00,0x22,0x1a,0x71,0x70,0x47,0x1a,0x78,0x42,0xf0,0x80,0x02,
0x1a,0x70,0x70,0x47,0x00,0x00,0x0c,0x20,0x10,0x30,0x0c,0x40,0x00,0x30,0x0c,0x40,
0x38,0xb5,0x00,0x20,0xff,0xf7,0x8e,0xff,0xc0,0x21,0x05,0x20,0xff,0xf7,0x80,0xff,
0x0b,0x4b,0x0c,0x4a,0x6f,0xf0,0x7f,0x44,0x6f,0xf0,0x2e,0x00,0x19,0x46,0x18,0x70,
0x0d,0x78,0xed,0x09,0xfc,0xd1,0x15,0x78,0xed,0x07,0x01,0xd5,0x01,0x3c,0xf6,0xd1,
0x01,0x20,0xff,0xf7,0x77,0xff,0x00,0x2c,0x0c,0xbf,0x03,0x20,0x00,0x20,0x38,0xbd,
0x1e,0x00,0x02,0x40,0x1a,0x00,0x02,0x40,0x08,0xb5,0xc0,0x21,0x06,0x20,0xff,0xf7, 0x1e,0x00,0x02,0x40,0x1a,0x00,0x02,0x40,0x08,0xb5,0xc0,0x21,0x06,0x20,0xff,0xf7,
0xc7,0xff,0xff,0xf7,0xcf,0xff,0x28,0xb9,0x03,0x4b,0x1b,0x78,0x13,0xf0,0x02,0x0f, 0x5f,0xff,0xff,0xf7,0xd5,0xff,0x28,0xb9,0x03,0x4b,0x1b,0x78,0x13,0xf0,0x02,0x0f,
0x08,0xbf,0x02,0x20,0x08,0xbd,0x00,0xbf,0x1a,0x00,0x02,0x40,0xf8,0xb5,0x12,0x4c, 0x08,0xbf,0x02,0x20,0x08,0xbd,0x00,0xbf,0x1a,0x00,0x02,0x40,0x70,0x47,0x00,0x00,
0x23,0x78,0x03,0xf0,0xfd,0x03,0x23,0x70,0x10,0x4b,0x17,0x46,0xc0,0xf3,0x07,0x42, 0x38,0xb5,0x17,0x4c,0xc1,0x21,0x05,0x20,0xff,0xf7,0x4a,0xff,0x25,0x78,0xc1,0x21,
0x1a,0x70,0xc0,0xf3,0x07,0x22,0xc0,0xb2,0x03,0xf8,0x01,0x2c,0x0e,0x46,0x03,0xf8, 0x35,0x20,0xff,0xf7,0x45,0xff,0x23,0x78,0xed,0xb2,0xdb,0xb2,0x05,0xb9,0xd3,0xb1,
0x02,0x0c,0xe8,0x21,0x02,0x20,0xff,0xf7,0xa3,0xff,0x00,0x25,0xae,0x42,0x04,0xd8, 0xff,0xf7,0xda,0xff,0xd0,0xb9,0x0f,0x4b,0x20,0x70,0xf2,0x21,0x18,0x70,0x01,0x20,
0x23,0x78,0x43,0xf0,0x02,0x03,0x23,0x70,0xf8,0xbd,0x78,0x5d,0xe0,0x21,0xff,0xf7, 0xff,0xf7,0x36,0xff,0xff,0xf7,0xac,0xff,0x80,0xb9,0xc1,0x21,0x05,0x20,0xff,0xf7,
0x97,0xff,0x01,0x35,0xf2,0xe7,0x00,0xbf,0x1f,0x00,0x02,0x40,0x19,0x00,0x02,0x40, 0x2f,0xff,0x25,0x78,0xc1,0x21,0x35,0x20,0xff,0xf7,0x2a,0xff,0x23,0x78,0xed,0xb2,
0x70,0x47,0x2d,0xe9,0xf0,0x41,0x00,0xf1,0xff,0x06,0x26,0xf0,0xff,0x06,0x34,0x1a, 0xdb,0xb2,0x15,0xb9,0x0b,0xb9,0x00,0x20,0x38,0xbd,0x02,0x20,0x38,0xbd,0x00,0xbf,
0x8c,0x42,0x28,0xbf,0x0c,0x46,0x80,0x46,0x0d,0x46,0x17,0x46,0x5c,0xb1,0xff,0xf7, 0x1a,0x00,0x02,0x40,0x1b,0x00,0x02,0x40,0x2d,0xe9,0xf8,0x43,0x81,0x46,0x0d,0x46,
0xb3,0xff,0x58,0xb9,0x3a,0x46,0xa1,0xb2,0x40,0x46,0xff,0xf7,0xbf,0xff,0xff,0xf7, 0x90,0x46,0xff,0xf7,0x75,0xff,0xff,0xf7,0xc3,0xff,0x06,0x46,0xb8,0xb9,0x09,0xf1,
0x81,0xff,0x18,0xb9,0x27,0x44,0x2c,0x1b,0x14,0xb9,0x20,0x46,0xbd,0xe8,0xf0,0x81, 0xff,0x07,0x27,0xf0,0xff,0x07,0xa7,0xeb,0x09,0x04,0xac,0x42,0x28,0xbf,0x2c,0x46,
0xb4,0xf5,0x80,0x7f,0x25,0x46,0x28,0xbf,0x4f,0xf4,0x80,0x75,0xff,0xf7,0x9c,0xff, 0x5c,0xb1,0xff,0xf7,0xa1,0xff,0x10,0xbb,0x42,0x46,0xa1,0xb2,0x48,0x46,0xff,0xf7,
0x00,0x28,0xf3,0xd1,0x3a,0x46,0xa9,0xb2,0x30,0x46,0xff,0xf7,0xa7,0xff,0xff,0xf7, 0x37,0xff,0xff,0xf7,0x75,0xff,0xd0,0xb9,0xa0,0x44,0x2c,0x1b,0x14,0xb9,0x30,0x46,
0x69,0xff,0x00,0x28,0xea,0xd1,0x2f,0x44,0x2e,0x44,0x64,0x1b,0xe4,0xe7,0x00,0x00, 0xbd,0xe8,0xf8,0x83,0xff,0xf7,0x90,0xff,0x88,0xb9,0xb4,0xf5,0x80,0x7f,0x25,0x46,
0x2d,0xe9,0xf0,0x47,0x14,0x4e,0x15,0x4f,0xdf,0xf8,0x54,0x80,0x05,0x46,0x0c,0x46, 0x28,0xbf,0x4f,0xf4,0x80,0x75,0x42,0x46,0xa9,0xb2,0x38,0x46,0xff,0xf7,0x20,0xff,
0x8a,0x46,0x05,0xeb,0x04,0x09,0xa9,0xeb,0x0a,0x09,0xba,0xf1,0x00,0x0f,0x02,0xd1, 0xff,0xf7,0x5e,0xff,0x18,0xb9,0xa8,0x44,0x2f,0x44,0x64,0x1b,0xe6,0xe7,0x06,0x46,
0x50,0x46,0xbd,0xe8,0xf0,0x87,0xff,0xf7,0x77,0xff,0x00,0x28,0xf9,0xd1,0xc9,0xf3, 0xe5,0xe7,0x00,0x00,0x2d,0xe9,0xf7,0x4f,0x06,0x46,0x0d,0x46,0xff,0xf7,0x38,0xff,
0x07,0x43,0x33,0x70,0xc9,0xf3,0x07,0x23,0x5f,0xfa,0x89,0xf9,0x3b,0x70,0xc8,0x21, 0xff,0xf7,0x86,0xff,0x82,0x46,0x58,0xb9,0x15,0x4f,0xdf,0xf8,0x58,0x80,0xdf,0xf8,
0x20,0x20,0x88,0xf8,0x00,0x90,0xff,0xf7,0x33,0xff,0xff,0xf7,0x3b,0xff,0x00,0x28, 0x58,0x90,0xab,0x46,0x74,0x19,0xa4,0xeb,0x0b,0x04,0xbb,0xf1,0x00,0x0f,0x03,0xd1,
0xe7,0xd1,0xaa,0xf5,0x80,0x5a,0xdc,0xe7,0x19,0x00,0x02,0x40,0x18,0x00,0x02,0x40, 0x50,0x46,0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0xff,0xf7,0x5e,0xff,0xa8,0xb9,0x01,0x94,
0x17,0x00,0x02,0x40,0x08,0xb5,0xff,0xf7,0x57,0xff,0x38,0xb9,0xc0,0x21,0xc7,0x20, 0xc4,0xf3,0x07,0x44,0x3c,0x70,0x9d,0xf8,0x05,0x30,0x88,0xf8,0x00,0x30,0x9d,0xf8,
0xff,0xf7,0x1e,0xff,0xbd,0xe8,0x08,0x40,0xff,0xf7,0x24,0xbf,0x08,0xbd,0x00,0x00, 0x04,0x30,0x89,0xf8,0x00,0x30,0xf3,0x21,0x20,0x20,0xff,0xf7,0xb1,0xfe,0xff,0xf7,
0x38,0xb5,0xff,0xf7,0x49,0xff,0x04,0x46,0xc0,0xb9,0x0d,0x4b,0x0d,0x4d,0xf2,0x21, 0x27,0xff,0x10,0xb9,0xab,0xf5,0x80,0x5b,0xdc,0xe7,0x82,0x46,0xe0,0xe7,0x00,0xbf,
0x28,0x70,0x18,0x70,0x01,0x20,0xff,0xf7,0x0b,0xff,0xff,0xf7,0x13,0xff,0x04,0x46, 0x1a,0x00,0x02,0x40,0x1b,0x00,0x02,0x40,0x1c,0x00,0x02,0x40,0x08,0xb5,0xff,0xf7,
0x60,0xb9,0xc1,0x21,0x05,0x20,0xff,0xf7,0x03,0xff,0x2b,0x78,0x2b,0xb9,0xc1,0x21, 0xff,0xfe,0xff,0xf7,0x4d,0xff,0x50,0xb9,0xff,0xf7,0x36,0xff,0x38,0xb9,0xc0,0x21,
0x35,0x20,0xff,0xf7,0xfd,0xfe,0x2b,0x78,0x03,0xb1,0x02,0x24,0x20,0x46,0x38,0xbd, 0xc7,0x20,0xff,0xf7,0x95,0xfe,0xbd,0xe8,0x08,0x40,0xff,0xf7,0x09,0xbf,0x08,0xbd,
0x1b,0x00,0x02,0x40,0x1a,0x00,0x02,0x40,0x10,0xb5,0xc3,0x21,0x04,0x46,0x9f,0x20, 0x10,0xb5,0x04,0x46,0xff,0xf7,0xec,0xfe,0xc3,0x21,0x9f,0x20,0xff,0xf7,0x88,0xfe,
0xff,0xf7,0xee,0xfe,0x06,0x4b,0x07,0x4a,0x19,0x78,0x01,0x33,0x00,0x20,0x1b,0x78, 0x06,0x4b,0x07,0x4a,0x19,0x78,0x01,0x33,0x00,0x20,0x1b,0x78,0x12,0x78,0x1b,0x02,
0x12,0x78,0x1b,0x02,0x43,0xea,0x01,0x43,0x13,0x43,0x23,0x60,0x10,0xbd,0x00,0xbf, 0x43,0xea,0x01,0x43,0x13,0x43,0x23,0x60,0x10,0xbd,0x00,0xbf,0x1a,0x00,0x02,0x40,
0x1a,0x00,0x02,0x40,0x1c,0x00,0x02,0x40,0x08,0xb5,0x10,0x22,0x00,0x21,0x00,0xf0, 0x1c,0x00,0x02,0x40,0x08,0xb5,0x14,0x22,0x00,0x21,0x00,0xf0,0x41,0xf8,0x00,0x20,
0x4d,0xf8,0x00,0x20,0x08,0xbd,0x00,0x00,0x73,0xb5,0x21,0x48,0x20,0x4c,0xff,0xf7, 0x08,0xbd,0x00,0x00,0x73,0xb5,0x1c,0x48,0x1b,0x4e,0x1c,0x4d,0xff,0xf7,0xf2,0xff,
0xf3,0xff,0x20,0x4a,0x13,0x78,0x43,0xf0,0x80,0x03,0x13,0x70,0xff,0xf7,0xb0,0xff, 0x34,0x46,0x33,0x69,0x00,0x2b,0xfc,0xd0,0xf3,0x68,0x01,0x3b,0x03,0x2b,0x29,0xd8,
0x05,0x46,0x58,0xb9,0x1c,0x4e,0xe3,0x68,0x00,0x2b,0xfc,0xd0,0xa3,0x68,0x01,0x3b, 0xdf,0xe8,0x03,0xf0,0x02,0x17,0x1f,0x22,0x01,0xa8,0xff,0xf7,0xc9,0xff,0xb0,0xb9,
0x03,0x2b,0x2a,0xd8,0xdf,0xe8,0x03,0xf0,0x04,0x18,0x20,0x23,0xe5,0x60,0xfd,0xe7, 0x01,0x9b,0x2b,0x70,0x19,0x0a,0x1b,0x0c,0x69,0x70,0xab,0x70,0xe8,0x70,0x23,0x7c,
0x01,0xa8,0xff,0xf7,0xc1,0xff,0xa8,0xb9,0x01,0x9b,0x33,0x70,0x1a,0x0a,0x1b,0x0c, 0x00,0x23,0x23,0x74,0x62,0x7c,0x63,0x74,0xa2,0x7c,0xa3,0x74,0xe2,0x7c,0xe3,0x74,
0x72,0x70,0xb3,0x70,0xf0,0x70,0x23,0x7b,0x25,0x73,0x63,0x7b,0x65,0x73,0xa3,0x7b, 0xdf,0xe7,0x60,0x68,0xa1,0x68,0xff,0xf7,0x65,0xff,0x00,0x28,0xef,0xd0,0x20,0x61,
0xa5,0x73,0xe3,0x7b,0xe5,0x73,0xde,0xe7,0x20,0x68,0x61,0x68,0xff,0xf7,0x48,0xff, 0xfe,0xe7,0xff,0xf7,0x9b,0xff,0xf8,0xe7,0x60,0x68,0xa1,0x68,0x2a,0x46,0xff,0xf7,
0x00,0x28,0xf0,0xd0,0xe0,0x60,0xfe,0xe7,0xff,0xf7,0x74,0xff,0xf8,0xe7,0x20,0x68, 0x1b,0xff,0xf2,0xe7,0x01,0x20,0xf2,0xe7,0x00,0x00,0x0c,0x20,0x14,0x00,0x0c,0x20,
0x61,0x68,0x32,0x46,0xff,0xf7,0x05,0xff,0xf2,0xe7,0x01,0x20,0xf2,0xe7,0x00,0xbf, 0xf0,0xb5,0x83,0x07,0x47,0xd0,0x54,0x1e,0x00,0x2a,0x41,0xd0,0x0d,0x06,0x2d,0x0e,
0x00,0x00,0x0c,0x20,0x10,0x30,0x0c,0x40,0x10,0x00,0x0c,0x20,0xf0,0xb5,0x05,0x00, 0x02,0x00,0x03,0x26,0x02,0xe0,0x1a,0x00,0x01,0x3c,0x39,0xd3,0x53,0x1c,0x15,0x70,
0x83,0x07,0x4e,0xd0,0x54,0x1e,0x00,0x2a,0x46,0xd0,0x0a,0x06,0x12,0x0e,0x03,0x00, 0x33,0x42,0xf8,0xd1,0x03,0x2c,0x2a,0xd9,0xff,0x22,0x0a,0x40,0x15,0x02,0x15,0x43,
0x03,0x26,0x02,0xe0,0x01,0x35,0x01,0x3c,0x3e,0xd3,0x01,0x33,0x2a,0x70,0x33,0x42, 0x2a,0x04,0x15,0x43,0x0f,0x2c,0x14,0xd9,0x27,0x00,0x1a,0x00,0x10,0x3f,0x3e,0x09,
0xf8,0xd1,0x03,0x2c,0x2f,0xd9,0xff,0x22,0x0a,0x40,0x15,0x02,0x15,0x43,0x2a,0x04, 0x01,0x36,0x36,0x01,0x9e,0x19,0x15,0x60,0x55,0x60,0x95,0x60,0xd5,0x60,0x10,0x32,
0x15,0x43,0x0f,0x2c,0x38,0xd9,0x27,0x00,0x10,0x3f,0x3f,0x09,0x3e,0x01,0xb4,0x46, 0x96,0x42,0xf8,0xd1,0x0f,0x22,0x97,0x43,0x10,0x37,0xdb,0x19,0x14,0x40,0x03,0x2c,
0x1e,0x00,0x1a,0x00,0x10,0x36,0x66,0x44,0x15,0x60,0x55,0x60,0x95,0x60,0xd5,0x60, 0x0d,0xd9,0x1a,0x00,0x27,0x1f,0xbe,0x08,0x01,0x36,0xb6,0x00,0x9e,0x19,0x20,0xc2,
0x10,0x32,0xb2,0x42,0xf8,0xd1,0x0f,0x26,0x0c,0x22,0x01,0x37,0x3f,0x01,0x26,0x40, 0xb2,0x42,0xfc,0xd1,0x03,0x22,0x97,0x43,0x04,0x37,0xdb,0x19,0x14,0x40,0x00,0x2c,
0xdb,0x19,0x37,0x00,0x22,0x42,0x1a,0xd0,0x3e,0x1f,0xb6,0x08,0xb4,0x00,0xa4,0x46, 0x06,0xd0,0x09,0x06,0x1c,0x19,0x09,0x0e,0x19,0x70,0x01,0x33,0x9c,0x42,0xfb,0xd1,
0x1a,0x00,0x1c,0x1d,0x64,0x44,0x20,0xc2,0xa2,0x42,0xfc,0xd1,0x03,0x24,0x01,0x36, 0xf0,0xbc,0x02,0xbc,0x08,0x47,0x14,0x00,0x03,0x00,0xc3,0xe7,
0xb6,0x00,0x9b,0x19,0x3c,0x40,0x00,0x2c,0x06,0xd0,0x09,0x06,0x1c,0x19,0x09,0x0e,
0x19,0x70,0x01,0x33,0x9c,0x42,0xfb,0xd1,0xf0,0xbc,0x02,0xbc,0x08,0x47,0x34,0x00,
0xf1,0xe7,0x14,0x00,0x03,0x00,0xbc,0xe7,0x27,0x00,0xdd,0xe7,

View File

@ -10,9 +10,29 @@
#include <string.h> #include <string.h>
#include "npcx_flash.h" #include "npcx_flash.h"
/* flashloader parameter structure */
__attribute__ ((section(".buffers.g_cfg")))
static volatile struct npcx_flash_params g_cfg;
/* data buffer */
__attribute__ ((section(".buffers.g_buf")))
static uint8_t g_buf[NPCX_FLASH_LOADER_BUFFER_SIZE];
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
* NPCX flash driver * NPCX flash driver
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static void flash_init(void)
{
if (g_cfg.fiu_ver == NPCX_FIU_NPCK) {
/* Set pinmux to SHD flash */
NPCX_DEVCNT = 0x80;
NPCX_DEVALT(0) = 0xC0;
NPCX_DEVALT(4) = 0x00;
} else {
/* Avoid F_CS0 toggles while programming the internal flash. */
NPCX_SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_NO_F_SPI);
}
}
static void flash_execute_cmd(uint8_t code, uint8_t cts) static void flash_execute_cmd(uint8_t code, uint8_t cts)
{ {
/* Set UMA code */ /* Set UMA code */
@ -26,11 +46,26 @@ static void flash_execute_cmd(uint8_t code, uint8_t cts)
static void flash_cs_level(uint8_t level) static void flash_cs_level(uint8_t level)
{ {
int sw_cs = 0;
if (g_cfg.fiu_ver == NPCX_FIU_NPCX) {
sw_cs = 1;
} else if (g_cfg.fiu_ver == NPCX_FIU_NPCX_V2) {
sw_cs = 0;
} else if (g_cfg.fiu_ver == NPCX_FIU_NPCK) {
sw_cs = 1;
/* Unlock UMA before pulling down CS in NPCK series */
if (level)
NPCX_CLEAR_BIT(NPCX_FIU_MSR_IE_CFG, NPCX_FIU_MSR_IE_CFG_UMA_BLOCK);
else
NPCX_SET_BIT(NPCX_FIU_MSR_IE_CFG, NPCX_FIU_MSR_IE_CFG_UMA_BLOCK);
}
/* Program chip select pin to high/low level */ /* Program chip select pin to high/low level */
if (level) if (level)
NPCX_SET_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_SW_CS1); NPCX_SET_BIT(NPCX_UMA_ECTS, sw_cs);
else else
NPCX_CLEAR_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_SW_CS1); NPCX_CLEAR_BIT(NPCX_UMA_ECTS, sw_cs);
} }
static void flash_set_address(uint32_t dest_addr) static void flash_set_address(uint32_t dest_addr)
@ -38,15 +73,15 @@ static void flash_set_address(uint32_t dest_addr)
uint8_t *addr = (uint8_t *)&dest_addr; uint8_t *addr = (uint8_t *)&dest_addr;
/* Set target flash address */ /* Set target flash address */
NPCX_UMA_AB2 = addr[2]; NPCX_UMA_DB0 = addr[2];
NPCX_UMA_AB1 = addr[1]; NPCX_UMA_DB1 = addr[1];
NPCX_UMA_AB0 = addr[0]; NPCX_UMA_DB2 = addr[0];
} }
void delay(uint32_t i) static void delay(uint32_t i)
{ {
while (i--) while (i--)
; __asm__ volatile ("nop");
} }
static int flash_wait_ready(uint32_t timeout) static int flash_wait_ready(uint32_t timeout)
@ -104,7 +139,7 @@ static void flash_burst_write(uint32_t dest_addr, uint16_t bytes,
/* Set write address */ /* Set write address */
flash_set_address(dest_addr); flash_set_address(dest_addr);
/* Start programming */ /* Start programming */
flash_execute_cmd(NPCX_CMD_FLASH_PROGRAM, NPCX_MASK_CMD_WR_ADR); flash_execute_cmd(NPCX_CMD_FLASH_PROGRAM, NPCX_MASK_CMD_WR_3BYTE);
for (uint32_t i = 0; i < bytes; i++) { for (uint32_t i = 0; i < bytes; i++) {
flash_execute_cmd(*data, NPCX_MASK_CMD_WR_ONLY); flash_execute_cmd(*data, NPCX_MASK_CMD_WR_ONLY);
data++; data++;
@ -114,6 +149,15 @@ static void flash_burst_write(uint32_t dest_addr, uint16_t bytes,
flash_cs_level(1); flash_cs_level(1);
} }
static void flash_get_stsreg(uint8_t *reg1, uint8_t *reg2)
{
/* Read status register 1/2 for checking */
flash_execute_cmd(NPCX_CMD_READ_STATUS_REG, NPCX_MASK_CMD_RD_1BYTE);
*reg1 = NPCX_UMA_DB0;
flash_execute_cmd(NPCX_CMD_READ_STATUS_REG2, NPCX_MASK_CMD_RD_1BYTE);
*reg2 = NPCX_UMA_DB0;
}
/* The data to write cannot cross 256 Bytes boundary */ /* The data to write cannot cross 256 Bytes boundary */
static int flash_program_write(uint32_t addr, uint32_t size, static int flash_program_write(uint32_t addr, uint32_t size,
const uint8_t *data) const uint8_t *data)
@ -126,7 +170,41 @@ static int flash_program_write(uint32_t addr, uint32_t size,
return flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT); return flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT);
} }
int flash_physical_write(uint32_t offset, uint32_t size, const uint8_t *data) static int flash_physical_clear_stsreg(void)
{
int status;
uint8_t reg1, reg2;
/* Read status register 1/2 for checking */
flash_get_stsreg(&reg1, &reg2);
if (reg1 == 0x00 && reg2 == 0x00)
return NPCX_FLASH_STATUS_OK;
/* Enable write */
status = flash_write_enable();
if (status != NPCX_FLASH_STATUS_OK)
return status;
NPCX_UMA_DB0 = 0x0;
NPCX_UMA_DB1 = 0x0;
/* Write status register 1/2 */
flash_execute_cmd(NPCX_CMD_WRITE_STATUS_REG, NPCX_MASK_CMD_WR_2BYTE);
/* Wait writing completed */
status = flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT);
if (status != NPCX_FLASH_STATUS_OK)
return status;
/* Read status register 1/2 for checking */
flash_get_stsreg(&reg1, &reg2);
if (reg1 != 0x00 || reg2 != 0x00)
return NPCX_FLASH_STATUS_FAILED;
return NPCX_FLASH_STATUS_OK;
}
static int flash_physical_write(uint32_t offset, uint32_t size, const uint8_t *data)
{ {
int status; int status;
uint32_t trunk_start = (offset + 0xff) & ~0xff; uint32_t trunk_start = (offset + 0xff) & ~0xff;
@ -135,6 +213,13 @@ int flash_physical_write(uint32_t offset, uint32_t size, const uint8_t *data)
uint32_t dest_addr = offset; uint32_t dest_addr = offset;
uint32_t write_len = ((trunk_start - offset) > size) ? size : (trunk_start - offset); uint32_t write_len = ((trunk_start - offset) > size) ? size : (trunk_start - offset);
/* Configure fiu and clear status registers if needed */
flash_init();
status = flash_physical_clear_stsreg();
if (status != NPCX_FLASH_STATUS_OK)
return status;
if (write_len) { if (write_len) {
status = flash_program_write(dest_addr, write_len, data); status = flash_program_write(dest_addr, write_len, data);
if (status != NPCX_FLASH_STATUS_OK) if (status != NPCX_FLASH_STATUS_OK)
@ -162,8 +247,16 @@ int flash_physical_write(uint32_t offset, uint32_t size, const uint8_t *data)
return NPCX_FLASH_STATUS_OK; return NPCX_FLASH_STATUS_OK;
} }
int flash_physical_erase(uint32_t offset, uint32_t size) static int flash_physical_erase(uint32_t offset, uint32_t size)
{ {
/* Configure fiu */
flash_init();
/* clear flash status registers */
int status = flash_physical_clear_stsreg();
if (status != NPCX_FLASH_STATUS_OK)
return status;
/* Alignment has been checked in upper layer */ /* Alignment has been checked in upper layer */
for (; size > 0; size -= NPCX_FLASH_ERASE_SIZE, for (; size > 0; size -= NPCX_FLASH_ERASE_SIZE,
offset += NPCX_FLASH_ERASE_SIZE) { offset += NPCX_FLASH_ERASE_SIZE) {
@ -175,7 +268,7 @@ int flash_physical_erase(uint32_t offset, uint32_t size)
/* Set erase address */ /* Set erase address */
flash_set_address(offset); flash_set_address(offset);
/* Start erase */ /* Start erase */
flash_execute_cmd(NPCX_CMD_SECTOR_ERASE, NPCX_MASK_CMD_ADR); flash_execute_cmd(NPCX_CMD_SECTOR_ERASE, NPCX_MASK_CMD_WR_3BYTE);
/* Wait erase completed */ /* Wait erase completed */
status = flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT); status = flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT);
if (status != NPCX_FLASH_STATUS_OK) if (status != NPCX_FLASH_STATUS_OK)
@ -185,10 +278,18 @@ int flash_physical_erase(uint32_t offset, uint32_t size)
return NPCX_FLASH_STATUS_OK; return NPCX_FLASH_STATUS_OK;
} }
int flash_physical_erase_all(void) static int flash_physical_erase_all(void)
{ {
int status;
/* Configure fiu and clear status register if needed */
flash_init();
status = flash_physical_clear_stsreg();
if (status != NPCX_FLASH_STATUS_OK)
return status;
/* Enable write */ /* Enable write */
int status = flash_write_enable(); status = flash_write_enable();
if (status != NPCX_FLASH_STATUS_OK) if (status != NPCX_FLASH_STATUS_OK)
return status; return status;
@ -203,37 +304,10 @@ int flash_physical_erase_all(void)
return NPCX_FLASH_STATUS_OK; return NPCX_FLASH_STATUS_OK;
} }
int flash_physical_clear_stsreg(void) static int flash_get_id(uint32_t *id)
{ {
/* Enable write */ flash_init();
int status = flash_write_enable();
if (status != NPCX_FLASH_STATUS_OK)
return status;
NPCX_UMA_DB0 = 0x0;
NPCX_UMA_DB1 = 0x0;
/* Write status register 1/2 */
flash_execute_cmd(NPCX_CMD_WRITE_STATUS_REG, NPCX_MASK_CMD_WR_2BYTE);
/* Wait writing completed */
status = flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT);
if (status != NPCX_FLASH_STATUS_OK)
return status;
/* Read status register 1/2 for checking */
flash_execute_cmd(NPCX_CMD_READ_STATUS_REG, NPCX_MASK_CMD_RD_1BYTE);
if (NPCX_UMA_DB0 != 0x00)
return NPCX_FLASH_STATUS_FAILED;
flash_execute_cmd(NPCX_CMD_READ_STATUS_REG2, NPCX_MASK_CMD_RD_1BYTE);
if (NPCX_UMA_DB0 != 0x00)
return NPCX_FLASH_STATUS_FAILED;
return NPCX_FLASH_STATUS_OK;
}
int flash_get_id(uint32_t *id)
{
flash_execute_cmd(NPCX_CMD_READ_ID, NPCX_MASK_CMD_RD_3BYTE); flash_execute_cmd(NPCX_CMD_READ_ID, NPCX_MASK_CMD_RD_3BYTE);
*id = NPCX_UMA_DB0 << 16 | NPCX_UMA_DB1 << 8 | NPCX_UMA_DB2; *id = NPCX_UMA_DB0 << 16 | NPCX_UMA_DB1 << 8 | NPCX_UMA_DB2;
@ -243,7 +317,7 @@ int flash_get_id(uint32_t *id)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
* flash loader function * flash loader function
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint32_t flashloader_init(struct npcx_flash_params *params) static uint32_t flashloader_init(struct npcx_flash_params *params)
{ {
/* Initialize params buffers */ /* Initialize params buffers */
memset(params, 0, sizeof(struct npcx_flash_params)); memset(params, 0, sizeof(struct npcx_flash_params));
@ -254,30 +328,13 @@ uint32_t flashloader_init(struct npcx_flash_params *params)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
* Functions * Functions
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
/* flashloader parameter structure */ static int main(void)
__attribute__ ((section(".buffers.g_cfg")))
volatile struct npcx_flash_params g_cfg;
/* data buffer */
__attribute__ ((section(".buffers.g_buf")))
uint8_t g_buf[NPCX_FLASH_LOADER_BUFFER_SIZE];
int main(void)
{ {
uint32_t id; uint32_t id, status;
/* set buffer */ /* set buffer */
flashloader_init((struct npcx_flash_params *)&g_cfg); flashloader_init((struct npcx_flash_params *)&g_cfg);
/* Avoid F_CS0 toggles while programming the internal flash. */
NPCX_SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_NO_F_SPI);
/* clear flash status registers */
int status = flash_physical_clear_stsreg();
if (status != NPCX_FLASH_STATUS_OK) {
while (1)
g_cfg.sync = status;
}
while (1) { while (1) {
/* wait command*/ /* wait command*/
while (g_cfg.sync == NPCX_FLASH_LOADER_WAIT) while (g_cfg.sync == NPCX_FLASH_LOADER_WAIT)

View File

@ -80,6 +80,7 @@
#define NPCX_FIU_DMM_CYC NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x032) #define NPCX_FIU_DMM_CYC NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x032)
#define NPCX_FIU_EXT_CFG NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x033) #define NPCX_FIU_EXT_CFG NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x033)
#define NPCX_FIU_UMA_AB0_3 NPCX_HW_DWORD(NPCX_FIU_BASE_ADDR + 0x034) #define NPCX_FIU_UMA_AB0_3 NPCX_HW_DWORD(NPCX_FIU_BASE_ADDR + 0x034)
#define NPCX_FIU_MSR_IE_CFG NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x043)
/* FIU register fields */ /* FIU register fields */
#define NPCX_RESP_CFG_IAD_EN 0 #define NPCX_RESP_CFG_IAD_EN 0
@ -93,6 +94,7 @@
#define NPCX_UMA_ECTS_SW_CS1 1 #define NPCX_UMA_ECTS_SW_CS1 1
#define NPCX_UMA_ECTS_SEC_CS 2 #define NPCX_UMA_ECTS_SEC_CS 2
#define NPCX_UMA_ECTS_UMA_LOCK 3 #define NPCX_UMA_ECTS_UMA_LOCK 3
#define NPCX_FIU_MSR_IE_CFG_UMA_BLOCK 3
/* Flash UMA commands for npcx internal SPI flash */ /* Flash UMA commands for npcx internal SPI flash */
#define NPCX_CMD_READ_ID 0x9F #define NPCX_CMD_READ_ID 0x9F
@ -130,7 +132,6 @@
#define NPCX_SPI_FLASH_SR1_BUSY (1 << 0) #define NPCX_SPI_FLASH_SR1_BUSY (1 << 0)
#define NPCX_MASK_CMD_ONLY (0xC0) #define NPCX_MASK_CMD_ONLY (0xC0)
#define NPCX_MASK_CMD_ADR (0xC0 | 0x08)
#define NPCX_MASK_CMD_ADR_WR (0xC0 | 0x20 | 0x08 | 0x01) #define NPCX_MASK_CMD_ADR_WR (0xC0 | 0x20 | 0x08 | 0x01)
#define NPCX_MASK_RD_1BYTE (0xC0 | 0x10 | 0x01) #define NPCX_MASK_RD_1BYTE (0xC0 | 0x10 | 0x01)
#define NPCX_MASK_RD_2BYTE (0xC0 | 0x10 | 0x02) #define NPCX_MASK_RD_2BYTE (0xC0 | 0x10 | 0x02)
@ -143,10 +144,12 @@
#define NPCX_MASK_CMD_WR_ONLY (0xC0 | 0x20) #define NPCX_MASK_CMD_WR_ONLY (0xC0 | 0x20)
#define NPCX_MASK_CMD_WR_1BYTE (0xC0 | 0x20 | 0x10 | 0x01) #define NPCX_MASK_CMD_WR_1BYTE (0xC0 | 0x20 | 0x10 | 0x01)
#define NPCX_MASK_CMD_WR_2BYTE (0xC0 | 0x20 | 0x10 | 0x02) #define NPCX_MASK_CMD_WR_2BYTE (0xC0 | 0x20 | 0x10 | 0x02)
#define NPCX_MASK_CMD_WR_ADR (0xC0 | 0x20 | 0x08) #define NPCX_MASK_CMD_WR_3BYTE (0xC0 | 0x20 | 0x10 | 0x03)
#define NPCX_MASK_CMD_WR_4BYTE (0xC0 | 0x20 | 0x10 | 0x04)
/* Flash loader parameters */ /* Flash loader parameters */
struct __attribute__((__packed__)) npcx_flash_params { struct __attribute__((__packed__)) npcx_flash_params {
uint32_t fiu_ver; /* Flash controller unit version */
uint32_t addr; /* Address in flash */ uint32_t addr; /* Address in flash */
uint32_t len; /* Number of bytes */ uint32_t len; /* Number of bytes */
uint32_t cmd; /* Command */ uint32_t cmd; /* Command */
@ -176,4 +179,10 @@ enum npcx_flash_status {
NPCX_FLASH_STATUS_FAILED_TIMEOUT, NPCX_FLASH_STATUS_FAILED_TIMEOUT,
}; };
enum npcx_fiu_ver {
NPCX_FIU_NPCX = 0,
NPCX_FIU_NPCX_V2,
NPCX_FIU_NPCK,
};
#endif /* OPENOCD_LOADERS_FLASH_NPCX_NPCX_FLASH_H */ #endif /* OPENOCD_LOADERS_FLASH_NPCX_NPCX_FLASH_H */

View File

@ -18,7 +18,7 @@
/* NPCX flash loader information */ /* NPCX flash loader information */
#define NPCX_FLASH_LOADER_WORKING_ADDR 0x200C0000 #define NPCX_FLASH_LOADER_WORKING_ADDR 0x200C0000
#define NPCX_FLASH_LOADER_PARAMS_ADDR NPCX_FLASH_LOADER_WORKING_ADDR #define NPCX_FLASH_LOADER_PARAMS_ADDR NPCX_FLASH_LOADER_WORKING_ADDR
#define NPCX_FLASH_LOADER_PARAMS_SIZE 16 #define NPCX_FLASH_LOADER_PARAMS_SIZE 20
#define NPCX_FLASH_LOADER_BUFFER_ADDR (NPCX_FLASH_LOADER_PARAMS_ADDR + NPCX_FLASH_LOADER_PARAMS_SIZE) #define NPCX_FLASH_LOADER_BUFFER_ADDR (NPCX_FLASH_LOADER_PARAMS_ADDR + NPCX_FLASH_LOADER_PARAMS_SIZE)
#define NPCX_FLASH_LOADER_BUFFER_SIZE NPCX_FLASH_ERASE_SIZE #define NPCX_FLASH_LOADER_BUFFER_SIZE NPCX_FLASH_ERASE_SIZE
#define NPCX_FLASH_LOADER_PROGRAM_ADDR (NPCX_FLASH_LOADER_BUFFER_ADDR + NPCX_FLASH_LOADER_BUFFER_SIZE) #define NPCX_FLASH_LOADER_PROGRAM_ADDR (NPCX_FLASH_LOADER_BUFFER_ADDR + NPCX_FLASH_LOADER_BUFFER_SIZE)

View File

@ -111,8 +111,8 @@ Finally, try to avoid lines of code that are longer than 72-80 columns:
@section stylenames Naming Rules @section stylenames Naming Rules
- most identifiers must use lower-case letters (and digits) only. - most identifiers must use lower-case letters (and digits) only.
- macros must use upper-case letters (and digits) only. - macros and enumerators must use upper-case letters (and digits) only.
- OpenOCD identifiers should NEVER use @c MixedCaps. - OpenOCD identifiers should NEVER use @c MixedCaps, aka @c CamelCase.
- @c typedef names must end with the '_t' suffix. - @c typedef names must end with the '_t' suffix.
- This should be reserved for types that should be passed by value. - This should be reserved for types that should be passed by value.
- Do @b not mix the typedef keyword with @c struct. - Do @b not mix the typedef keyword with @c struct.

View File

@ -5929,24 +5929,42 @@ flash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME
@c "cfi part_id" disabled @c "cfi part_id" disabled
@end deffn @end deffn
@anchor{jtagspi}
@deffn {Flash Driver} {jtagspi} @deffn {Flash Driver} {jtagspi}
@cindex Generic JTAG2SPI driver @cindex Generic JTAG2SPI driver
@cindex SPI @cindex SPI
@cindex jtagspi @cindex jtagspi
@cindex bscan_spi @cindex bscan_spi
Several FPGAs and CPLDs can retrieve their configuration (bitstream) from a Several FPGAs and CPLDs can retrieve their configuration (bitstream) from a
SPI flash connected to them. To access this flash from the host, the device SPI flash connected to them. To access this flash from the host, some FPGA
is first programmed with a special proxy bitstream that device provides dedicated JTAG instructions, while other FPGA devices should
exposes the SPI flash on the device's JTAG interface. The flash can then be be programmed with a special proxy bitstream that exposes the SPI flash on
accessed through JTAG. the device's JTAG interface. The flash can then be accessed through JTAG.
Since signaling between JTAG and SPI is compatible, all that is required for Since signalling between JTAG and SPI is compatible, all that is required for
a proxy bitstream is to connect TDI-MOSI, TDO-MISO, TCK-CLK and activate a proxy bitstream is to connect TDI-MOSI, TDO-MISO, TCK-CLK and activate
the flash chip select when the JTAG state machine is in SHIFT-DR. Such the flash chip select when the JTAG state machine is in SHIFT-DR.
a bitstream for several Xilinx FPGAs can be found in
Such a bitstream for several Xilinx FPGAs can be found in
@file{contrib/loaders/flash/fpga/xilinx_bscan_spi.py}. It requires @file{contrib/loaders/flash/fpga/xilinx_bscan_spi.py}. It requires
@uref{https://github.com/m-labs/migen, migen} and a Xilinx toolchain to build. @uref{https://github.com/m-labs/migen, migen} and a Xilinx toolchain to build.
This mechanism with a proxy bitstream can also be used for FPGAs from Intel and
Efinix. FPGAs from Lattice and Cologne Chip have dedicated JTAG instructions
and procedure to connect the JTAG to the SPI signals and don't need a proxy
bitstream. Support for these devices with dedicated procedure is provided by
the pld drivers. For convenience the PLD drivers will provide the USERx code
for FPGAs with a proxy bitstream. Currently the following PLD drivers are able
to support jtagspi:
@itemize
@item Efinix: proxy-bitstream
@item Gatemate: dedicated procedure
@item Intel/Altera: proxy-bitstream
@item Lattice: dedicated procedure supporting ECP2, ECP3, ECP5, Certus and Certus Pro devices
@item AMD/Xilinx: proxy-bitstream
@end itemize
This flash bank driver requires a target on a JTAG tap and will access that This flash bank driver requires a target on a JTAG tap and will access that
tap directly. Since no support from the target is needed, the target can be a tap directly. Since no support from the target is needed, the target can be a
"testee" dummy. Since the target does not expose the flash memory "testee" dummy. Since the target does not expose the flash memory
@ -5964,14 +5982,25 @@ command, see below.
@item @var{ir} ... is loaded into the JTAG IR to map the flash as the JTAG DR. @item @var{ir} ... is loaded into the JTAG IR to map the flash as the JTAG DR.
For the bitstreams generated from @file{xilinx_bscan_spi.py} this is the For the bitstreams generated from @file{xilinx_bscan_spi.py} this is the
@var{USER1} instruction. @var{USER1} instruction.
@end itemize @example
target create $_TARGETNAME testee -chain-position $_CHIPNAME.tap
set _USER1_INSTR_CODE 0x02
flash bank $_FLASHNAME jtagspi 0x0 0 0 0 \
$_TARGETNAME $_USER1_INSTR_CODE
@end example
@item The option @option{-pld} @var{name} is used to have support from the
PLD driver of pld device @var{name}. The name is the name of the pld device
given during creation of the pld device.
Pld device names are shown by the @command{pld devices} command.
@example @example
target create $_TARGETNAME testee -chain-position $_CHIPNAME.fpga target create $_TARGETNAME testee -chain-position $_CHIPNAME.tap
set _XILINX_USER1 0x02 set _JTAGSPI_CHAIN_ID $_CHIPNAME.pld
flash bank $_FLASHNAME spi 0x0 0 0 0 \ flash bank $_FLASHNAME jtagspi 0x0 0 0 0 \
$_TARGETNAME $_XILINX_USER1 $_TARGETNAME -pld $_JTAGSPI_CHAIN_ID
@end example @end example
@end itemize
@deffn Command {jtagspi set} bank_id name total_size page_size read_cmd unused pprg_cmd mass_erase_cmd sector_size sector_erase_cmd @deffn Command {jtagspi set} bank_id name total_size page_size read_cmd unused pprg_cmd mass_erase_cmd sector_size sector_erase_cmd
Sets flash parameters: @var{name} human readable string, @var{total_size} Sets flash parameters: @var{name} human readable string, @var{total_size}
@ -7222,10 +7251,16 @@ Show information about flash driver.
All versions of the NPCX microcontroller families from Nuvoton include internal All versions of the NPCX microcontroller families from Nuvoton include internal
flash. The NPCX flash driver supports the NPCX family of devices. The driver flash. The NPCX flash driver supports the NPCX family of devices. The driver
automatically recognizes the specific version's flash parameters and automatically recognizes the specific version's flash parameters and
autoconfigures itself. The flash bank starts at address 0x64000000. autoconfigures itself. The flash bank starts at address 0x64000000. An optional additional
parameter sets the FIU version for the bank, with the default FIU is @var{npcx.fiu}.
@example @example
flash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME npcx_v2.fiu
# FIU defaults to npcx.fiu
flash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME flash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME
@end example @end example
@end deffn @end deffn
@ -8691,7 +8726,8 @@ Accordingly, both are called PLDs here.
As it does for JTAG TAPs, debug targets, and flash chips (both NOR and NAND), As it does for JTAG TAPs, debug targets, and flash chips (both NOR and NAND),
OpenOCD maintains a list of PLDs available for use in various commands. OpenOCD maintains a list of PLDs available for use in various commands.
Also, each such PLD requires a driver. Also, each such PLD requires a driver. PLD drivers may also be needed to program
SPI flash connected to the FPGA to store the bitstream (@xref{jtagspi} for details).
They are referenced by the name which was given when the pld was created or They are referenced by the name which was given when the pld was created or
the number shown by the @command{pld devices} command. the number shown by the @command{pld devices} command.
@ -8757,8 +8793,8 @@ Change values for boundary scan instructions selecting the registers USER1 to US
Description of the arguments can be found at command @command{virtex2 set_instr_codes}. Description of the arguments can be found at command @command{virtex2 set_instr_codes}.
@end deffn @end deffn
@deffn {Command} {virtex2 program} pld_name @deffn {Command} {virtex2 refresh} pld_name
Load the bitstream from external memory for FPGA @var{pld_name}. A.k.a. refresh. Load the bitstream from external memory for FPGA @var{pld_name}. A.k.a. program.
@end deffn @end deffn
@end deffn @end deffn
@ -8789,6 +8825,10 @@ for FPGA @var{pld_name} with value @var{val}.
Set the length of the register for the preload. This is needed when the JTAG ID of the device is not known by openocd (newer NX devices). Set the length of the register for the preload. This is needed when the JTAG ID of the device is not known by openocd (newer NX devices).
The load command for the FPGA @var{pld_name} will use a length for the preload of @var{length}. The load command for the FPGA @var{pld_name} will use a length for the preload of @var{length}.
@end deffn @end deffn
@deffn {Command} {lattice refresh} pld_name
Load the bitstream from external memory for FPGA @var{pld_name}. A.k.a program.
@end deffn
@end deffn @end deffn
@ -8843,9 +8883,9 @@ Reads and displays the user register
for FPGA @var{pld_name}. for FPGA @var{pld_name}.
@end deffn @end deffn
@deffn {Command} {gowin reload} pld_name @deffn {Command} {gowin refresh} pld_name
Load the bitstream from external memory for Load the bitstream from external memory for
FPGA @var{pld_name}. A.k.a. refresh. FPGA @var{pld_name}. A.k.a. reload.
@end deffn @end deffn
@end deffn @end deffn

View File

@ -560,12 +560,22 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
if (bnk > 0) { if (bnk > 0) {
if (!t_bank->next) { if (!t_bank->next) {
/* create a new flash bank element */ /* create a new flash bank element */
struct flash_bank *fb = malloc(sizeof(struct flash_bank)); struct flash_bank *fb = calloc(sizeof(struct flash_bank), 1);
if (!fb) {
LOG_ERROR("No memory for flash bank");
return ERROR_FAIL;
}
fb->target = target; fb->target = target;
fb->driver = bank->driver; fb->driver = bank->driver;
fb->default_padded_value = 0xff;
fb->erased_value = 0xff;
fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank)); fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
fb->name = "sam7_probed"; if (!fb->driver_priv) {
fb->next = NULL; free(fb);
LOG_ERROR("No memory for flash driver priv");
return ERROR_FAIL;
}
fb->name = strdup("sam7_probed");
/* link created bank in 'flash_banks' list */ /* link created bank in 'flash_banks' list */
t_bank->next = fb; t_bank->next = fb;
@ -738,12 +748,22 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
if (bnk > 0) { if (bnk > 0) {
if (!t_bank->next) { if (!t_bank->next) {
/* create a new bank element */ /* create a new bank element */
struct flash_bank *fb = malloc(sizeof(struct flash_bank)); struct flash_bank *fb = calloc(sizeof(struct flash_bank), 1);
if (!fb) {
LOG_ERROR("No memory for flash bank");
return ERROR_FAIL;
}
fb->target = target; fb->target = target;
fb->driver = bank->driver; fb->driver = bank->driver;
fb->default_padded_value = 0xff;
fb->erased_value = 0xff;
fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank)); fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
fb->name = "sam7_probed"; if (!fb->driver_priv) {
fb->next = NULL; free(fb);
LOG_ERROR("No memory for flash driver priv");
return ERROR_FAIL;
}
fb->name = strdup("sam7_probed");
/* link created bank in 'flash_banks' list */ /* link created bank in 'flash_banks' list */
t_bank->next = fb; t_bank->next = fb;

View File

@ -261,7 +261,6 @@ FLASH_BANK_COMMAND_HANDLER(cc26xx_flash_bank_command)
/* Finish initialization of bank */ /* Finish initialization of bank */
bank->driver_priv = cc26xx_bank; bank->driver_priv = cc26xx_bank;
bank->next = NULL;
return ERROR_OK; return ERROR_OK;
} }

View File

@ -96,7 +96,6 @@ FLASH_BANK_COMMAND_HANDLER(cc3220sf_flash_bank_command)
/* Finish initialization of flash bank */ /* Finish initialization of flash bank */
bank->driver_priv = cc3220sf_bank; bank->driver_priv = cc3220sf_bank;
bank->next = NULL;
return ERROR_OK; return ERROR_OK;
} }

View File

@ -12,6 +12,7 @@
#include <jtag/jtag.h> #include <jtag/jtag.h>
#include <flash/nor/spi.h> #include <flash/nor/spi.h>
#include <helper/time_support.h> #include <helper/time_support.h>
#include <pld/pld.h>
#define JTAGSPI_MAX_TIMEOUT 3000 #define JTAGSPI_MAX_TIMEOUT 3000
@ -21,19 +22,44 @@ struct jtagspi_flash_bank {
struct flash_device dev; struct flash_device dev;
char devname[32]; char devname[32];
bool probed; bool probed;
bool always_4byte; /* use always 4-byte address except for basic read 0x03 */ bool always_4byte; /* use always 4-byte address except for basic read 0x03 */
uint32_t ir; unsigned int addr_len; /* address length in bytes */
unsigned int addr_len; /* address length in bytes */ struct pld_device *pld_device; /* if not NULL, the PLD has special instructions for JTAGSPI */
uint32_t ir; /* when !pld_device, this instruction code is used in
jtagspi_set_user_ir to connect through a proxy bitstream */
}; };
FLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command) FLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command)
{ {
struct jtagspi_flash_bank *info;
if (CMD_ARGC < 7) if (CMD_ARGC < 7)
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
info = malloc(sizeof(struct jtagspi_flash_bank)); unsigned int ir = 0;
struct pld_device *device = NULL;
if (strcmp(CMD_ARGV[6], "-pld") == 0) {
if (CMD_ARGC < 8)
return ERROR_COMMAND_SYNTAX_ERROR;
device = get_pld_device_by_name_or_numstr(CMD_ARGV[7]);
if (device) {
bool has_jtagspi_instruction = false;
int retval = pld_has_jtagspi_instruction(device, &has_jtagspi_instruction);
if (retval != ERROR_OK)
return retval;
if (!has_jtagspi_instruction) {
retval = pld_get_jtagspi_userircode(device, &ir);
if (retval != ERROR_OK)
return retval;
device = NULL;
}
} else {
LOG_ERROR("pld device '#%s' is out of bounds or unknown", CMD_ARGV[7]);
return ERROR_FAIL;
}
} else {
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[6], ir);
}
struct jtagspi_flash_bank *info = calloc(1, sizeof(struct jtagspi_flash_bank));
if (!info) { if (!info) {
LOG_ERROR("no memory for flash bank info"); LOG_ERROR("no memory for flash bank info");
return ERROR_FAIL; return ERROR_FAIL;
@ -47,18 +73,19 @@ FLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command)
} }
info->tap = bank->target->tap; info->tap = bank->target->tap;
info->probed = false; info->probed = false;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], info->ir);
info->ir = ir;
info->pld_device = device;
return ERROR_OK; return ERROR_OK;
} }
static void jtagspi_set_ir(struct flash_bank *bank) static void jtagspi_set_user_ir(struct jtagspi_flash_bank *info)
{ {
struct jtagspi_flash_bank *info = bank->driver_priv;
struct scan_field field; struct scan_field field;
uint8_t buf[4] = { 0 }; uint8_t buf[4] = { 0 };
LOG_DEBUG("loading jtagspi ir"); LOG_DEBUG("loading jtagspi ir(0x%" PRIx32 ")", info->ir);
buf_set_u32(buf, 0, info->tap->ir_length, info->ir); buf_set_u32(buf, 0, info->tap->ir_length, info->ir);
field.num_bits = info->tap->ir_length; field.num_bits = info->tap->ir_length;
field.out_value = buf; field.out_value = buf;
@ -79,6 +106,7 @@ static int jtagspi_cmd(struct flash_bank *bank, uint8_t cmd,
assert(data_buffer || data_len == 0); assert(data_buffer || data_len == 0);
struct scan_field fields[6]; struct scan_field fields[6];
struct jtagspi_flash_bank *info = bank->driver_priv;
LOG_DEBUG("cmd=0x%02x write_len=%d data_len=%d", cmd, write_len, data_len); LOG_DEBUG("cmd=0x%02x write_len=%d data_len=%d", cmd, write_len, data_len);
@ -87,22 +115,34 @@ static int jtagspi_cmd(struct flash_bank *bank, uint8_t cmd,
if (is_read) if (is_read)
data_len = -data_len; data_len = -data_len;
unsigned int facing_read_bits = 0;
unsigned int trailing_write_bits = 0;
if (info->pld_device) {
int retval = pld_get_jtagspi_stuff_bits(info->pld_device, &facing_read_bits, &trailing_write_bits);
if (retval != ERROR_OK)
return retval;
}
int n = 0; int n = 0;
const uint8_t marker = 1; const uint8_t marker = 1;
fields[n].num_bits = 1;
fields[n].out_value = &marker;
fields[n].in_value = NULL;
n++;
/* transfer length = cmd + address + read/write,
* -1 due to the counter implementation */
uint8_t xfer_bits[4]; uint8_t xfer_bits[4];
h_u32_to_be(xfer_bits, ((sizeof(cmd) + write_len + data_len) * CHAR_BIT) - 1); if (!info->pld_device) { /* mode == JTAGSPI_MODE_PROXY_BITSTREAM */
flip_u8(xfer_bits, xfer_bits, sizeof(xfer_bits)); facing_read_bits = jtag_tap_count_enabled();
fields[n].num_bits = sizeof(xfer_bits) * CHAR_BIT; fields[n].num_bits = 1;
fields[n].out_value = xfer_bits; fields[n].out_value = &marker;
fields[n].in_value = NULL; fields[n].in_value = NULL;
n++; n++;
/* transfer length = cmd + address + read/write,
* -1 due to the counter implementation */
h_u32_to_be(xfer_bits, ((sizeof(cmd) + write_len + data_len) * CHAR_BIT) - 1);
flip_u8(xfer_bits, xfer_bits, sizeof(xfer_bits));
fields[n].num_bits = sizeof(xfer_bits) * CHAR_BIT;
fields[n].out_value = xfer_bits;
fields[n].in_value = NULL;
n++;
}
flip_u8(&cmd, &cmd, sizeof(cmd)); flip_u8(&cmd, &cmd, sizeof(cmd));
fields[n].num_bits = sizeof(cmd) * CHAR_BIT; fields[n].num_bits = sizeof(cmd) * CHAR_BIT;
@ -120,10 +160,12 @@ static int jtagspi_cmd(struct flash_bank *bank, uint8_t cmd,
if (data_len > 0) { if (data_len > 0) {
if (is_read) { if (is_read) {
fields[n].num_bits = jtag_tap_count_enabled(); if (facing_read_bits) {
fields[n].out_value = NULL; fields[n].num_bits = facing_read_bits;
fields[n].in_value = NULL; fields[n].out_value = NULL;
n++; fields[n].in_value = NULL;
n++;
}
fields[n].out_value = NULL; fields[n].out_value = NULL;
fields[n].in_value = data_buffer; fields[n].in_value = data_buffer;
@ -135,16 +177,33 @@ static int jtagspi_cmd(struct flash_bank *bank, uint8_t cmd,
fields[n].num_bits = data_len * CHAR_BIT; fields[n].num_bits = data_len * CHAR_BIT;
n++; n++;
} }
if (!is_read && trailing_write_bits) {
fields[n].num_bits = trailing_write_bits;
fields[n].out_value = NULL;
fields[n].in_value = NULL;
n++;
}
if (info->pld_device) {
int retval = pld_connect_spi_to_jtag(info->pld_device);
if (retval != ERROR_OK)
return retval;
} else {
jtagspi_set_user_ir(info);
}
jtagspi_set_ir(bank);
/* passing from an IR scan to SHIFT-DR clears BYPASS registers */ /* passing from an IR scan to SHIFT-DR clears BYPASS registers */
struct jtagspi_flash_bank *info = bank->driver_priv;
jtag_add_dr_scan(info->tap, n, fields, TAP_IDLE); jtag_add_dr_scan(info->tap, n, fields, TAP_IDLE);
int retval = jtag_execute_queue(); int retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval;
if (is_read) if (is_read)
flip_u8(data_buffer, data_buffer, data_len); flip_u8(data_buffer, data_buffer, data_len);
return retval;
if (info->pld_device)
return pld_disconnect_spi_from_jtag(info->pld_device);
return ERROR_OK;
} }
COMMAND_HANDLER(jtagspi_handle_set) COMMAND_HANDLER(jtagspi_handle_set)

View File

@ -4,6 +4,7 @@
* Copyright (C) 2020 by Nuvoton Technology Corporation * Copyright (C) 2020 by Nuvoton Technology Corporation
* Mulin Chao <mlchao@nuvoton.com> * Mulin Chao <mlchao@nuvoton.com>
* Wealian Liao <WHLIAO@nuvoton.com> * Wealian Liao <WHLIAO@nuvoton.com>
* Luca Hung <YCHUNG0@nuvoton.com>
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -22,7 +23,6 @@ static const uint8_t npcx_algo[] = {
}; };
#define NPCX_FLASH_TIMEOUT_MS 8000 #define NPCX_FLASH_TIMEOUT_MS 8000
#define NPCX_FLASH_BASE_ADDR 0x64000000
/* flash list */ /* flash list */
enum npcx_flash_device_index { enum npcx_flash_device_index {
@ -33,7 +33,6 @@ enum npcx_flash_device_index {
}; };
struct npcx_flash_bank { struct npcx_flash_bank {
const char *family_name;
uint32_t sector_length; uint32_t sector_length;
bool probed; bool probed;
enum npcx_flash_device_index flash; enum npcx_flash_device_index flash;
@ -44,6 +43,7 @@ struct npcx_flash_bank {
uint32_t algo_working_size; uint32_t algo_working_size;
uint32_t buffer_addr; uint32_t buffer_addr;
uint32_t params_addr; uint32_t params_addr;
uint32_t fiu_ver;
}; };
struct npcx_flash_info { struct npcx_flash_info {
@ -90,7 +90,7 @@ static int npcx_init(struct flash_bank *bank)
/* Confirm the defined working address is the area we need to use */ /* Confirm the defined working address is the area we need to use */
if (npcx_bank->working_area->address != NPCX_FLASH_LOADER_WORKING_ADDR) { if (npcx_bank->working_area->address != NPCX_FLASH_LOADER_WORKING_ADDR) {
LOG_ERROR("%s: Invalid working address", npcx_bank->family_name); LOG_TARGET_ERROR(target, "Invalid working address");
LOG_INFO("Hint: Use '-work-area-phys 0x%" PRIx32 "' in your target configuration", LOG_INFO("Hint: Use '-work-area-phys 0x%" PRIx32 "' in your target configuration",
NPCX_FLASH_LOADER_WORKING_ADDR); NPCX_FLASH_LOADER_WORKING_ADDR);
target_free_working_area(target, npcx_bank->working_area); target_free_working_area(target, npcx_bank->working_area);
@ -102,8 +102,7 @@ static int npcx_init(struct flash_bank *bank)
retval = target_write_buffer(target, NPCX_FLASH_LOADER_PROGRAM_ADDR, retval = target_write_buffer(target, NPCX_FLASH_LOADER_PROGRAM_ADDR,
npcx_bank->algo_size, npcx_bank->algo_code); npcx_bank->algo_size, npcx_bank->algo_code);
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
LOG_ERROR("%s: Failed to load flash helper algorithm", LOG_TARGET_ERROR(target, "Failed to load flash helper algorithm");
npcx_bank->family_name);
target_free_working_area(target, npcx_bank->working_area); target_free_working_area(target, npcx_bank->working_area);
npcx_bank->working_area = NULL; npcx_bank->working_area = NULL;
return retval; return retval;
@ -118,8 +117,7 @@ static int npcx_init(struct flash_bank *bank)
NPCX_FLASH_LOADER_PROGRAM_ADDR, 0, NPCX_FLASH_LOADER_PROGRAM_ADDR, 0,
&npcx_bank->armv7m_info); &npcx_bank->armv7m_info);
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
LOG_ERROR("%s: Failed to start flash helper algorithm", LOG_TARGET_ERROR(target, "Failed to start flash helper algorithm");
npcx_bank->family_name);
target_free_working_area(target, npcx_bank->working_area); target_free_working_area(target, npcx_bank->working_area);
npcx_bank->working_area = NULL; npcx_bank->working_area = NULL;
return retval; return retval;
@ -154,7 +152,6 @@ static int npcx_quit(struct flash_bank *bank)
static int npcx_wait_algo_done(struct flash_bank *bank, uint32_t params_addr) static int npcx_wait_algo_done(struct flash_bank *bank, uint32_t params_addr)
{ {
struct target *target = bank->target; struct target *target = bank->target;
struct npcx_flash_bank *npcx_bank = bank->driver_priv;
uint32_t status_addr = params_addr + offsetof(struct npcx_flash_params, sync); uint32_t status_addr = params_addr + offsetof(struct npcx_flash_params, sync);
uint32_t status; uint32_t status;
int64_t start_ms = timeval_ms(); int64_t start_ms = timeval_ms();
@ -172,9 +169,7 @@ static int npcx_wait_algo_done(struct flash_bank *bank, uint32_t params_addr)
} while (status == NPCX_FLASH_LOADER_EXECUTE); } while (status == NPCX_FLASH_LOADER_EXECUTE);
if (status != NPCX_FLASH_LOADER_WAIT) { if (status != NPCX_FLASH_LOADER_WAIT) {
LOG_ERROR("%s: Flash operation failed, status=0x%" PRIx32, LOG_TARGET_ERROR(target, "Flash operation failed, status (%0x" PRIX32 ") ", status);
npcx_bank->family_name,
status);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -197,6 +192,7 @@ static enum npcx_flash_device_index npcx_get_flash_id(struct flash_bank *bank, u
return retval; return retval;
/* Set up algorithm parameters for get flash ID command */ /* Set up algorithm parameters for get flash ID command */
target_buffer_set_u32(target, (uint8_t *)&algo_params.fiu_ver, npcx_bank->fiu_ver);
target_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_GET_FLASH_ID); target_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_GET_FLASH_ID);
target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT); target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);
@ -250,6 +246,7 @@ static int npcx_probe(struct flash_bank *bank)
npcx_bank->buffer_addr = NPCX_FLASH_LOADER_BUFFER_ADDR; npcx_bank->buffer_addr = NPCX_FLASH_LOADER_BUFFER_ADDR;
npcx_bank->params_addr = NPCX_FLASH_LOADER_PARAMS_ADDR; npcx_bank->params_addr = NPCX_FLASH_LOADER_PARAMS_ADDR;
int retval = npcx_get_flash_id(bank, &flash_id); int retval = npcx_get_flash_id(bank, &flash_id);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -264,7 +261,6 @@ static int npcx_probe(struct flash_bank *bank)
return ERROR_FAIL; return ERROR_FAIL;
} }
bank->base = NPCX_FLASH_BASE_ADDR;
bank->num_sectors = num_sectors; bank->num_sectors = num_sectors;
bank->size = num_sectors * sector_length; bank->size = num_sectors * sector_length;
bank->write_start_alignment = 0; bank->write_start_alignment = 0;
@ -300,7 +296,7 @@ FLASH_BANK_COMMAND_HANDLER(npcx_flash_bank_command)
{ {
struct npcx_flash_bank *npcx_bank; struct npcx_flash_bank *npcx_bank;
if (CMD_ARGC < 6) if (CMD_ARGC < 6 || CMD_ARGC > 7)
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
npcx_bank = calloc(1, sizeof(struct npcx_flash_bank)); npcx_bank = calloc(1, sizeof(struct npcx_flash_bank));
@ -309,13 +305,32 @@ FLASH_BANK_COMMAND_HANDLER(npcx_flash_bank_command)
return ERROR_FAIL; return ERROR_FAIL;
} }
const char *fiu;
if (CMD_ARGC == 6) {
LOG_WARNING("No FIU is selection, using default.");
npcx_bank->fiu_ver = NPCX_FIU_NPCX;
}
if (CMD_ARGC == 7) {
fiu = CMD_ARGV[6];
if (strcmp(fiu, "npcx.fiu") == 0) {
npcx_bank->fiu_ver = NPCX_FIU_NPCX;
} else if (strcmp(fiu, "npcx_v2.fiu") == 0) {
npcx_bank->fiu_ver = NPCX_FIU_NPCX_V2;
} else if (strcmp(fiu, "npck.fiu") == 0) {
npcx_bank->fiu_ver = NPCX_FIU_NPCK;
} else {
LOG_ERROR("%s is not a valid fiu", fiu);
free(npcx_bank);
return ERROR_TARGET_INVALID;
}
}
/* Initialize private flash information */ /* Initialize private flash information */
npcx_bank->family_name = "npcx";
npcx_bank->sector_length = NPCX_FLASH_ERASE_SIZE; npcx_bank->sector_length = NPCX_FLASH_ERASE_SIZE;
/* Finish initialization of bank */ /* Finish initialization of bank */
bank->driver_priv = npcx_bank; bank->driver_priv = npcx_bank;
bank->next = NULL;
return ERROR_OK; return ERROR_OK;
} }
@ -341,6 +356,7 @@ static int npcx_chip_erase(struct flash_bank *bank)
return retval; return retval;
/* Set up algorithm parameters for chip erase command */ /* Set up algorithm parameters for chip erase command */
target_buffer_set_u32(target, (uint8_t *)&algo_params.fiu_ver, npcx_bank->fiu_ver);
target_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_ERASE_ALL); target_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_ERASE_ALL);
target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT); target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);
@ -397,6 +413,7 @@ static int npcx_erase(struct flash_bank *bank, unsigned int first,
return retval; return retval;
/* Set up algorithm parameters for erase command */ /* Set up algorithm parameters for erase command */
target_buffer_set_u32(target, (uint8_t *)&algo_params.fiu_ver, npcx_bank->fiu_ver);
target_buffer_set_u32(target, (uint8_t *)&algo_params.addr, address); target_buffer_set_u32(target, (uint8_t *)&algo_params.addr, address);
target_buffer_set_u32(target, (uint8_t *)&algo_params.len, length); target_buffer_set_u32(target, (uint8_t *)&algo_params.len, length);
target_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_ERASE_SECTORS); target_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_ERASE_SECTORS);
@ -464,6 +481,7 @@ static int npcx_write(struct flash_bank *bank, const uint8_t *buffer,
} }
/* Update algo parameters for flash write */ /* Update algo parameters for flash write */
target_buffer_set_u32(target, (uint8_t *)&algo_params.fiu_ver, npcx_bank->fiu_ver);
target_buffer_set_u32(target, (uint8_t *)&algo_params.addr, address); target_buffer_set_u32(target, (uint8_t *)&algo_params.addr, address);
target_buffer_set_u32(target, (uint8_t *)&algo_params.len, size); target_buffer_set_u32(target, (uint8_t *)&algo_params.len, size);
target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT); target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);
@ -502,7 +520,7 @@ static int npcx_info(struct flash_bank *bank, struct command_invocation *cmd)
struct npcx_flash_bank *npcx_bank = bank->driver_priv; struct npcx_flash_bank *npcx_bank = bank->driver_priv;
command_print_sameline(cmd, "%s flash: %s\n", command_print_sameline(cmd, "%s flash: %s\n",
npcx_bank->family_name, target_name(bank->target),
flash_info[npcx_bank->flash].name); flash_info[npcx_bank->flash].name);
return ERROR_OK; return ERROR_OK;

View File

@ -57,6 +57,9 @@
*/ */
/* STM32WBxxx series for reference. /* STM32WBxxx series for reference.
*
* RM0493 (STM32WBA52x)
* http://www.st.com/resource/en/reference_manual/dm00821869.pdf
* *
* RM0434 (STM32WB55/WB35x) * RM0434 (STM32WB55/WB35x)
* http://www.st.com/resource/en/reference_manual/dm00318631.pdf * http://www.st.com/resource/en/reference_manual/dm00318631.pdf
@ -346,6 +349,10 @@ static const struct stm32l4_rev stm32u57_u58xx_revs[] = {
{ 0x2001, "X" }, { 0x3000, "C" }, { 0x2001, "X" }, { 0x3000, "C" },
}; };
static const struct stm32l4_rev stm32wba5x_revs[] = {
{ 0x1000, "A" },
};
static const struct stm32l4_rev stm32wb1xx_revs[] = { static const struct stm32l4_rev stm32wb1xx_revs[] = {
{ 0x1000, "A" }, { 0x2000, "B" }, { 0x1000, "A" }, { 0x2000, "B" },
}; };
@ -579,6 +586,18 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
.otp_base = 0x0BFA0000, .otp_base = 0x0BFA0000,
.otp_size = 512, .otp_size = 512,
}, },
{
.id = DEVID_STM32WBA5X,
.revs = stm32wba5x_revs,
.num_revs = ARRAY_SIZE(stm32wba5x_revs),
.device_str = "STM32WBA5x",
.max_flash_size_kb = 1024,
.flags = F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS,
.flash_regs_base = 0x40022000,
.fsize_addr = 0x0FF907A0,
.otp_base = 0x0FF90000,
.otp_size = 512,
},
{ {
.id = DEVID_STM32WB1XX, .id = DEVID_STM32WB1XX,
.revs = stm32wb1xx_revs, .revs = stm32wb1xx_revs,
@ -1993,6 +2012,12 @@ static int stm32l4_probe(struct flash_bank *bank)
stm32l4_info->bank1_sectors = num_pages / 2; stm32l4_info->bank1_sectors = num_pages / 2;
} }
break; break;
case DEVID_STM32WBA5X:
/* single bank flash */
page_size_kb = 8;
num_pages = flash_size_kb / page_size_kb;
stm32l4_info->bank1_sectors = num_pages;
break;
case DEVID_STM32WB5XX: case DEVID_STM32WB5XX:
case DEVID_STM32WB3XX: case DEVID_STM32WB3XX:
/* single bank flash */ /* single bank flash */

View File

@ -103,6 +103,7 @@
#define DEVID_STM32L55_L56XX 0x472 #define DEVID_STM32L55_L56XX 0x472
#define DEVID_STM32G49_G4AXX 0x479 #define DEVID_STM32G49_G4AXX 0x479
#define DEVID_STM32U57_U58XX 0x482 #define DEVID_STM32U57_U58XX 0x482
#define DEVID_STM32WBA5X 0x492
#define DEVID_STM32WB1XX 0x494 #define DEVID_STM32WB1XX 0x494
#define DEVID_STM32WB5XX 0x495 #define DEVID_STM32WB5XX 0x495
#define DEVID_STM32WB3XX 0x496 #define DEVID_STM32WB3XX 0x496

View File

@ -184,7 +184,8 @@ static void initialize_gpio(enum adapter_gpio_config_index idx)
} }
/* Direction for non push-pull is already set by set_gpio_value() */ /* Direction for non push-pull is already set by set_gpio_value() */
if (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL) if (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL
&& adapter_gpio_config[idx].init_state != ADAPTER_GPIO_INIT_STATE_INPUT)
AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]); AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]);
} }

View File

@ -254,8 +254,8 @@ static int rshim_dp_q_write(struct adiv5_dap *dap, unsigned int reg,
dp_ctrl_stat = data; dp_ctrl_stat = data;
break; break;
case DP_SELECT: case DP_SELECT:
ap_sel = (data & DP_SELECT_APSEL) >> 24; ap_sel = (data & ADIV5_DP_SELECT_APSEL) >> 24;
ap_bank = (data & DP_SELECT_APBANK) >> 4; ap_bank = (data & ADIV5_DP_SELECT_APBANK) >> 4;
break; break;
default: default:
LOG_INFO("Unknown command"); LOG_INFO("Unknown command");

View File

@ -1098,9 +1098,9 @@ static int vdebug_dap_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, ui
static int vdebug_dap_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data) static int vdebug_dap_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)
{ {
if ((reg & DP_SELECT_APBANK) != ap->dap->select) { if ((reg & ADIV5_DP_SELECT_APBANK) != ap->dap->select) {
vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0); vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & ADIV5_DP_SELECT_APBANK, VD_ASPACE_DP, 0);
ap->dap->select = reg & DP_SELECT_APBANK; ap->dap->select = reg & ADIV5_DP_SELECT_APBANK;
} }
vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, NULL, VD_ASPACE_AP, 0); vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, NULL, VD_ASPACE_AP, 0);
@ -1110,9 +1110,9 @@ static int vdebug_dap_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint3
static int vdebug_dap_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data) static int vdebug_dap_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data)
{ {
if ((reg & DP_SELECT_APBANK) != ap->dap->select) { if ((reg & ADIV5_DP_SELECT_APBANK) != ap->dap->select) {
vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0); vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & ADIV5_DP_SELECT_APBANK, VD_ASPACE_DP, 0);
ap->dap->select = reg & DP_SELECT_APBANK; ap->dap->select = reg & ADIV5_DP_SELECT_APBANK;
} }
return vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_AP, 0); return vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_AP, 0);

View File

@ -231,3 +231,100 @@ int lattice_certus_load(struct lattice_pld_device *lattice_device, struct lattic
return lattice_certus_exit_programming_mode(tap); return lattice_certus_exit_programming_mode(tap);
} }
int lattice_certus_connect_spi_to_jtag(struct lattice_pld_device *pld_device_info)
{
if (!pld_device_info)
return ERROR_FAIL;
struct jtag_tap *tap = pld_device_info->tap;
if (!tap)
return ERROR_FAIL;
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == PROGRAM_SPI)
return ERROR_OK;
// erase configuration
int retval = lattice_preload(pld_device_info);
if (retval != ERROR_OK)
return retval;
retval = lattice_certus_enable_programming(tap);
if (retval != ERROR_OK)
return retval;
retval = lattice_certus_erase_device(pld_device_info);
if (retval != ERROR_OK) {
LOG_ERROR("erasing device failed");
return retval;
}
retval = lattice_certus_exit_programming_mode(tap);
if (retval != ERROR_OK)
return retval;
// connect jtag to spi pins
retval = lattice_set_instr(tap, PROGRAM_SPI, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
struct scan_field field;
uint8_t buffer[2] = {0xfe, 0x68};
field.num_bits = 16;
field.out_value = buffer;
field.in_value = NULL;
jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
return jtag_execute_queue();
}
int lattice_certus_disconnect_spi_from_jtag(struct lattice_pld_device *pld_device_info)
{
if (!pld_device_info)
return ERROR_FAIL;
struct jtag_tap *tap = pld_device_info->tap;
if (!tap)
return ERROR_FAIL;
/* Connecting it again takes way too long to do it multiple times for writing
a bitstream (ca. 0.4s each access).
We just leave it connected since SCS will not be active when not in shift_dr state.
So there is no need to change instruction, just make sure we are not in shift dr state. */
jtag_add_runtest(2, TAP_IDLE);
return jtag_execute_queue();
}
int lattice_certus_get_facing_read_bits(struct lattice_pld_device *pld_device_info, unsigned int *facing_read_bits)
{
if (!pld_device_info)
return ERROR_FAIL;
*facing_read_bits = 0;
return ERROR_OK;
}
int lattice_certus_refresh(struct lattice_pld_device *lattice_device)
{
struct jtag_tap *tap = lattice_device->tap;
if (!tap)
return ERROR_FAIL;
int retval = lattice_preload(lattice_device);
if (retval != ERROR_OK)
return retval;
retval = lattice_set_instr(tap, LSC_REFRESH, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
jtag_add_runtest(2, TAP_IDLE);
jtag_add_sleep(200000);
retval = lattice_set_instr(tap, BYPASS, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
jtag_add_runtest(100, TAP_IDLE);
jtag_add_sleep(1000);
return jtag_execute_queue();
}

View File

@ -14,5 +14,9 @@ int lattice_certus_read_status(struct jtag_tap *tap, uint64_t *status, uint64_t
int lattice_certus_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out); int lattice_certus_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out);
int lattice_certus_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode); int lattice_certus_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode);
int lattice_certus_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file); int lattice_certus_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file);
int lattice_certus_connect_spi_to_jtag(struct lattice_pld_device *pld_device_info);
int lattice_certus_disconnect_spi_from_jtag(struct lattice_pld_device *pld_device_info);
int lattice_certus_get_facing_read_bits(struct lattice_pld_device *pld_device_info, unsigned int *facing_read_bits);
int lattice_certus_refresh(struct lattice_pld_device *lattice_device);
#endif /* OPENOCD_PLD_CERTUS_H */ #endif /* OPENOCD_PLD_CERTUS_H */

View File

@ -21,6 +21,7 @@
#define ISC_DISABLE 0x1E #define ISC_DISABLE 0x1E
#define LSCC_READ_STATUS 0x53 #define LSCC_READ_STATUS 0x53
#define LSCC_BITSTREAM_BURST 0x02 #define LSCC_BITSTREAM_BURST 0x02
#define PROGRAM_SPI 0x3A
#define STATUS_DONE_BIT 0x00020000 #define STATUS_DONE_BIT 0x00020000
#define STATUS_ERROR_BITS_ECP2 0x00040003 #define STATUS_ERROR_BITS_ECP2 0x00040003
@ -249,3 +250,68 @@ int lattice_ecp3_load(struct lattice_pld_device *lattice_device, struct lattice_
const uint32_t expected = STATUS_DONE_BIT; const uint32_t expected = STATUS_DONE_BIT;
return lattice_verify_status_register_u32(lattice_device, out, expected, mask, false); return lattice_verify_status_register_u32(lattice_device, out, expected, mask, false);
} }
int lattice_ecp2_3_connect_spi_to_jtag(struct lattice_pld_device *pld_device_info)
{
if (!pld_device_info)
return ERROR_FAIL;
struct jtag_tap *tap = pld_device_info->tap;
if (!tap)
return ERROR_FAIL;
// erase configuration
int retval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
retval = lattice_set_instr(tap, ISC_ERASE, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
retval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
// connect jtag to spi pins
retval = lattice_set_instr(tap, PROGRAM_SPI, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
return jtag_execute_queue();
}
int lattice_ecp2_3_disconnect_spi_from_jtag(struct lattice_pld_device *pld_device_info)
{
if (!pld_device_info)
return ERROR_FAIL;
struct jtag_tap *tap = pld_device_info->tap;
if (!tap)
return ERROR_FAIL;
int retval = lattice_set_instr(tap, BYPASS, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
return jtag_execute_queue();
}
int lattice_ecp2_3_get_facing_read_bits(struct lattice_pld_device *pld_device_info, unsigned int *facing_read_bits)
{
if (!pld_device_info)
return ERROR_FAIL;
*facing_read_bits = 1;
return ERROR_OK;
}
int lattice_ecp2_3_refresh(struct lattice_pld_device *lattice_device)
{
if (!lattice_device || !lattice_device->tap)
return ERROR_FAIL;
int retval = lattice_set_instr(lattice_device->tap, LSCC_REFRESH, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
return jtag_execute_queue();
}

View File

@ -15,5 +15,9 @@ int lattice_ecp2_3_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint3
int lattice_ecp2_3_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode); int lattice_ecp2_3_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode);
int lattice_ecp2_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file); int lattice_ecp2_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file);
int lattice_ecp3_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file); int lattice_ecp3_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file);
int lattice_ecp2_3_connect_spi_to_jtag(struct lattice_pld_device *pld_device_info);
int lattice_ecp2_3_disconnect_spi_from_jtag(struct lattice_pld_device *pld_device_info);
int lattice_ecp2_3_get_facing_read_bits(struct lattice_pld_device *pld_device_info, unsigned int *facing_read_bits);
int lattice_ecp2_3_refresh(struct lattice_pld_device *lattice_device);
#endif /* OPENOCD_PLD_ECP2_3_H */ #endif /* OPENOCD_PLD_ECP2_3_H */

View File

@ -205,3 +205,98 @@ int lattice_ecp5_load(struct lattice_pld_device *lattice_device, struct lattice_
const uint32_t mask3 = STATUS_DONE_BIT | STATUS_FAIL_FLAG; const uint32_t mask3 = STATUS_DONE_BIT | STATUS_FAIL_FLAG;
return lattice_verify_status_register_u32(lattice_device, out, expected2, mask3, false); return lattice_verify_status_register_u32(lattice_device, out, expected2, mask3, false);
} }
int lattice_ecp5_connect_spi_to_jtag(struct lattice_pld_device *pld_device_info)
{
if (!pld_device_info)
return ERROR_FAIL;
struct jtag_tap *tap = pld_device_info->tap;
if (!tap)
return ERROR_FAIL;
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == PROGRAM_SPI)
return ERROR_OK;
// erase configuration
int retval = lattice_preload(pld_device_info);
if (retval != ERROR_OK)
return retval;
retval = lattice_ecp5_enable_sram_programming(tap);
if (retval != ERROR_OK)
return retval;
retval = lattice_ecp5_erase_sram(tap);
if (retval != ERROR_OK)
return retval;
retval = lattice_ecp5_exit_programming_mode(tap);
if (retval != ERROR_OK)
return retval;
// connect jtag to spi pins
retval = lattice_set_instr(tap, PROGRAM_SPI, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
struct scan_field field;
uint8_t buffer[2] = {0xfe, 0x68};
field.num_bits = 16;
field.out_value = buffer;
field.in_value = NULL;
jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
return jtag_execute_queue();
}
int lattice_ecp5_disconnect_spi_from_jtag(struct lattice_pld_device *pld_device_info)
{
if (!pld_device_info)
return ERROR_FAIL;
struct jtag_tap *tap = pld_device_info->tap;
if (!tap)
return ERROR_FAIL;
/* Connecting it again takes way too long to do it multiple times for writing
a bitstream (ca. 0.4s each access).
We just leave it connected since SCS will not be active when not in shift_dr state.
So there is no need to change instruction, just make sure we are not in shift dr state. */
jtag_add_runtest(2, TAP_IDLE);
return jtag_execute_queue();
}
int lattice_ecp5_get_facing_read_bits(struct lattice_pld_device *pld_device_info, unsigned int *facing_read_bits)
{
if (!pld_device_info)
return ERROR_FAIL;
*facing_read_bits = 0;
return ERROR_OK;
}
int lattice_ecp5_refresh(struct lattice_pld_device *lattice_device)
{
struct jtag_tap *tap = lattice_device->tap;
if (!tap)
return ERROR_FAIL;
int retval = lattice_preload(lattice_device);
if (retval != ERROR_OK)
return retval;
retval = lattice_set_instr(tap, LSC_REFRESH, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
jtag_add_runtest(2, TAP_IDLE);
jtag_add_sleep(200000);
retval = lattice_set_instr(tap, BYPASS, TAP_IDLE);
if (retval != ERROR_OK)
return retval;
jtag_add_runtest(100, TAP_IDLE);
jtag_add_sleep(1000);
return jtag_execute_queue();
}

View File

@ -14,5 +14,9 @@ int lattice_ecp5_read_status(struct jtag_tap *tap, uint32_t *status, uint32_t ou
int lattice_ecp5_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out); int lattice_ecp5_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out);
int lattice_ecp5_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode); int lattice_ecp5_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode);
int lattice_ecp5_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file); int lattice_ecp5_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file);
int lattice_ecp5_connect_spi_to_jtag(struct lattice_pld_device *pld_device_info);
int lattice_ecp5_disconnect_spi_from_jtag(struct lattice_pld_device *pld_device_info);
int lattice_ecp5_get_facing_read_bits(struct lattice_pld_device *pld_device_info, unsigned int *facing_read_bits);
int lattice_ecp5_refresh(struct lattice_pld_device *lattice_device);
#endif /* OPENOCD_PLD_ECP5_H */ #endif /* OPENOCD_PLD_ECP5_H */

View File

@ -249,6 +249,12 @@ static int efinix_get_ipdbg_hub(int user_num, struct pld_device *pld_device, str
return ERROR_OK; return ERROR_OK;
} }
static int efinix_get_jtagspi_userircode(struct pld_device *pld_device, unsigned int *ir)
{
*ir = USER1;
return ERROR_OK;
}
PLD_CREATE_COMMAND_HANDLER(efinix_pld_create_command) PLD_CREATE_COMMAND_HANDLER(efinix_pld_create_command)
{ {
if (CMD_ARGC != 4 && CMD_ARGC != 6) if (CMD_ARGC != 4 && CMD_ARGC != 6)
@ -296,4 +302,5 @@ struct pld_driver efinix_pld = {
.pld_create_command = &efinix_pld_create_command, .pld_create_command = &efinix_pld_create_command,
.load = &efinix_load, .load = &efinix_load,
.get_ipdbg_hub = efinix_get_ipdbg_hub, .get_ipdbg_hub = efinix_get_ipdbg_hub,
.get_jtagspi_userircode = efinix_get_jtagspi_userircode,
}; };

View File

@ -15,6 +15,8 @@
#include "raw_bit.h" #include "raw_bit.h"
#define JTAG_CONFIGURE 0x06 #define JTAG_CONFIGURE 0x06
#define JTAG_SPI_BYPASS 0x05
#define BYPASS 0x3F
struct gatemate_pld_device { struct gatemate_pld_device {
struct jtag_tap *tap; struct jtag_tap *tap;
@ -209,6 +211,66 @@ static int gatemate_load(struct pld_device *pld_device, const char *filename)
return retval; return retval;
} }
static int gatemate_has_jtagspi_instruction(struct pld_device *device, bool *has_instruction)
{
*has_instruction = true;
return ERROR_OK;
}
static int gatemate_connect_spi_to_jtag(struct pld_device *pld_device)
{
if (!pld_device)
return ERROR_FAIL;
struct gatemate_pld_device *pld_device_info = pld_device->driver_priv;
if (!pld_device_info)
return ERROR_FAIL;
struct jtag_tap *tap = pld_device_info->tap;
if (!tap)
return ERROR_FAIL;
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == JTAG_SPI_BYPASS)
return ERROR_OK;
gatemate_set_instr(tap, JTAG_SPI_BYPASS);
return jtag_execute_queue();
}
static int gatemate_disconnect_spi_from_jtag(struct pld_device *pld_device)
{
if (!pld_device)
return ERROR_FAIL;
struct gatemate_pld_device *pld_device_info = pld_device->driver_priv;
if (!pld_device_info)
return ERROR_FAIL;
struct jtag_tap *tap = pld_device_info->tap;
if (!tap)
return ERROR_FAIL;
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != JTAG_SPI_BYPASS)
return ERROR_OK;
gatemate_set_instr(tap, BYPASS);
return jtag_execute_queue();
}
static int gatemate_get_stuff_bits(struct pld_device *pld_device, unsigned int *facing_read_bits,
unsigned int *trailing_write_bits)
{
if (!pld_device)
return ERROR_FAIL;
*facing_read_bits = 1;
*trailing_write_bits = 1;
return ERROR_OK;
}
PLD_CREATE_COMMAND_HANDLER(gatemate_pld_create_command) PLD_CREATE_COMMAND_HANDLER(gatemate_pld_create_command)
{ {
if (CMD_ARGC != 4) if (CMD_ARGC != 4)
@ -239,4 +301,8 @@ struct pld_driver gatemate_pld = {
.name = "gatemate", .name = "gatemate",
.pld_create_command = &gatemate_pld_create_command, .pld_create_command = &gatemate_pld_create_command,
.load = &gatemate_load, .load = &gatemate_load,
.has_jtagspi_instruction = gatemate_has_jtagspi_instruction,
.connect_spi_to_jtag = gatemate_connect_spi_to_jtag,
.disconnect_spi_from_jtag = gatemate_disconnect_spi_from_jtag,
.get_stuff_bits = gatemate_get_stuff_bits,
}; };

View File

@ -543,10 +543,10 @@ static const struct command_registration gowin_exec_command_handlers[] = {
.help = "reading user register from FPGA", .help = "reading user register from FPGA",
.usage = "pld_name", .usage = "pld_name",
}, { }, {
.name = "reload", .name = "refresh",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.handler = gowin_reload_command_handler, .handler = gowin_reload_command_handler,
.help = "reloading bitstream from flash to SRAM", .help = "reload bitstream from flash to SRAM",
.usage = "pld_name", .usage = "pld_name",
}, },
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE

View File

@ -362,6 +362,12 @@ static int intel_get_ipdbg_hub(int user_num, struct pld_device *pld_device, stru
return ERROR_OK; return ERROR_OK;
} }
static int intel_get_jtagspi_userircode(struct pld_device *pld_device, unsigned int *ir)
{
*ir = USER1;
return ERROR_OK;
}
COMMAND_HANDLER(intel_set_bscan_command_handler) COMMAND_HANDLER(intel_set_bscan_command_handler)
{ {
unsigned int boundary_scan_length; unsigned int boundary_scan_length;
@ -412,7 +418,6 @@ COMMAND_HANDLER(intel_set_check_pos_command_handler)
return ERROR_OK; return ERROR_OK;
} }
PLD_CREATE_COMMAND_HANDLER(intel_pld_create_command) PLD_CREATE_COMMAND_HANDLER(intel_pld_create_command)
{ {
if (CMD_ARGC != 4 && CMD_ARGC != 6) if (CMD_ARGC != 4 && CMD_ARGC != 6)
@ -498,4 +503,5 @@ struct pld_driver intel_pld = {
.pld_create_command = &intel_pld_create_command, .pld_create_command = &intel_pld_create_command,
.load = &intel_load, .load = &intel_load,
.get_ipdbg_hub = intel_get_ipdbg_hub, .get_ipdbg_hub = intel_get_ipdbg_hub,
.get_jtagspi_userircode = intel_get_jtagspi_userircode,
}; };

View File

@ -342,6 +342,76 @@ static int lattice_get_ipdbg_hub(int user_num, struct pld_device *pld_device, st
return ERROR_OK; return ERROR_OK;
} }
static int lattice_connect_spi_to_jtag(struct pld_device *pld_device)
{
if (!pld_device)
return ERROR_FAIL;
struct lattice_pld_device *pld_device_info = pld_device->driver_priv;
int retval = lattice_check_device_family(pld_device_info);
if (retval != ERROR_OK)
return retval;
if (pld_device_info->family == LATTICE_ECP2 || pld_device_info->family == LATTICE_ECP3)
return lattice_ecp2_3_connect_spi_to_jtag(pld_device_info);
else if (pld_device_info->family == LATTICE_ECP5)
return lattice_ecp5_connect_spi_to_jtag(pld_device_info);
else if (pld_device_info->family == LATTICE_CERTUS)
return lattice_certus_connect_spi_to_jtag(pld_device_info);
return ERROR_FAIL;
}
static int lattice_disconnect_spi_from_jtag(struct pld_device *pld_device)
{
if (!pld_device)
return ERROR_FAIL;
struct lattice_pld_device *pld_device_info = pld_device->driver_priv;
int retval = lattice_check_device_family(pld_device_info);
if (retval != ERROR_OK)
return retval;
if (pld_device_info->family == LATTICE_ECP2 || pld_device_info->family == LATTICE_ECP3)
return lattice_ecp2_3_disconnect_spi_from_jtag(pld_device_info);
else if (pld_device_info->family == LATTICE_ECP5)
return lattice_ecp5_disconnect_spi_from_jtag(pld_device_info);
else if (pld_device_info->family == LATTICE_CERTUS)
return lattice_certus_disconnect_spi_from_jtag(pld_device_info);
return ERROR_FAIL;
}
static int lattice_get_stuff_bits(struct pld_device *pld_device, unsigned int *facing_read_bits,
unsigned int *trailing_write_bits)
{
if (!pld_device)
return ERROR_FAIL;
struct lattice_pld_device *pld_device_info = pld_device->driver_priv;
int retval = lattice_check_device_family(pld_device_info);
if (retval != ERROR_OK)
return retval;
if (pld_device_info->family == LATTICE_ECP2 || pld_device_info->family == LATTICE_ECP3)
return lattice_ecp2_3_get_facing_read_bits(pld_device_info, facing_read_bits);
else if (pld_device_info->family == LATTICE_ECP5)
return lattice_ecp5_get_facing_read_bits(pld_device_info, facing_read_bits);
else if (pld_device_info->family == LATTICE_CERTUS)
return lattice_certus_get_facing_read_bits(pld_device_info, facing_read_bits);
return ERROR_FAIL;
}
static int lattice_has_jtagspi_instruction(struct pld_device *device, bool *has_instruction)
{
*has_instruction = true;
return ERROR_OK;
}
PLD_CREATE_COMMAND_HANDLER(lattice_pld_create_command) PLD_CREATE_COMMAND_HANDLER(lattice_pld_create_command)
{ {
if (CMD_ARGC != 4 && CMD_ARGC != 6) if (CMD_ARGC != 4 && CMD_ARGC != 6)
@ -505,6 +575,35 @@ COMMAND_HANDLER(lattice_read_status_command_handler)
return retval; return retval;
} }
COMMAND_HANDLER(lattice_refresh_command_handler)
{
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
struct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!device) {
command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
struct lattice_pld_device *lattice_device = device->driver_priv;
if (!lattice_device)
return ERROR_FAIL;
int retval = lattice_check_device_family(lattice_device);
if (retval != ERROR_OK)
return retval;
if (lattice_device->family == LATTICE_ECP2 || lattice_device->family == LATTICE_ECP3)
return lattice_ecp2_3_refresh(lattice_device);
else if (lattice_device->family == LATTICE_ECP5)
return lattice_ecp5_refresh(lattice_device);
else if (lattice_device->family == LATTICE_CERTUS)
return lattice_certus_refresh(lattice_device);
return ERROR_FAIL;
}
static const struct command_registration lattice_exec_command_handlers[] = { static const struct command_registration lattice_exec_command_handlers[] = {
{ {
.name = "read_status", .name = "read_status",
@ -530,6 +629,12 @@ static const struct command_registration lattice_exec_command_handlers[] = {
.handler = lattice_set_preload_command_handler, .handler = lattice_set_preload_command_handler,
.help = "set length for preload (device specific)", .help = "set length for preload (device specific)",
.usage = "pld_name value", .usage = "pld_name value",
}, {
.name = "refresh",
.mode = COMMAND_EXEC,
.handler = lattice_refresh_command_handler,
.help = "refresh from configuration memory",
.usage = "pld_name",
}, },
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };
@ -551,4 +656,8 @@ struct pld_driver lattice_pld = {
.pld_create_command = &lattice_pld_create_command, .pld_create_command = &lattice_pld_create_command,
.load = &lattice_load_command, .load = &lattice_load_command,
.get_ipdbg_hub = lattice_get_ipdbg_hub, .get_ipdbg_hub = lattice_get_ipdbg_hub,
.has_jtagspi_instruction = lattice_has_jtagspi_instruction,
.connect_spi_to_jtag = lattice_connect_spi_to_jtag,
.disconnect_spi_from_jtag = lattice_disconnect_spi_from_jtag,
.get_stuff_bits = lattice_get_stuff_bits,
}; };

View File

@ -10,8 +10,10 @@
#define ISC_ERASE 0x0E #define ISC_ERASE 0x0E
#define ISC_DISABLE 0x26 #define ISC_DISABLE 0x26
#define PROGRAM_SPI 0x3A
#define LSC_READ_STATUS 0x3C #define LSC_READ_STATUS 0x3C
#define LSC_INIT_ADDRESS 0x46 #define LSC_INIT_ADDRESS 0x46
#define LSC_REFRESH 0x79
#define LSC_BITSTREAM_BURST 0x7A #define LSC_BITSTREAM_BURST 0x7A
#define READ_USERCODE 0xC0 #define READ_USERCODE 0xC0
#define ISC_ENABLE 0xC6 #define ISC_ENABLE 0xC6

View File

@ -69,8 +69,95 @@ struct pld_device *get_pld_device_by_name_or_numstr(const char *str)
return get_pld_device_by_num(dev_num); return get_pld_device_by_num(dev_num);
} }
/* @deffn {Config Command} {pld create} pld_name driver -chain-position tap_name [options]
*/ int pld_has_jtagspi_instruction(struct pld_device *pld_device, bool *has_instruction)
{
*has_instruction = false; /* default is using a proxy bitstream */
if (!pld_device)
return ERROR_FAIL;
struct pld_driver *pld_driver = pld_device->driver;
if (!pld_driver) {
LOG_ERROR("pld device has no associated driver");
return ERROR_FAIL;
}
if (pld_driver->has_jtagspi_instruction)
return pld_driver->has_jtagspi_instruction(pld_device, has_instruction);
/* else, take the default (proxy bitstream) */
return ERROR_OK;
}
int pld_get_jtagspi_userircode(struct pld_device *pld_device, unsigned int *ir)
{
if (!pld_device)
return ERROR_FAIL;
struct pld_driver *pld_driver = pld_device->driver;
if (!pld_driver) {
LOG_ERROR("pld device has no associated driver");
return ERROR_FAIL;
}
if (pld_driver->get_jtagspi_userircode)
return pld_driver->get_jtagspi_userircode(pld_device, ir);
return ERROR_FAIL;
}
int pld_get_jtagspi_stuff_bits(struct pld_device *pld_device, unsigned int *facing_read_bits,
unsigned int *trailing_write_bits)
{
if (!pld_device)
return ERROR_FAIL;
struct pld_driver *pld_driver = pld_device->driver;
if (!pld_driver) {
LOG_ERROR("pld device has no associated driver");
return ERROR_FAIL;
}
if (pld_driver->get_stuff_bits)
return pld_driver->get_stuff_bits(pld_device, facing_read_bits, trailing_write_bits);
return ERROR_OK;
}
int pld_connect_spi_to_jtag(struct pld_device *pld_device)
{
if (!pld_device)
return ERROR_FAIL;
struct pld_driver *pld_driver = pld_device->driver;
if (!pld_driver) {
LOG_ERROR("pld device has no associated driver");
return ERROR_FAIL;
}
if (pld_driver->connect_spi_to_jtag)
return pld_driver->connect_spi_to_jtag(pld_device);
return ERROR_FAIL;
}
int pld_disconnect_spi_from_jtag(struct pld_device *pld_device)
{
if (!pld_device)
return ERROR_FAIL;
struct pld_driver *pld_driver = pld_device->driver;
if (!pld_driver) {
LOG_ERROR("pld device has no associated driver");
return ERROR_FAIL;
}
if (pld_driver->disconnect_spi_from_jtag)
return pld_driver->disconnect_spi_from_jtag(pld_device);
return ERROR_FAIL;
}
COMMAND_HANDLER(handle_pld_create_command) COMMAND_HANDLER(handle_pld_create_command)
{ {
if (CMD_ARGC < 2) if (CMD_ARGC < 2)

View File

@ -20,12 +20,26 @@ struct pld_ipdbg_hub {
unsigned int user_ir_code; unsigned int user_ir_code;
}; };
int pld_has_jtagspi_instruction(struct pld_device *device, bool *has_instruction);
int pld_get_jtagspi_userircode(struct pld_device *pld_device, unsigned int *ir);
int pld_get_jtagspi_stuff_bits(struct pld_device *pld_device, unsigned int *facing_read_bits,
unsigned int *trailing_write_bits);
int pld_connect_spi_to_jtag(struct pld_device *pld_device);
int pld_disconnect_spi_from_jtag(struct pld_device *pld_device);
struct pld_driver { struct pld_driver {
const char *name; const char *name;
__PLD_CREATE_COMMAND((*pld_create_command)); __PLD_CREATE_COMMAND((*pld_create_command));
const struct command_registration *commands; const struct command_registration *commands;
int (*load)(struct pld_device *pld_device, const char *filename); int (*load)(struct pld_device *pld_device, const char *filename);
int (*get_ipdbg_hub)(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub); int (*get_ipdbg_hub)(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub);
int (*has_jtagspi_instruction)(struct pld_device *device, bool *has_instruction);
int (*get_jtagspi_userircode)(struct pld_device *pld_device, unsigned int *ir);
int (*connect_spi_to_jtag)(struct pld_device *pld_device);
int (*disconnect_spi_from_jtag)(struct pld_device *pld_device);
int (*get_stuff_bits)(struct pld_device *pld_device, unsigned int *facing_read_bits,
unsigned int *trailing_write_bits);
}; };
#define PLD_CREATE_COMMAND_HANDLER(name) \ #define PLD_CREATE_COMMAND_HANDLER(name) \

View File

@ -265,7 +265,7 @@ static int virtex2_load(struct pld_device *pld_device, const char *filename)
return retval; return retval;
} }
COMMAND_HANDLER(virtex2_handle_program_command) COMMAND_HANDLER(virtex2_handle_refresh_command)
{ {
struct pld_device *device; struct pld_device *device;
@ -326,6 +326,21 @@ static int xilinx_get_ipdbg_hub(int user_num, struct pld_device *pld_device, str
return ERROR_OK; return ERROR_OK;
} }
static int xilinx_get_jtagspi_userircode(struct pld_device *pld_device, unsigned int *ir)
{
if (!pld_device || !pld_device->driver_priv)
return ERROR_FAIL;
struct virtex2_pld_device *pld_device_info = pld_device->driver_priv;
if (pld_device_info->command_set.num_user < 1) {
LOG_ERROR("code for command 'select user1' is unknown");
return ERROR_FAIL;
}
*ir = pld_device_info->command_set.user[0];
return ERROR_OK;
}
COMMAND_HANDLER(virtex2_handle_set_instuction_codes_command) COMMAND_HANDLER(virtex2_handle_set_instuction_codes_command)
{ {
if (CMD_ARGC < 6 || CMD_ARGC > (6 + VIRTEX2_MAX_USER_INSTRUCTIONS)) if (CMD_ARGC < 6 || CMD_ARGC > (6 + VIRTEX2_MAX_USER_INSTRUCTIONS))
@ -434,10 +449,10 @@ static const struct command_registration virtex2_exec_command_handlers[] = {
.help = "set instructions codes used for jtag-hub", .help = "set instructions codes used for jtag-hub",
.usage = "pld_name user1 [user2 [user3 [user4]]]", .usage = "pld_name user1 [user2 [user3 [user4]]]",
}, { }, {
.name = "program", .name = "refresh",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.handler = virtex2_handle_program_command, .handler = virtex2_handle_refresh_command,
.help = "start loading of configuration (refresh)", .help = "start loading of configuration (program)",
.usage = "pld_name", .usage = "pld_name",
}, },
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
@ -460,4 +475,5 @@ struct pld_driver virtex2_pld = {
.pld_create_command = &virtex2_pld_create_command, .pld_create_command = &virtex2_pld_create_command,
.load = &virtex2_load, .load = &virtex2_load,
.get_ipdbg_hub = xilinx_get_ipdbg_hub, .get_ipdbg_hub = xilinx_get_ipdbg_hub,
.get_jtagspi_userircode = xilinx_get_jtagspi_userircode,
}; };

View File

@ -1253,6 +1253,27 @@ static void gdb_target_to_reg(struct target *target,
} }
} }
/* get register value if needed and fill the buffer accordingly */
static int gdb_get_reg_value_as_str(struct target *target, char *tstr, struct reg *reg)
{
int retval = ERROR_OK;
if (!reg->valid)
retval = reg->type->get(reg);
const unsigned int len = DIV_ROUND_UP(reg->size, 8) * 2;
switch (retval) {
case ERROR_OK:
gdb_str_to_target(target, tstr, reg);
return ERROR_OK;
case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
memset(tstr, 'x', len);
tstr[len] = '\0';
return ERROR_OK;
}
return ERROR_FAIL;
}
static int gdb_get_registers_packet(struct connection *connection, static int gdb_get_registers_packet(struct connection *connection,
char const *packet, int packet_size) char const *packet, int packet_size)
{ {
@ -1294,16 +1315,11 @@ static int gdb_get_registers_packet(struct connection *connection,
for (i = 0; i < reg_list_size; i++) { for (i = 0; i < reg_list_size; i++) {
if (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden) if (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden)
continue; continue;
if (!reg_list[i]->valid) { if (gdb_get_reg_value_as_str(target, reg_packet_p, reg_list[i]) != ERROR_OK) {
retval = reg_list[i]->type->get(reg_list[i]); free(reg_packet);
if (retval != ERROR_OK && gdb_report_register_access_error) { free(reg_list);
LOG_DEBUG("Couldn't get register %s.", reg_list[i]->name); return gdb_error(connection, retval);
free(reg_packet);
free(reg_list);
return gdb_error(connection, retval);
}
} }
gdb_str_to_target(target, reg_packet_p, reg_list[i]);
reg_packet_p += DIV_ROUND_UP(reg_list[i]->size, 8) * 2; reg_packet_p += DIV_ROUND_UP(reg_list[i]->size, 8) * 2;
} }
@ -1420,18 +1436,13 @@ static int gdb_get_register_packet(struct connection *connection,
return gdb_error(connection, ERROR_FAIL); return gdb_error(connection, ERROR_FAIL);
} }
if (!reg_list[reg_num]->valid) {
retval = reg_list[reg_num]->type->get(reg_list[reg_num]);
if (retval != ERROR_OK && gdb_report_register_access_error) {
LOG_DEBUG("Couldn't get register %s.", reg_list[reg_num]->name);
free(reg_list);
return gdb_error(connection, retval);
}
}
reg_packet = calloc(DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2 + 1, 1); /* plus one for string termination null */ reg_packet = calloc(DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2 + 1, 1); /* plus one for string termination null */
gdb_str_to_target(target, reg_packet, reg_list[reg_num]); if (gdb_get_reg_value_as_str(target, reg_packet, reg_list[reg_num]) != ERROR_OK) {
free(reg_packet);
free(reg_list);
return gdb_error(connection, retval);
}
gdb_put_packet(connection, reg_packet, DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2); gdb_put_packet(connection, reg_packet, DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2);

View File

@ -2047,6 +2047,11 @@ static int aarch64_write_cpu_memory_slow(struct target *target,
struct arm *arm = &armv8->arm; struct arm *arm = &armv8->arm;
int retval; int retval;
if (size > 4 && arm->core_state != ARM_STATE_AARCH64) {
LOG_ERROR("memory write sizes greater than 4 bytes is only supported for AArch64 state");
return ERROR_FAIL;
}
armv8_reg_current(arm, 1)->dirty = true; armv8_reg_current(arm, 1)->dirty = true;
/* change DCC to normal mode if necessary */ /* change DCC to normal mode if necessary */
@ -2059,22 +2064,32 @@ static int aarch64_write_cpu_memory_slow(struct target *target,
} }
while (count) { while (count) {
uint32_t data, opcode; uint32_t opcode;
uint64_t data;
/* write the data to store into DTRRX */ /* write the data to store into DTRRX (and DTRTX for 64-bit) */
if (size == 1) if (size == 1)
data = *buffer; data = *buffer;
else if (size == 2) else if (size == 2)
data = target_buffer_get_u16(target, buffer); data = target_buffer_get_u16(target, buffer);
else else if (size == 4)
data = target_buffer_get_u32(target, buffer); data = target_buffer_get_u32(target, buffer);
else
data = target_buffer_get_u64(target, buffer);
retval = mem_ap_write_atomic_u32(armv8->debug_ap, retval = mem_ap_write_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_DTRRX, data); armv8->debug_base + CPUV8_DBG_DTRRX, (uint32_t)data);
if (retval == ERROR_OK && size > 4)
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_DTRTX, (uint32_t)(data >> 32));
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if (arm->core_state == ARM_STATE_AARCH64) if (arm->core_state == ARM_STATE_AARCH64)
retval = dpm->instr_execute(dpm, ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0, 1)); if (size <= 4)
retval = dpm->instr_execute(dpm, ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0, 1));
else
retval = dpm->instr_execute(dpm, ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 1));
else else
retval = dpm->instr_execute(dpm, ARMV4_5_MRC(14, 0, 1, 0, 5, 0)); retval = dpm->instr_execute(dpm, ARMV4_5_MRC(14, 0, 1, 0, 5, 0));
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -2084,8 +2099,11 @@ static int aarch64_write_cpu_memory_slow(struct target *target,
opcode = armv8_opcode(armv8, ARMV8_OPC_STRB_IP); opcode = armv8_opcode(armv8, ARMV8_OPC_STRB_IP);
else if (size == 2) else if (size == 2)
opcode = armv8_opcode(armv8, ARMV8_OPC_STRH_IP); opcode = armv8_opcode(armv8, ARMV8_OPC_STRH_IP);
else else if (size == 4)
opcode = armv8_opcode(armv8, ARMV8_OPC_STRW_IP); opcode = armv8_opcode(armv8, ARMV8_OPC_STRW_IP);
else
opcode = armv8_opcode(armv8, ARMV8_OPC_STRD_IP);
retval = dpm->instr_execute(dpm, opcode); retval = dpm->instr_execute(dpm, opcode);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -2226,6 +2244,11 @@ static int aarch64_read_cpu_memory_slow(struct target *target,
struct arm *arm = &armv8->arm; struct arm *arm = &armv8->arm;
int retval; int retval;
if (size > 4 && arm->core_state != ARM_STATE_AARCH64) {
LOG_ERROR("memory read sizes greater than 4 bytes is only supported for AArch64 state");
return ERROR_FAIL;
}
armv8_reg_current(arm, 1)->dirty = true; armv8_reg_current(arm, 1)->dirty = true;
/* change DCC to normal mode (if necessary) */ /* change DCC to normal mode (if necessary) */
@ -2238,36 +2261,56 @@ static int aarch64_read_cpu_memory_slow(struct target *target,
} }
while (count) { while (count) {
uint32_t opcode, data; uint32_t opcode;
uint32_t lower;
uint32_t higher;
uint64_t data;
if (size == 1) if (size == 1)
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRB_IP); opcode = armv8_opcode(armv8, ARMV8_OPC_LDRB_IP);
else if (size == 2) else if (size == 2)
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRH_IP); opcode = armv8_opcode(armv8, ARMV8_OPC_LDRH_IP);
else else if (size == 4)
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRW_IP); opcode = armv8_opcode(armv8, ARMV8_OPC_LDRW_IP);
else
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRD_IP);
retval = dpm->instr_execute(dpm, opcode); retval = dpm->instr_execute(dpm, opcode);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if (arm->core_state == ARM_STATE_AARCH64) if (arm->core_state == ARM_STATE_AARCH64)
retval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0, 1)); if (size <= 4)
retval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0, 1));
else
retval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, 1));
else else
retval = dpm->instr_execute(dpm, ARMV4_5_MCR(14, 0, 1, 0, 5, 0)); retval = dpm->instr_execute(dpm, ARMV4_5_MCR(14, 0, 1, 0, 5, 0));
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
retval = mem_ap_read_atomic_u32(armv8->debug_ap, retval = mem_ap_read_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_DTRTX, &data); armv8->debug_base + CPUV8_DBG_DTRTX, &lower);
if (retval == ERROR_OK) {
if (size > 4)
retval = mem_ap_read_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_DTRRX, &higher);
else
higher = 0;
}
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
data = (uint64_t)lower | (uint64_t)higher << 32;
if (size == 1) if (size == 1)
*buffer = (uint8_t)data; *buffer = (uint8_t)data;
else if (size == 2) else if (size == 2)
target_buffer_set_u16(target, buffer, (uint16_t)data); target_buffer_set_u16(target, buffer, (uint16_t)data);
else if (size == 4)
target_buffer_set_u32(target, buffer, (uint32_t)data);
else else
target_buffer_set_u32(target, buffer, data); target_buffer_set_u64(target, buffer, data);
/* Advance */ /* Advance */
buffer += size; buffer += size;

View File

@ -350,7 +350,7 @@ static int adi_jtag_dp_scan_u32(struct adiv5_dap *dap,
{ {
uint8_t out_value_buf[4]; uint8_t out_value_buf[4];
int retval; int retval;
uint64_t sel = (reg_addr >> 4) & 0xf; uint64_t sel = (reg_addr >> 4) & DP_SELECT_DPBANK;
/* No need to change SELECT or RDBUFF as they are not banked */ /* No need to change SELECT or RDBUFF as they are not banked */
if (instr == JTAG_DP_DPACC && reg_addr != DP_SELECT && reg_addr != DP_RDBUFF && if (instr == JTAG_DP_DPACC && reg_addr != DP_SELECT && reg_addr != DP_RDBUFF &&
@ -775,7 +775,7 @@ static int jtag_ap_q_bankselect(struct adiv5_ap *ap, unsigned reg)
} }
/* ADIv5 */ /* ADIv5 */
sel = (ap->ap_num << 24) | (reg & 0x000000F0); sel = (ap->ap_num << 24) | (reg & ADIV5_DP_SELECT_APBANK);
if (sel == dap->select) if (sel == dap->select)
return ERROR_OK; return ERROR_OK;

View File

@ -147,7 +147,7 @@ static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg,
swd_finish_read(dap); swd_finish_read(dap);
if (reg == DP_SELECT) { if (reg == DP_SELECT) {
dap->select = data & (DP_SELECT_APSEL | DP_SELECT_APBANK | DP_SELECT_DPBANK); dap->select = data & (ADIV5_DP_SELECT_APSEL | ADIV5_DP_SELECT_APBANK | DP_SELECT_DPBANK);
swd->write_reg(swd_cmd(false, false, reg), data, 0); swd->write_reg(swd_cmd(false, false, reg), data, 0);
@ -523,7 +523,7 @@ static int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned reg)
} }
/* ADIv5 */ /* ADIv5 */
sel = (ap->ap_num << 24) | (reg & 0x000000F0); sel = (ap->ap_num << 24) | (reg & ADIV5_DP_SELECT_APBANK);
if (dap->select != DP_SELECT_INVALID) if (dap->select != DP_SELECT_INVALID)
sel |= dap->select & DP_SELECT_DPBANK; sel |= dap->select & DP_SELECT_DPBANK;

View File

@ -97,16 +97,16 @@
#define DP_DLPIDR_PROTVSN 1u #define DP_DLPIDR_PROTVSN 1u
#define DP_SELECT_APSEL 0xFF000000 #define ADIV5_DP_SELECT_APSEL 0xFF000000
#define DP_SELECT_APBANK 0x000000F0 #define ADIV5_DP_SELECT_APBANK 0x000000F0
#define DP_SELECT_DPBANK 0x0000000F #define DP_SELECT_DPBANK 0x0000000F
#define DP_SELECT_INVALID 0x00FFFF00 /* Reserved bits one */ #define DP_SELECT_INVALID 0x00FFFF00 /* Reserved bits one */
#define DP_APSEL_MAX (255) /* for ADIv5 only */ #define DP_APSEL_MAX (255) /* Strict limit for ADIv5, number of AP buffers for ADIv6 */
#define DP_APSEL_INVALID 0xF00 /* more than DP_APSEL_MAX and not ADIv6 aligned 4k */ #define DP_APSEL_INVALID 0xF00 /* more than DP_APSEL_MAX and not ADIv6 aligned 4k */
#define DP_TARGETSEL_INVALID 0xFFFFFFFFU #define DP_TARGETSEL_INVALID 0xFFFFFFFFU
#define DP_TARGETSEL_DPID_MASK 0x0FFFFFFFU #define DP_TARGETSEL_DPID_MASK 0x0FFFFFFFU
#define DP_TARGETSEL_INSTANCEID_MASK 0xF0000000U #define DP_TARGETSEL_INSTANCEID_MASK 0xF0000000U
#define DP_TARGETSEL_INSTANCEID_SHIFT 28 #define DP_TARGETSEL_INSTANCEID_SHIFT 28

View File

@ -36,9 +36,11 @@ static const uint32_t a64_opcodes[ARMV8_OPC_NUM] = {
[ARMV8_OPC_LDRB_IP] = ARMV8_LDRB_IP(1, 0), [ARMV8_OPC_LDRB_IP] = ARMV8_LDRB_IP(1, 0),
[ARMV8_OPC_LDRH_IP] = ARMV8_LDRH_IP(1, 0), [ARMV8_OPC_LDRH_IP] = ARMV8_LDRH_IP(1, 0),
[ARMV8_OPC_LDRW_IP] = ARMV8_LDRW_IP(1, 0), [ARMV8_OPC_LDRW_IP] = ARMV8_LDRW_IP(1, 0),
[ARMV8_OPC_LDRD_IP] = ARMV8_LDRD_IP(1, 0),
[ARMV8_OPC_STRB_IP] = ARMV8_STRB_IP(1, 0), [ARMV8_OPC_STRB_IP] = ARMV8_STRB_IP(1, 0),
[ARMV8_OPC_STRH_IP] = ARMV8_STRH_IP(1, 0), [ARMV8_OPC_STRH_IP] = ARMV8_STRH_IP(1, 0),
[ARMV8_OPC_STRW_IP] = ARMV8_STRW_IP(1, 0), [ARMV8_OPC_STRW_IP] = ARMV8_STRW_IP(1, 0),
[ARMV8_OPC_STRD_IP] = ARMV8_STRD_IP(1, 0),
}; };
static const uint32_t t32_opcodes[ARMV8_OPC_NUM] = { static const uint32_t t32_opcodes[ARMV8_OPC_NUM] = {

View File

@ -155,6 +155,7 @@
#define ARMV8_LDRB_IP(rd, rn) (0x38401400 | (rn << 5) | rd) #define ARMV8_LDRB_IP(rd, rn) (0x38401400 | (rn << 5) | rd)
#define ARMV8_LDRH_IP(rd, rn) (0x78402400 | (rn << 5) | rd) #define ARMV8_LDRH_IP(rd, rn) (0x78402400 | (rn << 5) | rd)
#define ARMV8_LDRW_IP(rd, rn) (0xb8404400 | (rn << 5) | rd) #define ARMV8_LDRW_IP(rd, rn) (0xb8404400 | (rn << 5) | rd)
#define ARMV8_LDRD_IP(rd, rn) (0xf8408400 | (rn << 5) | rd)
#define ARMV8_LDRB_IP_T3(rd, rn) (0xf8100b01 | (rn << 16) | (rd << 12)) #define ARMV8_LDRB_IP_T3(rd, rn) (0xf8100b01 | (rn << 16) | (rd << 12))
#define ARMV8_LDRH_IP_T3(rd, rn) (0xf8300b02 | (rn << 16) | (rd << 12)) #define ARMV8_LDRH_IP_T3(rd, rn) (0xf8300b02 | (rn << 16) | (rd << 12))
@ -163,6 +164,7 @@
#define ARMV8_STRB_IP(rd, rn) (0x38001400 | (rn << 5) | rd) #define ARMV8_STRB_IP(rd, rn) (0x38001400 | (rn << 5) | rd)
#define ARMV8_STRH_IP(rd, rn) (0x78002400 | (rn << 5) | rd) #define ARMV8_STRH_IP(rd, rn) (0x78002400 | (rn << 5) | rd)
#define ARMV8_STRW_IP(rd, rn) (0xb8004400 | (rn << 5) | rd) #define ARMV8_STRW_IP(rd, rn) (0xb8004400 | (rn << 5) | rd)
#define ARMV8_STRD_IP(rd, rn) (0xf8008400 | (rn << 5) | rd)
#define ARMV8_STRB_IP_T3(rd, rn) (0xf8000b01 | (rn << 16) | (rd << 12)) #define ARMV8_STRB_IP_T3(rd, rn) (0xf8000b01 | (rn << 16) | (rd << 12))
#define ARMV8_STRH_IP_T3(rd, rn) (0xf8200b02 | (rn << 16) | (rd << 12)) #define ARMV8_STRH_IP_T3(rd, rn) (0xf8200b02 | (rn << 16) | (rd << 12))
@ -200,9 +202,11 @@ enum armv8_opcode {
ARMV8_OPC_STRB_IP, ARMV8_OPC_STRB_IP,
ARMV8_OPC_STRH_IP, ARMV8_OPC_STRH_IP,
ARMV8_OPC_STRW_IP, ARMV8_OPC_STRW_IP,
ARMV8_OPC_STRD_IP,
ARMV8_OPC_LDRB_IP, ARMV8_OPC_LDRB_IP,
ARMV8_OPC_LDRH_IP, ARMV8_OPC_LDRH_IP,
ARMV8_OPC_LDRW_IP, ARMV8_OPC_LDRW_IP,
ARMV8_OPC_LDRD_IP,
ARMV8_OPC_NUM, ARMV8_OPC_NUM,
}; };

View File

@ -1959,7 +1959,8 @@ static int cortex_m_set_watchpoint(struct target *target, struct watchpoint *wat
target_write_u32(target, comparator->dwt_comparator_address + 0, target_write_u32(target, comparator->dwt_comparator_address + 0,
comparator->comp); comparator->comp);
if ((cortex_m->dwt_devarch & 0x1FFFFF) != DWT_DEVARCH_ARMV8M) { if ((cortex_m->dwt_devarch & 0x1FFFFF) != DWT_DEVARCH_ARMV8M_V2_0
&& (cortex_m->dwt_devarch & 0x1FFFFF) != DWT_DEVARCH_ARMV8M_V2_1) {
uint32_t mask = 0, temp; uint32_t mask = 0, temp;
/* watchpoint params were validated earlier */ /* watchpoint params were validated earlier */

View File

@ -92,7 +92,8 @@ struct cortex_m_part_info {
#define DWT_FUNCTION0 0xE0001028 #define DWT_FUNCTION0 0xE0001028
#define DWT_DEVARCH 0xE0001FBC #define DWT_DEVARCH 0xE0001FBC
#define DWT_DEVARCH_ARMV8M 0x101A02 #define DWT_DEVARCH_ARMV8M_V2_0 0x101A02
#define DWT_DEVARCH_ARMV8M_V2_1 0x111A02
#define FP_CTRL 0xE0002000 #define FP_CTRL 0xE0002000
#define FP_REMAP 0xE0002004 #define FP_REMAP 0xE0002004

View File

@ -50,13 +50,16 @@ static int autodetect_image_type(struct image *image, const char *url)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
retval = fileio_read(fileio, 9, buffer, &read_bytes); retval = fileio_read(fileio, 9, buffer, &read_bytes);
if (retval == ERROR_OK) {
if (read_bytes != 9)
retval = ERROR_FILEIO_OPERATION_FAILED;
}
fileio_close(fileio); fileio_close(fileio);
/* If the file is smaller than 9 bytes, it can only be bin */
if (retval == ERROR_OK && read_bytes != 9) {
LOG_DEBUG("Less than 9 bytes in the image file found.");
LOG_DEBUG("BIN image detected.");
image->type = IMAGE_BINARY;
return ERROR_OK;
}
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -82,8 +85,10 @@ static int autodetect_image_type(struct image *image, const char *url)
&& (buffer[1] >= '0') && (buffer[1] < '9')) { && (buffer[1] >= '0') && (buffer[1] < '9')) {
LOG_DEBUG("S19 image detected."); LOG_DEBUG("S19 image detected.");
image->type = IMAGE_SRECORD; image->type = IMAGE_SRECORD;
} else } else {
LOG_DEBUG("BIN image detected.");
image->type = IMAGE_BINARY; image->type = IMAGE_BINARY;
}
return ERROR_OK; return ERROR_OK;
} }

View File

@ -3928,24 +3928,24 @@ static int handle_bp_command_list(struct command_invocation *cmd)
if (breakpoint->type == BKPT_SOFT) { if (breakpoint->type == BKPT_SOFT) {
char *buf = buf_to_hex_str(breakpoint->orig_instr, char *buf = buf_to_hex_str(breakpoint->orig_instr,
breakpoint->length); breakpoint->length);
command_print(cmd, "IVA breakpoint: " TARGET_ADDR_FMT ", 0x%x, 0x%s", command_print(cmd, "Software breakpoint(IVA): addr=" TARGET_ADDR_FMT ", len=0x%x, orig_instr=0x%s",
breakpoint->address, breakpoint->address,
breakpoint->length, breakpoint->length,
buf); buf);
free(buf); free(buf);
} else { } else {
if ((breakpoint->address == 0) && (breakpoint->asid != 0)) if ((breakpoint->address == 0) && (breakpoint->asid != 0))
command_print(cmd, "Context breakpoint: 0x%8.8" PRIx32 ", 0x%x, %u", command_print(cmd, "Context breakpoint: asid=0x%8.8" PRIx32 ", len=0x%x, num=%u",
breakpoint->asid, breakpoint->asid,
breakpoint->length, breakpoint->number); breakpoint->length, breakpoint->number);
else if ((breakpoint->address != 0) && (breakpoint->asid != 0)) { else if ((breakpoint->address != 0) && (breakpoint->asid != 0)) {
command_print(cmd, "Hybrid breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %u", command_print(cmd, "Hybrid breakpoint(IVA): addr=" TARGET_ADDR_FMT ", len=0x%x, num=%u",
breakpoint->address, breakpoint->address,
breakpoint->length, breakpoint->number); breakpoint->length, breakpoint->number);
command_print(cmd, "\t|--->linked with ContextID: 0x%8.8" PRIx32, command_print(cmd, "\t|--->linked with ContextID: 0x%8.8" PRIx32,
breakpoint->asid); breakpoint->asid);
} else } else
command_print(cmd, "Breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %u", command_print(cmd, "Hardware breakpoint(IVA): addr=" TARGET_ADDR_FMT ", len=0x%x, num=%u",
breakpoint->address, breakpoint->address,
breakpoint->length, breakpoint->number); breakpoint->length, breakpoint->number);
} }

View File

@ -16,5 +16,9 @@ source [find fpga/altera-cycloneiii.cfg]
#quartus_cpf --option=bitstream_compression=off -c output_files\cycloneiii_blinker.sof cycloneiii_blinker.rbf #quartus_cpf --option=bitstream_compression=off -c output_files\cycloneiii_blinker.sof cycloneiii_blinker.rbf
#openocd -f board/bemicro_cycloneiii.cfg -c "init" -c "pld load 0 cycloneiii_blinker.rbf" #openocd -f board/bemicro_cycloneiii.cfg -c "init" -c "pld load cycloneiii.pld cycloneiii_blinker.rbf"
# "ipdbg -start -tap cycloneiii.tap -hub 0x00e -tool 0 -port 5555" # "ipdbg -start -tap cycloneiii.tap -hub 0x00e -tool 0 -port 5555"
set JTAGSPI_CHAIN_ID cycloneiii.pld
source [find cpld/jtagspi.cfg]

View File

@ -12,3 +12,11 @@ transport select jtag
adapter speed 10000 adapter speed 10000
source [find fpga/lattice_certuspro.cfg] source [find fpga/lattice_certuspro.cfg]
#openocd -f board/certuspro_evaluation.cfg -c "init" -c "pld load certuspro.pld shared_folder/certuspro_blinker_impl_1.bit"
set JTAGSPI_CHAIN_ID certuspro.pld
source [find cpld/jtagspi.cfg]
#jtagspi_init certuspro.pld "" -1
#jtagspi_program shared_folder/certuspro_blinker_impl1.bit 0

View File

@ -0,0 +1,25 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# digilent CMOD S7
# https://digilent.com/reference/programmable-logic/cmod-s7/reference-manual
adapter driver ftdi
ftdi channel 0
ftdi layout_init 0x0008 0x008b
ftdi vid_pid 0x0403 0x6010
reset_config none
transport select jtag
adapter speed 10000
source [find cpld/xilinx-xc7.cfg]
# "ipdbg -start -tap xc7.tap -hub 0x02 -tool 0 -port 5555"
#openocd -f board/digilent_cmod_s7.cfg -c "init" -c "pld load xc7.pld shared_folder/cmod_s7_fast.bit"
set JTAGSPI_CHAIN_ID xc7.pld
source [find cpld/jtagspi.cfg]
#jtagspi_init xc7.pld "shared_folder/bscan_spi_xc7s25.bit" 0xab
#jtagspi_program shared_folder/cmod_s7_fast.bit 0

View File

@ -15,5 +15,11 @@ adapter speed 6000
source [find fpga/lattice_ecp5.cfg] source [find fpga/lattice_ecp5.cfg]
#openocd -f board/ecp5_evaluation.cfg -c "init" -c "pld load 0 shared_folder/ecp5_blinker_impl1.bit" #openocd -f board/ecp5_evaluation.cfg -c "init" -c "pld load ecp5.pld shared_folder/ecp5_blinker_impl1.bit"
#ipdbg -start -tap ecp5.tap -hub 0x32 -port 5555 -tool 0 #ipdbg -start -tap ecp5.tap -hub 0x32 -port 5555 -tool 0
set JTAGSPI_CHAIN_ID ecp5.pld
source [find cpld/jtagspi.cfg]
#jtagspi_init ecp5.pld "" -1
#jtagspi_program shared_folder/ecp5_blinker_impl1_slow.bit 0

View File

@ -14,3 +14,9 @@ transport select jtag
adapter speed 6000 adapter speed 6000
source [find fpga/gatemate.cfg] source [find fpga/gatemate.cfg]
set JTAGSPI_CHAIN_ID gatemate.pld
source [find cpld/jtagspi.cfg]
#jtagspi_init gatemate.pld "" -1
#jtagspi_program workspace/blink/blink_slow.cfg.bit 0

24
tcl/board/ti_am62pevm.cfg Normal file
View File

@ -0,0 +1,24 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
#
# Texas Instruments SK-AM62P: https://www.ti.com/lit/zip/sprr487
#
# AM62P SK/EVM has an xds110 onboard.
source [find interface/xds110.cfg]
transport select jtag
# default JTAG configuration has only SRST and no TRST
reset_config srst_only srst_push_pull
# delay after SRST goes inactive
adapter srst delay 20
if { ![info exists SOC] } {
set SOC am62p
}
source [find target/ti_k3.cfg]
adapter speed 2500

View File

@ -0,0 +1,25 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
#
# Texas Instruments J784S4 EVM: https://www.ti.com/tool/J784S4XEVM
# Texas Instruments SK-AM69: https://www.ti.com/tool/SK-AM69
#
# J784S4/AM69 SK/EVM has an xds110 onboard.
source [find interface/xds110.cfg]
transport select jtag
# default JTAG configuration has only SRST and no TRST
reset_config srst_only srst_push_pull
# delay after SRST goes inactive
adapter srst delay 20
if { ![info exists SOC] } {
set SOC j784s4
}
source [find target/ti_k3.cfg]
adapter speed 2500

View File

@ -19,6 +19,11 @@ adapter speed 6000
source [find fpga/efinix_trion.cfg] source [find fpga/efinix_trion.cfg]
#openocd -f board/trion_t20_bga256.cfg -c "init" -c "pld load 0 outflow/trion_blinker.bit" #openocd -f board/trion_t20_bga256.cfg -c "init" -c "pld load trion.pld outflow/trion_blinker.bit"
#ipdbg -start -tap trion.tap -hub 0x8 -port 5555 -tool 0 #ipdbg -start -tap trion.tap -hub 0x8 -port 5555 -tool 0
set JTAGSPI_CHAIN_ID trion.pld
source [find cpld/jtagspi.cfg]
#jtagspi_init trion.pld "trion_jtagspi/outflow/trion_jtagspi.bit" 0xAB
#jtagspi_program trion_blinker/outflow/trion_blinker.bin 0

View File

@ -4,6 +4,8 @@ set _USER1 0x02
if { [info exists JTAGSPI_IR] } { if { [info exists JTAGSPI_IR] } {
set _JTAGSPI_IR $JTAGSPI_IR set _JTAGSPI_IR $JTAGSPI_IR
} elseif {[info exists JTAGSPI_CHAIN_ID]} {
set _JTAGSPI_CHAIN_ID $JTAGSPI_CHAIN_ID
} else { } else {
set _JTAGSPI_IR $_USER1 set _JTAGSPI_IR $_USER1
} }
@ -21,7 +23,11 @@ if { [info exists FLASHNAME] } {
} }
target create $_TARGETNAME testee -chain-position $_CHIPNAME.tap target create $_TARGETNAME testee -chain-position $_CHIPNAME.tap
flash bank $_FLASHNAME jtagspi 0 0 0 0 $_TARGETNAME $_JTAGSPI_IR if { [info exists _JTAGSPI_IR] } {
flash bank $_FLASHNAME jtagspi 0 0 0 0 $_TARGETNAME $_JTAGSPI_IR
} else {
flash bank $_FLASHNAME jtagspi 0 0 0 0 $_TARGETNAME -pld $_JTAGSPI_CHAIN_ID
}
# initialize jtagspi flash # initialize jtagspi flash
# chain_id: identifier of pld (you can get a list with 'pld devices') # chain_id: identifier of pld (you can get a list with 'pld devices')
@ -33,7 +39,9 @@ flash bank $_FLASHNAME jtagspi 0 0 0 0 $_TARGETNAME $_JTAGSPI_IR
proc jtagspi_init {chain_id proxy_bit {release_from_pwr_down_cmd -1}} { proc jtagspi_init {chain_id proxy_bit {release_from_pwr_down_cmd -1}} {
# load proxy bitstream $proxy_bit and probe spi flash # load proxy bitstream $proxy_bit and probe spi flash
global _FLASHNAME global _FLASHNAME
pld load $chain_id $proxy_bit if { $proxy_bit ne "" } {
pld load $chain_id $proxy_bit
}
reset halt reset halt
if {$release_from_pwr_down_cmd != -1} { if {$release_from_pwr_down_cmd != -1} {
jtagspi cmd $_FLASHNAME 0 $release_from_pwr_down_cmd jtagspi cmd $_FLASHNAME 0 $release_from_pwr_down_cmd

View File

@ -2,11 +2,17 @@
# this supports JTAG-HS2 (and apparently Nexys4 as well) # this supports JTAG-HS2 (and apparently Nexys4 as well)
# ADBUS5 controls TMS tri-state buffer enable
# ACBUS6=SEL_TMS controls mux to TMS output buffer: 0=TMS 1=TDI
# ACBUS5=SEL_TDO controls mux to TDO input: 0=TDO 1=TMS
adapter driver ftdi adapter driver ftdi
ftdi device_desc "Digilent Adept USB Device" ftdi device_desc "Digilent Adept USB Device"
ftdi vid_pid 0x0403 0x6014 ftdi vid_pid 0x0403 0x6014
ftdi channel 0 ftdi channel 0
ftdi layout_init 0x00e8 0x60eb ftdi layout_init 0x00e8 0x60eb
ftdi layout_signal SWD_EN -data 0x6000
ftdi layout_signal SWDIO_OE -data 0x20
reset_config none reset_config none

View File

@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Cavium Octeon II CN61xx (PrID 0x000D9301)
jtag newtap cpu tap0 -irlen 5
jtag newtap cpu tap1 -irlen 5
target create cpu.core0 mips_mips64 -chain-position cpu.tap0 -endian big -rtos hwthread -coreid 0
target create cpu.core1 mips_mips64 -chain-position cpu.tap1 -endian big -rtos hwthread -coreid 1
target smp cpu.core0 cpu.core1
cpu.core0 configure -work-area-phys 0xffffffffa2000000 -work-area-size 0x20000
cpu.core1 configure -work-area-phys 0xffffffffa2000000 -work-area-size 0x20000
targets cpu.core0

View File

@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Target: XLP304 processor by NetLogic Microsystems
#
set XLP_NT 4
source [find target/netl_xlp3xx.cfg]

View File

@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Target: XLP308 processor by NetLogic Microsystems
#
set XLP_NT 8
source [find target/netl_xlp3xx.cfg]

View File

@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Target: XLP316 processor by NetLogic Microsystems
#
set XLP_NT 16
source [find target/netl_xlp3xx.cfg]

View File

@ -0,0 +1,39 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Target: XLP 300-series processors by NetLogic Microsystems
#
# See http://www.broadcom.com/products/Processors/Enterprise/XLP300-Series
#
# Use xlp304.cfg, xlp308.cfg, xlp316.cfg for particular processor model.
#
transport select jtag
global XLP_NT
for {set i $XLP_NT} {$i > 0} {incr i -1} {
jtag newtap xlp cpu_$i -irlen 5 -disable
if {$i != 1} {
jtag configure xlp.cpu_$i -event tap-enable {}
}
}
jtag newtap xlp jrc -irlen 16 -expected-id 0x00011449
jtag configure xlp.cpu_1 -event tap-enable {
global XLP_NT
irscan xlp.jrc 0xe0
drscan xlp.jrc 1 1
for {set i $XLP_NT} {$i > 1} {incr i -1} {
jtag tapenable xlp.cpu_$i
}
}
proc chipreset {} {
irscan xlp.jrc 0xab
drscan xlp.jrc 1 1
drscan xlp.jrc 1 0
}
jtag configure xlp.jrc -event setup "jtag tapenable xlp.cpu_1"
target create xlp.cpu_1 mips_mips64 -endian big -chain-position xlp.cpu_1

View File

@ -9,7 +9,7 @@ source [find target/swj-dp.tcl]
if { [info exists CHIPNAME] } { if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME set _CHIPNAME $CHIPNAME
} else { } else {
set _CHIPNAME NPCX_M4 set _CHIPNAME npcx
} }
# SWD DAP ID of Nuvoton NPCX Cortex-M4. # SWD DAP ID of Nuvoton NPCX Cortex-M4.
@ -27,6 +27,12 @@ if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE 0x8000 set _WORKAREASIZE 0x8000
} }
if { [info exists FIUNAME]} {
set _FIUNAME $FIUNAME
} else {
set _FIUNAME npcx.fiu
}
# Debug Adapter Target Settings # Debug Adapter Target Settings
swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
@ -48,4 +54,4 @@ cortex_m reset_config sysresetreq
# flash configuration # flash configuration
set _FLASHNAME $_CHIPNAME.flash set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME flash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME $_FIUNAME

106
tcl/target/stm32wbax.cfg Normal file
View File

@ -0,0 +1,106 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# script for stm32wbax family
#
# stm32wba devices support both JTAG and SWD transports.
#
source [find target/swj-dp.tcl]
source [find mem_helper.tcl]
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME stm32wbax
}
# Work-area is a space in RAM used for flash programming
# By default use 64kB
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x10000
}
#jtag scan chain
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
if { [using_jtag] } {
set _CPUTAPID 0x6ba00477
} else {
# SWD IDCODE (single drop, arm)
set _CPUTAPID 0x6ba02477
}
}
swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
if {[using_jtag]} {
jtag newtap $_CHIPNAME bs -irlen 5
}
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap -ap-num 1
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
flash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME
flash bank $_CHIPNAME.otp stm32l4x 0x0FF90000 0 0 0 $_TARGETNAME
# Common knowledges tells JTAG speed should be <= F_CPU/6.
# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on
# the safe side.
#
# Note that there is a pretty wide band where things are
# more or less stable, see http://openocd.zylin.com/#/c/3366/
adapter speed 500
adapter srst delay 100
if {[using_jtag]} {
jtag_ntrst_delay 100
}
reset_config srst_nogate
if {![using_hla]} {
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
cortex_m reset_config sysresetreq
}
$_TARGETNAME configure -event reset-init {
# CPU comes out of reset with HSION | HSIRDY.
# Use HSI 16 MHz clock, compliant even with VOS == 2.
# 1 WS compliant with VOS == 2 and 16 MHz.
mmw 0x40022000 0x00000001 0x0000000E ;# FLASH_ACR: Latency = 1
mmw 0x56020C00 0x00000100 0x00000000 ;# RCC_CR |= HSION
mmw 0x56020C1C 0x00000000 0x00000002 ;# RCC_CFGR1: SW=HSI16
# Boost JTAG frequency
adapter speed 4000
}
$_TARGETNAME configure -event reset-start {
# Reset clock is HSI (16 MHz)
adapter speed 2000
}
$_TARGETNAME configure -event examine-end {
# Enable debug during low power modes (uses more power)
# DBGMCU_CR |= DBG_STANDBY | DBG_STOP
mmw 0xE0042004 0x00000006 0
# Stop watchdog counters during halt
# DBGMCU_APB1LFZR |= DBG_IWDG_STOP | DBG_WWDG_STOP
mmw 0xE0042008 0x00001800 0
}
tpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000
lappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu
proc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {
targets $_targetname
}
$_CHIPNAME.tpiu configure -event pre-enable "_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME"

View File

@ -10,12 +10,16 @@
# Has 2 ARMV8 Cores and 4 R5 Cores and an M3 # Has 2 ARMV8 Cores and 4 R5 Cores and an M3
# * J721S2: https://www.ti.com/lit/pdf/spruj28 # * J721S2: https://www.ti.com/lit/pdf/spruj28
# Has 2 ARMV8 Cores and 6 R5 Cores and an M4F # Has 2 ARMV8 Cores and 6 R5 Cores and an M4F
# * J784S4/AM69: http://www.ti.com/lit/zip/spruj52
# Has 8 ARMV8 Cores and 8 R5 Cores
# * AM642: https://www.ti.com/lit/pdf/spruim2 # * AM642: https://www.ti.com/lit/pdf/spruim2
# Has 2 ARMV8 Cores and 4 R5 Cores, M4F and an M3 # Has 2 ARMV8 Cores and 4 R5 Cores, M4F and an M3
# * AM625: https://www.ti.com/lit/pdf/spruiv7a # * AM625: https://www.ti.com/lit/pdf/spruiv7a
# Has 4 ARMV8 Cores and 1 R5 Core and an M4F # Has 4 ARMV8 Cores and 1 R5 Core and an M4F
# * AM62a7: https://www.ti.com/lit/pdf/spruj16a # * AM62a7: https://www.ti.com/lit/pdf/spruj16a
# Has 4 ARMV8 Cores and 2 R5 Cores # Has 4 ARMV8 Cores and 2 R5 Cores
# * AM62P: https://www.ti.com/lit/pdf/spruj83
# Has 4 ARMV8 Cores and 2 R5 Cores
# #
source [find target/swj-dp.tcl] source [find target/swj-dp.tcl]
@ -63,7 +67,6 @@ set _gp_mcu_ap_unlock_offsets {0xf0 0x60}
# Set configuration overrides for each SOC # Set configuration overrides for each SOC
switch $_soc { switch $_soc {
am654 { am654 {
set _CHIPNAME am654
set _K3_DAP_TAPID 0x0bb5a02f set _K3_DAP_TAPID 0x0bb5a02f
# AM654 has 2 clusters of 2 A53 cores each. # AM654 has 2 clusters of 2 A53 cores each.
@ -78,7 +81,6 @@ switch $_soc {
set _sysctrl_ap_unlock_offsets {0xf0 0x50} set _sysctrl_ap_unlock_offsets {0xf0 0x50}
} }
am642 { am642 {
set _CHIPNAME am642
set _K3_DAP_TAPID 0x0bb3802f set _K3_DAP_TAPID 0x0bb3802f
# AM642 has 1 clusters of 2 A53 cores each. # AM642 has 1 clusters of 2 A53 cores each.
@ -97,7 +99,6 @@ switch $_soc {
set _gp_mcu_cores 1 set _gp_mcu_cores 1
} }
am625 { am625 {
set _CHIPNAME am625
set _K3_DAP_TAPID 0x0bb7e02f set _K3_DAP_TAPID 0x0bb7e02f
# AM625 has 1 clusters of 4 A53 cores. # AM625 has 1 clusters of 4 A53 cores.
@ -131,17 +132,17 @@ switch $_soc {
set _dmem_emu_base_address_map_to 0x1d500000 set _dmem_emu_base_address_map_to 0x1d500000
set _dmem_emu_ap_list 1 set _dmem_emu_ap_list 1
} }
am62p -
am62a7 { am62a7 {
set _CHIPNAME am62a7
set _K3_DAP_TAPID 0x0bb8d02f set _K3_DAP_TAPID 0x0bb8d02f
# AM62a7 has 1 clusters of 4 A53 cores. # AM62a7/AM62P has 1 cluster of 4 A53 cores.
set _armv8_cpu_name a53 set _armv8_cpu_name a53
set _armv8_cores 4 set _armv8_cores 4
set ARMV8_DBGBASE {0x90010000 0x90110000 0x90210000 0x90310000} set ARMV8_DBGBASE {0x90010000 0x90110000 0x90210000 0x90310000}
set ARMV8_CTIBASE {0x90020000 0x90120000 0x90220000 0x90320000} set ARMV8_CTIBASE {0x90020000 0x90120000 0x90220000 0x90320000}
# AM62a7 has 2 cluster of 1 R5s core. # AM62a7/AM62P has 2 cluster of 1 R5 core.
set _r5_cores 2 set _r5_cores 2
set R5_NAMES {main0_r5.0 mcu0_r5.0} set R5_NAMES {main0_r5.0 mcu0_r5.0}
set R5_DBGBASE {0x9d410000 0x9d810000} set R5_DBGBASE {0x9d410000 0x9d810000}
@ -151,9 +152,14 @@ switch $_soc {
set CM3_CTIBASE {0x20001000} set CM3_CTIBASE {0x20001000}
# Sysctrl power-ap unlock offsets # Sysctrl power-ap unlock offsets
set _sysctrl_ap_unlock_offsets {0xf0 0x78} set _sysctrl_ap_unlock_offsets {0xf0 0x78}
# Overrides for am62p
if { "$_soc" == "am62p" } {
set _K3_DAP_TAPID 0x0bb9d02f
set R5_NAMES {wkup0_r5.0 mcu0_r5.0}
}
} }
j721e { j721e {
set _CHIPNAME j721e
set _K3_DAP_TAPID 0x0bb6402f set _K3_DAP_TAPID 0x0bb6402f
# J721E has 1 cluster of 2 A72 cores. # J721E has 1 cluster of 2 A72 cores.
set _armv8_cpu_name a72 set _armv8_cpu_name a72
@ -173,7 +179,6 @@ switch $_soc {
set _dmem_emu_ap_list 1 set _dmem_emu_ap_list 1
} }
j7200 { j7200 {
set _CHIPNAME j7200
set _K3_DAP_TAPID 0x0bb6d02f set _K3_DAP_TAPID 0x0bb6d02f
# J7200 has 1 cluster of 2 A72 cores. # J7200 has 1 cluster of 2 A72 cores.
@ -189,7 +194,6 @@ switch $_soc {
set CM3_CTIBASE {0x20001000} set CM3_CTIBASE {0x20001000}
} }
j721s2 { j721s2 {
set _CHIPNAME j721s2
set _K3_DAP_TAPID 0x0bb7502f set _K3_DAP_TAPID 0x0bb7502f
# J721s2 has 1 cluster of 2 A72 cores. # J721s2 has 1 cluster of 2 A72 cores.
@ -208,11 +212,44 @@ switch $_soc {
set _gp_mcu_cores 1 set _gp_mcu_cores 1
set _gp_mcu_ap_unlock_offsets {0xf0 0x7c} set _gp_mcu_ap_unlock_offsets {0xf0 0x7c}
} }
j784s4 {
set _K3_DAP_TAPID 0x0bb8002f
# j784s4 has 2 cluster of 4 A72 cores each.
set _armv8_cpu_name a72
set _armv8_cores 8
set ARMV8_DBGBASE {0x90410000 0x90510000 0x90610000 0x90710000
0x90810000 0x90910000 0x90a10000 0x90b10000}
set ARMV8_CTIBASE {0x90420000 0x90520000 0x90620000 0x90720000
0x90820000 0x90920000 0x90a20000 0x90b20000}
# J721s2 has 4 clusters of 2 R5 cores each.
set _r5_cores 8
set R5_DBGBASE {0x9d010000 0x9d012000
0x9d410000 0x9d412000
0x9d510000 0x9d512000
0x9d610000 0x9d612000}
set R5_CTIBASE {0x9d018000 0x9d019000
0x9d418000 0x9d419000
0x9d518000 0x9d519000
0x9d618000 0x9d619000}
set R5_NAMES {mcu_r5.0 mcu_r5.1
main0_r5.0 main0_r5.1
main1_r5.0 main1_r5.1
main2_r5.0 main2_r5.1}
# sysctrl CTI base
set CM3_CTIBASE {0x20001000}
# Sysctrl power-ap unlock offsets
set _sysctrl_ap_unlock_offsets {0xf0 0x78}
}
default { default {
echo "'$_soc' is invalid!" echo "'$_soc' is invalid!"
} }
} }
set _CHIPNAME $_soc
swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_K3_DAP_TAPID -ignore-version swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_K3_DAP_TAPID -ignore-version
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu