diff options
Diffstat (limited to 'results/classifier/118/all/1525')
| -rw-r--r-- | results/classifier/118/all/1525 | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/results/classifier/118/all/1525 b/results/classifier/118/all/1525 new file mode 100644 index 00000000..b4a3a8d4 --- /dev/null +++ b/results/classifier/118/all/1525 @@ -0,0 +1,108 @@ +semantic: 0.967 +permissions: 0.966 +graphic: 0.962 +debug: 0.960 +architecture: 0.947 +device: 0.935 +user-level: 0.931 +socket: 0.928 +assembly: 0.927 +virtual: 0.922 +arm: 0.922 +mistranslation: 0.909 +PID: 0.909 +files: 0.905 +boot: 0.905 +hypervisor: 0.899 +register: 0.895 +performance: 0.893 +risc-v: 0.882 +ppc: 0.864 +VMM: 0.861 +KVM: 0.856 +peripherals: 0.852 +vnc: 0.845 +network: 0.840 +TCG: 0.838 +kernel: 0.827 +x86: 0.756 +i386: 0.661 + +Wrong initial value of stack pointer on AVR devices +Description of problem: +The initial value of stack pointer of AVR MCUs should be RAMEND (address of the end of their RAM), but QEMU initialize them to 0. + +`qemu-system-avr -machine help` lists 4 flavors of MCUs which are ATmega168, ATmega2560, ATmega1280, ATmega328P. According to their datasheets, the stack pointer should be initialized as follows on reset. + +- [ATmega168](https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-9365-Automotive-Microcontrollers-ATmega88-ATmega168_Datasheet.pdf#page=12): RAMEND (which is 0x04FF) +- [ATmega2560 and ATmega1280](https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf#page=15): RAMEND (which is 0x21FF) +- [ATmega328P](https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/DataSheets/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf#page=22): RAMEND (which is 0x08FF) +Steps to reproduce: +1. Assemble the assembly code below: `avrasm2 -fI test.asm` + + ```asm + ;; test.asm + .INCLUDE "m328Pdef.inc" + + .EQU F_CPU = 16000000 + .EQU BAUD_RATE = 9600 + .EQU PRESCALE = (F_CPU / (16 * BAUD_RATE)) - 1 + + .CSEG + start: + ;; initialize USART (serial port) + LDI R16, LOW(PRESCALE) + LDI R17, HIGH(PRESCALE) + STS UBRR0L, R16 + STS UBRR0H, R17 + LDI R16, (1 << RXEN0) | (1 << TXEN0) + STS UCSR0B, R16 + + ;; Get stack pointer low byte and print it in ASCII + IN R16, SPL + LDI R17, 0x30 + ADD R16, R17 + print1: + LDS r17, UCSR0A + SBRS r17, UDRE0 + RJMP print1 + STS UDR0, r16 + + ;; Get stack pointer high byte and print it in ASCII + IN R16, SPH + LDI R17, 0x30 + ADD R16, R17 + print2: + LDS r17, UCSR0A + SBRS r17, UDRE0 + RJMP print2 + STS UDR0, r16 + + end: + RJMP end + ``` + +2. Convert it to bin file: `avr-objcopy --input-target=ihex --output-target=binary test.hex test.bin` + +3. Run it with QEMU: `qemu-system-avr -machine uno -bios test.bin -serial stdio` + +This should print 00 which means that the stack pointer is initialized to 0. +Additional information: +I examined the source code and I think that editing the function `avr_cpu_reset_hold` in `/target/avr/cpu.c` might fix this issue. This is my first time seeing QEMU source code, so I might be wrong, though. + +```c +// in /target/avr/cpu.c line 70 +static void avr_cpu_reset_hold(Object *obj) +{ + // ... + + env->rampD = 0; + env->rampX = 0; + env->rampY = 0; + env->rampZ = 0; + env->eind = 0; + env->sp = 0; // <-- change this value in accordance with board type? + + //... +} +``` |