Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Implement undocument wifi registers, get AP mode working (QEMU-155) #80

Open
wants to merge 56 commits into
base: esp-develop
Choose a base branch
from

Conversation

redfast00
Copy link

@redfast00 redfast00 commented Jul 4, 2023

This is a WIP PR that adds support for the ESP32 wifi peripheral. The code was ported from https://github.com/a159x36/qemu: the wifi changes were separated from the SPI changes, the code was cleaned up, and the bugs in the code that translated 802.11 packets to Ethernet packets were fixed.

At the moment, using the ESP32 in STA mode, getting an IP address via DHPC and sending HTTP requests from it works.

This PR is not ready to be merged as-is, but I'd like to get some feedback on it. The hardware registers were reverse engineered, so some registers might have a better name or different semantics than suggested in the code.

At the moment, using the ESP32 as AP is not yet supported; only using it in STA mode works. There is already some code that was copied from the a159x36/qemu repo, but this code is untested.

ESP32 as client, QEMU as AP works with the following command:

build/qemu-system-xtensa -nic user,model=misc.esp32_wifi,id=u1 -no-reboot -S -s -nographic -machine esp32 -drive file=../http_request/meshtest_http_10.0.0.8.bin,if=mtd,format=raw -object filter-dump,id=f1,file=dump.pcap,netdev=u1 -drive file=../efuse.bin,if=none,format=raw,id=efuse -global driver=nvram.esp32.efuse,property=drive,value=efuse

(this starts QEMU paused, so you'll need to resume it with gdb: ~/.espressif/tools/xtensa-esp-elf-gdb/11.2_20220823/xtensa-esp-elf-gdb/bin/xtensa-esp32-elf-gdb ../http_request/build/meshtest_http_10.0.0.8.elf -ex "target remote :1234" -ex "c")

The efuse file was dumped from a real ESP32 with espefuse.py dump; the separate files are then concatenated into a single file.

The meshtest_http_... file was built from
esp-idf/examples/protocols/http_request, configured to connect to one of the APs hardcoded in hw/misc/esp32_wifi_ap.c

dump.pcap will contain the Ethernet packets as seen on the QEMU network bus.

igrr and others added 30 commits May 22, 2023 14:17
Co-authored-by: Anton Maklakov <[email protected]>
Co-authored-by: Omar Chebib <[email protected]>
GDB considers window registers as pseudo registers, meaning that they
are calculated by GDB using the values of AR registers and windowbase.
This patch removes the window registers from the total number of
registers that QEMU will send to GDB, making the number of registers
match the one that GDB expects to see.
This commit introduces two environment variables which can be used
to adjust the list of registers sent from QEMU to GDB:
* If QEMU_XTENSA_CORE_REGS_ONLY is set, only non-privileged registers
  will be sent to GDB. This behavior is compatible with Espressif
  builds of GDB up to esp-2021r1.
* If QEMU_XTENSA_COUNT_WINDOW_REGS is set, QEMU will send window
  registers (a0-a15) to GDB. Enable this if you don't have a build of
  GDB which considers a0-a15 to be "raw" registers.
DP83848C PHY emulated by opencores_eth has several vendor-specific
MII registers at 0x10-0x1d. Reading these registers resulted in an
out-of-bounds access to the regs array.
Part of this commit adds bounds checking.
Since the PHYSTS vendor-specific register is accessed by some of the
embedded DP83848C drivers, the rest of the commit adds simple
emulation of this register, setting the bits depending on the link
status.
Co-authored-by: Maksim Naumenko <[email protected]>
This is an SSIPeripheral instance that knows how to respond to read_id
command. It doesn't store any data. It is sufficient for the IDF
driver to decide to turn on the PSRAM cache. Actual data storage in
PSRAM is emulated in DPORT.
Espressif RISC-V CPU has a different has way of treating interrupts, which is
not standard. Thus, this class will override the default RISC-V CPU behavior
to have 31 interrupt lines.
C3 UART overrides ESP32's UART
o-marshmallow and others added 14 commits May 22, 2023 14:17
This also includes the C3 BIOS (ROM bootloader)
* Closes espressif#75

These commands are used by when bootstraping the chip. This lets
the `esptool` flash any image to the emulated SPI flash.
… legacy synonym

The xkb official name for the Arabic keyboard layout is 'ara'.
However xkb has for at least the past 15 years also permitted it to
be named via the legacy synonym 'ar'.  In xkeyboard-config 2.39 this
synoynm was removed, which breaks compilation of QEMU:

FAILED: pc-bios/keymaps/ar
/home/fred/qemu-git/src/qemu/build-full/qemu-keymap -f pc-bios/keymaps/ar -l ar
xkbcommon: ERROR: Couldn't find file "symbols/ar" in include paths
xkbcommon: ERROR: 1 include paths searched:
xkbcommon: ERROR: 	/usr/share/X11/xkb
xkbcommon: ERROR: 3 include paths could not be added:
xkbcommon: ERROR: 	/home/fred/.config/xkb
xkbcommon: ERROR: 	/home/fred/.xkb
xkbcommon: ERROR: 	/etc/xkb
xkbcommon: ERROR: Abandoning symbols file "(unnamed)"
xkbcommon: ERROR: Failed to compile xkb_symbols
xkbcommon: ERROR: Failed to compile keymap

The upstream xkeyboard-config change removing the compat
mapping is:
https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/commit/470ad2cd8fea84d7210377161d86b31999bb5ea6

Make QEMU always ask for the 'ara' xkb layout, which should work on
both older and newer xkeyboard-config.  We leave the QEMU name for
this keyboard layout as 'ar'; it is not the only one where our name
for it deviates from the xkb standard name.

Cc: [email protected]
Signed-off-by: Peter Maydell <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Reviewed-by: Daniel P. Berrangé <[email protected]>
Message-id: [email protected]
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1709
Implement a first interface for Peripheral-to-Memory and Memory-to-Peripheral
transfers.
Cache entries where incorrectly described, which resulted in wrong values
being returned to the guest programs.
ESP32 as client, QEMU as AP works with the following command:

build/qemu-system-xtensa -nic user,model=misc.esp32_wifi,id=u1 -no-reboot -S -s -nographic -machine esp32 -drive file=../http_request/meshtest_http_10.0.0.8.bin,if=mtd,format=raw -object filter-dump,id=f1,file=dump.pcap,netdev=u1 -drive file=../efuse.bin,if=none,format=raw,id=efuse -global driver=nvram.esp32.efuse,property=drive,value=efuse

The efuse file was dumped from a real ESP32 with espefuse.py dump

The meshtest_http_... file was built from
esp-idf/examples/protocols/http_request, configured to connect to
one of the APs hardcoded in hw/misc/esp32_wifi_ap.c

Co-authored-by: Martin Johnson <[email protected]>
@github-actions github-actions bot changed the title WIP: Implement undocument wifi registers, get AP mode working WIP: Implement undocument wifi registers, get AP mode working (QEMU-155) Jul 4, 2023
@lcgamboa
Copy link

lcgamboa commented Jul 4, 2023

Hi @redfast00,

I use as a basis for Wifi support this same fork in Qemu that I use in the PICSimLab simulator. In the original code the MAC address is not read from the efuse file (it is hardwired to 0x10,0x01,0x00,0xc4,0x0a,0x24), I made some modifications to add this support. Take a look at the commits 60937cc and 912c7a9 .
As soon as I have time available I will look at your improvements.

@lcgamboa
Copy link

Hi @redfast00 ,

do you have made any progress on mapping the registers?
I made some modifications to my repository to use action frames with the ESP-NOW protocol.
It partially worked. I can send and receive data using ESP-NOW functions between some Qemu but the ACK frame is never generated. When sending a unicast packet, even unsuccessfully (without receiving the ACK) the callback function registered with esp_now_register_send_cb always reports that the packet was received.
I've already looked in the wifi simulation code where the information that the packet was sent successfully is passed to the esp32 and I haven't found it yet. If you have any tips I would be grateful.
I believe that the implementation of the confirmation of receipt part has to be added to the wifi simulation code, but to start I need to know where to pass the information to the esp32.
To put all Qemu on the same network I used the option below (each one must have a different mac address).
-nic socket,model=esp32_wifi,id=u1,mcast=230.0.0.1:1234

@redfast00
Copy link
Author

@lcgamboa I hope I'll be able to share something soon, but I haven't mapped out the ACK registers yet

@lcgamboa
Copy link

@redfast00 I managed to find out that device address 0x270 of esp32_phya returns the transmission status. It returns 0x00000000 when successful and 0x00002300 when not receiving the ACK. When I have time I will try to implement the communication synchronization part so that the ESPNOW examples work 100% in Qemu.

@redfast00
Copy link
Author

@lcgamboa I've since started reverse engineering the ESP32 MAC and PHY, see https://zeus.gent/blog/23-24/open-source-esp32-wifi-mac/

@lcgamboa
Copy link

lcgamboa commented Dec 9, 2023

@lcgamboa I've since started reverse engineering the ESP32 MAC and PHY, see https://zeus.gent/blog/23-24/open-source-esp32-wifi-mac/

Very cool work! In the meantime, I added WIFI support to Qemu ESP32C3 on my fork. I think it is better in your case to use a RISCV than Xtensa for your research.

@lcgamboa
Copy link

lcgamboa commented Dec 9, 2023

I made some modifications to my fork and managed to get SoftAp mode to work too. The only thing that still doesn't work is if a reset is applied. It is working for ESP32 and ESP32C3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants