CHERIoT-Platform/cheriot-rtos

No firmware works with Ibex on Arty A7 100T

Closed this issue · 15 comments

Hello,
I've build the Ibex safe version for the Arty A7 100T board at 33MHz.

I've a correct result on /dev/ttyUSB1:

Ready to load firmware, hold BTN0 to ignore UART input.

I've build with the devcontainer the test-suite and the examples and no one works.

For the 01.hello_world, I've configured it :

xmake config --sdk=/cheriot-tools/ --board=ibex-arty-a7-100

Then, I've converted the result to a firmware with ibex-build-firmware.sh and send it to the serial port :

Ready to load firmware, hold BTN0 to ignore UART input.
Starting loading.  First word was: 200406B7
.......................................
Finished loading.  Last word was: 020001F4
Number of words loaded to IRAM: 000026A1
Loaded firmware, jumping to IRAM.

The cpu0_iram.vhx file contains :

200406B7
31068693
40000593
....
0300002C
0300015E
03000176
020001F4

which is correct but I get no output.

I've tried the different examples with no result.

Perhaps the memory map has changed ?

OpenOCD and gdb are not available in the devcontainer, so I can not try to trace the execution from the CPU point of view.

Any help would be appreciated.

That does look like the right start for a VHX file.

How are you loading it? I just tried and it works fine if you load the firmware in minicom with the 'paste file' functionality, but does not seem to work if you use cat firmware/cpu0_iram.vhx >> /dev/tty.usb....

Can you try this vhx:
cpu0_iram.vhx

This is built from the test suite (current head of tree). It works for me if I load it in minicom. If I cat it to the tty, it doesn't work, which confuses me (I hadn't tried loading it with cat previously, but I expected it to work).

Interesting, I've just noticed that loading via cat, I see:

Finished loading.  Last word was: 0300016E                                                        
Number of words loaded to IRAM: 00008214                                                          

But with paste file, I see:

Finished loading.  Last word was: 0300016E
Number of words loaded to IRAM: 00008217

So it looks as if cat is going too fast. The last word is correct, but something is being dropped in the middle.

I haven't got around to putting this link somewhere sensible yet, but we also have a CHERIoT public Signal chat, which may be helpful for debugging this issue (some of the US folks are waking up around now).

Thank you very much for your fast answer !

You're right, I used the following command that is working in another design based on the PicoRV32 :
stty -F /dev/ttyUSB1 raw 115200; cat firmware/cpu0_iram.vhx > /dev/ttyUSB1
I'll try with minicom but the menu to select the file is garbled with a lot of blank lines and I could not select the correct directory.
You have a very good eye ! I've missed the mismatch between the number of words uploaded and in the file.
I will try on another computer to get a better version of minicom.

If you hit g, minicom pops up a thing to change directory. I've found just pasting the target directory in works, then you can usually select it easily. It doesn't handle long names well, but once you're in the firmware directory there should be only two files.

This is the result with minicom where I've pasted directly the path to the directory (probably a problem with some unicode character in my home directory) :

Ready to load firmware, hold BTN0 to ignore UART input.                                                                             
Starting loading.  First word was: 200406B7                                                                                         
.......................................                                                                                             
Finished loading.  Last word was: 020001F4                                                                                          
Number of words loaded to IRAM: 000026A4                                                                                            
Loaded firmware, jumping to IRAM.   

Got 3 more words uploaded but no result...

Odd. Can you try with the test suite vhx I uploaded?

And from vim I get 9892 lines :

❯ python3 -c "print(hex(9892))"
0x26a4

I've tried with the file you have uploaded :

Ready to load firmware, hold BTN0 to ignore UART input.                                                                             
Starting loading.  First word was: 200406B7                                                                                         
................................................................................................................................... 
Finished loading.  Last word was: 0300016E                                                                                          
Number of words loaded to IRAM: 00008217                                                                                            
Loaded firmware, jumping to IRAM.                                                                                                   

No output.
With minicom I've got always stuck at the first dot and I've to press a key to let it continue.

My A7 bitstream is a bit out of date, let me build a new one tomorrow and see if it works. Kunyan redid some of the timing recently, which should have made things more stable, but possibly broke something.

I'll try to use a 20MHz version of the design and modify the xmake.config accordingly.

It’s the .json file you’ll need to modify with the timer.

It sounds as if there are some issues with the latest version of the bitstreams. If you revert CHERIoT-SAFE to a version from before the clock refactoring, it should work.

I believe I've found the reason for this. We recently updated the CHERIoT ISA (and the Ibex implementation) with some support for control-flow integrity. In particular, the cjr instruction with cra (link register) as the operand now requires a valid return sentry as the operand.

Unfortunately, the ROM loader in the Arty A7 build uses cjr cra to jump to the firmware image in RAM that it's just loaded. With the new sentry checking, this will trap and so we don't ever make it to the first instruction in the loaded firmware.

This should now be fixed, please update CHERIoT-SAFE and rebuild the bitstream. Reopen this issue if it doesn't work for you. Thanks for the report!

All examples are working now ! Thank you very much.

I've tested successfully the following command if you want to avoid the hassle with minicom under Linux:
stty -F /dev/ttyUSB1 115200; perl -pe "select undef,undef,undef,.002" firmware/cpu0_iram.vhx > /dev/ttyUSB1
The trick is to send slowly each character from the firmware and I've found this solution on superuser.com.

Do you have the correct options to provide to openocd to connect to the board ?

All examples are working now ! Thank you very much.

Thanks for the report! I've written up a longer explanation of the reason for the issue, if you're interested.

stty -F /dev/ttyUSB1 115200; perl -pe "select undef,undef,undef,.002" firmware/cpu0_iram.vhx > /dev/ttyUSB1

Thanks. It would be nice to have this (probably with some selection of the device from an environment variable: on macOS, for example, the device node's name is stable because it includes the board's serial number, but that means you can't embed it in the script) in the script that xmake run calls.

Do you have the correct options to provide to openocd to connect to the board ?

We don't yet have openocd working, unfortunately. There are some OpenOCD scripts in the CHERIoT-SAFE repo, but I believe they were written for our previous FPGA. I have no experience at all with openocd, so patches would be very welcome!