sim:config: use upstream sel4 extensions

Change-Id: I31ef32a5c7687a35d1f479975c8be7e6fdec5a30
diff --git a/gdbscript.py b/gdbscript.py
deleted file mode 100755
index b4ed8ac..0000000
--- a/gdbscript.py
+++ /dev/null
@@ -1,303 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import os.path
-from glob import glob
-
-
-def source(callable):
-    """Convenience decorator for sourcing gdb commands"""
-    callable()
-    return callable
-
-
-@source
-class seL4(gdb.Command):
-    """Utility functions for debugging seL4 applications"""
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4', gdb.COMMAND_USER, prefix=True)
-
-
-@source
-class seL4BreakpointsEnabled(gdb.Command):
-    """Enable or disable breakpoints (disabled by default)"""
-
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4 breakpoints-enabled', gdb.COMMAND_STATUS)
-
-    def complete(self, text, words):
-        return [c for c in ['True', 'False'] if c.startswith(text)]
-
-    def invoke(self, arg, from_tty):
-        if arg:
-            breakpoints_enabled(arg)
-        else:
-            print(breakpoints_enabled())
-
-
-@source
-class seL4Threads(gdb.Command):
-    """Lists all seL4 threads"""
-
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4 threads', gdb.COMMAND_STATUS)
-
-    def invoke(self, arg, from_tty):
-        print('\n'.join(get_threads()))
-
-
-@source
-class seL4Thread(gdb.Command):
-    """Returns current seL4 thread"""
-
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4 thread', gdb.COMMAND_STATUS)
-
-    def invoke(self, arg, from_tty):
-        print(get_current_thread())
-
-@source
-class seL4WaitForThread(gdb.Command):
-    """Waits for given thread to be avaiable"""
-
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4 wait-for-thread', gdb.COMMAND_BREAKPOINTS)
-
-    def complete(self, text, word):
-        return list(thread for thread in get_threads() if thread.startswith(text))
-
-    def invoke(self, arg, from_tty):
-        gdb.execute('mon seL4 WaitForThread "{}"'.format(arg))
-        gdb.execute('continue')
-
-
-@source
-class seL4SwitchSymbols(gdb.Command):
-    """Forcibly switches symbols to ones of the given component
-
-    sel4 switch-symbols [component]
-
-    Forcibly sets symbol-file to file corresponding to given component.
-    If no comonent name is given or thread is "default" then default
-    binary is loaded instead."""
-
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4 switch-symbols', gdb.COMMAND_FILES)
-
-    def complete(self, text, word):
-        global BINARIES
-
-        components = list(BINARIES.keys())
-        components.append('default')
-        return list(component for component in components if component.startswith(text))
-
-    def invoke(self, arg, from_tty):
-        if not arg or arg == 'default':
-            switch_symbols(verbose=True)
-        else:
-            switch_symbols(arg, fallback=False, verbose=True)
-
-
-@source
-class seL4Break(gdb.Command):
-    """Creates breakpoint
-
-    sel4 break thread [address]
-
-    Creates breakpoint in <thread> on optional <address>
-    If no address is given, the breakpoint will be set on
-    first address after context-switch"""
-
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4 break', gdb.COMMAND_BREAKPOINTS)
-
-    def complete(self, text, word):
-        words = text.split(' ')
-        if not text or len(words) <= 1:
-            return list(thread for thread in get_threads() if thread.startswith(word))
-        elif len(words) == 2:
-            return gdb.COMPLETE_SYMBOL
-        else:
-            return gdb.COMPLETE_NONE
-
-    def invoke(self, arg, from_tty):
-        args = arg.split(' ')
-
-        if len(args) < 1 or not args[0]:
-            raise gdb.GdbError("sel4 break: thread argument is required")
-
-        thread = args[0] if len(args) >= 1 else None
-        symbol_name = args[1] if len(args) >= 2 else None
-
-        if symbol_name:
-            symbol, _ = gdb.lookup_symbol(symbol_name)
-            address = int(symbol.value().address)
-            gdb.execute('mon seL4 SetBreakpoint "{}" {}'.format(thread, hex(address)))
-        else:
-            gdb.execute('mon seL4 SetBreakpoint "{}"'.format(thread))
-
-
-@source
-class seL4Delete(gdb.Command):
-    """Removes breakpoint
-
-    sel4 delete thread [address]
-
-    Removes given breakpoint. If no address is given, the context-switch
-    breakpoint is removed"""
-
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4 delete', gdb.COMMAND_BREAKPOINTS)
-
-    def complete(self, text, word):
-        words = text.split(' ')
-        if not text or len(words) <= 1:
-            return list(thread for thread in get_threads() if thread.startswith(word))
-        elif len(words) == 2:
-            breakpoints = get_breakpoints(words[0])
-            lines = breakpoints.split('\n')[3:][:-1]
-            completions = []
-            for line in lines:
-                values = line.split('|')
-                thread = values[1].strip()
-
-                if words[0] not in thread:
-                    continue
-
-                if 'null' in values[2]:
-                    continue
-
-                address = values[2].strip();
-                if address.startswith(word):
-                    completions.append(address)
-            return completions
-        else:
-            return gdb.COMPLETE_NONE
-
-    def invoke(self, arg, from_tty):
-        args = arg.split(' ')
-
-        if len(args) < 1 or not args[0]:
-            raise gdb.GdbError("sel4 delete: thread argument is required")
-
-        thread = args[0] if len(args) >= 1 else None
-        address = args[1] if len(args) >= 2 else None
-
-        if address:
-            gdb.execute('mon seL4 RemoveBreakpoint "{}" {}'.format(thread, address))
-        else:
-            gdb.execute('mon seL4 RemoveBreakpoint "{}"'.format(thread))
-
-
-@source
-class seL4DeleteAll(gdb.Command):
-    """Removes all breakpoints assigned to thread
-
-    sel4 delete-all thread"""
-
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4 delete-all', gdb.COMMAND_BREAKPOINTS)
-
-    def complete(self, text, word):
-        return list(thread for thread in get_threads() if thread.startswith(text))
-
-    def invoke(self, arg, from_tty):
-        gdb.execute('mon seL4 RemoveBreakpoint "{}" 0x0 True'.format(arg))
-
-
-@source
-class seL4ListBreakpoints(gdb.Command):
-    """Lists all breakpoints
-
-    sel4 list-breakpoints [thread]
-    """
-
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4 list-breakpoints', gdb.COMMAND_BREAKPOINTS)
-
-    def complete(self, text, word):
-        return list(thread for thread in get_threads() if thread.startswith(text))
-
-    def invoke(self, arg, from_tty):
-        print(get_breakpoints())
-
-
-@source
-class seL4Ready(gdb.Command):
-    """Returns ready state of seL4 extensions"""
-
-    def __init__(self):
-        super(self.__class__, self).__init__('sel4 ready', gdb.COMMAND_STATUS)
-
-    def invoke(self, arg, from_tty):
-        gdb.execute('mon seL4 Ready')
-
-
-@source
-def find_binaries():
-    global BINARIES, DEFAULT_BINARY
-    BINARIES = {}
-
-    out = os.environ['OUT']
-    kata_path = os.path.join(out, 'kata', 'riscv32-unknown-elf', 'debug')
-    DEFAULT_BINARY = os.path.join(kata_path, 'kernel', 'kernel.elf')
-
-    images_path = os.path.join(kata_path, '*.instance.bin')
-    for image_path in glob(images_path):
-        image_name = os.path.basename(image_path).split('.instance.bin')[0]
-        BINARIES[image_name] = image_path
-
-    BINARIES['rootserver'] = os.path.join(kata_path, 'capdl-loader')
-
-
-def get_breakpoints(thread=None):
-    if not thread:
-        breakpoints = gdb.execute('mon seL4 GetBreakpoints', to_string=True).strip()
-    else:
-        breakpoints = gdb.execute('mon seL4 GetBreakpoints \"{}\"'.format(thread), to_string=True).strip()
-    return breakpoints
-
-
-def get_current_thread():
-    return gdb.execute('mon seL4 CurrentThread', to_string=True).strip()
-
-
-def get_threads():
-    threads = ', '.join(gdb.execute('mon seL4 Threads', to_string=True).strip().split('\n')[1:-1])
-    return [thread.strip() for thread in threads.split(',') if thread.strip()]
-
-
-def breakpoints_enabled(value=None):
-    if value:
-        gdb.execute('mon seL4 BreakpointsEnabled {}'.format(value))
-    else:
-        return gdb.execute('mon seL4 BreakpointsEnabled', to_string=True).strip()
-
-
-def switch_symbols(thread=None, fallback=True, verbose=False):
-    global BINARIES, DEFAULT_BINARY
-
-    if thread is None:
-        gdb.execute('symbol-file {}'.format(DEFAULT_BINARY), from_tty=verbose)
-        return
-
-    image_name = next((key for key in BINARIES.keys() if key in thread), None)
-    if image_name is not None:
-        image_path = BINARIES[image_name]
-    elif image_name is None and fallback:
-        image_path = DEFAULT_BINARY
-    else:
-        raise gdb.GdbError("no symbol-file found for thread/component {}".format(thread))
-
-    gdb.execute('symbol-file {}'.format(image_path), from_tty=verbose)
-
-
-def stop_handler(event):
-    if not isinstance(event, gdb.StopEvent):
-        return
-
-    thread = get_current_thread()
-    switch_symbols(thread)
-
-
-gdb.events.stop.connect(stop_handler)
diff --git a/shodan.resc b/shodan.resc
index 9be4dcb..e0f09c9 100644
--- a/shodan.resc
+++ b/shodan.resc
@@ -12,7 +12,7 @@
 include @sim/config/shodan_infrastructure/SmcRiscV32.cs
 include @sim/config/shodan_infrastructure/OpenTitan2_UART.cs
 include @sim/config/shodan_infrastructure/Mailbox.cs
-include @sim/config/shodan_infrastructure/seL4Extensions.cs
+include @sim/renode/tools/sel4_extensions/seL4Extensions.cs
 
 machine LoadPlatformDescription @sim/config/platforms/shodan.repl
 
diff --git a/shodan_infrastructure/seL4Extensions.cs b/shodan_infrastructure/seL4Extensions.cs
deleted file mode 100644
index b4b09c9..0000000
--- a/shodan_infrastructure/seL4Extensions.cs
+++ /dev/null
@@ -1,278 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Antmicro.Renode.Core;
-using Antmicro.Renode.Logging;
-using Antmicro.Renode.Peripherals.CPU;
-using Antmicro.Renode.Peripherals.Bus;
-using Antmicro.Renode.Utilities;
-
-namespace Antmicro.Renode.Debug
-{
-    public static class seL4Extensions
-    {
-        public static void CreateseL4(this RiscV32 @this)
-        {
-            EmulationManager.Instance.CurrentEmulation.ExternalsManager.AddExternal(new seL4(@this), "seL4");
-        }
-    }
-
-    public class seL4 : IExternal
-    {
-        public seL4(RiscV32 cpu)
-        {
-            this.cpu = cpu;
-            this.mapping = new Dictionary<ulong, string>();
-            this.breakpoints = new Dictionary<string, SortedSet<ulong?>>();
-
-            var handleUnknownSyscallAddress = bus.GetSymbolAddress("handleUnknownSyscall");
-            this.cpu.AddHook(handleUnknownSyscallAddress, HandleUnknownSyscall);
-            var idleThreadAddresss = bus.GetSymbolAddress("idle_thread");
-            this.cpu.AddHook(idleThreadAddresss, Finalize);
-        }
-
-        public string CurrentThread()
-        {
-            var tcb = bus.ReadDoubleWord(this.ksCurThreadPhysAddress, context: cpu);
-            if(!mapping.ContainsKey(tcb))
-            {
-                return "default";
-            }
-            return mapping[tcb];
-        }
-
-        public void WaitForThread(string threadName)
-        {
-            pendingThreadName = threadName;
-        }
-
-        public void SetBreakpoint(string threadName, ulong? address = null)
-        {
-            var realThreadName = mapping.Values.Where(thread => thread.Contains(threadName)).FirstOrDefault();
-            if(String.IsNullOrEmpty(realThreadName))
-            {
-                this.Log(LogLevel.Warning, "No thread with name '{0}' found.", threadName);
-                return;
-            }
-
-            if(!breakpoints.ContainsKey(realThreadName))
-            {
-                breakpoints.Add(realThreadName, new SortedSet<ulong?>());
-            }
-
-            if(!breakpoints[realThreadName].Add(address))
-            {
-                this.Log(LogLevel.Warning, "This breakpoint already exists.");
-            }
-        }
-
-        public void RemoveBreakpoint(string threadName, ulong? address = null, bool removeAll = false)
-        {
-            var realThreadName = mapping.Values.Where(thread => thread.Contains(threadName)).FirstOrDefault();
-            if(String.IsNullOrEmpty(realThreadName))
-            {
-                this.Log(LogLevel.Warning, "No thread with name '{0}' found.", threadName);
-                return;
-            }
-
-            if(!breakpoints.ContainsKey(realThreadName))
-            {
-                return;
-            }
-
-            if(removeAll)
-            {
-                foreach(var addr in breakpoints[realThreadName])
-                {
-                    if(addr != null)
-                    {
-                        cpu.RemoveHook(addr.Value, HandleBreakpoint);
-                    }
-                }
-
-                breakpoints.Remove(realThreadName);
-            }
-            else
-            {
-                if(breakpoints[realThreadName].Remove(address) && address != null)
-                {
-                    cpu.RemoveHook(address.Value, HandleBreakpoint);
-                }
-            }
-        }
-
-        public string[,] GetBreakpoints(string threadName = null)
-        {
-            var entries = breakpoints.SelectMany(t => t.Value, (thread, address) => new { Thread = thread.Key, Address = address });
-            if(threadName != null)
-            {
-                entries = entries.Where(x => x.Thread.Contains(threadName));
-            }
-            var table = new Table().AddRow("Thread", "Address");
-            table.AddRows(entries, x => x.Thread, x => x.Address == null ? "null" : "0x{0:X}".FormatWith(x.Address));
-            return table.ToArray();
-        }
-
-        private void HandleUnknownSyscall(ICpuSupportingGdb _cpu, ulong address)
-        {
-            if(cpu.A[0] != DebugThreadNameSyscall)
-            {
-                return;
-            }
-
-            cpu.RemoveHook(address, HandleUnknownSyscall);
-
-            var ksCurThreadAddress = bus.GetSymbolAddress("ksCurThread");
-            var lookupIPCBufferAddress = bus.GetSymbolAddress("lookupIPCBuffer");
-            var lookupCapAndSlotAddress = bus.GetSymbolAddress("lookupCapAndSlot");
-
-            ksCurThreadPhysAddress = cpu.TranslateAddress(ksCurThreadAddress, MpuAccess.Read);
-            cpu.AddHook(lookupCapAndSlotAddress, HandleLookupCapAndSlotAddress);
-            cpu.AddHook(lookupIPCBufferAddress, HandleLookupIPCBuffer);
-        }
-
-        private void Finalize(ICpuSupportingGdb _cpu, ulong address)
-        {
-            cpu.RemoveHook(address, Finalize);
-            Ready = true;
-            this.Log(LogLevel.Info, "Initialization complete.");
-        }
-
-        private void ksCurThreadChanged(ICpuSupportingGdb _cpu, ulong address)
-        {
-            foreach(var addr in breakpoints.Values.SelectMany(v => v).Where(v => v != null))
-            {
-                cpu.RemoveHook(addr.Value, HandleBreakpoint);
-            }
-
-            var thread = CurrentThread();
-            if(!breakpoints.ContainsKey(thread))
-            {
-                return;
-            }
-
-            var tcb = cpu.TranslateAddress((ulong)bus.ReadDoubleWord(this.ksCurThreadPhysAddress, context: cpu) + 0x88, MpuAccess.Read);
-            var pc = bus.ReadDoubleWord(tcb, context: cpu);
-            cpu.AddHook(pc, HandleThreadSwitch);
-        }
-
-        private void HandleThreadSwitch(ICpuSupportingGdb _cpu, ulong address)
-        {
-            cpu.RemoveHook(address, HandleThreadSwitch);
-
-            var thread = CurrentThread();
-            foreach(var addr in breakpoints[thread])
-            {
-                if(addr == null)
-                {
-                    continue;
-                }
-
-                cpu.AddHook(addr.Value, HandleBreakpoint);
-            }
-
-            if(breakpoints[thread].Contains(null))
-            {
-                cpu.Pause();
-                cpu.EnterSingleStepModeSafely(new HaltArguments(HaltReason.Breakpoint, cpu.Id, address, BreakpointType.MemoryBreakpoint), true);
-            }
-        }
-
-        private void HandleBreakpoint(ICpuSupportingGdb _cpu, ulong address)
-        {
-            cpu.Pause();
-            cpu.EnterSingleStepModeSafely(new HaltArguments(HaltReason.Breakpoint, cpu.Id, address, BreakpointType.MemoryBreakpoint), true);
-        }
-
-        private void HandleLookupCapAndSlotAddress(ICpuSupportingGdb _cpu, ulong address)
-        {
-            cpu.RemoveHook(address, HandleLookupCapAndSlotAddress);
-            cpu.AddHook(cpu.RA, HandlePostLookupCapAndSlotAddress);
-        }
-
-        private void HandlePostLookupCapAndSlotAddress(ICpuSupportingGdb _cpu, ulong address)
-        {
-            var luRet = cpu.A[0];
-            var paddr = cpu.TranslateAddress(luRet + 0x4UL, MpuAccess.Read);
-            var underlying = bus.ReadDoubleWord(paddr, context: cpu);
-            currentTCB = underlying & 0xffffff00;
-        }
-
-
-        private void HandleLookupIPCBuffer(ICpuSupportingGdb _cpu, ulong address)
-        {
-            cpu.RemoveHook(address, HandleLookupIPCBuffer);
-            cpu.AddHook(cpu.RA, HandlePostLookupIPCBuffer);
-        }
-
-        private void HandlePostLookupIPCBuffer(ICpuSupportingGdb _cpu, ulong address)
-        {
-            var paddr = cpu.TranslateAddress(cpu.A[0] + 0x4UL, MpuAccess.Read);
-            // NOTE(mwitkowski): 100 bytes is arbitrary
-            var bytes = bus.ReadBytes(paddr, 100, context: cpu)
-                           .TakeWhile(b => b != 0)
-                           .ToArray();
-            var threadName = System.Text.Encoding.ASCII.GetString(bytes);
-
-            if(!mapping.ContainsKey(currentTCB))
-            {
-                mapping.Add(currentTCB, threadName);
-            }
-            else if(threadName.Contains("_control"))
-            {
-                mapping[currentTCB] = threadName;
-            }
-
-            if(pendingThreadName != null && threadName.Contains(pendingThreadName))
-            {
-                pendingThreadName = null;
-                cpu.Pause();
-                cpu.EnterSingleStepModeSafely(new HaltArguments(HaltReason.Breakpoint, cpu.Id, address, BreakpointType.MemoryBreakpoint), true);
-            }
-        }
-
-        public bool BreakpointsEnabled
-        {
-            get
-            {
-                return breakpointsEnabled;
-            }
-            set
-            {
-                if(breakpointsEnabled == value)
-                {
-                    return;
-                }
-
-                breakpointsEnabled = value;
-                var address = bus.GetSymbolAddress("restore_user_context");
-                if(value)
-                {
-                    cpu.AddHook(address, ksCurThreadChanged);
-                }
-                else
-                {
-                    cpu.RemoveHook(address, ksCurThreadChanged);
-                }
-            }
-        }
-
-        public string[] Threads => mapping.Values.ToArray();
-
-        public bool Ready { get; private set; }
-
-        private const uint DebugThreadNameSyscall = 0xffffffef;
-
-        private readonly Dictionary<string, SortedSet<ulong?>> breakpoints;
-        private readonly Dictionary<ulong, string> mapping;
-        private readonly RiscV32 cpu;
-        private SystemBus bus => cpu.Bus;
-
-        private bool breakpointsEnabled;
-        private ulong ksCurThreadPhysAddress;
-        private string pendingThreadName;
-        private ulong currentTCB;
-    }
-}
-