[libre-riscv-dev] [OpenPOWER-HDL-Cores] system call (sc) LEV "reserved field"

Paul Mackerras paulus at ozlabs.org
Thu Jul 23 04:14:50 BST 2020

On Thu, Jul 23, 2020 at 12:41:15AM +0100, Luke Kenneth Casson Leighton wrote:
> On Wednesday, July 22, 2020, Paul Mackerras <paulus at ozlabs.org> wrote:
> > On Wed, Jul 22, 2020 at 03:22:43PM +0100, Luke Kenneth Casson Leighton
> > wrote:
> > > hi, we're just reviewing the behaviour needed when LEV != 0, and are
> > > following what microwatt does (which does not have hypervisor support
> > > yet)
> > >
> > > https://bugs.libre-soc.org/show_bug.cgi?id=325#c106
> > >
> > > so the trail - i am so glad that the PDF has cross-reference linking -
> > > jumps from one section to another and after jumping 5 times we
> > > eventually ascertain the hypothesis that reserved fields, if set,
> > > should raise an "illegal instruction".
> >
> > The first sentence of Book I section 1.3.3 says "Reserved fields in
> > instructions are ignored by the processor."  What led you to confirm
> > your hypothesis that reserved bits being set should cause an illegal
> > instruction interrupt?
> because i did not expect that behaviour, because doing so (ignoring them)
> makes it impossible to trap and emulate.  (it becomes necessary to use JIT
> analysis)
> so, when some bit is added in the future, an older processor (and the
> device it is in) basically has to be thrown into landfill.

No, it depends on what the new bits do.  Generally when a previously
reserved field in an existing instruction is defined to have a
meaning, it is done in such a way that the behaviour of old processors
is an acceptable implementation of the instruction for any value of
the new field (though perhaps not the most performant).  Two examples:

1. The sync instruction had a reserved field which later got defined
as the "L" field for the instruction, with L=1 defined as light-weight
sync.  Light-weight sync does less than the normal sync and runs
faster.  Old processors that ignore the L field do the full normal
sync, which is acceptable if you are asking for the light-weight sync.

2. When the mfocrf (move from one CR field) instruction was created,
the architects deliberately used the same major/minor opcode as mfcr
(move from CR) and defined mfocrf in such a way that the mfcr
behaviour would be an acceptable implementation of mfocrf.
Unfortunately it turned out that the hardware designers of the
previous generation processor (which was POWER3) had put in a check
that reserved instruction fields had to be zero, which then meant that
software couldn't just use mfocrf everywhere, but had to be careful
to use mfcr rather than mfocrf on POWER3.

I agree that if a previously reserved field was given a meaning that
completely changed an instruction's behaviour, that would cause real
problems, but the Power ISA architects have not done that.  In cases
where significantly different or new behaviour is needed, a new major
or minor opcode would be assigned.  Undefined opcodes definitely do
cause an illegal instruction interrupt.

> if however reserved bits being set cause an exception, the "old" processor
> stands a chance of emulating the new behaviour (in software, even if that's
> slow), giving it a chance of keeping out of landfill for slightly longer.

The cost here is that you have broken compatibility for older system
software versions that don't understand the reason for the illegal
instruction interrupt.

> however it is not appropriate for all systems to raise exceptions on
> reserved bits: the cost of having the detection hardware (a full POWER9
> decoder and also illegal/unsupported/reserved SPR detection) can be very
> high especially for resource and power constrained silicon or FPGAs.
> (example: i know someone - yea, you Sam - who implemented RV64 to comply
> with the UNIX RISCV spec rather than the Embedded RISCV spec: the "CSR
> detection" just to support all the zeros and illegal CSRs took a whopping
> 15% of an ICE40 FPGA!)
> in RISC-V they get this right, by having two separate Platforms:
> * Embedded which is permitted to ignore reserved bits entirely
> * UNIX, which definitely is not.
> for Embedded, the vendor customises the firmware entirely, and binary
> interoperability as well as legacy software support is completely
> unimportant.
> for UNIXen, interoperability and longterm stability we know very well is
> critical.

Which has been a critical consideration for Power server processors
over the last 25 years, and has been achieved by discipline on how new
things get architected rather than by emulation.

> bottom line if it is correct that on the PowerISA UNIX Platform reserved
> bits can be ignored that is cause for some concern, where for Embedded it
> would be the other way round: cause for concern if the reserved bits could
> *not* be ignored.
> > > however this is so unclear (because of the referral from one section
> > > to another) that i am seeking confirmation.  should we raise an
> > > "illegal instruction" when "LEV > 1" on sc?
> >
> > Section 1.8.2 (Book I) says "any attempt to execute an invalid form of
> > an instruction will either cause the system illegal instruction
> > handler to be invoked or yield boundedly undefined results".  Putting
> > LEV=1 in sc would be an example of an invalid form (on an
> > implementation without hypervisor mode).
> ok that helps clarify what that means, thank you.
> >   A boundedly undefined result
> > is one which could be obtained by a sequence of valid instructions,
> > so in the case of sc 1, making it do what sc 0 does meets the
> > boundedly undefined results requirement.
> ok so that... if i am understanding correctly, means, "you can in fact do
> something different and OS software has to detect it and sort it out to
> yield expected behaviour"
> which, if i am being honest, makes me nervous :)

There is of course a quality of implementation question here - this
isn't really a licence for hardware designers to do any crazy thing
they want.  I think it would be impossibly unwieldy for the
architecture to try to define in black-letter law what constitutes
"reasonable" vs. "crazy" behaviour for the undefined cases.  By saying
"boundedly" undefined they are at least saying that there must be no
way to escape privilege boundaries by exploiting undefined behaviour.
Beyond that it's up to the hardware designers to do something


More information about the libre-riscv-dev mailing list