flash/nor: add support for Nuvoton NPCX4/K3 series flash

Added NPCX flash driver to support the Nuvoton NPCX4/K3 series
microcontrollers. Add config file for these series.

Change-Id: I0b6e128fa51146b561f422e23a98260594b1f138
Signed-off-by: Luca Hung <YCHUNG0@nuvoton.com>
Signed-off-by: Mulin CHao <mlchao@nuvoton.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7794
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
Luca Hung 2023-07-31 15:08:18 +08:00 committed by Antonio Borneo
parent 2839a873a3
commit 62f76b2169
7 changed files with 247 additions and 141 deletions

View File

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

View File

@ -10,9 +10,29 @@
#include <string.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
*----------------------------------------------------------------------------*/
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)
{
/* 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)
{
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 */
if (level)
NPCX_SET_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_SW_CS1);
NPCX_SET_BIT(NPCX_UMA_ECTS, sw_cs);
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)
@ -38,15 +73,15 @@ static void flash_set_address(uint32_t dest_addr)
uint8_t *addr = (uint8_t *)&dest_addr;
/* Set target flash address */
NPCX_UMA_AB2 = addr[2];
NPCX_UMA_AB1 = addr[1];
NPCX_UMA_AB0 = addr[0];
NPCX_UMA_DB0 = addr[2];
NPCX_UMA_DB1 = addr[1];
NPCX_UMA_DB2 = addr[0];
}
void delay(uint32_t i)
static void delay(uint32_t i)
{
while (i--)
;
__asm__ volatile ("nop");
}
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 */
flash_set_address(dest_addr);
/* 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++) {
flash_execute_cmd(*data, NPCX_MASK_CMD_WR_ONLY);
data++;
@ -114,6 +149,15 @@ static void flash_burst_write(uint32_t dest_addr, uint16_t bytes,
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 */
static int flash_program_write(uint32_t addr, uint32_t size,
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);
}
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;
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 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) {
status = flash_program_write(dest_addr, write_len, data);
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;
}
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 */
for (; size > 0; size -= 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 */
flash_set_address(offset);
/* 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 */
status = flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT);
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;
}
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 */
int status = flash_write_enable();
status = flash_write_enable();
if (status != NPCX_FLASH_STATUS_OK)
return status;
@ -203,37 +304,10 @@ int flash_physical_erase_all(void)
return NPCX_FLASH_STATUS_OK;
}
int flash_physical_clear_stsreg(void)
static int flash_get_id(uint32_t *id)
{
/* Enable write */
int status = flash_write_enable();
if (status != NPCX_FLASH_STATUS_OK)
return status;
flash_init();
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);
*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
*----------------------------------------------------------------------------*/
uint32_t flashloader_init(struct npcx_flash_params *params)
static uint32_t flashloader_init(struct npcx_flash_params *params)
{
/* Initialize params buffers */
memset(params, 0, sizeof(struct npcx_flash_params));
@ -254,30 +328,13 @@ uint32_t flashloader_init(struct npcx_flash_params *params)
/*----------------------------------------------------------------------------
* Functions
*----------------------------------------------------------------------------*/
/* flashloader parameter structure */
__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)
static int main(void)
{
uint32_t id;
uint32_t id, status;
/* set buffer */
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) {
/* wait command*/
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_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_MSR_IE_CFG NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x043)
/* FIU register fields */
#define NPCX_RESP_CFG_IAD_EN 0
@ -93,6 +94,7 @@
#define NPCX_UMA_ECTS_SW_CS1 1
#define NPCX_UMA_ECTS_SEC_CS 2
#define NPCX_UMA_ECTS_UMA_LOCK 3
#define NPCX_FIU_MSR_IE_CFG_UMA_BLOCK 3
/* Flash UMA commands for npcx internal SPI flash */
#define NPCX_CMD_READ_ID 0x9F
@ -130,7 +132,6 @@
#define NPCX_SPI_FLASH_SR1_BUSY (1 << 0)
#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_RD_1BYTE (0xC0 | 0x10 | 0x01)
#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_1BYTE (0xC0 | 0x20 | 0x10 | 0x01)
#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 */
struct __attribute__((__packed__)) npcx_flash_params {
uint32_t fiu_ver; /* Flash controller unit version */
uint32_t addr; /* Address in flash */
uint32_t len; /* Number of bytes */
uint32_t cmd; /* Command */
@ -176,4 +179,10 @@ enum npcx_flash_status {
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 */

View File

@ -18,7 +18,7 @@
/* NPCX flash loader information */
#define NPCX_FLASH_LOADER_WORKING_ADDR 0x200C0000
#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_SIZE NPCX_FLASH_ERASE_SIZE
#define NPCX_FLASH_LOADER_PROGRAM_ADDR (NPCX_FLASH_LOADER_BUFFER_ADDR + NPCX_FLASH_LOADER_BUFFER_SIZE)

View File

@ -7193,10 +7193,16 @@ Show information about flash driver.
All versions of the NPCX microcontroller families from Nuvoton include internal
flash. The NPCX flash driver supports the NPCX family of devices. The driver
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
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
@end example
@end deffn

View File

@ -4,6 +4,7 @@
* Copyright (C) 2020 by Nuvoton Technology Corporation
* Mulin Chao <mlchao@nuvoton.com>
* Wealian Liao <WHLIAO@nuvoton.com>
* Luca Hung <YCHUNG0@nuvoton.com>
*/
#ifdef HAVE_CONFIG_H
@ -22,7 +23,6 @@ static const uint8_t npcx_algo[] = {
};
#define NPCX_FLASH_TIMEOUT_MS 8000
#define NPCX_FLASH_BASE_ADDR 0x64000000
/* flash list */
enum npcx_flash_device_index {
@ -33,7 +33,6 @@ enum npcx_flash_device_index {
};
struct npcx_flash_bank {
const char *family_name;
uint32_t sector_length;
bool probed;
enum npcx_flash_device_index flash;
@ -44,6 +43,7 @@ struct npcx_flash_bank {
uint32_t algo_working_size;
uint32_t buffer_addr;
uint32_t params_addr;
uint32_t fiu_ver;
};
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 */
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",
NPCX_FLASH_LOADER_WORKING_ADDR);
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,
npcx_bank->algo_size, npcx_bank->algo_code);
if (retval != ERROR_OK) {
LOG_ERROR("%s: Failed to load flash helper algorithm",
npcx_bank->family_name);
LOG_TARGET_ERROR(target, "Failed to load flash helper algorithm");
target_free_working_area(target, npcx_bank->working_area);
npcx_bank->working_area = NULL;
return retval;
@ -118,8 +117,7 @@ static int npcx_init(struct flash_bank *bank)
NPCX_FLASH_LOADER_PROGRAM_ADDR, 0,
&npcx_bank->armv7m_info);
if (retval != ERROR_OK) {
LOG_ERROR("%s: Failed to start flash helper algorithm",
npcx_bank->family_name);
LOG_TARGET_ERROR(target, "Failed to start flash helper algorithm");
target_free_working_area(target, npcx_bank->working_area);
npcx_bank->working_area = NULL;
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)
{
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;
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);
if (status != NPCX_FLASH_LOADER_WAIT) {
LOG_ERROR("%s: Flash operation failed, status=0x%" PRIx32,
npcx_bank->family_name,
status);
LOG_TARGET_ERROR(target, "Flash operation failed, status (%0x" PRIX32 ") ", status);
return ERROR_FAIL;
}
@ -197,6 +192,7 @@ static enum npcx_flash_device_index npcx_get_flash_id(struct flash_bank *bank, u
return retval;
/* 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.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->params_addr = NPCX_FLASH_LOADER_PARAMS_ADDR;
int retval = npcx_get_flash_id(bank, &flash_id);
if (retval != ERROR_OK)
return retval;
@ -264,7 +261,6 @@ static int npcx_probe(struct flash_bank *bank)
return ERROR_FAIL;
}
bank->base = NPCX_FLASH_BASE_ADDR;
bank->num_sectors = num_sectors;
bank->size = num_sectors * sector_length;
bank->write_start_alignment = 0;
@ -300,7 +296,7 @@ FLASH_BANK_COMMAND_HANDLER(npcx_flash_bank_command)
{
struct npcx_flash_bank *npcx_bank;
if (CMD_ARGC < 6)
if (CMD_ARGC < 6 || CMD_ARGC > 7)
return ERROR_COMMAND_SYNTAX_ERROR;
npcx_bank = calloc(1, sizeof(struct npcx_flash_bank));
@ -309,8 +305,27 @@ FLASH_BANK_COMMAND_HANDLER(npcx_flash_bank_command)
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);
return ERROR_TARGET_INVALID;
}
}
/* Initialize private flash information */
npcx_bank->family_name = "npcx";
npcx_bank->sector_length = NPCX_FLASH_ERASE_SIZE;
/* Finish initialization of bank */
@ -341,6 +356,7 @@ static int npcx_chip_erase(struct flash_bank *bank)
return retval;
/* 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.sync, NPCX_FLASH_LOADER_WAIT);
@ -397,6 +413,7 @@ static int npcx_erase(struct flash_bank *bank, unsigned int first,
return retval;
/* 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.len, length);
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 */
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.len, size);
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;
command_print_sameline(cmd, "%s flash: %s\n",
npcx_bank->family_name,
target_name(bank->target),
flash_info[npcx_bank->flash].name);
return ERROR_OK;

View File

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