On Tue, Mar 20, 2012 at 3:10 PM, R. Diez <[email protected]> wrote:
>
>> I don't agree... in the same way that you don't have to respect any ABI
>> as long as you aren't calling into "external" code, you are free
>> to fiddle with r0 as much as you want.  "r0 contains 0" is ABI, it is not
>> a hardware detail.  A bit weird, I agree, but not fundamentally incorrect.
>
> The architecture specification document does not currently distinguish well 
> between CPU core specification and ABI specification with regards to R0. How 
> about we change the document to say, on the CPU specification side: "R0 may 
> be hard-wired to zero", and then move the "R0 is used as a constant zero" 
> statement to the ABI specification.
>
> The CPU specification states that "R0 should never be used as a destination 
> register". This is problematic as it could be interpreted as "the CPU can 
> generate an exception if the user tries to write to R0". Generic software may 
> not know whether the CPU allows non-zero values in R0, so we should specify a 
> safe way to deal with R0 on start-up.
>
> There are 2 options I can think of:
>
> 1) Add to the CPU specification this: "Therefore, writing to R0 is allowed 
> but may have no effect".
>
> 2) Provide in the specification a safe way to clear R0 on start-up if not 
> already zero. The document should state then something along this line:
>
> The standard software ABI requires R0 to be zero. In order to clear R0 
> safely, standard ABI software should read R0's value on start-up, and then:
>
> a) If the value is already zero, the software must not write to R0, as that 
> could generate a CPU exception.
>
> b) If the value is not already zero, the software shold write value zero to 
> R0, and that must not generate a CPU exception.
>
> I guess there should be no room in the CPU specification for R0 not being 
> writeable and not being zero at the same time, as that would invalidate the 
> API specification. It is then implementation specific whether the CPU allows 
> writing non-zero values to R0.
>

Interesting discussion so far.

It looks like the ISA is, on one hand, going too far by saying r0
should be 'used as a constant zero' (should probably be in the ABI)
but then not far enough when saying '[w]hether or not R0 is actually
hardwired to zero is implementation dependent' by leaving out a
description of what happens if you write to it when it's hardwired to
zero.

I reckon we clean this up by removing all reference to r0 being zero
or hardwired in section 4.4 (ISA spec) and put rules about clearing r0
at startup and then never using it as a destination register again.
This results in an implementation where r0 is just like the other 31
GPRs (the most likely scenario for an implementation.)

I accept that a problematic thing here would be if there are
implementations out there which have hardwired gpr0 to 0, there's
really no way for software, which wants to use r0 outside of what the
ABI in the spec says, to formally check this at runtime. (Although,
actually, you can check that, easily.)

I also believe this whole discussion began due to questions about r0's
writability for security purposes. I think this solution should fix
that (assume it's writable and be sure to take care of it) but of
course adds overhead of ensuring r0 is restored to zero. But this, at
most, should be a 1-cycle instruction overhead when restoring state
(no need to save its contents, just always clear it).

This whole discussion raises an interesting point for the future,
which is how far should ABI features be absorbed/required by the
implementation spec? This GPR0 usage is a good example - Jonas has a
good point about if you want to use it arbitrarily (outside of the
specified ABI) on or1k it looks like you almost could, depending on
whether it's writable or not.

Cheers

Julius
_______________________________________________
OpenRISC mailing list
[email protected]
http://lists.openrisc.net/listinfo/openrisc

Reply via email to