1 //
2 // Copyright (c) 2010-2023 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using Microsoft.Scripting.Hosting;
10 using Antmicro.Migrant;
11 using Antmicro.Migrant.Hooks;
12 using Antmicro.Renode.Peripherals.Bus;
13 using Antmicro.Renode.Core;
14 using Antmicro.Renode.Logging;
15 using Antmicro.Renode.Exceptions;
16 
17 namespace Antmicro.Renode.Hooks
18 {
19     public class BusPeripheralsHooksPythonEngine : PythonEngine
20     {
BusPeripheralsHooksPythonEngine(IBusController sysbus, IBusPeripheral peripheral, string readScript = null, string writeScript = null)21         public BusPeripheralsHooksPythonEngine(IBusController sysbus, IBusPeripheral peripheral, string readScript = null, string writeScript = null)
22         {
23             Peripheral = peripheral;
24             Sysbus = sysbus;
25             ReadScript = readScript;
26             WriteScript = writeScript;
27 
28             InnerInit();
29 
30             if (WriteScript != null)
31             {
32                 WriteHook = new Func<ulong, long, ulong>((valueToWrite, offset) =>
33                     {
34                         Scope.SetVariable("value", valueToWrite);
35                         Scope.SetVariable("offset", offset);
36                         Execute(writeCode, error =>
37                         {
38                             Sysbus.Log(LogLevel.Error, "Python runtime error: {0}", error);
39                         });
40                         return (ulong)Scope.GetVariable("value");
41                     });
42             }
43 
44             if (ReadScript != null)
45             {
46                 ReadHook = new Func<ulong, long, ulong>((readValue, offset) =>
47                     {
48                         Scope.SetVariable("value", readValue);
49                         Scope.SetVariable("offset", offset);
50                         Execute(readCode, error =>
51                         {
52                             Sysbus.Log(LogLevel.Error, "Python runtime error: {0}", error);
53                         });
54                         return (ulong)Scope.GetVariable("value");
55                     });
56             }
57         }
58 
59         [PostDeserialization]
InnerInit()60         private void InnerInit()
61         {
62             Scope.SetVariable("self", Peripheral);
63             Scope.SetVariable("sysbus", Sysbus);
64             Scope.SetVariable(Machine.MachineKeyword, Sysbus.Machine);
65 
66             if(ReadScript != null)
67             {
68                 var source = Engine.CreateScriptSourceFromString(ReadScript);
69                 readCode = Compile(source);
70             }
71             if(WriteScript != null)
72             {
73                 var source = Engine.CreateScriptSourceFromString(WriteScript);
74                 writeCode = Compile(source);
75             }
76         }
77 
78         public Func<ulong, long, ulong> WriteHook { get; private set; }
79         public Func<ulong, long, ulong> ReadHook { get; private set; }
80 
81         [Transient]
82         private CompiledCode readCode;
83         [Transient]
84         private CompiledCode writeCode;
85 
86         private readonly string ReadScript;
87         private readonly string WriteScript;
88         private readonly IBusPeripheral Peripheral;
89         private readonly IBusController Sysbus;
90     }
91 }
92 
93