[#60671] CreationDriver: Accept alternative parameter names specified in NameAlias attributes
diff --git a/src/Renode/PlatformDescription/CreationDriver.cs b/src/Renode/PlatformDescription/CreationDriver.cs
index 833ef94..4e5900f 100644
--- a/src/Renode/PlatformDescription/CreationDriver.cs
+++ b/src/Renode/PlatformDescription/CreationDriver.cs
@@ -663,14 +663,14 @@
             for(var i = 0; i < parameters.Length; i++)
             {
                 var parameter = parameters[i];
-                var attribute = attributes.SingleOrDefault(x => x.Name == parameter.Name);
+                var attribute = attributes.SingleOrDefault(x => ParameterNameMatches(x.Name, parameter, silent: true));
                 if(attribute == null)
                 {
                     FillDefaultParameter(ref parameterValues[i], parameter);
                     continue;
                 }
 
-                if(TryConvertSimpleValue(parameter.ParameterType, attribute.Value, out parameterValues[i]).ResultType == ConversionResultType.ConversionSuccessful)
+                if(TryConvertSimpleValue(parameter.ParameterType, attribute.Value, out parameterValues[i], silent: true).ResultType == ConversionResultType.ConversionSuccessful)
                 {
                     continue;
                 }
@@ -1282,7 +1282,7 @@
             return ConversionResult.Success;
         }
 
-        private ConversionResult TryConvertSimpleValue(Type expectedType, Value value, out object result)
+        private ConversionResult TryConvertSimpleValue(Type expectedType, Value value, out object result, bool silent = false)
         {
             result = null;
 
@@ -1329,16 +1329,27 @@
                 {
                     return new ConversionResult(ConversionResultType.ConversionUnsuccesful, ParsingError.TypeMismatch, string.Format(TypeMismatchMessage, expectedType));
                 }
-                var namespaceAndType = expectedType.Namespace.Split('.').Concat(new[] { expectedType.Name });
-                var givenReversedTypeAndNamespace = enumValue.TypeAndReversedNamespace;
 
-                // zip compares elements of the namespace from the end one by one and looks for the first difference
-                var error = givenReversedTypeAndNamespace.Zip(namespaceAndType.Reverse(), (first, second) => first != second ? Tuple.Create(first, second) : null).FirstOrDefault(x => x != null);
-                if(error != null)
+                // Compare types first as enum's type may use an alias
+                if(!TypeNameMatches(enumValue.TypeName, expectedType, silent))
                 {
                     return new ConversionResult(ConversionResultType.ConversionUnsuccesful, ParsingError.EnumMismatch,
-                                                $"Enum namespace or type mismatch, expected '{error.Item2}' instead of '{error.Item1}'.");
+                                                $"Enum type mismatch, expected '{expectedType.Name}' instead of '{enumValue.TypeName}'.");
                 }
+
+                var expectedNamespace = expectedType.Namespace.Split('.');
+                var givenNamespace = enumValue.ReversedNamespace;
+
+                // Compare namespaces
+                foreach(var names in givenNamespace.Zip(expectedNamespace.Reverse(), (first, second) => Tuple.Create(first, second)))
+                {
+                    if(names.Item1 != names.Item2)
+                    {
+                        return new ConversionResult(ConversionResultType.ConversionUnsuccesful, ParsingError.EnumMismatch,
+                                                    $"Enum namespace mismatch, expected '{names.Item2}' instead of '{names.Item1}'.");
+                    }
+                }
+
                 if(!SmartParser.Instance.TryParse(enumValue.Value, expectedType, out result))
                 {
                     return new ConversionResult(ConversionResultType.ConversionUnsuccesful, ParsingError.EnumMismatch,
@@ -1407,7 +1418,7 @@
 
                 foreach(var argument in ctor.GetParameters())
                 {
-                    var correspondingAttribute = attributes.SingleOrDefault(x => x.Name == argument.Name);
+                    var correspondingAttribute = attributes.SingleOrDefault(x => ParameterNameMatches(x.Name, argument));
                     if(correspondingAttribute == null)
                     {
                         object defaultValue = null;
@@ -1529,6 +1540,36 @@
             return false;
         }
 
+        private bool ParameterNameMatches(string given, ParameterInfo info, bool silent = false)
+        {
+            return NameOrAliasMatches(given, info.Name, "parameter", info.GetCustomAttribute<NameAliasAttribute>(), silent);
+        }
+
+        private bool TypeNameMatches(string given, Type type, bool silent = false)
+        {
+            return NameOrAliasMatches(given, type.Name, "type", type.GetCustomAttribute<NameAliasAttribute>(), silent);
+        }
+
+        private bool NameOrAliasMatches(string given, string name, string typeClass, NameAliasAttribute alias, bool silent = false)
+        {
+            if(given == name)
+            {
+                return true;
+            }
+
+            if(alias != null && alias.Name == given)
+            {
+                if(!silent && alias.WarnOnUsage)
+                {
+                    Logger.Log(LogLevel.Warning, "Using alias '{0}' for {1} '{2}'", alias.Name, typeClass, name);
+                }
+
+                return true;
+            }
+
+            return false;
+        }
+
         private void HandleInternalError(IWithPosition failingObject = null,
             [CallerMemberName] string callingMethod = "",
             [CallerFilePath] string callingFilePath = "",
diff --git a/src/Renode/PlatformDescription/Syntax/EnumValue.cs b/src/Renode/PlatformDescription/Syntax/EnumValue.cs
index 1e4b97d..348c6d7 100644
--- a/src/Renode/PlatformDescription/Syntax/EnumValue.cs
+++ b/src/Renode/PlatformDescription/Syntax/EnumValue.cs
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2010-2018 Antmicro
+// Copyright (c) 2010-2024 Antmicro
 //
 // This file is licensed under the MIT License.
 // Full license text is available in 'licenses/MIT.txt'.
@@ -22,7 +22,8 @@
                 nameSpaceAndType.Push(element);
             }
             Value = nameSpaceAndType.Pop();
-            TypeAndReversedNamespace = nameSpaceAndType;
+            TypeName = nameSpaceAndType.Pop();
+            ReversedNamespace = nameSpaceAndType;
         }
 
         public override string ToString()
@@ -32,10 +33,11 @@
 
         public string ToShortString()
         {
-            return TypeAndReversedNamespace.Reverse().Concat(new[] { Value }).Aggregate((x, y) => x + '.' + y);
+            return ReversedNamespace.Reverse().Concat(new[] { TypeName, Value }).Aggregate((x, y) => x + '.' + y);
         }
 
-        public IEnumerable<string> TypeAndReversedNamespace { get; private set; }
+        public IEnumerable<string> ReversedNamespace { get; private set; }
         public string Value { get; private set; }
+        public string TypeName { get; }
     }
 }