public static void SaveReg(HardwareRegisterSet registers, string pOutFolder, CortexCore core) { registers.UserFriendlyName = "ARM Cortex " + (core.ToString().Replace("Plus", "+")); string outputFile = $@"{pOutFolder}\core_{core}.xml"; Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); XmlTools.SaveObject(registers, outputFile); }
static public void SaveReg(HardwareRegisterSet registers, string pOutFolder, CortexCore core) { registers.UserFriendlyName = "ARM Cortex " + (core.ToString().Replace("Plus", "+")); string outputFile = $@"{pOutFolder}\core_{core}.xml"; Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); XmlTools.SaveObject(registers, outputFile); }
public static List <HardwareRegisterSet> ProcessRegisterSetBaseAdress(string pFileName, List <HardwareRegisterSet> pLstHardReg) { Dictionary <string, Int32> aDicBaseAdr = new Dictionary <string, Int32>(); List <AdrTypReg> aLstTypBase = new List <AdrTypReg>(); List <HardwareRegisterSet> oPerReg = new List <HardwareRegisterSet>(); foreach (var ln in File.ReadAllLines(pFileName)) { Match m = Regex.Match(ln.Replace("(uint32_t)", ""), @"#define[ \t]+([\w]+)_BASE[ \t]+[\(]?([\w ]+)[\)]?.*"); if (m.Success) { int aAdrBase; var str = m.Groups[2].Value.Replace("UL", "").Replace(" ", ""); if (aDicBaseAdr.ContainsKey(str)) { //aAdrBase = aDicBaseAdr[str]; continue; } else { aAdrBase = Convert.ToInt32(str, 16); } aDicBaseAdr.Add(m.Groups[1].Value + "_BASE", aAdrBase); } m = Regex.Match(ln, @"#define[ \t]+([\w]+)[ \t]+[\(]*([\w]+)_TypeDef[ \t\*\)]+([\w]+).*"); if (m.Success) { aLstTypBase.Add(new AdrTypReg() { mStrTypAdr = m.Groups[2].Value, mStrNameBaseAdr = m.Groups[3].Value }); } } foreach (var aPointBase in aLstTypBase) { foreach (var aPerepReg in pLstHardReg) { if (aPointBase.mStrTypAdr == aPerepReg.UserFriendlyName) { HardwareRegisterSet aPerepMcuReg = DeepCopy(aPerepReg); var aBaseAdrUnit = aDicBaseAdr[aPointBase.mStrNameBaseAdr]; int aCntAdr = 0; foreach (var aHardReg in aPerepMcuReg.Registers) { aBaseAdrUnit += aCntAdr; aHardReg.Address = FormatToHex((ulong)aBaseAdrUnit); aCntAdr = aHardReg.SizeInBits / 8; } aPerepMcuReg.UserFriendlyName = aPointBase.mStrNameBaseAdr.Replace("_BASE", ""); oPerReg.Add(aPerepMcuReg); break; } } } return(oPerReg); }
public static MCUDefinitionWithPredicate ParseSVDFile(string file, string deviceName) { var doc = new XmlDocument(); doc.Load(file); List <HardwareRegisterSet> sets = new List <HardwareRegisterSet>(); Dictionary <string, XmlElement> periphNodes = new Dictionary <string, XmlElement>(); foreach (XmlElement periph in doc.DocumentElement.SelectNodes("peripherals/peripheral")) { string name = periph.SelectSingleNode("name").InnerText; uint baseAddr = ParseScaledNonNegativeInteger(periph.SelectSingleNode("baseAddress").InnerText); uint? defaultRegisterSize = null; var defaultRegisterSizeProp = periph.SelectSingleNode("size"); if (defaultRegisterSizeProp != null) { defaultRegisterSize = ParseScaledNonNegativeInteger(defaultRegisterSizeProp.InnerText); } periphNodes[name] = periph; List <HardwareRegister> registers = new List <HardwareRegister>(); var basePeriph = periph.GetAttribute("derivedFrom"); List <XmlNode> regNodes = periph.SelectNodes("registers/*").Cast <XmlNode>().ToList(); if (!string.IsNullOrEmpty(basePeriph)) { regNodes.InsertRange(0, periphNodes[basePeriph].SelectNodes("registers/*").Cast <XmlNode>()); } foreach (XmlElement reg in regNodes) { if (reg.Name == "register") { ProcessRegister(reg, registers, null, baseAddr, defaultRegisterSize); } else if (reg.Name == "cluster") { ProcessCluster(reg, registers, null, baseAddr, defaultRegisterSize); } } HardwareRegisterSet set = new HardwareRegisterSet { UserFriendlyName = name, Registers = registers.ToArray() }; sets.Add(set); } return(new MCUDefinitionWithPredicate { MCUName = deviceName, RegisterSets = sets.ToArray() }); }
static public void SaveReg(HardwareRegisterSet registers, string pOutFolder, CortexCore core, bool extendNVICRegisters) { if (extendNVICRegisters) { var lst = registers.Registers.ToList(); Regex rgName = new Regex("NVIC_(.*)3"); for (int i = 0; i < lst.Count; i++) { var m = rgName.Match(lst[i].Name); if (m.Success) { if (lst[i - 1].Name != lst[i].Name.Replace("3", "2")) { continue; } if (lst[i + 1].Name == lst[i].Name.Replace("3", "4")) { continue; } else { var originalReg = lst[i]; ulong address = TryParseMaybeHex(originalReg.Address).Value; ulong increment = TryParseMaybeHex(lst[i].Address).Value - TryParseMaybeHex(lst[i - 1].Address).Value; for (int j = 4; j < 8; j++) { var reg = XmlTools.LoadObjectFromString <HardwareRegister>(XmlTools.SaveObjectToString(originalReg)); reg.Name = $"NVIC_{m.Groups[1].Value}{j}"; address += increment; reg.Address = $"0x{address:x8}"; lst.Insert(++i, reg); } } } } registers.Registers = lst.ToArray(); } registers.UserFriendlyName = "ARM Cortex " + (core.ToString().Replace("Plus", "+")); string outputFile = $@"{pOutFolder}\core_{core}.xml"; Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); XmlTools.SaveObject(registers, outputFile); }
public static List <HardwareRegisterSet> ProcessRegisterSetBaseAdress(string pFileName, List <HardwareRegisterSet> pLstHardReg) { Dictionary <string, Int32> aDicBaseAdr = new Dictionary <string, Int32>(); List <AdrTypReg> aLstTypBase = new List <AdrTypReg>(); List <HardwareRegisterSet> oPerReg = new List <HardwareRegisterSet>(); foreach (var ln in File.ReadAllLines(pFileName)) { //#define SPI ((Spi *)0x40008000U) /**< \brief (SPI ) Base Address */ Match m = Regex.Match(ln, @"#define[ \t]+([\w]+)[ \t]+[\(]+([\w]+)[* \t\)]+0x([\w]+)[\)]?.*"); if (m.Success) { var str = m.Groups[3].Value.Replace("U", ""); str = str.Replace("L", ""); var aAdrBase = Convert.ToInt32(str, 16); aDicBaseAdr.Add(m.Groups[1].Value, aAdrBase); aLstTypBase.Add(new AdrTypReg() { mStrTypAdr = m.Groups[2].Value, mStrNameBaseAdr = m.Groups[1].Value }); } } foreach (var aPointBase in aLstTypBase) { foreach (var aPerepReg in pLstHardReg) { if (aPointBase.mStrTypAdr == aPerepReg.UserFriendlyName) { HardwareRegisterSet aPerepMcuReg = DeepCopy(aPerepReg); var aBaseAdrUnit = aDicBaseAdr[aPointBase.mStrNameBaseAdr]; int aCntAdr = 0; foreach (var aHardReg in aPerepMcuReg.Registers) { aBaseAdrUnit += aCntAdr; aHardReg.Address = FormatToHex((ulong)aBaseAdrUnit); aCntAdr = aHardReg.SizeInBits / 8; } aPerepMcuReg.UserFriendlyName = aPointBase.mStrNameBaseAdr.Replace("_BASE", ""); oPerReg.Add(aPerepMcuReg); break; } } } return(oPerReg); }
private static HardwareRegisterSet DeepCopy(HardwareRegisterSet set) { HardwareRegisterSet set_new = new HardwareRegisterSet { UserFriendlyName = set.UserFriendlyName, ExpressionPrefix = set.ExpressionPrefix, }; if (set.Registers != null) { set_new.Registers = new HardwareRegister[set.Registers.Length]; for (int i = 0; i < set.Registers.Length; i++) { set_new.Registers[i] = DeepCopy(set.Registers[i]); } } return(set_new); }
private void OnStart() { _processedBits = 0; _registerNameToAddress = new Dictionary <string, string>(); _registerSetToAddress = new Dictionary <string, string>(); _subRegistersKnownValues = new Dictionary <string, IList <KeyValuePair <string, ulong> > >(); _registers = new List <HardwareRegister>(); _registerSets = new List <HardwareRegisterSet>(); _subRegisters = new List <HardwareSubRegister>(); _registersWithWrongBitsSum = new List <string>(); _duplicateRegisterDefinition = false; _lastMatch = Match.Empty; _matchedRegex = null; _registerSet = null; _register = null; _subRegister = null; _registerBits = new Dictionary <string, HardwareSubRegister>(); _expectedMatches = new List <Regex> { REGISTER_SET_ADDRESS }; }
public static Dictionary <string, HardwareRegisterSet[]> GenerateFamilyPeripheralRegistersEFM32(string familyDirectory, string fam) { // Create the hardware register sets for each subfamily Dictionary <string, HardwareRegisterSet[]> peripherals = new Dictionary <string, HardwareRegisterSet[]>(); // Create a hardware register set for each base address with the correctly calculated addresses List <HardwareRegisterSet> sets = new List <HardwareRegisterSet>(); HardwareRegisterSet set = new HardwareRegisterSet(); List <HardwareRegister> lstRegCustomType = new List <HardwareRegister>(); List <HardwareRegisterSet> setsCustom = new List <HardwareRegisterSet>(); Dictionary <string, int> aDicSizeTypeDefStuct = new Dictionary <string, int>(); int aSizeStruct = 0; foreach (var fn in Directory.GetFiles(familyDirectory, fam + "_*.h")) { var aHRegs = ProcessRegisterSetNamesList(fn, ref lstRegCustomType); if (aHRegs != null) { sets.AddRange(aHRegs); } } foreach (var fn in Directory.GetFiles(familyDirectory, fam + "*.h")) { string sr = "^" + fam + "[0-9]+.*"; if (!Regex.IsMatch(Path.GetFileName(fn), sr, RegexOptions.IgnoreCase)) { continue; } setsCustom = ProcessRegisterSetNamesList(fn, ref lstRegCustomType); List <HardwareRegisterSet> setsCustomMcu = new List <HardwareRegisterSet>(); foreach (var aHRegMcu in sets) { bool aflRegRedefined = false; foreach (var aHrCustom in setsCustom) { if (aHrCustom.UserFriendlyName == aHRegMcu.UserFriendlyName) { aflRegRedefined = true; setsCustomMcu.Add(aHrCustom); break; } } if (!aflRegRedefined) { setsCustomMcu.Add(aHRegMcu); } } //Calculate size Struct foreach (var PerStruct in setsCustomMcu) { aSizeStruct = 0; foreach (var reg in PerStruct.Registers) { if (reg.SizeInBits == 0) { aSizeStruct = 0; break; } else { aSizeStruct += reg.SizeInBits; } } aDicSizeTypeDefStuct[PerStruct.UserFriendlyName] = aSizeStruct; } //Calculate size array custom type foreach (var CustTypReg in lstRegCustomType) { int strIdx1 = CustTypReg.Name.IndexOf("-"); int strIdx2 = CustTypReg.Name.IndexOf(":"); if (strIdx1 < 0 || strIdx2 < 0) { continue; } string str1 = CustTypReg.Name.Substring(strIdx1 + 1, CustTypReg.Name.Length - strIdx1 - 1); string asArray = CustTypReg.Name.Substring(strIdx2 + 1, strIdx1 - strIdx2 - 1); int asize = aDicSizeTypeDefStuct[str1] * Convert.ToInt32(asArray); CustTypReg.SizeInBits = asize; if (asize <= 32) { CustTypReg.Name = CustTypReg.Name.Substring(0, strIdx2); } } //Rename big strucures foreach (var v in setsCustomMcu) { List <HardwareRegister> lr = new List <HardwareRegister>(); foreach (var r in v.Registers) { int strIdx1 = r.Name.IndexOf("-"); int strIdx2 = r.Name.IndexOf(":"); if (r.SizeInBits <= 32 || r.Name.Contains("RESERVED")) { lr.Add(DeepCopy(r)); continue; } string typ = r.Name.Substring(strIdx1 + 1, r.Name.Length - strIdx1 - 1); foreach (var st in setsCustomMcu) { if (st.UserFriendlyName != typ) { continue; } foreach (var stsub in st.Registers) { HardwareRegister hr = DeepCopy(r); hr.Name = hr.Name.Substring(0, strIdx2) + "." + stsub.Name; hr.SizeInBits = stsub.SizeInBits; lr.Add(hr); } } } v.Registers = lr.ToArray(); } ///Set Base adress var aHrdRegFile = ProcessRegisterSetBaseAdress(fn, setsCustomMcu); peripherals.Add(Path.GetFileNameWithoutExtension(fn).ToUpper(), aHrdRegFile.ToArray()); } return(peripherals); }
public static Dictionary <string, HardwareRegisterSet[]> GenerateFamilyPeripheralRegistersAtmel(string familyDirectory, string fam) { // Create the hardware register sets for each subfamily Dictionary <string, HardwareRegisterSet[]> peripherals = new Dictionary <string, HardwareRegisterSet[]>(); // Create a hardware register set for each base address with the correctly calculated addresses List <HardwareRegisterSet> sets = new List <HardwareRegisterSet>(); HardwareRegisterSet set = new HardwareRegisterSet(); List <HardwareRegister> lstRegCustomType = new List <HardwareRegister>(); List <HardwareRegisterSet> setsCustom = new List <HardwareRegisterSet>(); aDicSizeTypeDefStuct.Clear(); int aSizeStruct = 0; Console.WriteLine("{0}Process PeripheralRegisters{1} ", ++aCountProgress, fam); // var aHRegs = UpdateSetsReg(familyDirectory, ref lstRegCustomType); // if (aHRegs != null) sets.AddRange(UpdateSetsReg(familyDirectory, ref lstRegCustomType)); /* if (fam.Contains("SAMl21")) * { * var aAddDir = familyDirectory.Replace("\\Include", "\\Include_b"); * sets.AddRange(UpdateSetsReg(familyDirectory, ref lstRegCustomType)); * }*/ List <HardwareRegisterSet> setsCustomMcu = sets; //Calculate size Struct foreach (var PerStruct in setsCustomMcu) { aSizeStruct = 0; foreach (var reg in PerStruct.Registers) { if (reg.SizeInBits == 0) { aSizeStruct = 0; break; } else { aSizeStruct += reg.SizeInBits; } } aDicSizeTypeDefStuct[PerStruct.UserFriendlyName] = aSizeStruct; } //Calculate size array custom type foreach (var CustTypReg in lstRegCustomType) { int strIdx1 = CustTypReg.Name.IndexOf("-"); int strIdx2 = CustTypReg.Name.IndexOf(":"); if (strIdx1 < 0 || strIdx2 < 0) { continue; } string str1 = CustTypReg.Name.Substring(strIdx1 + 1, CustTypReg.Name.Length - strIdx1 - 1); string asArray = CustTypReg.Name.Substring(strIdx2 + 1, strIdx1 - strIdx2 - 1); int asize; if (str1.StartsWith("RwReg") || str1.StartsWith("RoReg") || str1.StartsWith("WoReg")) { asize = int.Parse(str1.Substring(5)); } else { asize = aDicSizeTypeDefStuct[str1] * Convert.ToInt32(asArray); } CustTypReg.SizeInBits = asize; if (asize <= 32 && asize != 0) { CustTypReg.Name = CustTypReg.Name.Substring(0, strIdx2); } } //Rename big strucures foreach (var v in setsCustomMcu) { List <HardwareRegister> lr = new List <HardwareRegister>(); foreach (var r in v.Registers) { int strIdx1 = r.Name.IndexOf("-"); int strIdx2 = r.Name.IndexOf(":"); if (((r.SizeInBits <= 32 || r.Name.Contains("RESERVED")) && r.SizeInBits != 0)) { lr.Add(DeepCopy(r)); continue; } string typ = r.Name.Substring(strIdx1 + 1, r.Name.Length - strIdx1 - 1); foreach (var st in setsCustomMcu) { if (st.UserFriendlyName != typ) { continue; } foreach (var stsub in st.Registers) { HardwareRegister hr = DeepCopy(r); hr.Name = hr.Name.Substring(0, strIdx2) + "." + stsub.Name; hr.SizeInBits = stsub.SizeInBits; lr.Add(hr); } } } v.Registers = lr.ToArray(); } foreach (var fn in Directory.GetFiles(familyDirectory, "*.h")) { string aFileNameout = fn; if (fn.EndsWith("_1.h")) { continue; } if (fn.EndsWith("_0.h")) { aFileNameout = fn.Replace("_0.h", ".h"); } ///Set Base adress var aHrdRegFile = ProcessRegisterSetBaseAdress(fn, sets);//etsCustomMcu); if (aHrdRegFile.Count > 0) { peripherals.Add(Path.GetFileNameWithoutExtension(aFileNameout).ToUpper(), aHrdRegFile.ToArray()); } } /*if (fam.Contains("SAMl21")) * { * var aAddDir = familyDirectory.Replace("\\Include", "\\Include_b"); * * foreach (var fn in Directory.GetFiles(aAddDir, "*.h")) * { * string aFileNameout = fn; * if (fn.EndsWith("_1.h")) * continue; * if (fn.EndsWith("_0.h")) * aFileNameout = fn.Replace("_0.h", ".h"); * * ///Set Base adress * var aHrdRegFile = ProcessRegisterSetBaseAdress(fn, sets);//etsCustomMcu); * if (aHrdRegFile.Count > 0) * peripherals.Add(Path.GetFileNameWithoutExtension(aFileNameout).ToUpper(), aHrdRegFile.ToArray()); * } * }*/ return(peripherals); }
public static List <HardwareRegisterSet> ProcessRegisterSetNamesList(string pFileName, ref List <HardwareRegister> lstRegCustomType) { List <HardwareRegisterSet> oReg = new List <HardwareRegisterSet>(); bool aStartCheckReg = false; Regex argSearchReg = new Regex(@"[ \t]*([\w]+)[ \t]+([\w]+)[[]*([\w]+)*[]]*[;]?.*"); Regex argSearchFrendName = new Regex(@"^[ \t]*}[ ]*([\w]*).*"); List <HardwareRegister> lstReg = new List <HardwareRegister>(); int sizeArray; bool aflUnion = false; Match m1; int aSizeUnion = 0; foreach (var ln in File.ReadAllLines(pFileName)) { if (ln.Contains("typedef struct")) { lstReg = new List <HardwareRegister>(); aStartCheckReg = true; continue; } if (ln.Contains("typedef union {")) { aflUnion = true; continue; } if (aflUnion) { m1 = Regex.Match(ln, @"[ ]*(uint[\d]+_t).*"); if (m1.Success) { aSizeUnion = GetSizeInBitsPoor(m1.Groups[1].Value); continue; } m1 = Regex.Match(ln, @"^}[ ]*([\w_]+).*"); if (m1.Success) { if (aSizeUnion == 0) { throw new Exception(m1.Groups[1].Value + " is 0 in " + ln); } if (!aDicSizeTypeDefStuct.ContainsKey(m1.Groups[1].Value)) { aDicSizeTypeDefStuct.Add(m1.Groups[1].Value, aSizeUnion); } aflUnion = false; } continue; } if (!aStartCheckReg) { continue; } Match m = argSearchReg.Match(ln); if (m.Success) { sizeArray = 0; if (m.Groups[1].Value == "__I" || m.Groups[1].Value == "__O" || m.Groups[1].Value == "__IO") {//SAM4 m = Regex.Match(ln, @"[ \t]*[_IO]+[ \t]+(uint32_t|uint16_t|uint8_t|[\w_]+)[ \t]+([a-zA-Z0-9_]+)[[]*([0-9]+)*[]]*[;]?.*"); if (!m.Success) { throw new Exception("unkonow format registr :" + ln); } } if (m.Groups[3].Value.StartsWith("0x")) { string aDigStr = m.Groups[3].Value.Replace("0x", ""); sizeArray = Convert.ToInt32(aDigStr, 16); } else if (IsDigit(m.Groups[3].Value)) { sizeArray = m.Groups[3].Value == "" ? 1 : Convert.ToInt16(m.Groups[3].Value); } else { string astrDefArray = m.Groups[3].Value; foreach (var lndef in File.ReadAllLines(pFileName)) { var md = Regex.Match(lndef, @"[ \t]*#define[ \t]+" + astrDefArray + @"[ \t]+([0-9]+).*"); if (md.Success) { if (IsDigit(md.Groups[1].Value)) { sizeArray = Convert.ToInt16(md.Groups[1].Value); } else { throw new Exception("No define " + astrDefArray); } } } } string aType = m.Groups[1].Value; for (int a_cnt = 0; a_cnt < sizeArray; a_cnt++) { HardwareRegister setReg = new HardwareRegister(); if (aType == "PortGroup") { setReg.Name = m.Groups[2].Value + "[" + a_cnt + "]"; } else { setReg.Name = (sizeArray > 1) ? m.Groups[2].Value + "[" + a_cnt + "]" : m.Groups[2].Value; } setReg.ReadOnly = (aType == "RoReg" || m.Groups[0].Value.Contains("__I ")) ? true : false; if (!STANDARD_TYPE_SIZES.ContainsKey(aType)) { setReg.SizeInBits = 0; setReg.Name = setReg.Name + ":1-" + aType;//name register - custom type lstRegCustomType.Add(setReg); } else { setReg.SizeInBits = GetSizeInBitsPoor(aType); } lstReg.Add(setReg); } } else { //end m = argSearchFrendName.Match(ln); if (m.Success) { HardwareRegisterSet setReg = new HardwareRegisterSet(); setReg.UserFriendlyName = m.Groups[1].Value; aStartCheckReg = false; oReg.Add(setReg); foreach (var HardReg in lstReg) { var lstSubRegs = ProcessRegisterSetSubRegisters(pFileName); List <HardwareSubRegister> lstSubRegToHard = new List <HardwareSubRegister>(); string aPrefNameSubReg = (HardReg.Name + "_").ToUpper(); int idx = aPrefNameSubReg.LastIndexOf("["); if (idx > 0) { aPrefNameSubReg = aPrefNameSubReg.Substring(0, idx) + "_"; } foreach (var SubReg in lstSubRegs) { if (SubReg.Name.StartsWith(aPrefNameSubReg)) { SubReg.Name = SubReg.Name.Remove(0, aPrefNameSubReg.Length); SubReg.ParentRegister = HardReg; lstSubRegToHard.Add(SubReg); } } HardReg.SubRegisters = lstSubRegToHard.ToArray(); } setReg.Registers = lstReg.ToArray(); } } } return(oReg); }
static void AdjustHardwareRegisters(string ccsDir, string mcuName, ref HardwareRegisterSet[] hardwareRegisterSets) { string dir = ccsDir + @"\ccs_base\common\targetdb\devices"; if (!Directory.Exists(dir)) { throw new Exception("Missing " + dir); } string tiDefinitionFile = dir + "\\" + mcuName + ".xml"; if (!File.Exists(tiDefinitionFile)) { return; } XmlDocument doc = new XmlDocument(); doc.Load(tiDefinitionFile); Dictionary <string, ulong> oldRegisters = new Dictionary <string, ulong>(); foreach (var set in hardwareRegisterSets) { foreach (var reg in set.Registers) { string name = reg.Name; if (name.EndsWith("_H")) { continue; } else if (name.EndsWith("_L")) { name = name.Substring(0, name.Length - 2); } oldRegisters[name] = ParseAddr(reg.Address); } } List <HardwareRegisterSet> newRegisterSets = new List <HardwareRegisterSet>(); foreach (XmlNode node in doc.SelectNodes("device/cpu/instance")) { XmlElement el = node as XmlElement; if (el == null) { continue; } string peripheralDefinition = Path.Combine(Path.GetDirectoryName(tiDefinitionFile), el.Attributes["href"].Value); if (!File.Exists(peripheralDefinition)) { throw new NotSupportedException(); } string addr = el.Attributes["baseaddr"].Value; if (addr != "0x0000") { throw new NotSupportedException(); } if (peripheralDefinition.EndsWith("_NotVisible.xml")) { continue; } XmlDocument xmlModule = new XmlDocument(); xmlModule.Load(peripheralDefinition); var newSet = new HardwareRegisterSet { UserFriendlyName = xmlModule.SelectSingleNode("module").Attributes["description"].Value }; newRegisterSets.Add(newSet); List <HardwareRegister> newRegs = new List <HardwareRegister>(); foreach (XmlElement reg in xmlModule.SelectNodes("module/register")) { string registerID = reg.Attributes["id"].Value; ulong lAddr = ParseAddr(reg.Attributes["offset"].Value.Trim()); ulong oldAddr; int sizeInBits = int.Parse(reg.Attributes["width"].Value); if (oldRegisters.TryGetValue(registerID, out oldAddr)) { if (oldAddr != lAddr) { Debugger.Log(0, "Warning", "Address mismatch for " + registerID + "\n"); } oldRegisters[registerID] = ulong.MaxValue; } HardwareRegister newReg = new HardwareRegister { Name = registerID, Address = string.Format("0x{0:x}", lAddr), SizeInBits = sizeInBits }; List <HardwareSubRegister> subRegs = new List <HardwareSubRegister>(); foreach (XmlElement field in reg.SelectNodes("bitfield")) { string fieldID = field.Attributes["id"].Value; int start = int.Parse(field.Attributes["begin"].Value); int end = int.Parse(field.Attributes["end"].Value); int width = int.Parse(field.Attributes["width"].Value); if (start == (end + width - 1)) { int tmp = start; start = end; end = tmp; } if (end != (start + width - 1)) { throw new NotSupportedException(); } var subReg = new HardwareSubRegister { Name = fieldID, FirstBit = start, SizeInBits = width }; KnownSubRegisterValue[] subValues = null; bool bad = false; int bitenumValuesChecked = 0; foreach (XmlElement val in field.SelectNodes("bitenum")) { if (subValues == null) { subValues = new KnownSubRegisterValue[1 << width]; } string valName = val.Attributes["id"].Value; int value = int.Parse(val.Attributes["value"].Value); if (value >= subValues.Length) { bad = true; } else { subValues[value] = new KnownSubRegisterValue { Name = valName } }; bitenumValuesChecked++; } if (bad) { subValues = null; if (bitenumValuesChecked == (1 << width)) { //There's a typo in the XML files. Sometimes the 'value' for a divider is taken from the divider value and not the bitfield value. Let's try fixing it! subValues = new KnownSubRegisterValue[1 << width]; int idx = 0; int lastDividerValue = 0; foreach (XmlElement val in field.SelectNodes("bitenum")) { string valName = val.Attributes["id"].Value; int tmp = valName.LastIndexOf('_'); int dividerValue = int.Parse(valName.Substring(tmp + 1)); if (dividerValue < lastDividerValue) { throw new NotSupportedException(); //If the values are listed in the ascending order, we can assume that they are listed in the bitfield value order. } lastDividerValue = dividerValue; subValues[idx++] = new KnownSubRegisterValue { Name = valName }; } } } if (subValues != null) { foreach (var v in subValues) { if (v == null) { subValues = null; break; } } } subReg.KnownValues = subValues; subRegs.Add(subReg); } if (subRegs.Count > 0) { newReg.SubRegisters = subRegs.ToArray(); } newRegs.Add(newReg); } newSet.Registers = newRegs.ToArray(); } foreach (var kv in oldRegisters) { if (kv.Value != ulong.MaxValue) { Debugger.Log(0, "", "TI XML does not list " + kv.Key + "\n"); } } hardwareRegisterSets = newRegisterSets.ToArray(); }
private void OnRegisterSetBegin() { _registers = new List <HardwareRegister>(); _registerSet = new HardwareRegisterSet(); SetExpectedMatches(REGISTER_BEGIN, RESERVED_BITS, REGISTER_WITHOUT_SUBREGISTERS); }
public static HardwareRegisterSet[] GenerateFamilyPeripheralRegisters(string PeripheralHeaderFile) { string file = File.ReadAllText(PeripheralHeaderFile); Dictionary<string, HardwareRegisterSet> types = new Dictionary<string, HardwareRegisterSet>(); Dictionary<string, List<HardwareSubRegister>> subregisters = new Dictionary<string, List<HardwareSubRegister>>(); Dictionary<string, KeyValuePair<string, ulong>> addresses = new Dictionary<string, KeyValuePair<string, ulong>>(); var struct_regex = new Regex(@"typedef\s+struct\s*{(.+?)}\s*([^ ]*)_Type", RegexOptions.Singleline); // 1. Process all structures in the file one by one int file_index = 0; Match struct_m; while ((struct_m = struct_regex.Match(file, file_index)).Success) { // 2. Create the register set based on the structure string struct_name = struct_m.Groups[2].ToString(); string struct_regs = struct_m.Groups[1].ToString(); ulong struct_size; HardwareRegisterSet set = new HardwareRegisterSet() { UserFriendlyName = struct_name, // 3. Add the registers to the register set Registers = ProcessStructContents(struct_regs, false, out struct_size) }; types.Add(set.UserFriendlyName, set); file_index = struct_m.Index + struct_m.Length; // 3. Find the subregisters of the register set Regex register_masks_regex = new Regex(struct_name + @"_Register_Masks " + struct_name + @" Register Masks(.+?)@}", RegexOptions.Singleline); Match register_masks_m = register_masks_regex.Match(file, file_index); if (!register_masks_m.Success) throw new Exception("Failed to find register masks!"); string register_masks_content = register_masks_m.Groups[0].ToString(); Regex subregister_regex = new Regex(@"#define\s([^()\s]+)_MASK[\s]*([0-9A-Fa-fx]+)u\s*#define\s([^()\s]+)_SHIFT\s*([0-9]+)\s*", RegexOptions.Singleline); var subregisters_m = subregister_regex.Matches(register_masks_content); if ((subregisters_m.Count == 0) && !REGISTERSETS_WITHOUT_SUBREGISTERS.Contains(struct_name)) throw new Exception("No subregisters found from register masks!"); foreach (Match subregister_m in subregisters_m) { var subregister_mask_name = subregister_m.Groups[1].ToString(); if (!subregister_mask_name.StartsWith(set.UserFriendlyName)) { throw new Exception(string.Format("Wrong subregister mask name {0} for register set {1}", subregister_mask_name, set.UserFriendlyName)); } var subregister_mask_set_name = set.UserFriendlyName; var temp_subregister_mask_reg_subreg_name = subregister_mask_name.Substring(subregister_mask_set_name.Length + 1); string subregister_mask_reg_subreg_name = null; foreach (var register in set.Registers) { var cleaned_reg_name = CleanRegisterName(register.Name); if (cleaned_reg_name.EndsWith("r")) { cleaned_reg_name = cleaned_reg_name.Substring(0, cleaned_reg_name.Length - 1); } if (subregister_mask_name.Contains(cleaned_reg_name)) { subregister_mask_reg_subreg_name = temp_subregister_mask_reg_subreg_name; break; } } if (subregister_mask_reg_subreg_name == null) { throw new Exception(string.Format("Wrong combined register and subregister mask name {0} for register set {1}", temp_subregister_mask_reg_subreg_name, set.UserFriendlyName)); } string subregister_mask = subregister_m.Groups[2].ToString(); var subregister_shift_name = subregister_m.Groups[3].ToString(); if (!subregister_shift_name.StartsWith(set.UserFriendlyName)) { throw new Exception(string.Format("Wrong subregister shift name {0} for register set {1}", subregister_mask_name, set.UserFriendlyName)); } string subregister_shift_set_name = set.UserFriendlyName; string subregister_shift_reg_subreg_name = subregister_shift_name.Substring(subregister_shift_set_name.Length + 1); int subregister_first_bit = Int32.Parse(subregister_m.Groups[4].Value); if (subregister_mask_set_name != subregister_shift_set_name) throw new Exception("The subregister mask and shift have non-matching register set names!"); if (subregister_mask_reg_subreg_name != subregister_shift_reg_subreg_name) throw new Exception("The subregister mask and shift have non-matching register_subregister names!"); string subregister_register_name = null; string subregister_name = null; var foundRegisterLength = int.MinValue; foreach (var register in set.Registers) { string cleaned_reg_name = CleanRegisterName(register.Name); var testRegName = cleaned_reg_name; if (testRegName.EndsWith("r")) { testRegName = testRegName.Substring(0, testRegName.Length - 1); } if (subregister_mask_reg_subreg_name.StartsWith(testRegName + "_") && ((subregister_register_name == null) || (subregister_register_name.Length < cleaned_reg_name.Length)) && testRegName.Length > foundRegisterLength) { foundRegisterLength = cleaned_reg_name.Length; subregister_register_name = cleaned_reg_name; subregister_name = subregister_mask_reg_subreg_name.Substring((testRegName + "_").Length); } } string key = subregister_mask_set_name + "_" + subregister_register_name; if (!subregisters.ContainsKey(key)) subregisters[key] = new List<HardwareSubRegister>(); subregisters[key].Add(new HardwareSubRegister() { Name = subregister_name, FirstBit = subregister_first_bit, SizeInBits = BitMaskToBitLength(ParseHex(subregister_mask)) }); } file_index = register_masks_m.Index + register_masks_m.Length; // 4. Find the instances of the register sets Regex instance_addresses_regex = new Regex(struct_name + @" - Peripheral instance base addresses(.+?)/\* --", RegexOptions.Singleline); Match instance_addresses_m = instance_addresses_regex.Match(file, file_index); if (!instance_addresses_m.Success) throw new Exception("No register set base addresses found!"); string instance_addresses_content = instance_addresses_m.Groups[1].ToString(); Regex base_addresses_regex = new Regex(@"#define[ \t]+(.+)_BASE[_PTR]*[ \t]+\((.+)u\)"); var base_addresses_m = base_addresses_regex.Matches(instance_addresses_content); if (base_addresses_m.Count == 0) { throw new Exception("Failed to parse base addresses!"); } foreach (Match base_address_m in base_addresses_m) { string base_address_name = base_address_m.Groups[1].ToString(); string base_address_value = base_address_m.Groups[2].ToString(); addresses[base_address_name] = new KeyValuePair<string, ulong>(struct_name, ParseHex(base_address_value)); } file_index = instance_addresses_m.Index + instance_addresses_m.Length; } // Process registers and register sets List<HardwareRegisterSet> sets = new List<HardwareRegisterSet>(); foreach (var set_name in addresses.Keys) { HardwareRegisterSet set = DeepCopy(types[addresses[set_name].Key]); set.UserFriendlyName = set_name; foreach (var register in set.Registers) { // Fix the address register.Address = FormatToHex(ParseHex(register.Address) + addresses[set_name].Value); // Add the subregisters string cleaned_reg_name = register.Name; Regex reg_name_regex1 = new Regex(@"(.*)_[0-9]+_[0-9]+$"); Regex reg_name_regex2 = new Regex(@"(.*)_[0-9]+$"); Match reg_name1_m = reg_name_regex1.Match(register.Name); Match reg_name2_m = reg_name_regex2.Match(register.Name); if (reg_name1_m.Success) cleaned_reg_name = reg_name1_m.Groups[1].ToString(); else if (reg_name2_m.Success && !REGISTERS_ENDING_UNDERSCORE_NUMBER.Contains(register.Name)) cleaned_reg_name = reg_name2_m.Groups[1].ToString(); string key = addresses[set_name].Key + "_" + cleaned_reg_name; if (subregisters.ContainsKey(key)) { List<HardwareSubRegister> subs = new List<HardwareSubRegister>(); foreach (var sub in subregisters[key]) { subs.Add(DeepCopy(sub)); } register.SubRegisters = subs.ToArray(); } else if (!REGISTERSETS_WITHOUT_SUBREGISTERS.Contains(set_name) && !REGISTERS_WITHOUT_SUBREGISTERS.Contains(key)) { throw new Exception("No subregisters found!"); } } sets.Add(set); } return sets.ToArray(); }
private static HardwareRegisterSet DeepCopy(HardwareRegisterSet set) { HardwareRegisterSet set_new = new HardwareRegisterSet { UserFriendlyName = set.UserFriendlyName, ExpressionPrefix = set.ExpressionPrefix, }; if (set.Registers != null) { set_new.Registers = new HardwareRegister[set.Registers.Length]; for (int i = 0; i < set.Registers.Length; i++) { set_new.Registers[i] = DeepCopy(set.Registers[i]); } } return set_new; }
public static List <HardwareRegisterSet> ProcessRegisterSetNamesList(string pFileName, ref List <HardwareRegister> lstRegCustomType) { List <HardwareRegisterSet> oReg = new List <HardwareRegisterSet>(); bool aStartCheckReg = false; List <HardwareRegister> lstReg = new List <HardwareRegister>(); int sizeArray; foreach (var ln in File.ReadAllLines(pFileName)) { if (ln == "typedef struct") { lstReg = new List <HardwareRegister>(); aStartCheckReg = true; } if (!aStartCheckReg) { continue; } Match m = Regexes.argSearchReg.Match(ln); if (m.Success) { sizeArray = m.Groups[4].Value == "" ? 1 : Convert.ToInt16(m.Groups[4].Value); for (int a_cnt = 0; a_cnt < sizeArray; a_cnt++) { lstReg.Add(new HardwareRegister() { Name = (sizeArray > 1) ? m.Groups[3].Value + "[" + a_cnt + "]" : m.Groups[3].Value, ReadOnly = (m.Groups[1].Value == "__I") ? true : false, SizeInBits = GetSizeInBitsPoor(m.Groups[2].Value) }); } } else { m = Regexes.argSearchRegReserv.Match(ln); //reserverd array if (m.Success) { sizeArray = m.Groups[3].Value == "" ? 1 : Convert.ToInt32(m.Groups[3].Value); lstReg.Add(new HardwareRegister() { Name = m.Groups[2].Value, SizeInBits = GetSizeInBitsPoor(m.Groups[1].Value, Convert.ToInt32(sizeArray)), }); } // Typedef Array m = Regexes.argSearchRegTypeDef.Match(ln); if (m.Success) { sizeArray = m.Groups[3].Value == "" ? 1 : Convert.ToInt16(m.Groups[3].Value); for (int a_cnt = 0; a_cnt < sizeArray; a_cnt++) { HardwareRegister setReg = new HardwareRegister(); if (sizeArray > 1) { setReg.Name = m.Groups[2].Value + "[" + a_cnt + "]:1-" + m.Groups[1].Value;//name register - custom type } else { setReg.Name = m.Groups[2].Value + ":" + sizeArray + "-" + m.Groups[1].Value;//name register - custom type } setReg.SizeInBits = 0; lstReg.Add(setReg); lstRegCustomType.Add(setReg); } } //end m = Regexes.argSearchFrendName.Match(ln); if (m.Success) { HardwareRegisterSet setReg = new HardwareRegisterSet(); setReg.UserFriendlyName = m.Groups[1].Value; aStartCheckReg = false; oReg.Add(setReg); var originalSubRegs = ProcessRegisterSetSubRegisters(pFileName); foreach (var HardReg in lstReg) { var lstSubRegs = originalSubRegs.Select(s => CloneSubregister(s)).ToList(); List <HardwareSubRegister> lstSubRegToHard = new List <HardwareSubRegister>(); string aPrefNameSubReg = setReg.UserFriendlyName + "_" + HardReg.Name + "_"; foreach (var SubReg in lstSubRegs) { if (SubReg.Name.StartsWith(aPrefNameSubReg)) { SubReg.Name = SubReg.Name.Remove(0, aPrefNameSubReg.Length); SubReg.ParentRegister = HardReg; lstSubRegToHard.Add(SubReg); } } HardReg.SubRegisters = lstSubRegToHard.ToArray(); } setReg.Registers = lstReg.ToArray(); } } } return(oReg); }
private void OnRegisterSetBegin() { _registers = new List<HardwareRegister>(); _registerSet = new HardwareRegisterSet(); SetExpectedMatches(REGISTER_BEGIN, RESERVED_BITS, REGISTER_WITHOUT_SUBREGISTERS); }
private static Dictionary<string, HardwareRegisterSet> ProcessRegisterSetTypes(string file, out Dictionary<string, string> nested_types) { Dictionary<string, HardwareRegisterSet> types = new Dictionary<string, HardwareRegisterSet>(); nested_types = new Dictionary<string, string>(); Dictionary<string, int> dict_type_sizes = new Dictionary<string, int>(); dict_type_sizes["uint32_t"] = 32; dict_type_sizes["uint16_t"] = 16; dict_type_sizes["uint8_t"] = 8; Regex struct_regex = new Regex(@"typedef struct[ \t]*\r\n\{[ \t]*\r\n([^}]*)\r\n\}[ \t\r\n]*([A-Za-z0-9_]*)_(Global)?TypeDef;"); var structs = struct_regex.Matches(file); foreach (Match strct in structs) { HardwareRegisterSet set = new HardwareRegisterSet() { UserFriendlyName = strct.Groups[2].Value, ExpressionPrefix = strct.Groups[2].Value + "->" }; int set_size = 0; RegexOptions option = RegexOptions.IgnoreCase; Regex register_regex = new Regex(@"[ ]*(__IO|__I)*[ ]*(?:const )*[ ]*([^ #\r\n]*)[ ]*(?:const )*([^\[;#\r\n]*)[\[]?([0-9xXa-fA-F]+)*[\]]?;[ ]*(/\*)*(!<)*[ ]?([^,*\r\n]*)[,]?[ ]*(Ad[d]?ress)*( offset:)*[ ]*([0-9xXa-fA-F]*)[ ]?[-]?[ ]?([^ *\r\n]*)[ ]*(\*/)*[ ]*(\r\n)*", option); var regs = register_regex.Matches(strct.Groups[1].Value); List<HardwareRegister> hw_regs = new List<HardwareRegister>(); if (regs.Count == 0) throw new Exception("Register row parsing failed!"); foreach (Match m in regs) { string type = m.Groups[2].Value; if (!dict_type_sizes.ContainsKey(type)) throw new Exception("Unknown register type: " + type); int size = dict_type_sizes[type]; int array_size = 1; try { array_size = string.IsNullOrEmpty(m.Groups[4].Value) ? 1 : Int32.Parse(m.Groups[4].Value); } catch (FormatException ex) { string hex = m.Groups[4].Value; if (hex.StartsWith("0x")) hex = hex.Substring("0x".Length); array_size = Int32.Parse(hex, System.Globalization.NumberStyles.HexNumber); } string hex_offset = FormatToHex((ulong)(set_size / 8));// Do not use address from header file, sometimes they have errors //m.Groups[10].Value; if (size == 32)// all 32 bit addresses should start from an address divisible by 4 { hex_offset = FormatToHex((((ulong)(set_size / 8) + 3) / 4) * 4); set_size = Math.Max(set_size, (int)(ParseHex(hex_offset) * 8)) + array_size * size; } else set_size += array_size * size; string name = m.Groups[3].Value; if (name.StartsWith("RESERVED", StringComparison.InvariantCultureIgnoreCase)) continue; string readonly_type = m.Groups[1].Value; string desc = m.Groups[7].Value.TrimEnd(); bool flNameArrayFromOne = true; if (desc.StartsWith("DSI ")) flNameArrayFromOne = false; for (int i = 1; i <= array_size; i++) { if (array_size != 1) if ((set.UserFriendlyName == "GPIO") && (m.Groups[3].Value == "AFR")) { if (i == 1) name = m.Groups[3].Value + "L"; else if (i == 2) name = m.Groups[3].Value + "H"; else throw new Exception("Cannot use low-high naming with array sizes greater than 2!"); } else if(flNameArrayFromOne) name = m.Groups[3].Value + i.ToString(); else name = m.Groups[3].Value + (i-1).ToString(); if ((type != "uint32_t") && (type != "uint16_t") && (type != "uint8_t")) { int index = type.LastIndexOf("_TypeDef"); nested_types[set.UserFriendlyName + "_" + name] = type.Substring(0, index);// Chop the TypeDef off the type as it is easier to process later on } HardwareRegister hw_reg = new HardwareRegister { Name = name, SizeInBits = size, ReadOnly = (readonly_type == "__I") ? true : false, Address = hex_offset }; if (hw_regs.Find(x => ((x.Name == hw_reg.Name) && (x.Address == hw_reg.Address))) != null) throw new Exception("Register with the same name and address already exists in the set!"); hw_regs.Add(hw_reg); hex_offset = FormatToHex(ParseHex(hex_offset) + Math.Max((ulong)(size/8.0), (ulong)4)); } } dict_type_sizes[set.UserFriendlyName + "_TypeDef"] = set_size; set.Registers = hw_regs.ToArray(); if (types.ContainsKey(set.UserFriendlyName)) throw new Exception("Two registerset definitions with the same of " + set.UserFriendlyName + " found!"); types[set.UserFriendlyName] = set; } return types; }
private void OnStart() { _processedBits = 0; _registerNameToAddress = new Dictionary<string, string>(); _registerSetToAddress = new Dictionary<string, string>(); _subRegistersKnownValues = new Dictionary<string, IList<KeyValuePair<string, ulong>>>(); _registers = new List<HardwareRegister>(); _registerSets = new List<HardwareRegisterSet>(); _subRegisters = new List<HardwareSubRegister>(); _registersWithWrongBitsSum = new List<string>(); _duplicateRegisterDefinition = false; _lastMatch = Match.Empty; _matchedRegex = null; _registerSet = null; _register = null; _subRegister = null; _registerBits = new Dictionary<string, HardwareSubRegister>(); _expectedMatches = new List<Regex> { REGISTER_SET_ADDRESS }; }
public static HardwareRegisterSet[] GenerateFamilyPeripheralRegisters(string PeripheralHeaderFile) { string file = File.ReadAllText(PeripheralHeaderFile); Dictionary <string, HardwareRegisterSet> types = new Dictionary <string, HardwareRegisterSet>(); Dictionary <string, List <HardwareSubRegister> > subregisters = new Dictionary <string, List <HardwareSubRegister> >(); Dictionary <string, KeyValuePair <string, ulong> > addresses = new Dictionary <string, KeyValuePair <string, ulong> >(); var struct_regex = new Regex(@"typedef\s+struct\s*{(.+?)}\s*([^ ]*)_Type", RegexOptions.Singleline); // 1. Process all structures in the file one by one int file_index = 0; Match struct_m; while ((struct_m = struct_regex.Match(file, file_index)).Success) { // 2. Create the register set based on the structure string struct_name = struct_m.Groups[2].ToString(); string struct_regs = struct_m.Groups[1].ToString(); ulong struct_size; HardwareRegisterSet set = new HardwareRegisterSet() { UserFriendlyName = struct_name, // 3. Add the registers to the register set Registers = ProcessStructContents(struct_regs, false, out struct_size) }; types.Add(set.UserFriendlyName, set); file_index = struct_m.Index + struct_m.Length; // 3. Find the subregisters of the register set Regex register_masks_regex = new Regex(struct_name + @"_Register_Masks " + struct_name + @" Register Masks(.+?)@}", RegexOptions.Singleline); Match register_masks_m = register_masks_regex.Match(file, file_index); if (!register_masks_m.Success) { throw new Exception("Failed to find register masks!"); } string register_masks_content = register_masks_m.Groups[0].ToString(); Regex subregister_regex = new Regex(@"#define\s([^()\s]+)_MASK[\s]*([0-9A-Fa-fx]+)u\s*#define\s([^()\s]+)_SHIFT\s*([0-9]+)\s*", RegexOptions.Singleline); var subregisters_m = subregister_regex.Matches(register_masks_content); if ((subregisters_m.Count == 0) && !REGISTERSETS_WITHOUT_SUBREGISTERS.Contains(struct_name)) { throw new Exception("No subregisters found from register masks!"); } foreach (Match subregister_m in subregisters_m) { var subregister_mask_name = subregister_m.Groups[1].ToString(); if (!subregister_mask_name.StartsWith(set.UserFriendlyName)) { throw new Exception(string.Format("Wrong subregister mask name {0} for register set {1}", subregister_mask_name, set.UserFriendlyName)); } var subregister_mask_set_name = set.UserFriendlyName; var temp_subregister_mask_reg_subreg_name = subregister_mask_name.Substring(subregister_mask_set_name.Length + 1); string subregister_mask_reg_subreg_name = null; foreach (var register in set.Registers) { var cleaned_reg_name = CleanRegisterName(register.Name); if (cleaned_reg_name.EndsWith("r")) { cleaned_reg_name = cleaned_reg_name.Substring(0, cleaned_reg_name.Length - 1); } if (subregister_mask_name.Contains(cleaned_reg_name)) { subregister_mask_reg_subreg_name = temp_subregister_mask_reg_subreg_name; break; } } if (subregister_mask_reg_subreg_name == null) { throw new Exception(string.Format("Wrong combined register and subregister mask name {0} for register set {1}", temp_subregister_mask_reg_subreg_name, set.UserFriendlyName)); } string subregister_mask = subregister_m.Groups[2].ToString(); var subregister_shift_name = subregister_m.Groups[3].ToString(); if (!subregister_shift_name.StartsWith(set.UserFriendlyName)) { throw new Exception(string.Format("Wrong subregister shift name {0} for register set {1}", subregister_mask_name, set.UserFriendlyName)); } string subregister_shift_set_name = set.UserFriendlyName; string subregister_shift_reg_subreg_name = subregister_shift_name.Substring(subregister_shift_set_name.Length + 1); int subregister_first_bit = Int32.Parse(subregister_m.Groups[4].Value); if (subregister_mask_set_name != subregister_shift_set_name) { throw new Exception("The subregister mask and shift have non-matching register set names!"); } if (subregister_mask_reg_subreg_name != subregister_shift_reg_subreg_name) { throw new Exception("The subregister mask and shift have non-matching register_subregister names!"); } string subregister_register_name = null; string subregister_name = null; var foundRegisterLength = int.MinValue; foreach (var register in set.Registers) { string cleaned_reg_name = CleanRegisterName(register.Name); var testRegName = cleaned_reg_name; if (testRegName.EndsWith("r")) { testRegName = testRegName.Substring(0, testRegName.Length - 1); } if (subregister_mask_reg_subreg_name.StartsWith(testRegName + "_") && ((subregister_register_name == null) || (subregister_register_name.Length < cleaned_reg_name.Length)) && testRegName.Length > foundRegisterLength) { foundRegisterLength = cleaned_reg_name.Length; subregister_register_name = cleaned_reg_name; subregister_name = subregister_mask_reg_subreg_name.Substring((testRegName + "_").Length); } } string key = subregister_mask_set_name + "_" + subregister_register_name; if (!subregisters.ContainsKey(key)) { subregisters[key] = new List <HardwareSubRegister>(); } subregisters[key].Add(new HardwareSubRegister() { Name = subregister_name, FirstBit = subregister_first_bit, SizeInBits = BitMaskToBitLength(ParseHex(subregister_mask)) }); } file_index = register_masks_m.Index + register_masks_m.Length; // 4. Find the instances of the register sets Regex instance_addresses_regex = new Regex(struct_name + @" - Peripheral instance base addresses(.+?)/\* --", RegexOptions.Singleline); Match instance_addresses_m = instance_addresses_regex.Match(file, file_index); if (!instance_addresses_m.Success) { throw new Exception("No register set base addresses found!"); } string instance_addresses_content = instance_addresses_m.Groups[1].ToString(); Regex base_addresses_regex = new Regex(@"#define[ \t]+(.+)_BASE[_PTR]*[ \t]+\((.+)u\)"); var base_addresses_m = base_addresses_regex.Matches(instance_addresses_content); if (base_addresses_m.Count == 0) { throw new Exception("Failed to parse base addresses!"); } foreach (Match base_address_m in base_addresses_m) { string base_address_name = base_address_m.Groups[1].ToString(); string base_address_value = base_address_m.Groups[2].ToString(); addresses[base_address_name] = new KeyValuePair <string, ulong>(struct_name, ParseHex(base_address_value)); } file_index = instance_addresses_m.Index + instance_addresses_m.Length; } // Process registers and register sets List <HardwareRegisterSet> sets = new List <HardwareRegisterSet>(); foreach (var set_name in addresses.Keys) { HardwareRegisterSet set = DeepCopy(types[addresses[set_name].Key]); set.UserFriendlyName = set_name; foreach (var register in set.Registers) { // Fix the address register.Address = FormatToHex(ParseHex(register.Address) + addresses[set_name].Value); // Add the subregisters string cleaned_reg_name = register.Name; Regex reg_name_regex1 = new Regex(@"(.*)_[0-9]+_[0-9]+$"); Regex reg_name_regex2 = new Regex(@"(.*)_[0-9]+$"); Match reg_name1_m = reg_name_regex1.Match(register.Name); Match reg_name2_m = reg_name_regex2.Match(register.Name); if (reg_name1_m.Success) { cleaned_reg_name = reg_name1_m.Groups[1].ToString(); } else if (reg_name2_m.Success && !REGISTERS_ENDING_UNDERSCORE_NUMBER.Contains(register.Name)) { cleaned_reg_name = reg_name2_m.Groups[1].ToString(); } string key = addresses[set_name].Key + "_" + cleaned_reg_name; if (subregisters.ContainsKey(key)) { List <HardwareSubRegister> subs = new List <HardwareSubRegister>(); foreach (var sub in subregisters[key]) { subs.Add(DeepCopy(sub)); } register.SubRegisters = subs.ToArray(); } else if (!REGISTERSETS_WITHOUT_SUBREGISTERS.Contains(set_name) && !REGISTERS_WITHOUT_SUBREGISTERS.Contains(key)) { throw new Exception("No subregisters found!"); } } sets.Add(set); } return(sets.ToArray()); }