Page MenuHomeFreeBSD

riscv: T-HEAD early locore workaround
Needs ReviewPublic

Authored by mhorne on Tue, Nov 5, 8:42 PM.

Details

Reviewers
br
jrtc27
jhb
Group Reviewers
riscv
Summary

The T-HEAD custom PTE bits are defined in such a way that the
default/normal memory type is non-zero value. This _unthoughtful_ choice
means that, unlike the Svpbmt and non-Svpbmt cases, this field cannot be
left bare in our bootstrap PTEs, or the hardware will fail to proceed
far enough in boot (cache strangeness). On the other hand, we cannot
unconditionally apply the PTE_THEAD_MA_NONE attributes, as this is not
compatible with spec-compliant RISC-V hardware, and will result in a
fatal exception.

Therefore, in order to handle this errata, we are forced to perform a
check of the CPU type at the first moment possible. Do so, and fix up
the PTEs with the correct memory attribute bits in the T-HEAD case.

Test Plan

Tested on the Allwinner D1, and QEMU virtual machine (both Svpbmt and non-Svpbmt).

Will verify on SiFive hardware as well.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 60410
Build 57294: arc lint + arc unit

Event Timeline

Running C code without translation enabled is fragile and could break at any time, since it's not running at right address. You're relying on PC-relative addressing being used for everything (i.e. not absolute and not GOT-indirect), which happens to be true today with -mcmodel=medany for this code and all it uses, but there's no guarantee of that. This should really be in assembly (which shouldn't be hard to do, given sbi_get_mvendorid is just a wrapper around ecall?).

Running C code without translation enabled is fragile and could break at any time, since it's not running at right address. You're relying on PC-relative addressing being used for everything (i.e. not absolute and not GOT-indirect), which happens to be true today with -mcmodel=medany for this code and all it uses, but there's no guarantee of that. This should really be in assembly (which shouldn't be hard to do, given sbi_get_mvendorid is just a wrapper around ecall?).

I did find it was quite fragile what could be done this early, reads/writes to globals failed, for example. I am surprised that Linux is able to do as much as they do in this way.

Sure, I will convert it to asm.

Running C code without translation enabled is fragile and could break at any time, since it's not running at right address. You're relying on PC-relative addressing being used for everything (i.e. not absolute and not GOT-indirect), which happens to be true today with -mcmodel=medany for this code and all it uses, but there's no guarantee of that. This should really be in assembly (which shouldn't be hard to do, given sbi_get_mvendorid is just a wrapper around ecall?).

I did find it was quite fragile what could be done this early, reads/writes to globals failed, for example. I am surprised that Linux is able to do as much as they do in this way.

Sure, I will convert it to asm.

Yeah, we use -fPIE, which means GOT indirection for globals (with those GOT entries containing precomputed absolute virtual addresses from the linker), which we could jettison for modern LLVM as it was a workaround for undefined weak symbols. GCC+binutils never had that issue as GNU ld did some gross instruction rewriting for such references, so Linux doesn't use -fPIE, and I guess by the time Clang-built Linux was a thing for RISC-V we'd fixed the psABI and LLVM to not require such instruction rewriting.