933 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			933 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!doctype html>
 | |
| <html>
 | |
| 
 | |
| <head>
 | |
|     <meta charset="utf-8">
 | |
|     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
 | |
| 
 | |
|     <title>Renode: Easy CI for your Weird Hardware</title>
 | |
| 
 | |
|     <link rel="stylesheet" href="dist/reset.css">
 | |
|     <link rel="stylesheet" href="dist/reveal.css">
 | |
|     <link rel="stylesheet" href="dist/theme/night.css">
 | |
| 
 | |
|     <!-- Theme used for syntax highlighted code -->
 | |
|     <link rel="stylesheet" href="plugin/highlight/monokai.css">
 | |
| </head>
 | |
| 
 | |
| <!--
 | |
| * Emulators are useful tools
 | |
|     - PC emulator (e.g. Docker on Mac, WSL on Linux)
 | |
|     - NES emulator -- fun and games, realtime output
 | |
|         - Also have debugging emulators
 | |
|     - Renode
 | |
| 
 | |
| * Renode Stack
 | |
|     - CPU cores written in C
 | |
|         - arm, i386, ppc, riscv, sparc, xtensa
 | |
|     - Windows, Mac, Linux
 | |
|     - Peripherals and UI written in C#
 | |
|     - Extensible via Python and C#
 | |
|         - Write once. Run anywhere. Using C# to define new peripherals
 | |
| 
 | |
| * Three major users
 | |
|     - Designers of new boards
 | |
|     - Reverse engineering exsisting hardware
 | |
|     - Silicon designers
 | |
| 
 | |
| * Designers of new boards
 | |
|     - One or more chips
 | |
|     - How are they connected?
 | |
|     - What weird hardware exists?
 | |
| 
 | |
|     * Concurrent emulation of multiple devices
 | |
|         - Can connect multiple devices, e.g. via UART, GPIO, SPI, Ethernet, CAN...
 | |
|         - All devices are emulated using the same time source
 | |
|         - Helps to debug timing differences with different processors on a board
 | |
|     
 | |
|     * Board definition format
 | |
|         - Easily define memory layout
 | |
|         - Easily move blocks around
 | |
|         - Only define what's necessary
 | |
|         - You don't need to be perfect, just good enough!
 | |
|     
 | |
|     * Can read SVD files
 | |
| 
 | |
|     * Hardware has Similarities
 | |
|         - Picture of existing register sets
 | |
|         - There are only so many combinations
 | |
|         - Rip. Mix. Burn. Many chips are just copies of one another.
 | |
| 
 | |
|     * Tests in CI
 | |
| 
 | |
| * Reverse engineering existing hardware
 | |
| 
 | |
|     * If it's a supported architecture, it's easy to run code
 | |
|     * LoadBinary and set PC
 | |
|     * Can skip much of the boot ROM
 | |
|     * Attach GDB
 | |
|     * Reproducible makes it easy to test theories
 | |
| 
 | |
| * Developing new Silicon blocks
 | |
| 
 | |
|     * Betrusted hardware
 | |
|         - Create a new design in LiteX / Verilog
 | |
|         - Document the design
 | |
|         - Create a model
 | |
|         - Timing isn't as critical
 | |
| 
 | |
| -->
 | |
| 
 | |
| <body>
 | |
|     <div class="reveal">
 | |
|         <div class="slides">
 | |
|             <section>
 | |
|                 <section>
 | |
|                     <h2>Renode</h2>
 | |
|                     <p>I find it a useful tool. Maybe you will, too!
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>About Me: I Do Weird Hardware</h2>
 | |
|                     <ul>
 | |
|                         <li>Simmel: Contact Tracing with Audio</li>
 | |
|                         <li>Chibitronics: Programming Stickers with Audio</li>
 | |
|                         <li>Novena: Open Source Laptop</li>
 | |
|                         <li>Senoko: Open Source Power Board for Novena</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Hardware with Embedded Software</h2>
 | |
|                     <ul>
 | |
|                         <li>Software needs to be written</li>
 | |
|                         <li class="fragment">Software needs to be <strong>tested</strong></li>
 | |
|                         <li class="fragment">Software needs to be <i>debugged</i></li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>About Renode</h2>
 | |
|                     <ul>
 | |
|                         <li>Whole-System Emulator</li>
 | |
|                         <li>Supports concurrent emulation</li>
 | |
|                         <li>Extensible with C# and Python</li>
 | |
|                         <li>Windows, Mac, Linux</li>
 | |
|                         <li>MIT Licensed</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>About This Talk</h2>
 | |
|                     <ul>
 | |
|                         <li>Overview of Emulators</li>
 | |
|                         <li>Oevrview of Weird Hardware</li>
 | |
|                         <li>Cool things you can do</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Who will find this interesting?</h2>
 | |
|                     <ul>
 | |
|                         <li>Creators: Those making new boards or hardware</li>
 | |
|                         <li>Integrators: Running CI on firmware files</li>
 | |
|                         <li>Reverse Engineers: Understanding new hardware and firmware</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Creators: Making New Things!</h2>
 | |
|                     <ul>
 | |
|                         <li>Reusing an existing platform</li>
 | |
|                         <li>Reusing an existing microcontroller</li>
 | |
|                         <li>New microcontroller fron existing family</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Integrators: Making Sure Nothing Broke!</h2>
 | |
|                     <ul>
 | |
|                         <li>Hardware testing incompatible with cloud</li>
 | |
|                         <ul>
 | |
|                             <li>...it sure is effective, though</li>
 | |
|                         </ul>
 | |
|                         <li>Hardware crunch makes it difficult to get hardware</li>
 | |
|                         <li>Downloading software is much cheaper than shipping</li>
 | |
|                         <li>Can run tests on every code push</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Reverse Engineers: What Is This Blob Doing?</h2>
 | |
|                     <ul>
 | |
|                         <li>Staring at code flow is enlightening, but time-consuming</li>
 | |
|                         <li>What is it doing and how does it get there?</li>
 | |
|                         <li>How can we make it do $x?</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|             </section>
 | |
|             <section>
 | |
|                 <section data-transition="fade-out">
 | |
|                     <h2>What is an Emulator?</h2>
 | |
|                     <img class="fragment" src="media/bbs-example.png">
 | |
|                 </section>
 | |
|                 <section data-transition="fade">
 | |
|                     <h2>What is an Emulator?</h2>
 | |
|                     <img src="media/DEC_VT100_terminal_cropped.jpg">
 | |
|                 </section>
 | |
|                 <section data-transition="fade-in slide-out">
 | |
|                     <h2>What is an Emulator?</h2>
 | |
|                     <img src="media/bbs-example.png">
 | |
|                 </section>
 | |
|                 <section data-transition="slide-in fade-out">
 | |
|                     <h2>Whole-System Emulator</h2>
 | |
|                     <img src="media/fceux-smb.png">
 | |
|                     <!--
 | |
|                     <ul>
 | |
|                         <li>Wii Virtual Console</li>
 | |
|                         <li>VirtualBox</li>
 | |
|                         <li>Parallels</li>
 | |
|                     </ul>
 | |
|                     -->
 | |
|                 </section>
 | |
|                 <section data-transition="fade-in">
 | |
|                     <h2>Whole-System Emulator</h2>
 | |
|                     <img src="media/fceux-smb-debug.png">
 | |
|                     <!--
 | |
|                     <ul>
 | |
|                         <li>Wii Virtual Console</li>
 | |
|                         <li>VirtualBox</li>
 | |
|                         <li>Parallels</li>
 | |
|                     </ul>
 | |
|                     -->
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Transparent Emulator</h2>
 | |
|                     <ul>
 | |
|                         <li>WSL2/Docker</li>
 | |
|                         <li>qemu on Linux</li>
 | |
|                         <li>Rosetta on Mac</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Renode Is Many of These</h2>
 | |
|                     <ul>
 | |
|                         <li>Console: Able to present an interactive environment</li>
 | |
|                         <li>Transparent: Can run in CI via Robot commands</li>
 | |
|                         <li>Debugger: Has a GDB server built in</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|             </section>
 | |
| 
 | |
|             <section>
 | |
|                 <section data-transition="fade-out">
 | |
|                     <h2>What is a Computer?</h2>
 | |
|                     <img class="fragment" src="media/bluenrg-block-diagram.png">
 | |
|                 </section>
 | |
|                 <section data-transition="fade">
 | |
|                     <h2>What is a Computer?</h2>
 | |
|                     <ul>
 | |
|                         <li>A system of devices</li>
 | |
|                         <li>One or more processors</li>
 | |
|                         <li>One or more buses</li>
 | |
|                         <li>One or more blocks of memory</li>
 | |
|                         <li>Some I/O</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section data-transition="fade-out">
 | |
|                     <h2>What is a Computer?</h2>
 | |
|                     <img src="media/bluenrg-block-diagram.png">
 | |
|                 </section>
 | |
|                 <section data-transition="fade">
 | |
|                     <h2>What is a Computer?</h2>
 | |
|                     <img src="media/bluenrg-block-diagram-no-extra-bits.png">
 | |
|                 </section>
 | |
|                 <section data-transition="fade">
 | |
|                     <h2>What is a Computer?</h2>
 | |
|                     <img src="media/bluenrg-block-diagram-cpu.png">
 | |
|                 </section>
 | |
|                 <section data-transition="fade">
 | |
|                     <h2>What is a Computer?</h2>
 | |
|                     <img src="media/bluenrg-block-diagram-memories.png">
 | |
|                 </section>
 | |
|                 <section data-transition="fade-in">
 | |
|                     <h2>What is a Computer?</h2>
 | |
|                     <img src="media/bluenrg-block-diagram-peripherals.png">
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>What is a Computer?</h2>
 | |
|                     <img src="media/bluenrg-peripherals.png">
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>What is a Computer?</h2>
 | |
|                     <img src="media/bluenrg-memory-map.png">
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>What is a Computer?</h2>
 | |
|                     <img src="media/conceptual-diagram.png">
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Defining a Computer in Renode</h2>
 | |
|                     <pre><code data-trim>
 | |
|                         flash: Memory.MappedMemory @ sysbus 0x00000000
 | |
|                             size: 0x00008000
 | |
| 
 | |
|                         sram: Memory.MappedMemory @ sysbus 0x20000000
 | |
|                             size: 0x00001000
 | |
|     
 | |
|                         nvic: IRQControllers.NVIC @ sysbus 0xE000E000
 | |
|                             IRQ -> cpu@0
 | |
| 
 | |
|                         cpu: CPU.CortexM @ sysbus
 | |
|                             nvic: nvic
 | |
|                             cpuType: "cortex-m0+"
 | |
|                             PerformanceInMips: 24
 | |
|                     </code></pre>
 | |
|                 </section>
 | |
|             </section>
 | |
| 
 | |
|             <section>
 | |
|                 <h2>That's Nice, but What About...</h2>
 | |
|                 <ol>
 | |
|                     <li>Loading firmware?</li>
 | |
|                     <li>Adding peripherals?</li>
 | |
|                 </ol>
 | |
|             </section>
 | |
| 
 | |
|             <section>
 | |
|                 <section>
 | |
|                     <h2>What is "Firmware"?</h2>
 | |
|                     <blockquote class="fragment strike">Firmware is a series of instructions executed by the CPU in
 | |
|                         order to accomplish a task</blockquote>
 | |
|                     <blockquote class="fragment">Firmware is Memory</blockquote>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Loading Firmware in Renode</h2>
 | |
|                     <pre><code data-trim>
 | |
|                         sysbus LoadELF @firmware.elf
 | |
|                     </code></pre>
 | |
|                     <pre class="fragment"><code data-trim>
 | |
|                         sysbus LoadBinary @rom.bin 0x20000000
 | |
|                     </code></pre>
 | |
|                     <pre class="fragment"><code data-trim>
 | |
|                         sysbus LoadSymbolsFrom @rom.elf
 | |
|                     </code></pre>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>How does Renode Interact With $VENDOR_TOOL?</h2>
 | |
|                     <ul>
 | |
|                         <li>Hopefully your vendor tool produces ELF files</li>
 | |
|                         <li class="fragment">At the end of the day, it's all bytes. Just use <code>LoadBinary</code>!
 | |
|                         </li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>What About Boot ROMs?</h2>
 | |
|                     <ol>
 | |
|                         <li class="fragment strike semi-fade-out" data-fragment-index="1">Initialize peripherals</li>
 | |
|                         <li class="fragment strike semi-fade-out" data-fragment-index="1">Check for boot override</li>
 | |
|                         <li class="fragment strike semi-fade-out" data-fragment-index="1">Check for low-power state</li>
 | |
|                         <li class="fragment strike semi-fade-out" data-fragment-index="1">Load firmware into RAM</li>
 | |
|                         <li class="fragment strike semi-fade-out" data-fragment-index="1">Validate firmware</li>
 | |
|                         <li>Jump to loaded program</li>
 | |
|                     </ol>
 | |
|                     <pre class="fragment"><code data-trim>
 | |
|                         sysbus.cpu VectorTableOffset 0x20000000
 | |
|                         sysbus.cpu PC 0x20000c00
 | |
|                     </code></pre>
 | |
|                 </section>
 | |
|             </section>
 | |
|             <section>
 | |
|                 <section>
 | |
|                     <h2>What about New Peripherals?</h2>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>It's All About Small Victories</h2>
 | |
|                     <ul>
 | |
|                         <li>Serial ports are super rewarding</li>
 | |
|                         <li>They're also usually simple!</li>
 | |
|                         <li>They are easy to script</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section data-transition="fade-out">
 | |
|                     <h2>What is a Register?</h2>
 | |
|                     <img src="media/pl011-bluenrg.png">
 | |
|                     <img class="fragment" src="media/pl011-cc2538-cropped.png">
 | |
|                 </section>
 | |
|                 <section data-transition="fade">
 | |
|                     <h2>What is a Register?</h2>
 | |
|                     <img src="media/pl011-bcm2835-cropped.png">
 | |
|                 </section>
 | |
|                 <section data-transition="fade-in">
 | |
|                     <h2>What is a Register?</h2>
 | |
|                     <img src="media/pl011-arm.png">
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Reuse an Existing Block!</h2>
 | |
|                     <pre data-id="code-animation"><code data-trim data-line-numbers="|10-12">
 | |
|                         flash: Memory.MappedMemory @ sysbus 0x00000000
 | |
|                             size: 0x00008000
 | |
| 
 | |
|                         sram: Memory.MappedMemory @ sysbus 0x20000000
 | |
|                             size: 0x00001000
 | |
|                             
 | |
|                         nvic: IRQControllers.NVIC @ sysbus 0xE000E000
 | |
|                             IRQ -> cpu@0
 | |
| 
 | |
|                         // 👇 Add a UART with IRQ #10 at address 0x40300000
 | |
|                         uart: UART.PL011 @ sysbus 0x40300000
 | |
|                             -> nvic@10
 | |
|                     
 | |
|                         cpu: CPU.CortexM @ sysbus
 | |
|                             nvic: nvic
 | |
|                             cpuType: "cortex-m0+"
 | |
|                             PerformanceInMips: 24
 | |
|                     </code></pre>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Output Success!</h2>
 | |
|                     <img src="media/bluenrg-renode-uart.png">
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Always Check for Block Reuse</h2>
 | |
|                     Blocks are frequently reused across designs, and can save you from having to reimplement
 | |
|                     everything from scratch!
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>What if we need to write it ourselves?</h2>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Steps to Set Up a Serial Port</h2>
 | |
|                     <ol>
 | |
|                         <li class="fragment strike semi-fade-out" data-fragment-index="1">Enable peripheral</li>
 | |
|                         <li class="fragment strike semi-fade-out" data-fragment-index="1">Set up clock</li>
 | |
|                         <li class="fragment strike semi-fade-out" data-fragment-index="1">Mux GPIOs</li>
 | |
|                         <li class="fragment strike semi-fade-out" data-fragment-index="1">Calculate baud rate</li>
 | |
|                         <li>Write to UART TX register</li>
 | |
|                         <li>Read from UART RX register</li>
 | |
|                     </ol>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Steps to Set Up a Serial Port</h2>
 | |
|                     <ul>
 | |
|                         <li>Interrupt Support</li>
 | |
|                         <ul>
 | |
|                             <li>Handled as a GPIO within the peripheral</li>
 | |
|                         </ul>
 | |
|                         <li>DMA</li>
 | |
|                         <ul>
 | |
|                             <li>Handled as a different peripheral</li>
 | |
|                         </ul>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Example Serial Port</h2>
 | |
|                     <pre class="code-animation"><code class="cs" data-trim data-line-numbers="|132-140|118-126|125|20-33">
 | |
|                     //
 | |
|                     // Copyright (c) 2010-2018 Antmicro
 | |
|                     //
 | |
|                     // This file is licensed under the MIT License.
 | |
|                     // Full license text is available in 'licenses/MIT.txt'.
 | |
|                     //
 | |
|                     using System.Collections.Generic;
 | |
|                     using Antmicro.Renode.Peripherals.Bus;
 | |
|                     using Antmicro.Renode.Core.Structure.Registers;
 | |
|                     using Antmicro.Renode.Core;
 | |
|                     using Antmicro.Renode.Logging;
 | |
|                     
 | |
|                     namespace Antmicro.Renode.Peripherals.UART
 | |
|                     {
 | |
|                         public class LiteX_UART : UARTBase, IDoubleWordPeripheral, IBytePeripheral, IKnownSize
 | |
|                         {
 | |
|                             public LiteX_UART(Machine machine) : base(machine)
 | |
|                             {
 | |
|                                 IRQ = new GPIO();
 | |
|                                 var registersMap = new Dictionary<long, DoubleWordRegister>
 | |
|                                 {
 | |
|                                     {(long)Registers.RxTx, new DoubleWordRegister(this)
 | |
|                                     .WithValueField(0, 8,
 | |
|                                         writeCallback: (_, value) => 
 | |
|                                             this.TransmitCharacter((byte)value),
 | |
|                                         valueProviderCallback: _ => {
 | |
|                                             if(!TryGetCharacter(out var character))
 | |
|                                             {
 | |
|                                                 this.Log(LogLevel.Warning, "Empty Rx FIFO.");
 | |
|                                             }
 | |
|                                             return character;
 | |
|                                         })
 | |
|                                     },
 | |
|                                     {(long)Registers.TxFull, new DoubleWordRegister(this)
 | |
|                                         .WithFlag(0, FieldMode.Read) //tx is never full
 | |
|                                     },
 | |
|                                     {(long)Registers.RxEmpty, new DoubleWordRegister(this)
 | |
|                                         .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => Count == 0)
 | |
|                                     },
 | |
|                                     {(long)Registers.EventPending, new DoubleWordRegister(this)
 | |
|                                         // `txEventPending` implements `WriteOneToClear` semantics to avoid fake warnings
 | |
|                                         // `txEventPending` is generated on the falling edge of TxFull; in our case it means never
 | |
|                                         .WithFlag(0, FieldMode.Read | FieldMode.WriteOneToClear, valueProviderCallback: _ => false, name: "txEventPending")
 | |
|                                         .WithFlag(1, out rxEventPending, FieldMode.Read | FieldMode.WriteOneToClear, name: "rxEventPending")
 | |
|                                         .WithWriteCallback((_, __) => UpdateInterrupts())
 | |
|                                     },
 | |
|                                     {(long)Registers.EventEnable, new DoubleWordRegister(this)
 | |
|                                         .WithFlag(0, name: "txEventEnabled")
 | |
|                                         .WithFlag(1, out rxEventEnabled)
 | |
|                                         .WithWriteCallback((_, __) => UpdateInterrupts())
 | |
|                                     },
 | |
|                                 };
 | |
|                     
 | |
|                                 registers = new DoubleWordRegisterCollection(this, registersMap);
 | |
|                             }
 | |
|                     
 | |
|                             public uint ReadDoubleWord(long offset)
 | |
|                             {
 | |
|                                 return registers.Read(offset);
 | |
|                             }
 | |
|                     
 | |
|                             public byte ReadByte(long offset)
 | |
|                             {
 | |
|                                 if(offset % 4 != 0)
 | |
|                                 {
 | |
|                                     // in the current configuration, only the lowest byte
 | |
|                                     // contains a meaningful data
 | |
|                                     return 0;
 | |
|                                 }
 | |
|                                 return (byte)ReadDoubleWord(offset);
 | |
|                             }
 | |
|                     
 | |
|                             public override void Reset()
 | |
|                             {
 | |
|                                 base.Reset();
 | |
|                                 registers.Reset();
 | |
|                     
 | |
|                                 UpdateInterrupts();
 | |
|                             }
 | |
|                     
 | |
|                             public void WriteDoubleWord(long offset, uint value)
 | |
|                             {
 | |
|                                 registers.Write(offset, value);
 | |
|                             }
 | |
|                                 
 | |
|                             public void WriteByte(long offset, byte value)
 | |
|                             {
 | |
|                                 if(offset % 4 != 0)
 | |
|                                 {
 | |
|                                     // in the current configuration, only the lowest byte
 | |
|                                     // contains a meaningful data
 | |
|                                     return;
 | |
|                                 }
 | |
|                     
 | |
|                                 WriteDoubleWord(offset, value);
 | |
|                             }
 | |
|                             
 | |
|                             public long Size => 0x100;
 | |
|                     
 | |
|                             public GPIO IRQ { get; private set; }
 | |
|                     
 | |
|                             public override Bits StopBits => Bits.One;
 | |
|                     
 | |
|                             public override Parity ParityBit => Parity.None;
 | |
|                     
 | |
|                             public override uint BaudRate => 115200;
 | |
|                     
 | |
|                             protected override void CharWritten()
 | |
|                             {
 | |
|                                 UpdateInterrupts();
 | |
|                             }
 | |
|                     
 | |
|                             protected override void QueueEmptied()
 | |
|                             {
 | |
|                                 UpdateInterrupts();
 | |
|                             }
 | |
|                     
 | |
|                             private void UpdateInterrupts()
 | |
|                             {
 | |
|                                 // rxEventPending is latched
 | |
|                                 rxEventPending.Value = (Count != 0);
 | |
|                     
 | |
|                                 // tx fifo is never full, so `txEventPending` is always false
 | |
|                                 var eventPending = (rxEventEnabled.Value && rxEventPending.Value);
 | |
|                                 IRQ.Set(eventPending);
 | |
|                             }
 | |
|                     
 | |
|                             private IFlagRegisterField rxEventEnabled;
 | |
|                             private IFlagRegisterField rxEventPending;
 | |
|                             private readonly DoubleWordRegisterCollection registers;
 | |
|                     
 | |
|                             private enum Registers : long
 | |
|                             {
 | |
|                                 RxTx = 0x0,
 | |
|                                 TxFull = 0x04,
 | |
|                                 RxEmpty = 0x08,
 | |
|                                 EventStatus = 0x0c,
 | |
|                                 EventPending = 0x10,
 | |
|                                 EventEnable = 0x14,
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                     </code></pre>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Steps to Set Up a Serial Port</h2>
 | |
|                     <img src="media/renode-xous-kernel-uart.png">
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>What about Missing Definitions?</h2>
 | |
|                     <ul>
 | |
|                         <li>Most registers are unused</li>
 | |
|                         <ul>
 | |
|                             <li>Start/Stop bits</li>
 | |
|                             <li>One-wire mode</li>
 | |
|                             <li>Infrared mode</li>
 | |
|                         </ul>
 | |
|                         <li class="fragment">Most writes can be ignored</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section data-transition="fade-out">
 | |
|                     <h2>Advantages of Emulation</h2>
 | |
|                     <img src="media/betrusted-soc-uart-mux.png">
 | |
|                 </section>
 | |
|                 <section data-transition="fade-in">
 | |
|                     <h2>Advantages of Emulation</h2>
 | |
|                     <img src="media/renode-xous-double-uart-tiled.png">
 | |
|                 </section>
 | |
|             </section>
 | |
|             <!-- 
 | |
|             <section>
 | |
|                 <section>
 | |
|                     <h2>Example of Weird Hardware</h2>
 | |
|                     <ul>
 | |
|                         <li>NRF52840</li>
 | |
|                         <li>LM74 Temperature Sensor</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Example of Weird Hardware</h2>
 | |
|                     <ul>
 | |
|                         <li>NRF52833</li>
 | |
|                         <li>LM74 Temperature Sensor</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Example of Weird Hardware</h2>
 | |
|                     <ul>
 | |
|                         <li>BlueNRG1</li>
 | |
|                         <li>LM74 Temperature Sensor</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Example of Weird Hardware</h2>
 | |
|                     <ul>
 | |
|                         <li>RISC-V</li>
 | |
|                         <li>FPGA-based framebuffer</li>
 | |
|                         <li>Initial graphical demo in 1 hour</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|             </section>
 | |
|             <section>
 | |
|                 <section>
 | |
|                     <h2>What makes hardware "Weird"?</h2>
 | |
|                     <ul>
 | |
|                         <li>Unusual CPU architecture</li>
 | |
|                         <li>Different model of chip than commonly found</li>
 | |
|                         <li>Additional hardware</li>
 | |
|                         <li>More CPUs per board</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Unusual CPU architecture</h2>
 | |
|                     Sorry, can't help
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Different model CPU</h2>
 | |
|                     <ul>
 | |
|                         <li>Maybe it's just a variant</li>
 | |
|                         <li>Perhaps memory regions were shuffled</li>
 | |
|                         <li>Does it use the same hardware block as someone else?</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>New hardware version</h2>
 | |
|                     <ul>
 | |
|                         <li>Do you use the new, specialized features?</li>
 | |
|                         <li>Lots of UARTs support Infrared. Do you need that?</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Completely new hardware</h2>
 | |
|                     <ul>
 | |
|                         <li>Time to break out C#</li>
 | |
|                     </ul>
 | |
|                 </section>
 | |
|             </section> -->
 | |
|             <section>
 | |
|                 <section>
 | |
|                     <h2>Robot Framework: Running Tests in CI</h2>
 | |
|                     <pre class="code-animation"><code class="robot" data-trim data-line-numbers="|1-6|8-18|20-26|28-40">
 | |
|                             *** Settings ***
 | |
|                                 Suite Setup                   Setup
 | |
|                                 Suite Teardown                Teardown
 | |
|                                 Test Setup                    Reset Emulation
 | |
|                                 Test Teardown                 Test Teardown
 | |
|                                 Resource                      ${RENODEKEYWORDS}
 | |
|                                 
 | |
|                             *** Variables ***
 | |
|                                 ${UART}   sysbus.uart0
 | |
|                                 ${URI}    @https://dl.antmicro.com/projects/renode
 | |
|                                 
 | |
|                                 ${LIS2DS12}=     SEPARATOR=
 | |
|                                 ...  """                                                 ${\n}
 | |
|                                 ...  using "platforms/cpus/nrf52840.repl"                ${\n}
 | |
|                                 ...                                                      ${\n}
 | |
|                                 ...  lis2ds12: Sensors.LIS2DS12 @ twi1 0x1c              ${\n}
 | |
|                                 ...  ${SPACE*4}IRQ -> gpio0@28                           ${\n}
 | |
|                                 ...  """
 | |
| 
 | |
|                             *** Keywords ***
 | |
|                             Create Machine
 | |
|                                 Execute Command  mach create
 | |
|                                 Execute Command  machine 
 | |
|                                     ... LoadPlatformDescriptionFromString ${LIS2DS12}
 | |
|                                 Execute Command  sysbus LoadELF 
 | |
|                                     ... ${URI}/nrf52840--zephyr_lis2dh.elf-s_747800-163b7e7cc986d4b1115f06b5f3df44ed0defc1fa
 | |
| 
 | |
|                             *** Test Cases ***
 | |
|                             Should Read Acceleration
 | |
|                                 Create Machine
 | |
|                                 Create Terminal Tester    ${UART}
 | |
|                             
 | |
|                                 Execute Command sysbus.twi1.lis2ds12 AccelerationX 10
 | |
|                                 Execute Command sysbus.twi1.lis2ds12 AccelerationY 5
 | |
|                                 Execute Command sysbus.twi1.lis2ds12 AccelerationZ -5
 | |
|                             
 | |
|                                 Start Emulation
 | |
|                             
 | |
|                                 Wait For Line On Uart  
 | |
|                                     ... x 9.997213 , y 4.997410 , z -4.999803
 | |
|                         </code></pre>
 | |
|                 </section>
 | |
|             </section>
 | |
|             <section>
 | |
|                 <section>
 | |
|                     <h2>Renode for Reverse Engineering</h2>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>SVD: Standard Chip Documentation</h2>
 | |
|                     <pre class="code-animation"><code class="xml" data-trim data-line-numbers="|3-9|25-87|27-31|39-57|43|46-47|48-56">
 | |
|                         <?xml version='1.0' encoding='utf-8'?>
 | |
|                         <device xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="1.1" xsi:noNamespaceSchemaLocation="CMSIS-SVD_Schema_1_1_draft.xsd">
 | |
|                             <vendor>STMicroelectronics</vendor>
 | |
|                             <vendorID>ST</vendorID>
 | |
|                             <name>BlueNRG2</name>
 | |
|                             <series>BlueNRG1</series>
 | |
|                             <version>1.0.0</version>
 | |
|                             <description>ARM 32-bit Cortex-M0 Microcontroller based device, CPU clock up to 32MHz</description>
 | |
|                             <licenseText>License</licenseText>
 | |
|                             <cpu>
 | |
|                                 <name>CM0</name>
 | |
|                                 <revision>r0p0</revision>
 | |
|                                 <endian>little</endian>
 | |
|                                 <mpuPresent>false</mpuPresent>
 | |
|                                 <fpuPresent>false</fpuPresent>
 | |
|                                 <nvicPrioBits>2</nvicPrioBits>
 | |
|                                 <vendorSystickConfig>false</vendorSystickConfig>
 | |
|                             </cpu>
 | |
|                             <addressUnitBits>8</addressUnitBits>
 | |
|                             <width>32</width>
 | |
|                             <size>32</size>
 | |
|                             <access>read-write</access>
 | |
|                             <resetValue>0x00000000</resetValue>
 | |
|                             <resetMask>0xFFFFFFFF</resetMask>
 | |
|                             <peripherals>
 | |
|                                 <peripheral>
 | |
|                                     <name>RNG</name>
 | |
|                                     <version>1.0</version>
 | |
|                                     <description>RNG</description>
 | |
|                                     <groupName>RNG</groupName>
 | |
|                                     <baseAddress>0xB0000000</baseAddress>
 | |
|                                     <size>32</size>
 | |
|                                     <access>read-write</access>
 | |
|                                     <addressBlock>
 | |
|                                         <offset>0</offset>
 | |
|                                         <size>0x1000</size>
 | |
|                                         <usage>registers</usage>
 | |
|                                     </addressBlock>
 | |
|                                     <registers>
 | |
|                                         <register>
 | |
|                                             <name>CR</name>
 | |
|                                             <description>RNG configuration register</description>
 | |
|                                             <addressOffset>0x00</addressOffset>
 | |
|                                             <size>32</size>
 | |
|                                             <access>read-write</access>
 | |
|                                             <resetValue>0x00000000</resetValue>
 | |
|                                             <resetMask>0x0000FFFF</resetMask>
 | |
|                                             <fields>
 | |
|                                                 <field>
 | |
|                                                     <name>DIS</name>
 | |
|                                                     <description>Set the state of the random number generator.<ul><li>0: RNG is enable.</li><li>1: RNG is disabled. The internal free-running oscillators are put in power-down mode and the RNG clock is stopped at the input of the block.</li></ul></description>
 | |
|                                                     <bitOffset>2</bitOffset>
 | |
|                                                     <bitWidth>1</bitWidth>
 | |
|                                                     <access>read-write</access>
 | |
|                                                 </field>
 | |
|                                             </fields>
 | |
|                                         </register>
 | |
|                                         <register>
 | |
|                                             <name>SR</name>
 | |
|                                             <description>RNG status register</description>
 | |
|                                             <addressOffset>0x04</addressOffset>
 | |
|                                             <size>32</size>
 | |
|                                             <access>read-only</access>
 | |
|                                             <resetValue>0x00000000</resetValue>
 | |
|                                             <resetMask>0x0000FFFF</resetMask>
 | |
|                                             <fields>
 | |
|                                                 <field>
 | |
|                                                     <name>RDY</name>
 | |
|                                                     <description>New random value ready.<ul><li>0: The RNG_VAL register value is not yet valid. If performing a read access to VAL, the host will be put on hold (by wait-states insertion on the AHB bus) until a random value is available.</li><li>1: The VAL register contains a valid random number.</li></ul>This bit remains at 0 when the RNG is disabled (RNGDIS bit = 1b in CR)</description>
 | |
|                                                     <bitOffset>0</bitOffset>
 | |
|                                                     <bitWidth>1</bitWidth>
 | |
|                                                     <access>read-only</access>
 | |
|                                                 </field>
 | |
|                                             </fields>
 | |
|                                         </register>
 | |
|                                         <register>
 | |
|                                             <name>VAL</name>
 | |
|                                             <description>RNG 16 bit random value</description>
 | |
|                                             <addressOffset>0x08</addressOffset>
 | |
|                                             <size>32</size>
 | |
|                                             <access>read-only</access>
 | |
|                                             <resetValue>0x00000000</resetValue>
 | |
|                                             <resetMask>0x0000FFFF</resetMask>
 | |
|                                         </register>
 | |
|                                         </registers>
 | |
|                                 </peripheral>
 | |
|                             </peripherals>
 | |
|                         </device>
 | |
|                         </code></pre>
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>SVD: Using with Renode</h2>
 | |
|                     <pre class="code-animation"><code data-trim data-line-numbers="|1-6|8-18|20-26|28-40">
 | |
|                         sysbus ApplySVD @BlueNRG2.svd
 | |
|                     </code></pre>
 | |
|                     <img class="fragment" src="media/bluenrg-renode-svd.png">
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Logging Memory Accesses</h2>
 | |
|                     <img src="media/renode-betrusted-log.png">
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Debugging with GDB</h2>
 | |
|                     <img src="media/renode-start-gdb.png">
 | |
|                     <img class="fragment" src="media/renode-connect-gdb.png">
 | |
|                 </section>
 | |
|                 <section>
 | |
|                     <h2>Creating ELF Files</h2>
 | |
|                     <img src="media/ghidra-decompile.png">
 | |
|                 </section>
 | |
|             </section>
 | |
|             <section>
 | |
|                 <h2>Multi-System Emulation</h2>
 | |
|                 <img src="media/renode-multi-system.png">
 | |
|             </section>
 | |
|             <section>
 | |
|                 <h2>Multi-System Emulation</h2>
 | |
|                 <img src="media/betrusted-ec-com-1.png">
 | |
|             </section>
 | |
|             <section>
 | |
| 
 | |
|             </section>
 | |
|         </div>
 | |
|     </div>
 | |
| 
 | |
|     <script src="dist/reveal.js"></script>
 | |
|     <script src="plugin/notes/notes.js"></script>
 | |
|     <script src="plugin/zoom/zoom.js"></script>
 | |
|     <script src="plugin/markdown/markdown.js"></script>
 | |
|     <script src="plugin/highlight/highlight.js"></script>
 | |
|     <script type="text/javascript" src="js/robot.js"></script>
 | |
|     <script>
 | |
|         /** This used to be a part of Reveal.js, but was removed at some point */
 | |
|         function getQueryHash() {
 | |
|             function deserialize(value) {
 | |
|                 if (typeof value === 'string') {
 | |
|                     if (value === 'null') return null;
 | |
|                     else if (value === 'true') return true;
 | |
|                     else if (value === 'false') return false;
 | |
|                     else if (value.match(/^-?[\d\.]+$/)) return parseFloat(value);
 | |
|                 }
 | |
|                 return value;
 | |
|             }
 | |
| 
 | |
|             let query = {};
 | |
|             location.search.replace(/[A-Z0-9]+?=([\w\.%-]*)/gi, a => {
 | |
|                 query[a.split('=').shift()] = a.split('=').pop();
 | |
|             });
 | |
|             // Basic deserialization
 | |
|             for (let i in query) {
 | |
|                 let value = query[i];
 | |
| 
 | |
|                 query[i] = deserialize(unescape(value));
 | |
|             }
 | |
| 
 | |
|             // Do not accept new dependencies via query config to avoid
 | |
|             // the potential of malicious script injection
 | |
|             if (typeof query['dependencies'] !== 'undefined') delete query['dependencies'];
 | |
| 
 | |
|             return query;
 | |
|         }
 | |
|         var presenter = !!getQueryHash().s;
 | |
|         var stream = !!getQueryHash().stream;
 | |
| 
 | |
|         // More info about initialization & config:
 | |
|         // - https://revealjs.com/initialization/
 | |
|         // - https://revealjs.com/config/
 | |
|         reveal_dependencies = [
 | |
|             { src: 'https://reveal-multiplex.glitch.me/socket.io/socket.io.js', async: true },
 | |
|         ];
 | |
|         if (presenter) {
 | |
|             reveal_dependencies.push({ src: 'https://reveal-multiplex.glitch.me/master.js', async: true },);
 | |
|         } else {
 | |
|             reveal_dependencies.push({ src: 'https://reveal-multiplex.glitch.me/client.js', async: true });
 | |
|         }
 | |
|         Reveal.initialize({
 | |
|             hash: true,
 | |
| 
 | |
|             controls: presenter ? false : (stream ? false : true),
 | |
|             progress: true,
 | |
|             history: true,
 | |
|             center: true,
 | |
|             controlsTutorial: presenter ? false : (stream ? false : true),
 | |
| 
 | |
|             slideNumber: presenter ? null : (stream ? null : 'c/t'),
 | |
| 
 | |
|             // The "normal" size of the presentation, aspect ratio will be preserved
 | |
|             // when the presentation is scaled to fit different resolutions. Can be
 | |
|             // specified using percentage units.
 | |
|             width: 1280,
 | |
|             height: 840,
 | |
| 
 | |
|             // Factor of the display size that should remain empty around the content
 | |
|             margin: 0.1,
 | |
| 
 | |
|             multiplex: {
 | |
|                 // Example values. To generate your own, see the socket.io server instructions.
 | |
|                 secret: getQueryHash().s || null,
 | |
|                 id: 'ef4a6dfa448e19c1',
 | |
|                 url: 'https://p.xobs.io/'
 | |
|             },
 | |
| 
 | |
| 
 | |
|             // Bounds for smallest/largest possible scale to apply to content
 | |
|             minScale: 0.02,
 | |
|             maxScale: 5.5,
 | |
| 
 | |
|             transition: 'slide', // none/fade/slide/convex/concave/zoom
 | |
| 
 | |
|             highlight: {
 | |
|                 beforeHighlight: hljs => hljs.registerLanguage('robot', window.hljsDefineRobot)
 | |
|             },
 | |
| 
 | |
|             // Don't forget to add the dependencies
 | |
|             dependencies: reveal_dependencies,
 | |
| 
 | |
|             // Learn about plugins: https://revealjs.com/plugins/
 | |
|             plugins: [RevealMarkdown, RevealHighlight, RevealZoom]
 | |
|         });
 | |
| 
 | |
| 
 | |
|     </script>
 | |
| </body>
 | |
| 
 | |
| </html> |