7400,7410,7450 cpus vector have wrong exception prefix at reset

Bug #811683 reported by till on 2011-07-16
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
QEMU
Undecided
Unassigned

Bug Description

I have a proprietary ROM implementing system calls that are executed via the 'SC' instruction.

I use qemu-0.14.1,

qemu-system-ppc -M prep -cpu $CPU -bios my_bios -kernel my_kernel

That works fine on a 604 (CPU=0x00040103) - but does not on an emulated 7400 (CPU=0x000c0209) or 7450 (CPU=0x80000201). I found that the emulator jumps to 0x00000c00 instead of 0xfff00c00.
Probably this is due to a wrong setting in target-ppc/translate_init.c:

init_excp_604() correctly sets env->hreset_vector=0xfff00000UL;

but

init_excp_7400() says env->hreset_vector=0x00000000UL;

which seems wrong. (the 7400 manual says a hard-reset jumps initializes the
prefix to 0xfff00000.)

Likewise, init_excp_7450() (and probably other, related CPUs) are wrong.

Indeed, when I change the value in init_excp_7400() to 0xfff00000UL then
everything works as expected for me.

Hi,

Am 16.07.2011 um 23:49 schrieb till:

> I have a proprietary ROM implementing system calls that are executed
> via
> the 'SC' instruction.
>
> I use qemu-0.14.1,
>
> qemu-system-ppc -M prep -cpu $CPU -bios my_bios -kernel my_kernel
>
> That works fine on a 604 (CPU=0x00040103) - but does not on an
> emulated 7400 (CPU=0x000c0209) or 7450 (CPU=0x80000201). I found
> that the emulator jumps to 0x00000c00 instead of 0xfff00c00.
> Probably this is due to a wrong setting in target-ppc/
> translate_init.c:
>
> init_excp_604() correctly sets env->hreset_vector=0xfff00000UL;
>
> but
>
> init_excp_7400() says env->hreset_vector=0x00000000UL;
>
> which seems wrong. (the 7400 manual says a hard-reset jumps
> initializes the
> prefix to 0xfff00000.)

Do you have a link to a spec saying so? Should be trivial to change
then.

> Likewise, init_excp_7450() (and probably other, related CPUs) are
> wrong.
>
> Indeed, when I change the value in init_excp_7400() to 0xfff00000UL
> then
> everything works as expected for me.
>
> ** Affects: qemu
> Importance: Undecided
> Status: New

> Bug description:
> I have a proprietary ROM implementing system calls that are executed
> via the 'SC' instruction.
>
> I use qemu-0.14.1,
>
> qemu-system-ppc -M prep -cpu $CPU -bios my_bios -kernel my_kernel

We are currently in the process of revamping the PReP machine you are
using above. Is your BIOS available publicly so that we can test we
don't break anything for you?

Andreas

agraf (agraf) wrote :

On 18.07.2011, at 00:34, Andreas Färber wrote:

> Hi,
>
> Am 16.07.2011 um 23:49 schrieb till:
>
>> I have a proprietary ROM implementing system calls that are executed via
>> the 'SC' instruction.
>>
>> I use qemu-0.14.1,
>>
>> qemu-system-ppc -M prep -cpu $CPU -bios my_bios -kernel my_kernel
>>
>> That works fine on a 604 (CPU=0x00040103) - but does not on an emulated 7400 (CPU=0x000c0209) or 7450 (CPU=0x80000201). I found that the emulator jumps to 0x00000c00 instead of 0xfff00c00.
>> Probably this is due to a wrong setting in target-ppc/translate_init.c:
>>
>> init_excp_604() correctly sets env->hreset_vector=0xfff00000UL;
>>
>> but
>>
>> init_excp_7400() says env->hreset_vector=0x00000000UL;
>>
>> which seems wrong. (the 7400 manual says a hard-reset jumps initializes the
>> prefix to 0xfff00000.)
>
> Do you have a link to a spec saying so? Should be trivial to change then.

According to MPC7450UM.pdf:

MSR Bit Settings

Bit: 25
Name: IP

Exception prefix. The setting of this bit specifies whether an exception vector offset is prepended with Fs or 0s. In the following description, nnnnn is the offset of the exception.

  0 Exceptions are vectored to the physical address 0x000n_nnnn.
  1 Exceptions are vectored to the physical address 0xFFFn_nnnn.

[...]

9.9.1 Reset Inputs

The MPC7450 has two reset inputs, described as follows:
• HRESET (hard reset)—The HRESET signal is used for power-on reset sequences, or for situations in which the MPC7450 must go through the entire cold start sequence of internal hardware initialization. The MPC7450 will initiate burst transactions after power-on reset in 60x bus mode.
• SRESET (soft reset)—The soft reset input provides warm reset capability. This input can be used to avoid forcing the MPC7450 to complete the cold start sequence.
When either reset input negates, the processor attempts to fetch code from the system reset exception vector. The vector is located at offset 0x00100 from the exception prefix (MSR[IP]).

----> The MSR[IP] bit is set when HRESET negates.

So the correct implementation would be to set hreset_vector to 0xfff00000, but also set MSR_IP and clear hreset_vector when MSR_IP gets modified.

I'll happily take patches :).

Alex

till (till-straumann) wrote :

Google for MPC7450UM.pdf and MPC7410UM.pdf. These two documents cover the

7441, 7445, 7451, 7455, 7457, 7447, 7448 and the 7410 and 7400 CPUs, respectively.

For all these, Alex' description applies. However, (and I made a mistake in my original post),
the setting affected is

env->hreset_excp_prefix = 0xfff00000UL;

in addition, hreset_vector should be:

env->hreset_vector = 0x00000100UL;

NOTE - I believe the other points raised by Alex (initialize MSR[IP] -- which BTW is called MSR_EP in qemu -- and switching the exception prefix when MSR[IP] is changed) are already correctly handled, see:

target-ppc/helper.c: cpu_reset()
target-ppc/helper-hreg.h: hreg_store_msr()

Should I post a patch to the mailing-list?

Hi Andreas.

I posted a reply to the bug database. Regarding my 'bios' - it is really
nothing.
I need it to boot RTEMS. It just mocks up a minimal residual and jumps to
the kernel load address.
You can take a look at

http://www.rtems.org/viewvc/rtems/c/src/lib/libbsp/powerpc/shared/bootloader/

The stuff that goes into the dummy 'bios' is qemu_fakerom.S and
qemu_fakeres.c

Regards
- Till

On 07/17/2011 05:34 PM, Andreas Färber wrote:
> Hi,
>
> Am 16.07.2011 um 23:49 schrieb till:
>
>> I have a proprietary ROM implementing system calls that are executed
>> via
>> the 'SC' instruction.
>>
>> I use qemu-0.14.1,
>>
>> qemu-system-ppc -M prep -cpu $CPU -bios my_bios -kernel my_kernel
>>
>> That works fine on a 604 (CPU=0x00040103) - but does not on an
>> emulated 7400 (CPU=0x000c0209) or 7450 (CPU=0x80000201). I found
>> that the emulator jumps to 0x00000c00 instead of 0xfff00c00.
>> Probably this is due to a wrong setting in target-ppc/
>> translate_init.c:
>>
>> init_excp_604() correctly sets env->hreset_vector=0xfff00000UL;
>>
>> but
>>
>> init_excp_7400() says env->hreset_vector=0x00000000UL;
>>
>> which seems wrong. (the 7400 manual says a hard-reset jumps
>> initializes the
>> prefix to 0xfff00000.)
> Do you have a link to a spec saying so? Should be trivial to change
> then.
>
>> Likewise, init_excp_7450() (and probably other, related CPUs) are
>> wrong.
>>
>> Indeed, when I change the value in init_excp_7400() to 0xfff00000UL
>> then
>> everything works as expected for me.
>>
>> ** Affects: qemu
>> Importance: Undecided
>> Status: New
>> Bug description:
>> I have a proprietary ROM implementing system calls that are executed
>> via the 'SC' instruction.
>>
>> I use qemu-0.14.1,
>>
>> qemu-system-ppc -M prep -cpu $CPU -bios my_bios -kernel my_kernel
> We are currently in the process of revamping the PReP machine you are
> using above. Is your BIOS available publicly so that we can test we
> don't break anything for you?
>
> Andreas
>

Samuel Bronson (naesten) on 2012-08-03
tags: added: exceptions ppc
Thomas Huth (th-huth) wrote :

Looking through old bug tickets... can you still reproduce this issue with the latest version of QEMU? Or could we close this ticket nowadays?

Changed in qemu:
status: New → Incomplete
till (till-straumann) wrote :

I no longer have the test readily available. So I tried to print the initial MSR and IP register contents from the QEMU monitor:

qemu-system-ppc -machine none -cpu 7400 -S -monitor stdio
QEMU 5.0.93 monitor - type 'help' for more information
(qemu) info registers
NIP 00000000 LR 00000000 CTR 00000000 XER 00000000 CPU#0
MSR 00000000 HID0 00000000 HF 00000000 iidx 0 didx 0
Segmentation fault (core dumped)

Unfortunately this lets qemu (tried 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.29) as well as 5.1.0-rc3) segfault; apparently the time-base is not initialized but still accessed when -machine == none. Yet another bug, it seems. The NIP and MSR seem wrong, however.

I can generate an empty ppc_rom.bin and fool a prep machine under 2.11.1:

till@tillp1 $ ls -l empty.bin
-rw-r--r-- 1 till till 0 Aug 8 12:03 empty.bin

till@tillp1 $ qemu-system-ppc -bios ./empty.bin -cpu 7400 -machine prep -S -monitor stdio
QEMU 2.11.1 monitor - type 'help' for more information
(qemu) info registers
NIP fff00100 LR 00000000 CTR 00000000 XER 00000000 CPU#0
MSR 00000040 HID0 00000000 HF 00000000 iidx 3 didx 3

Here, the issue is fixed! Apparently it is fixed for the 'prep' machine but not 'none'. Unfortunately 'prep' is gone from 5.3.0 and 'none' is buggy; wait - it seems I can emulate 'prep' with '40p':

till@tillp1 $ build/ppc-softmmu/qemu-system-ppc -machine 40p -cpu 7400 -S -monitor stdio
QEMU 5.0.93 monitor - type 'help' for more information
(qemu) info registers
NIP fff00100 LR 00000000 CTR 00000000 XER 00000000 CPU#0
MSR 00000040 HID0 00000000 HF 00000000 iidx 3 didx 3

This looks good, so I suppose it is OK to close this bug.

Thomas Huth (th-huth) wrote :

Ok, thanks for checking! I'll keep the bug open, though, in case someone wants to have a look at the segfault with the "none" machine.

Changed in qemu:
status: Incomplete → Triaged

Please don't close ticket if there's a known problem just to at least
document there's a problem. Is this a CPU feature or board specific?

Doesn't these CPUs have some way to select the exception vectors base and
could that be set wrong? I've also seen some problems with these CPUs but
last time I asked nobody answered:
https://lists.nongnu.org/archive/html/qemu-ppc/2020-03/msg00292.html
Could this bug be related to that?

till (till-straumann) wrote :

Yes, it is a CPU feature, and yes you can select the exception vector prefix with the MSR[IP] bit which should be set by a hardware reset. The initial value seems wrong in qemu but that seems to fixed by the machine-specific initialization. The 'none' machine, however, just uses generic code and does not do anything PPC-specific. This means that

 - the MSR and probably other registers, too, are not initialized to what the hardware
   documentation specifies as reset values.
 - the time-base is not initialized at all (and this leads to a segfault when you start the
   ppc 'none' machine)
 - probably other things are not properly initialized. I wonder, e.g., about the MMU...

It seems that all registers are simply initialized to zero. Then, there seems to be a 'reset' function which initializes the registers to the proper reset values (well - sort of bug 812398 reports that HID0 is not properly initialized by some CPU flavours). However, that reset function
is not executed by the 'none' machine initialization....

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers