index: nearly done
Signed-off-by: Sean Cross <sean@xobs.io>
368
index.html
@ -167,11 +167,11 @@
|
||||
<h2>What is an Emulator?</h2>
|
||||
<img src="media/DEC_VT100_terminal_cropped.jpg">
|
||||
</section>
|
||||
<section data-transition="fade-in">
|
||||
<section data-transition="fade-in slide-out">
|
||||
<h2>What is an Emulator?</h2>
|
||||
<img src="media/bbs-example.png">
|
||||
</section>
|
||||
<section>
|
||||
<section data-transition="slide-in fade-out">
|
||||
<h2>Whole-System Emulator</h2>
|
||||
<img src="media/fceux-smb.png">
|
||||
<!--
|
||||
@ -182,7 +182,7 @@
|
||||
</ul>
|
||||
-->
|
||||
</section>
|
||||
<section>
|
||||
<section data-transition="fade-in">
|
||||
<h2>Whole-System Emulator</h2>
|
||||
<img src="media/fceux-smb-debug.png">
|
||||
<!--
|
||||
@ -228,7 +228,7 @@
|
||||
</section>
|
||||
<section data-transition="fade-out">
|
||||
<h2>What is a Computer?</h2>
|
||||
<img class="fragment" src="media/bluenrg-block-diagram.png">
|
||||
<img src="media/bluenrg-block-diagram.png">
|
||||
</section>
|
||||
<section data-transition="fade">
|
||||
<h2>What is a Computer?</h2>
|
||||
@ -341,8 +341,49 @@
|
||||
<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>Reusing an Existing Port</h2>
|
||||
<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>Steps to Set Up a Serial Port</h2>
|
||||
@ -354,25 +395,47 @@
|
||||
<li>Write to UART TX register</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Steps to Set Up a Serial Port</h2>
|
||||
<img src="media/renode-xous-kernel-uart.png">
|
||||
</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><code class="cs" data-trim>
|
||||
<pre class="code-animation"><code class="cs" data-trim data-line-numbers="|22-33|132-140">
|
||||
//
|
||||
// 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);
|
||||
},
|
||||
writeCallback: (_, value) =>
|
||||
this.TransmitCharacter((byte)value),
|
||||
valueProviderCallback: _ => {
|
||||
if(!TryGetCharacter(out var character))
|
||||
{
|
||||
@ -381,13 +444,131 @@
|
||||
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>
|
||||
<li>Most writes can be ignored</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">
|
||||
@ -468,10 +649,36 @@
|
||||
</section>
|
||||
</section> -->
|
||||
<section>
|
||||
|
||||
<section>
|
||||
<h2>Robot Framework: Running Tests in CI</h2>
|
||||
<pre><code class="hljs" data-trim>
|
||||
<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
|
||||
@ -483,34 +690,139 @@
|
||||
|
||||
Start Emulation
|
||||
|
||||
Wait For Line On Uart x 9.997213 , y 4.997410 , z -4.999803
|
||||
Wait For Line On Uart
|
||||
... x 9.997213 , y 4.997410 , z -4.999803
|
||||
</code></pre>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2>SVD Files</h2>
|
||||
<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|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>Software Assumes Hardware Works</h2>
|
||||
<ul>
|
||||
<li>Rarely checks for sane ranges (why would you?)</li>
|
||||
<li>TOC-TOU</li>
|
||||
</ul>
|
||||
<h2>Creating ELF Files</h2>
|
||||
<img src="media/ghidra-decompile.png">
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Incremental Changes</h2>
|
||||
<ul>
|
||||
<li>Small changes are very rewrding</li>
|
||||
<li>Device will work with only partial implementation</li>
|
||||
</ul>
|
||||
<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>
|
||||
|
BIN
media/betrusted-ec-com-1.png
Normal file
After Width: | Height: | Size: 91 KiB |
BIN
media/bluenrg-renode-svd.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
media/bluenrg-renode-uart.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
media/ghidra-decompile.png
Normal file
After Width: | Height: | Size: 162 KiB |
BIN
media/pl011-arm.png
Normal file
After Width: | Height: | Size: 98 KiB |
BIN
media/pl011-bcm2835-cropped.png
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
media/pl011-cc2538-cropped.png
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
media/renode-betrusted-log.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
media/renode-connect-gdb.png
Normal file
After Width: | Height: | Size: 369 KiB |
BIN
media/renode-multi-system.png
Normal file
After Width: | Height: | Size: 347 KiB |
BIN
media/renode-start-gdb.png
Normal file
After Width: | Height: | Size: 210 KiB |