예제 #1
0
        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());
            }
        }
예제 #2
0
        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;
        }