@@ -789,12 +789,12 @@ static bool ot_flash_write_backend(OtFlashState *s, const void *buffer,
789789 /* NOLINTEND(clang-analyzer-optin.core.EnumCastOutOfRange) */
790790}
791791
792- static bool ot_flash_is_disabled (OtFlashState * s )
792+ static bool ot_flash_is_disabled (const OtFlashState * s )
793793{
794794 return s -> regs [R_DIS ] != OT_MULTIBITBOOL4_FALSE ;
795795}
796796
797- static bool ot_flash_regs_is_wr_enabled (OtFlashState * s , unsigned regwen )
797+ static bool ot_flash_regs_is_wr_enabled (const OtFlashState * s , unsigned regwen )
798798{
799799 return (bool )(s -> regs [regwen ] & REGWEN_EN_MASK );
800800}
@@ -873,7 +873,7 @@ static void ot_flash_initialize(OtFlashState *s)
873873 qemu_clock_get_ns (OT_VIRTUAL_CLOCK ) + OP_INIT_DURATION_NS );
874874}
875875
876- static bool ot_flash_fifo_in_reset (OtFlashState * s )
876+ static bool ot_flash_fifo_in_reset (const OtFlashState * s )
877877{
878878 return (bool )s -> regs [R_FIFO_RST ];
879879}
@@ -923,6 +923,23 @@ static void ot_flash_op_complete(OtFlashState *s)
923923 ot_flash_update_irqs (s );
924924}
925925
926+ static bool ot_flash_can_erase_bank (const OtFlashState * s , unsigned bank )
927+ {
928+ switch (bank ) {
929+ case 0u :
930+ return (bool )FIELD_EX32 (s -> regs [R_MP_BANK_CFG_SHADOWED ],
931+ MP_BANK_CFG_SHADOWED , ERASE_EN_0 );
932+ case 1u :
933+ return (bool )FIELD_EX32 (s -> regs [R_MP_BANK_CFG_SHADOWED ],
934+ MP_BANK_CFG_SHADOWED , ERASE_EN_1 );
935+ default :
936+ qemu_log_mask (LOG_GUEST_ERROR ,
937+ "%s: unknown bank %u for bank erase operation" , __func__ ,
938+ bank );
939+ return false;
940+ }
941+ }
942+
926943static unsigned ot_flash_next_info_address (OtFlashState * s )
927944{
928945 OtFlashStorage * storage = & s -> flash ;
@@ -1122,6 +1139,127 @@ static void ot_flash_op_prog(OtFlashState *s)
11221139 }
11231140}
11241141
1142+ static void ot_flash_op_erase_page (OtFlashState * s , unsigned address )
1143+ {
1144+ OtFlashStorage * storage = & s -> flash ;
1145+ uint32_t * dest = s -> op .info_part ? storage -> info : storage -> data ;
1146+ unsigned page_size = BYTES_PER_PAGE ;
1147+ unsigned page_address = address - (address % page_size );
1148+ page_address /= sizeof (uint32_t ); /* convert to word address */
1149+
1150+ g_assert ((page_address + page_size ) <
1151+ ((s -> op .info_part ? storage -> info_size : storage -> data_size ) *
1152+ storage -> bank_count ));
1153+ memset (& dest [page_address ], 0xFFu , page_size );
1154+ trace_ot_flash_erase (s -> op .info_part , page_address , page_size );
1155+ if (ot_flash_is_backend_writable (s )) {
1156+ uintptr_t dest_offset = (uintptr_t )dest - (uintptr_t )storage -> data ;
1157+ if (ot_flash_write_backend (s , & dest [page_address ],
1158+ (unsigned )(dest_offset + page_address ),
1159+ page_size )) {
1160+ qemu_log_mask (LOG_GUEST_ERROR , "%s: cannot update flash backend\n" ,
1161+ __func__ );
1162+ ot_flash_set_error (s , R_ERR_CODE_PROG_ERR_MASK ,
1163+ address * sizeof (uint32_t ));
1164+ ot_flash_op_complete (s );
1165+ return ;
1166+ }
1167+ }
1168+
1169+ ot_flash_op_complete (s );
1170+ }
1171+
1172+ static void ot_flash_op_erase_bank (OtFlashState * s , unsigned address )
1173+ {
1174+ OtFlashStorage * storage = & s -> flash ;
1175+ unsigned bank_size =
1176+ s -> op .info_part ? storage -> info_size : storage -> data_size ;
1177+ unsigned bank = address / bank_size ;
1178+
1179+ if (!ot_flash_can_erase_bank (s , bank )) {
1180+ qemu_log_mask (
1181+ LOG_GUEST_ERROR ,
1182+ "%s: cannot erase bank %u when bank-wide erase not enabled\n" ,
1183+ __func__ , bank );
1184+ ot_flash_set_error (s , R_ERR_CODE_MP_ERR_MASK , address );
1185+ ot_flash_op_complete (s );
1186+ return ;
1187+ }
1188+
1189+ /*
1190+ * For bank erase only, if the data partition is selected, just the
1191+ * data partition is erased. If the info partition is selected, BOTH
1192+ * the data and info partitions are erased.
1193+ */
1194+ unsigned bank_address = address - (address % bank_size );
1195+ bank_address /= sizeof (uint32_t ); /* convert to word address */
1196+ unsigned data_address , info_address = 0u ;
1197+ if (!s -> op .info_part ) {
1198+ data_address = bank_address ;
1199+ g_assert ((data_address + bank_size ) <=
1200+ (storage -> data_size * storage -> bank_count ));
1201+ memset (& storage -> data [data_address ], 0xFFu , bank_size );
1202+ trace_ot_flash_erase (s -> op .info_part , data_address , bank_size );
1203+ } else {
1204+ info_address = bank_address ;
1205+ g_assert ((info_address + bank_size ) <=
1206+ (storage -> info_size * storage -> bank_count ));
1207+ memset (& storage -> info [info_address ], 0xFFu , bank_size );
1208+ trace_ot_flash_erase (true, info_address , bank_size );
1209+
1210+ bank_size = storage -> data_size ;
1211+ data_address = bank_size * bank / sizeof (uint32_t );
1212+ g_assert ((data_address + bank_size ) <=
1213+ (storage -> data_size * storage -> bank_count ));
1214+ memset (& storage -> data [data_address ], 0xFFu , bank_size );
1215+ trace_ot_flash_erase (false, data_address , bank_size );
1216+ }
1217+
1218+ if (ot_flash_is_backend_writable (s )) {
1219+ int data_write_err =
1220+ ot_flash_write_backend (s , & storage -> data [data_address ],
1221+ (unsigned )(data_address ),
1222+ storage -> data_size );
1223+ int info_write_err = 0u ;
1224+ if (s -> op .info_part ) {
1225+ uintptr_t offset =
1226+ (uintptr_t )storage -> info - (uintptr_t )storage -> data ;
1227+ info_write_err =
1228+ ot_flash_write_backend (s , & storage -> info [info_address ],
1229+ (unsigned )(offset + info_address ),
1230+ storage -> info_size );
1231+ }
1232+
1233+ if (data_write_err || info_write_err ) {
1234+ qemu_log_mask (LOG_GUEST_ERROR , "%s: cannot update flash backend\n" ,
1235+ __func__ );
1236+ ot_flash_set_error (s , R_ERR_CODE_PROG_ERR_MASK ,
1237+ address * sizeof (uint32_t ));
1238+ ot_flash_op_complete (s );
1239+ return ;
1240+ }
1241+ }
1242+
1243+ ot_flash_op_complete (s );
1244+ }
1245+
1246+ static void ot_flash_op_erase (OtFlashState * s )
1247+ {
1248+ unsigned address = s -> op .info_part ? ot_flash_next_info_address (s ) :
1249+ ot_flash_next_data_address (s );
1250+ if (s -> op .failed ) {
1251+ ot_flash_op_complete (s );
1252+ return ;
1253+ }
1254+
1255+ /* Try to erase all bits in the page/bank back to 1. */
1256+ if (s -> op .erase_sel == ERASE_SEL_PAGE ) {
1257+ ot_flash_op_erase_page (s , address );
1258+ } else { /* ERASE_SEL_BANK */
1259+ ot_flash_op_erase_bank (s , address );
1260+ }
1261+ }
1262+
11251263static void ot_flash_op_execute (OtFlashState * s )
11261264{
11271265 switch (s -> op .kind ) {
@@ -1133,6 +1271,10 @@ static void ot_flash_op_execute(OtFlashState *s)
11331271 trace_ot_flash_op_execute (OP_NAME (s -> op .kind ));
11341272 ot_flash_op_prog (s );
11351273 break ;
1274+ case OP_ERASE :
1275+ trace_ot_flash_op_execute (OP_NAME (s -> op .kind ));
1276+ ot_flash_op_erase (s );
1277+ break ;
11361278 default :
11371279 xtrace_ot_flash_error ("unsupported" );
11381280 break ;
0 commit comments