44 comments

[ 3.0 ms ] story [ 104 ms ] thread
Excited to see RISC-V supported in Box64. Great work ptitSeb!
ptitSeb is a dynarec god. I remember watching his progress during the Open Pandora days, getting stuff running on that machine that we never imagined possible..
Great work indeed.

Although I do wish Box64 could support statically compiled binaries as well.

I home RISC-V gets used more and eventually gets cheaper as volumes go up.

But, I hope they can avoid things like "Intel ME" and "TPM 1/2/...". If these are needed they should fully open the specs to people can inspect them. Also they should be disabled either by jumpers or whatever RISC uses for BIOS.

TPM spec is fully open. Stop FUD.
The TPM spec is fully open, but where do I get the CAD drawings for the TPM that goes in my gaming tower? Where can I audit the source code? Where can I upload my own source code package to the TPM hardware?
What "cad drawings?" it's standard pinout bare board, as long as you use like, a chip and not 10 it will fill
Something that I can send to PCBWay.
Pretty sure you can just make a software implementation on an Arduino or some microcontroller, and connect it to the SPI bus. Of course, it would be relatively easy to extract the keys from an Arduino's flash memory, which undermines the whole concept. An attacker stealing your desktop shouldn't be able to access anything stored in the TPM.

It's like a USB stick, but more secure, and for just a tiny bit of data. A Yubikey is some kind of TPM. In principle, it cannot be cloned if it falls into the wrong hands. Anybody is welcome to build their own, and they are kind of dumb storage elements (that can also encrypt data you send them), it is just not easy to extract data from them.

It's a small chip connected to the motherboard via either the LPC bus or the SPI bus. There is no constraint on size except the bus dimension and common sense.

If you want to draw a PCB, you can! Just like you can make your own USB-to-SATA board with an ASM1153 though, all you do is draw a board to connect a chip to the outside and give it some supporting crystals. An example TPM chip is SLB 9665, and you can get its datasheet here: https://www.infineon.com/dgdl/Infineon-data-sheet-SLB9665_2.... (if link goes stale, use Google)

As for source code: hardware being closed off is not exactly news (otherwise people would be a lot less angry at firmware issues). There are open-source TPM emulators in use by qemu, so you probably could convince a Raspberry Pi Zero or whatever to pretend to be one by using an emulator and speaking over SPI. There's also a report of TPM on a ARM+FPGA board (https://scholarsarchive.byu.edu/cgi/viewcontent.cgi?article=...) if that's what you want.

depends on your motherboard. most gaming motherboards have a TPM2.0 slot on them and that TPM is connected over either LPC or SPI nowadays (some I2C). And of those, basically everyone is moving to the SPI interface.

The exact pin-out of the slot depends on the motherboard but they are all basically minor variations on the pinout of a 13 pin (14 pin with 1 filled) or 20 pin connector. When you buy your motherboard you can find the full pinout in the manual. That gets you your connector to the motherboard.

For the actual chip itself and the PCB layout, buy an infineon TPM2.0. They cost a few dollars at most. The docs that you can pull off the site include the pinout and operating condition requirements. From that you can build a simple board to run the chip. Hell most of the docs include the plans for one (albeit you might need to change that to fit your mobo.

https://www.infineon.com/cms/en/product/security-smart-card-...

> most gaming motherboards have a TPM2.0 slot on them and that TPM is connected over either LPC or SPI nowadays

Mostly these days it's an fTPM, implemented in firmware (ME or AMD's "Security Processor") especially when it comes to TPM2.0 which is an entirely new madness of complexity hell compared to TPM1.

It shouldn't be? I got a new AM4 board a year or two ago and almost every board on the market at the time had TPM2.0 slots. The issue was that they aren't advertised and barely mentioned but they were there.

From taking a quick search, I selected the first AM5 motherboard I saw from ASRock, MSI, Gigabyte, and ASUS. All had TPM headers buried in the specs or only listed in the manual. Caveat that with ASUS it seems the ROG boards don't have TPM headers but the equivalent ASUS non-ROG boards consistently do.

Point being that they are still quite common and if that's a feature you care about, it's easy to accommodate in any build without even having to look for a different brand. The only issue is that they aren't well advertised or advertised at all.

Exactly, my Librem 15 can use TPM with my keys and free software.
By your logic, wouldn't EME be a good thing too, since its spec is also fully open?
Open source emulators implementing ME or TPM or whatever is not a problem, so long the user retains full control of private keys. Or if it’ll be even less of a problem if ME CPU is going to be emulated too, because then the community will get to record the evil overlord doing its thing.
> not a problem, so long the user retains full control of private keys

The whole point of these technologies is to transfer control of the user's computer to various other actors. So in practice this condition (the user retaining control) is not going to be true, so they remain problematic.

While this use might be common, it's far from "the whole point".

To avoid evil maid attacks, there isn't much of an alternative.

I said EME (Encrypted Media Extensions), not ME (Management Engine).
No. I like TPMs. I hate DRMs.

TPMs help me have a secure (as in preventing evil maid AND being forensics proof) computer to use. The current TPM2.0 specification had some problems (external TPMs are easy to MITM), so I can't trust it to hold my disk encryption keys. But it still HELPS A LOT in mitigating my risk of typing in my FDE keys into a phishing prompt.

DRMs contribute to worse and worse media playing experience.

Is it this hard to tell apart?

TPMs would be a good thing if they didn't allow remote attestation. That would give you all of the legitimate security benefits you want, while making them useless for evil purposes.
Pretty much anything "evil" that can be done with the Intel Management Engine stuff can be done in SM mode, which was introduced in the 386SL and in every x86 since. And that's before we get into update-able microcode, or even asserting that the chip actually matches the RTL if you had access to that.

If the supply chain is compromised and you can't trust them, they never needed any new hardware blocks to do bad things. I don't get why people are so obsessed with these new blocks - the level of required trust hasn't really increased.

So, binary translation at instruction-level granularity? I imagine widening the scope to basic blocks would help with quality of the generated code, but I suppose 2/3 of native speed is quite good already.
That's basically how the original qemu worked. It used GCC to generate target machine code "snippets" for each source instruction, and then simply stitched them together. (Nowadays the translation is a bit more complex and works at the basic block level.)
Wild tangent.

I've got a gist of what a basic block is due to online discussions. I know it is roughly a list of instructions and that jumps are the boundaries.

But I'm looking to understand it on a more fundamental level.

I'm guessing the subject is SSA / single static assignment and compiler theory? Just wanna ask publicly if I'm on the right track, and if I'm following this discussion correctly.

It's not specific to SSA, though SSA assumes it's working with basic blocks (as do a lot of compiler algorithms). And yeah, writeups of compiler theory (and compiler practice) are where to go for more detailed discussion.

The core idea I think is that control flow complicates the kinds of analysis a lot of optimisation and other compiler passes need to do; so by first breaking the input into pieces which have very restricted possible flows of control ("only entered at the top, only exited at the bottom" is the classic definition) then:

1. You can get quite a long way with optimisations that only work within a basic block, and the restriction to within-a-BB simplifies things a lot because it can entirely ignore control flow

2. Analysis that only cares about control flow can work on a graph of BBs and ignore the individual-statement/instruction details, because the BB graph captures all the detail of what can branch where

Read the book "Engineering a compiler" if you want to get a medium-hard but nicely written intro to basically all of the basics. Skip the bit about parsing, it doesn't matter for what you want to learn.
Yes, it would be more efficiant, but it will also be more costly to generate. It would also render the handling of Signal more tricky (need to always be able to go back from the RV64 address to the orignial x86_64 address in case of a SEGFAULT for example). Also, intra-block jump make this more complicated. Box64 does a limited full-block optimisation for the Flags handling and SSE/x87/MMX register attribution, but that's pretty much. Some constant propagation mecanism would be nice and could save a lot of opcode, but no worked as been done it that direction for now (maybe later, it always bother me when I look at generated code dump to see also those multiple constant assigned multiple time).
Constant propagation and also tracking of nonzero bits has been a huge performance improvement in QEMU. The latter helps a lot with x86's automated zero extension, because if you know the high 32 bits are zero you can use a 64-bit move instead of an AND.

But QEMU only does one basic block at a time without jumps so it's relatively easy to implement.

(I tested "7z b" and QEMU user mode emulation is about 30% for x86-on-x86, I'm curious to see how it fares for x86-on-RISCV but I don't have a board to test on).

"x86_64 programs can be now run on RISC-V with reasonable speed."

This is absolutely huge

Bearing in mind emulated x86_64 programs run at a quarter of the speed of native RISC-V code, and today's best RISC-V SBCs run at a quarter of the speed of current Intel and AMD -- somewhere around late Pentium III to Pentium-M or early Core 2.

This emulator is going to run at something like Pentium II speeds on current RISC-V boards.

That's fine if you want to run late 90s (or earlier) x86 software at the same speed it ran on then. Except that will be i386 code, not x86_64.

RISC-V boards are getting faster pretty quickly, but we're still going to need a better x86_64 emulator to get a Rosetta2-like experience on RISC-V even once the CPUs catch up.

That is good enough performance for the last-mile scenario where one has to use emulation to get something working.
Note these benchmarks only applies to pure emulation. For "real" programs, it will likely need some shared libraries. Box64 wraps some commonly used shared libraries, and function calls to these libraries will be forwarded to the corresponding native library for execution, which is almost native speed.
He probably should make BOX64_DYNAREC_RV64NOEXT=1 the default or at least detect it dynamically. Zba and Zbb isn't part of the application profile and other (faster) SoC do not necessarily have them (like TH1520).
The presence of Zba and Zbb extension is tested before using it.
TH1520 (and SG2042, D1) have THead custom extension that contains a lot of the same things as Zba and Zbb, just slightly different and with encodings in the custom opcode spaces.

e.g. "th.addsl rd, rs1, rs2, imm2" which has an immediate field for the shift instead of separate instructions (which is just documentation really), and shifts rs2 while Zba's sh1add, sh2add, sh3add shift rs1.

Also th.ff0, th.ff1, th.rev, th.tstnbz (same as orc.b but with inverted result)

They also have pre- and post-increment loads and stores with writeback of the incremented pointer, and [rs1 + rs2 << imm2] loads and stores, which can be useful for JITing x86 (or ARM) addressing modes.

https://github.com/T-head-Semi/thead-extension-spec/releases...

We need RISCV hardware with Ztso extension to shine here. Enforcing Total store ordering (TSO) over a release consistency (RC) memory model is otherwise a pain. I don't know if Dynarec is tackling this problem (or just focusing emulation on single-threaded software).
Ztso was only ratified in January. It'll be a while until hardware.
Dynarec can optionnaly handle Strong Memory Model emulation, but it's disable by default to have maximum emulation speed (it's the BOX86_DYNAREC_STRONGMEM env. var.).
This is really cool.

Even before the first batch of very high performance RISC-V CPUs hit the market, we're already ready to deal with applications/games that use the legacy x86.

Is it feasible to emulate the SIMD via the vector extension?