public bool Apply(ref RegisterID regId, string fullName, out string shortName) { if (Breakpoint) Debugger.Break(); shortName = null; Match mSet = null, mReg = null, mSubreg = null; if (_SetRegex != null) { mSet = _SetRegex.Match(regId.SetName); if (!mSet.Success) return false; } if (_RegisterRegex != null) { mReg = _RegisterRegex.Match(regId.RegName); if (!mReg.Success) return false; } mSubreg = _SubregisterRegex.Match(fullName); if (!mSubreg.Success) return false; shortName = ExpandString(NewSubregister, mSet, mReg, mSubreg); if (NewSet != null || NewRegister != null) { string setName = NewSet == null ? regId.SetName : ExpandString(NewSet, mSet, mReg, mSubreg); string regName = NewRegister == null ? regId.RegName : ExpandString(NewRegister, mSet, mReg, mSubreg); regId = new RegisterID(setName, regName); } if (StripRegisterNameFromSubregister) { if (!shortName.StartsWith(regId.RegName + "_", StringComparison.InvariantCultureIgnoreCase)) throw new Exception("Unexpected subregister name after transformation"); shortName = shortName.Substring(regId.RegName.Length + 1); } return true; }
public bool ApplySubregisterRenameRules(ref RegisterID thisReg, string subreg_name, out string shortSubregName) { shortSubregName = null; foreach (var rule in SubregisterRenameRules) if (rule.Apply(ref thisReg, subreg_name, out shortSubregName)) return true; return false; }
public bool Apply(ref RegisterID register) { if (register.SetName != OriginalName) return false; if (!_RegisterNames.Contains(register.RegName)) return false; register = new RegisterID(NewName == null ? register.SetName : NewName, NewRegisterName == null ? register.RegName : NewRegisterName); return true; }
private static Dictionary<string, List<HardwareSubRegister>> ProcessSubregisters(string fileContents, string fileName, RegisterParserConfiguration cfg, RegisterParserErrors errors) { Dictionary<string, List<HardwareSubRegister>> result = new Dictionary<string, List<HardwareSubRegister>>(); Dictionary<string, uint> aDefPosDict = new Dictionary<string, uint>(); // Process subregisters Regex rgSubregisterList = new Regex(@"/\*[!]?[<]?[\*]+[ ]+Bit[s]? definition [genric ]*for ([^_ ]*)_([^ ]*)[ ]+register[ ]+[*]+/[ ]*"); Regex rgSubregisterListWildcard = new Regex(@"/\*+ +Bit definition for ([A-Z0-9a-z]+)_([A-Z0-9a-z]+) \(x *=[^()]+\) +register +\*+/"); Regex rgSubregisterListWildcard2 = new Regex(@"/\*+ +Bit definition for ([A-Z0-9a-z]+)_([A-Z0-9a-z]+) registers? +\(x *=[^()]+\) +\*+/"); Regex rbSubregisterListEth = new Regex(@"/\*+[ ]+Bit definition for (.*) [Rr]egister[ ]+[1-9]*[ ]*\*+/"); Regex rbSubregisterListUsb = new Regex(@"/\*+ +([^ ]+ .*) register bits? definitions +\*+/", RegexOptions.IgnoreCase); Regex bit_def_regex = new Regex(@"#define[ ]+([^ \(\)]*)[ \t]+[,]?[ ]*\(\(([^\(\)]*)\)([0-9A-Fa-fx]*)[U]?\)[ ]*(/\*)?(!<)?[ ]*([^\*/]*)(\*/)?"); string[] lines = fileContents.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); int nextLine = 0; bool insideIgnoredBlock = false; for (;;) { if (nextLine >= lines.Length) break; string line = lines[nextLine++]; foreach (var patch in cfg.LinePatches) if (patch.Apply(ref line)) break; Match m; RegisterID thisReg; if ((m = rgSubregisterList.Match(line)).Success) thisReg = new RegisterID(m.Groups[1].Value, m.Groups[2].Value); else if (((m = rgSubregisterListWildcard.Match(line)).Success) || ((m = rgSubregisterListWildcard2.Match(line)).Success)) thisReg = new RegisterID(m.Groups[1].Value, m.Groups[2].Value); else if (((m = rbSubregisterListEth.Match(line)).Success) || (m = rbSubregisterListUsb.Match(line)).Success) { var m4 = bit_def_regex.Match(lines[nextLine]); if (!m4.Success) m4 = Regex.Match(lines[nextLine], @"#define[ \t]+([\w\d]+)[ \t]+([0-9A-Fa-fx]*)[U]?"); if (!m4.Success) errors.AddError(new RegisterParserErrors.BadBitDefinition { LineContents = line, LineNumber = nextLine - 1, FileName = fileName }); string subreg_def = m4.Groups[1].Value; int index = subreg_def.IndexOf("_"); if (index <= 0) { errors.AddError(new RegisterParserErrors.BadBitDefinition { LineContents = line, LineNumber = nextLine - 1, FileName = fileName }); continue; } string regSet = subreg_def.Substring(0, index); subreg_def = subreg_def.Substring(index + 1); index = subreg_def.IndexOf("_"); if (index <= 0) { errors.AddError(new RegisterParserErrors.BadBitDefinition { LineContents = line, LineNumber = nextLine - 1, FileName = fileName }); continue; } thisReg = new RegisterID(regSet, subreg_def.Substring(0, index)); } else { if (line.StartsWith("/**") && (line.Contains("Bit definition") || line.Contains("Bits definition"))) { if (cfg.IsBlockDefinitionIgnored(line)) insideIgnoredBlock = true; else errors.AddError(new RegisterParserErrors.BadBitDefinition { LineContents = line, LineNumber = nextLine - 1, FileName = fileName }); } if (line.StartsWith("#define") && line.Contains("0x") && !line.Contains("CLEAR_REG") && !line.Contains("USB_EP") && !line.Contains("FLASH_FKEY") && !line.Contains("FLASH_KEY") && !line.Contains("EXTI_EMR") && !line.Contains("FLASH_OPTKEY") && !line.Contains("(USB_BASE +") && !line.Contains("RTC_BKP_NUMBER") && !line.Contains("USB_ISTR") && !line.Contains("USB_LPMCSR") && !line.Contains("USB_DADDR") && !line.Contains("USB_BASE") && !line.Contains("USB_CNTR") && !line.Contains("USB_BCDR") && !line.Contains("USB_FNR") && !line.Contains("USB_PMAADDR") && !line.Contains("define HRTIM_") //Not much formal system in comments to parse. Currently ignoring. ) { if (result.Count > 0 && !insideIgnoredBlock) errors.AddError(new RegisterParserErrors.BadSubregisterDefinition { FileName = fileName, LineContents = line, LineNumber = nextLine - 1 }); } continue; } if (thisReg.RegName.Contains("/")) { int idx = thisReg.RegName.IndexOf('/'); thisReg = new RegisterID(thisReg.SetName, thisReg.RegName.Substring(0, idx).TrimEnd('1', '2', '3', '4')); } insideIgnoredBlock = false; //Apply name adjustment rules if ((thisReg.SetName == "DMA") && ((thisReg.RegName.Substring(0, thisReg.RegName.Length - 1) == "CCR") || (thisReg.RegName.Substring(0, thisReg.RegName.Length - 1) == "CNDTR") || (thisReg.RegName.Substring(0, thisReg.RegName.Length - 1) == "CPAR") || (thisReg.RegName.Substring(0, thisReg.RegName.Length - 1) == "CMAR")))// Header BUG: DMA_Channel defs not DMA defs thisReg = new RegisterID("DMA_Channel", thisReg.RegName.Substring(0, thisReg.RegName.Length - 1)); else { foreach (var rule in cfg.RegisterSetRenameRules) { if (rule.Apply(ref thisReg)) break; } } var subregisters = new List<HardwareSubRegister>(); for (;;) { if (nextLine >= lines.Length) break; line = lines[nextLine++]; foreach (var patch in cfg.SubregisterLinePatches) if (patch.Apply(ref line)) break; string subreg_name = ""; string reg_type = ""; string address_offset = ""; bool aParseOk = false; m = bit_def_regex.Match(line); if (!m.Success) { m = Regex.Match(line, @"#define[ \t]+([\w]+)[ \t]+[\(]?([\w]+)[\)]?"); if (m.Success && !m.Groups[1].Value.EndsWith("_Pos") && !m.Groups[1].Value.EndsWith("_Msk") && !line.Contains("<<")) { subreg_name = m.Groups[1].Value; if (subreg_name == "RTC_BKP_NUMBER") continue; reg_type = "uint32_t"; if (m.Groups[2].Value.StartsWith("0x")) { address_offset = m.Groups[2].Value.Replace("U", "");//#define GPIO_OTYPER_OT_0 (0x00000001U) aDefPosDict[m.Groups[1].Value] = UInt32.Parse(address_offset.Replace("x", ""), System.Globalization.NumberStyles.AllowHexSpecifier); } else { if (aDefPosDict.ContainsKey(m.Groups[2].Value)) { address_offset = FormatToHex(aDefPosDict[m.Groups[2].Value]); // for Legacy defines */ aDefPosDict[m.Groups[1].Value] = aDefPosDict[m.Groups[2].Value]; } else if (Regex.IsMatch(m.Groups[2].Value, "(0x[0-9A-FU]+)")) aDefPosDict.Add(m.Groups[1].Value, (uint)ParseHex(m.Groups[2].Value)); else { Console.WriteLine("No Hex value:{0}, : {1}", m.Groups[1].Value, m.Groups[2].Value); continue; } } aParseOk = true; } } else { subreg_name = m.Groups[1].Value; reg_type = m.Groups[2].Value; address_offset = m.Groups[3].Value; if (!aDefPosDict.ContainsKey(m.Groups[1].Value)) aDefPosDict.Add(m.Groups[1].Value, (uint)ParseHex(m.Groups[3].Value)); aParseOk = true; } if (aParseOk) { string shortSubregName; if (cfg.IsSubregisterIgnored(subreg_name)) continue; //Checks to see if any known values were missed from the above filters if (subreg_name.EndsWith("_RST") || subreg_name.EndsWith("HSI") || subreg_name.EndsWith("HSE") || subreg_name.EndsWith("LSI") || subreg_name.EndsWith("MSI") || subreg_name.EndsWith("PLL") || subreg_name.EndsWith("_NOCLOCK") || subreg_name.EndsWith("_SYSCLK") || subreg_name.EndsWith("KEY") ) { if (subreg_name != "MACTMR_CR_EN" && subreg_name != "MACTMR_CR_RST" && subreg_name != "ADC_DMACR_RST" && subreg_name != "RTC_WPR_KEY" && subreg_name != "IWDG_KR_KEY" && subreg_name != "SCB_AIRCR_VECTKEY" && subreg_name != "HASH_CR_LKEY" && subreg_name != "WDG_KR_KEY" && !subreg_name.StartsWith("RCC_CFGR_") && subreg_name != "FLASH_OPTR_SRAM2_RST") { throw new Exception("Potential missed known subregister value!"); } } int offset, size; try { ExtractFirstBitAndSize(ParseHex(address_offset), out size, out offset); } catch(Exception ex) { errors.AddError(new RegisterParserErrors.BitmaskNotSequential { FileName = fileName, LineContents = line, LineNumber = nextLine - 1 }); continue; } string desc = m.Groups[6].Value.TrimEnd(); if (subreg_name.StartsWith(thisReg.SubregisterPrefix)) shortSubregName = subreg_name.Substring(thisReg.SubregisterPrefix.Length); else { if (cfg.IsMismatchingSubregisterIgnored(subreg_name)) continue; if (!cfg.ApplySubregisterRenameRules(ref thisReg, subreg_name, out shortSubregName)) { errors.AddError(new RegisterParserErrors.UnexpectedSubregisterName { FileName = fileName, LineContents = line, LineNumber = nextLine - 1, SubregName = subreg_name }); continue; } } if (subregisters.Find(x => ((x.Name == shortSubregName) && (x.FirstBit == offset) && (x.SizeInBits == size))) != null) { Debug.WriteLine("Duplicate subregister not added: " + thisReg.SubregisterPrefix + shortSubregName); } else { subregisters.Add(new HardwareSubRegister { Name = shortSubregName, SizeInBits = size, FirstBit = offset, }); } } else { // if (line.StartsWith("#define") && line.Contains("0x") && !line.Contains("CLEAR_REG")) if (line.StartsWith("#define") && line.Contains("0x") && !line.Contains("CLEAR_REG") && !line.Contains("_Pos")) errors.AddError(new RegisterParserErrors.BadSubregisterDefinition { FileName = fileName, LineContents = line, LineNumber = nextLine - 1 }); else if (line.Contains("/* USB Device General registers */")) break; else if (line.StartsWith("/*******") || line.Contains("Bit definition") || line.StartsWith("/*!<Common registers */")) break; else { var m1 = Regex.Match(line, @"#define[ \t]+([\w]+_Pos)[ \t]+\(([0-9A-Fa-f]+)U\)"); if (m1.Success) aDefPosDict[m1.Groups[1].Value] = UInt32.Parse(m1.Groups[2].Value); else { m1 = Regex.Match(line, @"#define[ \t]+([\w]+)[ \t]+\(0x([0-9A-Fa-fx]+)U << ([\w]+)\)"); if (m1.Success) { UInt32 aValueMask = UInt32.Parse(m1.Groups[2].Value, System.Globalization.NumberStyles.AllowHexSpecifier); aValueMask = aValueMask << (int)aDefPosDict[m1.Groups[3].Value]; aDefPosDict[m1.Groups[1].Value] = aValueMask; } } } } } result[thisReg.ToString()] = subregisters; subregisters = new List<HardwareSubRegister>(); nextLine--; } //Remove useless subregisters that just define a numbered bit of another subregister value Regex numbered_name_regex = new Regex(@"(.*)_[0-9]+"); foreach (var list in result.Values) { for (int i = 0; i < list.Count;i++ ) { var element = list[i]; var m = numbered_name_regex.Match(element.Name); if (m.Success && (list.Find(x => (x.Name == m.Groups[1].Value)) != null) && (element.SizeInBits == 1)) { //Debug.WriteLine("Removed bit definition " + element.Name); list.Remove(element); i--; } } } return result; }