[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[openrisc] Bug in current or1k sim...



There appears to be a bug in the current version of
or1ksim. The scenario is as follows: in the reset()
routine or the except_handle() routine, both pc and
pcnext are set to the same value. If the next instruction
executed is a jump or a branch, the the pcnext value
is calculated as:

pcnext = pc + (signed)eval_operand(cur->op1) * 4 - 4;

(source - execute.c, function decode_execute(),
branch CURINSN("l.j"))

Since pc and pcnext are the same value, this has the
effect of miscalculating the jump address by 4. For
example, if the reset vector 0x00000100 contains
the instruction

l.j    0x0

The resolved address is 0x000000FC where it should
not change at all!  This is because during fetch(), pc
was set to pcnext, which did not actually advance
the instruction counter.

I believe the correct solution is that during reset or
exception handling, pc should be set to the resolved
address, and pcnext should be set to the resolved
address + 4. (Thus except_handle(EXCEPT_RESET)
should set 256 and 260).

Since this seems obvious and it was not done, I
am concerned there is a reason why this is not
implemented in this fashion. How is it implemented
in the RTL code?

If the first instruction is not a jump or a branch, then
this issue has the effect of executing the first instruction
twice after a reset or after an exception.

I have implemented the above change in my version
of or1ksim in order to continue, however I would like
to know why this was done, and if it safe to do this.

The change requires a modification to reset() in
cpu/or32/execute.c and to except_handle() in
cpu/or1k/except.c.

Comments?

Chris
chris@asics.ws