public static HardwareRegisterSet[] GeneratePeripheralRegisterDefinitionsFromHeaderFile(string peripheralHeaderFile, CortexCore core, ParseReportWriter reportWriter) { using (var handle = reportWriter.BeginParsingFile(peripheralHeaderFile)) { var parser = new HeaderFileParser(peripheralHeaderFile, handle); var parsedFile = parser.ParseHeaderFile(); if (core == CortexCore.M4 && parsedFile.PreprocessorMacros.TryGetValue("HSEM_COMMON", out var hsem)) { /* * This is the only relevant use of #ifdef in the STM32 headers: * #if defined(CORE_CM4) #define HSEM_COMMON ((HSEM_Common_TypeDef *) (HSEM_BASE + 0x110UL)) #else #define HSEM_COMMON ((HSEM_Common_TypeDef *) (HSEM_BASE + 0x100UL)) #endif * * Currently, instead of fully parsing it, we just patch it manually for the M4 core. */ for (int i = 0; i < hsem.Value.Length; i++) { if (hsem.Value[i].Value == "0x100UL") { hsem.Value[i].Value = "0x110UL"; } } } var peripherals = LocateStructsReferencedInBaseExpressions(parsedFile); var subregisterParser = new PeripheralSubregisterParser(handle); subregisterParser.AttachSubregisterDefinitions(parsedFile, peripherals); List <HardwareRegisterSet> sets = new List <HardwareRegisterSet>(); string coreFile = $@"../../../CoreReg/OutCorexx/core_{core}.xml"; if (core != CortexCore.Invalid) { if (!File.Exists(coreFile)) { throw new Exception("Unknown ARM core: " + core); } sets.Add(XmlTools.LoadObject <HardwareRegisterSet>(coreFile)); } foreach (var peripheral in peripherals) { sets.Add(new HardwareRegisterSet { Registers = peripheral.Registers.Select(r => r.ToHardwareRegister(peripheral)).ToArray(), UserFriendlyName = peripheral.Name, ExpressionPrefix = peripheral.Name + "->", }); } return(sets.ToArray()); } }
internal void CompareRegisterSets(PeripheralRegisterGenerator2.DiscoveredPeripheral[] peripherals, HardwareRegisterSet[] existingSets, string mcu) { Dictionary <ulong, HardwareRegister> oldRegisters = new Dictionary <ulong, HardwareRegister>(); foreach (var set in existingSets) { if (set.UserFriendlyName.StartsWith("ARM ")) { continue; } foreach (var reg in set.Registers) { oldRegisters[HeaderFileParser.ParseMaybeHex(reg.Address)] = reg; } } Dictionary <ulong, HardwareRegister> remainingOldRegisters = new Dictionary <ulong, HardwareRegister>(oldRegisters); _Log.WriteLine($"--- {mcu} ---"); foreach (var set in peripherals) { foreach (var reg in set.Registers) { _RegistersTotal++; var addr = set.ResolvedBaseAddress + reg.Offset; if (oldRegisters.TryGetValue(addr, out var oldReg)) { remainingOldRegisters.Remove(addr); if (oldReg.SizeInBits != reg.SizeInBytes * 8 || oldReg.ReadOnly != reg.IsReadOnly) { _MismatchingRegisters++; } var newSubregisters = reg.OriginalField?.Subregisters; _TotalOldSubregisters += oldReg.SubRegisters?.Length ?? 0; _TotalNewSubregisters += newSubregisters.Count; Dictionary <int, HardwareSubRegister> oldSubregistersByOffset = new Dictionary <int, HardwareSubRegister>(); foreach (var sr in oldReg.SubRegisters ?? new HardwareSubRegister[0]) { oldSubregistersByOffset[sr.FirstBit] = sr; } int oldSubregCount = oldSubregistersByOffset.Count; foreach (var sr in newSubregisters) { int firstBit = sr.Subregister.Offset; if (oldSubregistersByOffset.TryGetValue(firstBit, out var val)) { oldSubregistersByOffset.Remove(firstBit); } else { _SubregistersAdded++; } } _SubregistersRemoved += oldSubregistersByOffset.Count; if (oldSubregCount > 0) { _OldRegistersWithSubregisters++; if (newSubregisters.Count == 0) { _OldRegistersWithSubregistersGone++; _Log.WriteLine($"{set.Name}->{reg.Name}"); _UniqueRegisters.Add($"{set.Name}->{reg.Name}"); //Debug.WriteLine($"{set.Name}->{reg.Name}"); } } if (newSubregisters.Count > 0) { _NewRegistersWithSubregisters++; } } else { _RegistersAdded++; } } } _RegistersRemoved += remainingOldRegisters.Count; }