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 |