package com.microchip.mplab.ipelib.device; import com.microchip.crownking.Pair; import com.microchip.mplab.crownkingx.xMemoryPartition; import com.microchip.mplab.ipelib.common.SharedData; import com.microchip.mplab.mdbcore.OptSupport.NumberOptionValidator; import com.microchip.mplab.mdbcore.OptSupport.RuntimeProperties; import com.microchip.mplab.mdbcore.RealICETool.utils.RIUsefulFunctions; import java.util.ArrayList; import java.util.Properties; public class PreservePGMRangeValidator extends NumberOptionValidator { RuntimeProperties rtp = null; public String getHint() { String hint = ""; RuntimeProperties rtp = new RuntimeProperties(SharedData.getSingletonObject().getAssemblySession()); long Boundary = rtp.getProgramChunkSize(); return "Each range must be two hex numbers, representing the start and end addresses of the range, separated by a dash. Ranges must be separated by a comma(e.g. 0-ff, 200-2ff). Areas are reserved by reading them into MPLAB and then programming them back down when a program operation occurs. Thus the preserved areas must lie within a memory range that will be programmed. Ranges must be aligned on a 0x" + Long.toHexString(Boundary) + " address boundary."; } public boolean isValid(String arg0) { boolean RetVal = false; try { ArrayList> Addrs = new ArrayList<>(); this.rtp = new RuntimeProperties(SharedData.getSingletonObject().getAssemblySession()); Properties Props = this.rtp.getAssembly().GetToolProperties(); if (Props != null && Props.getProperty("programoptions.preserveprogramrange", "false").equals("false")) { RetVal = true; } else { xMemoryPartition XMP = this.rtp.getPic().getMainPartition(); if (XMP != null) { Pair P; if (XMP.hasSPIFlashMemory()) { P = XMP.getSPIFlashRange(); } else { P = XMP.getInstRange(); } if ((Long)P.second != 0L) { Addrs.add(new Pair(P.first, (Long)P.second - 1L)); } } XMP = (xMemoryPartition)this.rtp.getPic().getIDOntoPartition().get("first"); if (XMP != null && (Long)XMP.getInstRange().second != 0L) { Addrs.add(new Pair(XMP.getInstRange().first, (Long)XMP.getInstRange().second - 1L)); } XMP = (xMemoryPartition)this.rtp.getPic().getIDOntoPartition().get("second"); if (XMP != null && (Long)XMP.getInstRange().second != 0L) { Addrs.add(new Pair(XMP.getInstRange().first, (Long)XMP.getInstRange().second - 1L)); } XMP = (xMemoryPartition)this.rtp.getPic().getIDOntoPartition().get("only"); if (XMP != null && (Long)XMP.getInstRange().second != 0L) { Addrs.add(new Pair(XMP.getInstRange().first, (Long)XMP.getInstRange().second - 1L)); } RetVal = this.ValidateReserveRange(arg0, Props.getProperty("memories.programmemory.ranges", ""), Addrs, this.rtp.getProgramChunkSize()); } } catch (Exception var7) { RetVal = false; } return RetVal; } protected boolean ValidateReserveRange(String ReserveStr, String PgmRangeStr, ArrayList> Addresses, long Boundary) { boolean RetVal = true; try { RIUsefulFunctions UF = new RIUsefulFunctions(); ArrayList> PgmAddrs = null; ArrayList> ReserveAddrs = null; boolean InRange = false; if (ReserveStr.isEmpty()) { throw new Exception("Address field is empty"); } ReserveAddrs = UF.GetAddressFromString(ReserveStr); if (ReserveAddrs.isEmpty()) { throw new Exception("Invalid address"); } if (!PgmRangeStr.isEmpty()) { PgmAddrs = UF.GetAddressFromString(PgmRangeStr); } ArrayList> TempReserves = new ArrayList<>(); ArrayList> RemoveList = new ArrayList<>(); for (Pair P : ReserveAddrs) { TempReserves.add(P); } for (Pair P : Addresses) { RemoveList.clear(); for (Pair RP : TempReserves) { if ((Long)RP.first >= (Long)P.first && (Long)RP.second <= (Long)P.second) { if ((Long)RP.second % Boundary != Boundary - 1L && (Long)RP.second != (Long)P.second) { throw new Exception("Invalid boundry address"); } RemoveList.add(RP); } if ((Long)RP.first % Boundary != 0L) { throw new Exception("Preserve start address is not boundry aligned"); } } for (Pair Remove : RemoveList) { TempReserves.remove(Remove); } } if (!TempReserves.isEmpty()) { throw new Exception("Preserve range is not valid for this address"); } this.rtp = new RuntimeProperties(SharedData.getSingletonObject().getAssemblySession()); String Auto = this.rtp.getAssembly().GetToolProperties().getProperty("AutoSelectMemRanges"); if (PgmAddrs != null && !PgmAddrs.isEmpty()) { for (Pair RP : ReserveAddrs) { InRange = false; for (Pair P : PgmAddrs) { if ((Long)RP.first >= (Long)P.first && (Long)RP.second <= (Long)P.second) { InRange = true; break; } } if (!InRange) { throw new Exception(); } } } } catch (Exception var18) { RetVal = false; this.why = var18.getMessage(); if (this.why == null) { this.why = "The Preserve Program memory range falls outside of what will be programmed " + PgmRangeStr + "The given Preserve address range should either be within or equal to the Program memory range."; } } return RetVal; } }