espressif / qemu

Fork of QEMU with Espressif patches. See Wiki for details.
https://github.com/espressif/esp-toolchain-docs/blob/main/qemu/README.md
Other
230 stars 61 forks source link

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

Open redfast00 opened 1 year ago

redfast00 commented 1 year ago

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 meshtesthttp... 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.

lcgamboa commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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

lcgamboa commented 1 year ago

@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 commented 11 months ago

@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 commented 11 months ago

@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 commented 11 months ago

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.