Пример #1
0
        static void ProcessRegister(XmlElement reg, List <HardwareRegister> registers, string prefix, uint baseAddr, uint?defaultRegisterSize)
        {
            string regName     = reg.SelectSingleNode("name").InnerText;
            string access      = reg.SelectSingleNode("access")?.InnerText;
            uint   addrOff     = ParseScaledNonNegativeInteger(reg.SelectSingleNode("addressOffset").InnerText);
            var    regSizeProp = reg.SelectSingleNode("size");
            uint   regSize     = regSizeProp != null?ParseScaledNonNegativeInteger(regSizeProp.InnerText) : (defaultRegisterSize ?? 32);

            int    count = 1, step = 0;
            string dim = reg.SelectSingleNode("dim")?.InnerText;

            if (dim != null)
            {
                count = (int)ParseScaledNonNegativeInteger(dim);
                step  = (int)ParseScaledNonNegativeInteger(reg.SelectSingleNode("dimIncrement").InnerText);
                if (step * 8 != (int)regSize)
                {
                    throw new Exception("Mismatching array step for " + regName);
                }
            }

            for (int i = 0; i < count; i++)
            {
                List <HardwareSubRegister> subregs = new List <HardwareSubRegister>();
                foreach (XmlElement fld in reg.SelectNodes("fields/field"))
                {
                    var subreg = new HardwareSubRegister
                    {
                        Name = fld.SelectSingleNode("name").InnerText
                    };

                    var   bitRange = fld.SelectSingleNode("bitRange")?.InnerText;
                    Match m;
                    if (bitRange != null)
                    {
                        int bit1, bit2;

                        if ((m = rgBitRange.Match(bitRange)).Success)
                        {
                            bit1 = int.Parse(m.Groups[1].Value);
                            bit2 = int.Parse(m.Groups[2].Value);
                        }
                        else if ((m = rgSingleBit.Match(bitRange)).Success)
                        {
                            bit1 = bit2 = int.Parse(m.Groups[1].Value);
                        }
                        else
                        {
                            continue;
                        }

                        int lsb = Math.Min(bit1, bit2);
                        int msb = Math.Max(bit1, bit2);

                        subreg.FirstBit   = lsb;
                        subreg.SizeInBits = msb - lsb + 1;
                    }
                    else
                    {
                        var lsb      = fld.SelectSingleNode("lsb")?.InnerText ?? fld.SelectSingleNode("bitOffset")?.InnerText;
                        var msb      = fld.SelectSingleNode("msb")?.InnerText;
                        var bitWidth = fld.SelectSingleNode("bitWidth")?.InnerText;

                        if (lsb == null)
                        {
                            continue;
                        }
                        subreg.FirstBit = (int)ParseScaledNonNegativeInteger(lsb);

                        if (msb != null)
                        {
                            subreg.SizeInBits = (int)ParseScaledNonNegativeInteger(msb) - subreg.FirstBit + 1;
                        }
                        else if (bitWidth != null)
                        {
                            subreg.SizeInBits = (int)ParseScaledNonNegativeInteger(bitWidth);
                        }
                        else
                        {
                            continue;
                        }
                    }

                    XmlElement vals = (XmlElement)fld.SelectSingleNode("enumeratedValues");
                    var        numOfAddedKnownValues = 0;
                    Regex      rgTrivialKnownValue   = new Regex("^value[0-9]+$");
                    if (vals != null && subreg.SizeInBits > 1 && subreg.SizeInBits != 32)
                    {
                        if (subreg.SizeInBits > 8)
                        {
                            Console.WriteLine(string.Format("Warning: suspiciously large register with known values: {0} ({1} bits)", subreg.Name, subreg.SizeInBits));
                        }
                        else
                        {
                            KnownSubRegisterValue[] values  = new KnownSubRegisterValue[1 << subreg.SizeInBits];
                            bool foundNonTrivialDefinitions = false;
                            foreach (XmlElement ev in vals)
                            {
                                var knownValueProp = ev.SelectSingleNode("value");
                                if (DoNotCareBits(knownValueProp.InnerText))
                                {
                                    continue;
                                }
                                var knownValueIndex = (int)ParseScaledNonNegativeInteger(knownValueProp.InnerText);
                                var knowValueName   = ev.SelectSingleNode("name").InnerText;
                                if (IsUserFriendlyName(knowValueName))
                                {
                                    values[knownValueIndex] = new KnownSubRegisterValue {
                                        Name = knowValueName
                                    };
                                    ++numOfAddedKnownValues;
                                    if (!rgTrivialKnownValue.IsMatch(knowValueName))
                                    {
                                        foundNonTrivialDefinitions = true;
                                    }
                                }
                            }

                            if (numOfAddedKnownValues > 0 && foundNonTrivialDefinitions)
                            {
                                int found = 0;
                                for (int j = 0; j < values.Length; j++)
                                {
                                    if (values[j] == null)
                                    {
                                        values[j] = new KnownSubRegisterValue {
                                            Name = string.Format("Unknown (0x{0:x})", j)
                                        }
                                    }
                                    ;
                                    else
                                    {
                                        found++;
                                    }
                                }

                                double utilization = (double)found / values.Length;
                                if (utilization > 0.5 || values.Length < 16)
                                {
                                    subreg.KnownValues = values;
                                }
                            }
                        }
                    }
                    subregs.Add(subreg);
                }


                registers.Add(new HardwareRegister
                {
                    Address      = string.Format("0x{0:x8}", baseAddr + addrOff + i * step),
                    Name         = prefix + regName.Replace("%s", i.ToString()),
                    ReadOnly     = access == "read-only",
                    SubRegisters = subregs.Count == 0 ? null : subregs.ToArray(),
                    SizeInBits   = (int)regSize
                });
            }
        }
Пример #2
0
        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();
        }