diff mbox

[for-1.6] target-mips: do not raise exceptions when accessing invalid memory

Message ID 1374941897-11956-1-git-send-email-hpoussin@reactos.org
State New
Headers show

Commit Message

Hervé Poussineau July 27, 2013, 4:18 p.m. UTC
c658b94f6e8c206c59d02aa6fbac285b86b53d2c ("cpu: Turn cpu_unassigned_access()
into a CPUState hook") made MIPS raise exceptions when accessing
invalid memory for data, by unconditionally calling CPUState unassigned hook.

While this seems to be the right behaviour, this breaks a lot of guests
(Linux on Malta, NetBSD on Magnum...) which try to access not emulated devices
and crash because they don't handle the data load/store exception.

Revert to previous behaviour by not handling the !is_exec case in MIPS CPU hook.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---

Another solution would be to add a big dummy memory regions on all MIPS boards
to catch memory accesses and not raise an exception. However, this means that
each MIPS board will have its own unassigned memory handler, different from the
global QEMU one.

---
 target-mips/op_helper.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Andreas Färber July 27, 2013, 4:49 p.m. UTC | #1
Am 27.07.2013 18:18, schrieb Hervé Poussineau:
> c658b94f6e8c206c59d02aa6fbac285b86b53d2c ("cpu: Turn cpu_unassigned_access()
> into a CPUState hook") made MIPS raise exceptions when accessing
> invalid memory for data, by unconditionally calling CPUState unassigned hook.
> 
> While this seems to be the right behaviour, this breaks a lot of guests
> (Linux on Malta, NetBSD on Magnum...) which try to access not emulated devices
> and crash because they don't handle the data load/store exception.
> 
> Revert to previous behaviour by not handling the !is_exec case in MIPS CPU hook.
> 
> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>

So before my refactoring the following targets called it in files...

alpha: cputlb.c and memory.c
microblaze: memory.c
mips: cputlb.c
sparc: cputlb.c and memory.c

... and now all four call it in both places, breaking mips.

The proposed solution looks acceptable to me, but I am no mips expert;
CC'ing Aurélien, Stefan and some Imagination guys.

As a reminder, 1.6-rc0 is due on Monday.

> ---
> 
> Another solution would be to add a big dummy memory regions on all MIPS boards
> to catch memory accesses and not raise an exception. However, this means that
> each MIPS board will have its own unassigned memory handler, different from the
> global QEMU one.

sparc uses the empty_slot device to catch accesses to devices that we
are not yet emulating IIUC. I.e., empty_slot_init(addr, size).

Peter/Edgar, can you double-check whether calling the unassigned_access
handler from cputlb.c rather than cpu_abort()ing is OK for microblaze?

Thanks,
Andreas

> ---
>  target-mips/op_helper.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
> index 5cf1c3f..94f1692 100644
> --- a/target-mips/op_helper.c
> +++ b/target-mips/op_helper.c
> @@ -2156,7 +2156,8 @@ void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr,
>      if (is_exec) {
>          helper_raise_exception(env, EXCP_IBE);
>      } else {
> -        helper_raise_exception(env, EXCP_DBE);
> +        qemu_log_mask(LOG_UNIMP, "should raise DBE exception "
> +                      "due to accessing memory at %" HWADDR_PRIx "\n", addr);
>      }
>  }
>  #endif /* !CONFIG_USER_ONLY */
>
Peter Maydell July 27, 2013, 5:43 p.m. UTC | #2
On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
> Another solution would be to add a big dummy memory regions on all MIPS boards
> to catch memory accesses and not raise an exception. However, this means that
> each MIPS board will have its own unassigned memory handler, different from the
> global QEMU one.

Better would be to at least provide fake RAZ/WI implementations of
devices for the boards, rather than making the dummy region cover
the whole of the address space. Not 1.6 material, though.

-- PMM
Stefan Weil July 27, 2013, 7:37 p.m. UTC | #3
Am 27.07.2013 19:43, schrieb Peter Maydell:
> On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
>> Another solution would be to add a big dummy memory regions on all MIPS boards
>> to catch memory accesses and not raise an exception. However, this means that
>> each MIPS board will have its own unassigned memory handler, different from the
>> global QEMU one.
> Better would be to at least provide fake RAZ/WI implementations of
> devices for the boards, rather than making the dummy region cover
> the whole of the address space. Not 1.6 material, though.
>
> -- PMM

I prefer keeping the correct code for target-mips/op_helper.c
and adding either the big dummy memory regions or fake
device implementations (both with TODO comments) for 1.6.

It would also be acceptable to fix the boards in 1.6.1 and add
a comment to the 1.6 release notes about the "regression".

Stefan
Andreas Färber July 27, 2013, 8:43 p.m. UTC | #4
Am 27.07.2013 21:37, schrieb Stefan Weil:
> Am 27.07.2013 19:43, schrieb Peter Maydell:
>> On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
>>> Another solution would be to add a big dummy memory regions on all MIPS boards
>>> to catch memory accesses and not raise an exception. However, this means that
>>> each MIPS board will have its own unassigned memory handler, different from the
>>> global QEMU one.
>> Better would be to at least provide fake RAZ/WI implementations of
>> devices for the boards, rather than making the dummy region cover
>> the whole of the address space. Not 1.6 material, though.
> 
> I prefer keeping the correct code for target-mips/op_helper.c
> and adding either the big dummy memory regions or fake
> device implementations (both with TODO comments) for 1.6.

The problem I see with that is, so far no one has stepped up with a list
of what memory ranges / devices we are talking about.

The simplest for 1.6 might be to re-add an #ifndef TARGET_MIPS around
the refactored call to restore old behavior.

Andreas
Peter Maydell July 27, 2013, 8:57 p.m. UTC | #5
On 27 July 2013 21:43, Andreas Färber <afaerber@suse.de> wrote:
> Am 27.07.2013 21:37, schrieb Stefan Weil:
>> Am 27.07.2013 19:43, schrieb Peter Maydell:
>>> On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
>>>> Another solution would be to add a big dummy memory regions on all MIPS boards
>>>> to catch memory accesses and not raise an exception. However, this means that
>>>> each MIPS board will have its own unassigned memory handler, different from the
>>>> global QEMU one.
>>> Better would be to at least provide fake RAZ/WI implementations of
>>> devices for the boards, rather than making the dummy region cover
>>> the whole of the address space. Not 1.6 material, though.
>>
>> I prefer keeping the correct code for target-mips/op_helper.c
>> and adding either the big dummy memory regions or fake
>> device implementations (both with TODO comments) for 1.6.
>
> The problem I see with that is, so far no one has stepped up with a list
> of what memory ranges / devices we are talking about.

Yeah, that was what I meant with my comment about providing
fake devices being "not 1.6". Longer term if nobody
cares enough about the boards to dig up enough info to do this
then maybe we should drop the board models, but for 1.6 trying
to get that right for all the affected boards in the time we
have seems a bit risky.

> The simplest for 1.6 might be to re-add an #ifndef TARGET_MIPS around
> the refactored call to restore old behavior.

The advantage of adding single whole-space RAZ/WI regions
for each affected board is that then we can fix them up
one at a time to be more discriminating about how much
space they do this for. A single ifdef would certainly
be simpler though.

-- PMM
Stefan Weil July 27, 2013, 8:58 p.m. UTC | #6
Am 27.07.2013 22:43, schrieb Andreas Färber:
> Am 27.07.2013 21:37, schrieb Stefan Weil:
>> Am 27.07.2013 19:43, schrieb Peter Maydell:
>>> On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
>>>> Another solution would be to add a big dummy memory regions on all MIPS boards
>>>> to catch memory accesses and not raise an exception. However, this means that
>>>> each MIPS board will have its own unassigned memory handler, different from the
>>>> global QEMU one.
>>> Better would be to at least provide fake RAZ/WI implementations of
>>> devices for the boards, rather than making the dummy region cover
>>> the whole of the address space. Not 1.6 material, though.
>> I prefer keeping the correct code for target-mips/op_helper.c
>> and adding either the big dummy memory regions or fake
>> device implementations (both with TODO comments) for 1.6.
> The problem I see with that is, so far no one has stepped up with a list
> of what memory ranges / devices we are talking about.
>
> The simplest for 1.6 might be to re-add an #ifndef TARGET_MIPS around
> the refactored call to restore old behavior.
>
> Andreas

Hervé's patch or the big dummy memory region can be used to get
the memory addresses in a certain test scenario from log messages.

These addresses can then be added as "undefined devices" with a TODO comment.

I might send a fix for MIPS Malta which gets Linux working again,
but maybe not before 1.6.1.

Stefan
Stefan Weil July 29, 2013, 8:35 p.m. UTC | #7
Am 27.07.2013 22:58, schrieb Stefan Weil:
> Am 27.07.2013 22:43, schrieb Andreas Färber:
>> Am 27.07.2013 21:37, schrieb Stefan Weil:
>>> Am 27.07.2013 19:43, schrieb Peter Maydell:
>>>> On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
>>>>> Another solution would be to add a big dummy memory regions on all MIPS boards
>>>>> to catch memory accesses and not raise an exception. However, this means that
>>>>> each MIPS board will have its own unassigned memory handler, different from the
>>>>> global QEMU one.
>>>> Better would be to at least provide fake RAZ/WI implementations of
>>>> devices for the boards, rather than making the dummy region cover
>>>> the whole of the address space. Not 1.6 material, though.


For MIPS Malta, Linux boot can be fixed by handling read access for two
addresses:

0x1fbf8008
0x1bc80110

The corresponding definitions in the Linux kernel code seem to be these
lines:

#define GCMP_BASE_ADDR                  0x1fbf8000
#define GCMP_ADDRSPACE_SZ               (256 * 1024)
#define GCMP_GCB_GCMPB_OFS              0x0008          /* Global GCMP
Base */

#define MSC01_BIU_REG_BASE              0x1bc80000
#define MSC01_BIU_ADDRSPACE_SZ          (256 * 1024)
#define MSC01_SC_CFG_OFS                0x0110

=> mips_malta.c needs a handler for reads of
(GCMP_BASE_ADDR + GCMP_GCB_GCMPB_OFS) and
(MSC01_BIU_REG_BASE + MSC01_SC_CFG_OFS).

Regards,

Stefan W.
Aurelien Jarno Aug. 4, 2013, 10:04 p.m. UTC | #8
On Mon, Jul 29, 2013 at 10:35:31PM +0200, Stefan Weil wrote:
> Am 27.07.2013 22:58, schrieb Stefan Weil:
> > Am 27.07.2013 22:43, schrieb Andreas Färber:
> >> Am 27.07.2013 21:37, schrieb Stefan Weil:
> >>> Am 27.07.2013 19:43, schrieb Peter Maydell:
> >>>> On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
> >>>>> Another solution would be to add a big dummy memory regions on all MIPS boards
> >>>>> to catch memory accesses and not raise an exception. However, this means that
> >>>>> each MIPS board will have its own unassigned memory handler, different from the
> >>>>> global QEMU one.
> >>>> Better would be to at least provide fake RAZ/WI implementations of
> >>>> devices for the boards, rather than making the dummy region cover
> >>>> the whole of the address space. Not 1.6 material, though.
> 
> 
> For MIPS Malta, Linux boot can be fixed by handling read access for two
> addresses:
> 
> 0x1fbf8008
> 0x1bc80110
>
> The corresponding definitions in the Linux kernel code seem to be these
> lines:
> 
> #define GCMP_BASE_ADDR                  0x1fbf8000
> #define GCMP_ADDRSPACE_SZ               (256 * 1024)
> #define GCMP_GCB_GCMPB_OFS              0x0008          /* Global GCMP
> Base */
> 
> #define MSC01_BIU_REG_BASE              0x1bc80000
> #define MSC01_BIU_ADDRSPACE_SZ          (256 * 1024)
> #define MSC01_SC_CFG_OFS                0x0110
> 
> => mips_malta.c needs a handler for reads of
> (GCMP_BASE_ADDR + GCMP_GCB_GCMPB_OFS) and
> (MSC01_BIU_REG_BASE + MSC01_SC_CFG_OFS).

I don't think it would be correct to emulate them as this are not
present on the real Malta board, at least for the model emulated by
QEMU. Theses addresses correspond to the SMP controller, and is
therefore only present when an SMP daughter card is installed.

The Linux kernel probes theses addresses, and look if they return
something consistent. If not the corresponding devices are latter
ignored.

The real hardware probably returns all 1 or all 0 for addresses not
decoded to a device. This is what QEMU should model, and it should
not trigger a DBE or IBE exception. Looking at the current MIPS
documentation, Bus Error is defined as:

  A bus error exception occurs when an instruction or data access makes a
  bus request (due to a cache miss or an  uncacheable reference) and
  that request terminates in an error.

Older CPU documentation like the R4000 have a more precise definition:

  A Bus Error exception is raised by board-level circuitry for events such
  as bus time-out, backplane bus parity errors, and invalid physical memory
  addresses or access types.

As we don't model this kind of errors, we should definitely just not
trigger an exception in that case, and even logging the event as
unimplemented is probably wrong.
Peter Maydell Aug. 4, 2013, 10:37 p.m. UTC | #9
On 4 August 2013 23:04, Aurélien Jarno <aurelien@aurel32.net> wrote:
> The real hardware probably returns all 1 or all 0 for addresses not
> decoded to a device. This is what QEMU should model, and it should
> not trigger a DBE or IBE exception. Looking at the current MIPS
> documentation, Bus Error is defined as:
>
>   A bus error exception occurs when an instruction or data access makes a
>   bus request (due to a cache miss or an  uncacheable reference) and
>   that request terminates in an error.
>
> Older CPU documentation like the R4000 have a more precise definition:
>
>   A Bus Error exception is raised by board-level circuitry for events such
>   as bus time-out, backplane bus parity errors, and invalid physical memory
>   addresses or access types.
>
> As we don't model this kind of errors, we should definitely just not
> trigger an exception in that case, and even logging the event as
> unimplemented is probably wrong.

Well, we certainly can model invalid-physical-address and
bus-timeout where that's what the board does for accesses
to non-decoded addresses; but presumably in this case it
doesn't...

-- PMM
Stefan Weil Aug. 5, 2013, 5:19 a.m. UTC | #10
Am 05.08.2013 00:37, schrieb Peter Maydell:
> On 4 August 2013 23:04, Aurélien Jarno <aurelien@aurel32.net> wrote:
>> The real hardware probably returns all 1 or all 0 for addresses not
>> decoded to a device. This is what QEMU should model, and it should
>> not trigger a DBE or IBE exception. Looking at the current MIPS
>> documentation, Bus Error is defined as:
>>
>>   A bus error exception occurs when an instruction or data access makes a
>>   bus request (due to a cache miss or an  uncacheable reference) and
>>   that request terminates in an error.
>>
>> Older CPU documentation like the R4000 have a more precise definition:
>>
>>   A Bus Error exception is raised by board-level circuitry for events such
>>   as bus time-out, backplane bus parity errors, and invalid physical memory
>>   addresses or access types.
>>
>> As we don't model this kind of errors, we should definitely just not
>> trigger an exception in that case, and even logging the event as
>> unimplemented is probably wrong.
> Well, we certainly can model invalid-physical-address and
> bus-timeout where that's what the board does for accesses
> to non-decoded addresses; but presumably in this case it
> doesn't...
>
> -- PMM

Is there anybody who has access to physical Malta hardware?
It would be interesting to see whether there is an exception
during the gcmp test or not.

With latest QEMU, the MIPS Malta system emulation starts
handling the exception caused by the gcmp test, but then
gets a second exception which is fatal (see below).

There might be something missing in our very simple bios
emulation.

=> If real hardware triggers an exception, then fixing the
bios emulation would be the correct way to handle this in
QEMU.

Stefan




[    0.000000] CPU 0 Unable to handle kernel paging request at virtual
address 00000048, epc == 80100f74, ra == 80107f1c
[    0.000000] Oops[#1]:
[    0.000000] Cpu 0
[    0.000000] $ 0   : 00000000 10000000 f8000000 00000000
[    0.000000] $ 4   : 804edeb8 00000000 8051684c 00000000
[    0.000000] $ 8   : 10000000 1000001f 8f5b0000 277b0001
[    0.000000] $12   : af5b0000 80540000 00000000 42000018
[    0.000000] $16   : 00000000 804edeb8 00000002 00000004
[    0.000000] $20   : 00000000 00000000 00000000 80540000
[    0.000000] $24   : 00000000 8010f7f0                 
[    0.000000] $28   : 804ec000 804edd38 00000000 80107f1c
[    0.000000] Hi    : 00000000
[    0.000000] Lo    : 00000000
[    0.000000] epc   : 80100f74 malta_be_handler+0x4c/0x224     Not tainted
[    0.000000] ra    : 80107f1c do_be+0x11c/0x1ac
[    0.000000] Status: 10000002    KERNEL EXL
[    0.000000] Cause : 00800008
[    0.000000] BadVA : 00000048
[    0.000000] PrId  : 00019000 (MIPS 4KEc)
[    0.000000] Modules linked in:
[    0.000000] Process swapper (pid: 0, threadinfo=804ec000,
task=804ee168, tls=00000000)
[    0.000000] Stack : ffffffff 00000001 ffffffff 00000002 00000400
802ae1c0 804eded0 804edeee
[    0.000000]         ffffffff 804eded4 00000006 00000001 804edee8
804edf06 ffffffff 804edeec
[    0.000000]         00000006 00000001 80500000 ffffffff 804edf08
804edf26 ffffffff 804edf0c
[    0.000000]         00000006 00000001 80500000 ffffffff 7fb120e3
802ae1c0 802ae2a4 00000002
[    0.000000]         ffffffff 00000002 0000000a 00000006 ffffffff
00000001 00000775 00000775
[    0.000000]         ...
[    0.000000] Call Trace:
[    0.000000] [<80100f74>] malta_be_handler+0x4c/0x224
[    0.000000] [<80107f1c>] do_be+0x11c/0x1ac
[    0.000000] [<80101900>] ret_from_exception+0x0/0x24
[    0.000000] [<8051684c>] gcmp_probe+0x38/0xa0
[    0.000000] [<805168dc>] arch_init_irq+0x28/0x124
[    0.000000] [<8050eb10>] start_kernel+0x1d4/0x400
[    0.000000] [<80433cb0>] kernel_entry+0x0/0x90
Andreas Färber Aug. 5, 2013, 8:45 a.m. UTC | #11
Am 05.08.2013 00:04, schrieb Aurélien Jarno:
> On Mon, Jul 29, 2013 at 10:35:31PM +0200, Stefan Weil wrote:
>> Am 27.07.2013 22:58, schrieb Stefan Weil:
>>> Am 27.07.2013 22:43, schrieb Andreas Färber:
>>>> Am 27.07.2013 21:37, schrieb Stefan Weil:
>>>>> Am 27.07.2013 19:43, schrieb Peter Maydell:
>>>>>> On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
>>>>>>> Another solution would be to add a big dummy memory regions on all MIPS boards
>>>>>>> to catch memory accesses and not raise an exception. However, this means that
>>>>>>> each MIPS board will have its own unassigned memory handler, different from the
>>>>>>> global QEMU one.
>>>>>> Better would be to at least provide fake RAZ/WI implementations of
>>>>>> devices for the boards, rather than making the dummy region cover
>>>>>> the whole of the address space. Not 1.6 material, though.
>>
>>
>> For MIPS Malta, Linux boot can be fixed by handling read access for two
>> addresses:
>>
>> 0x1fbf8008
>> 0x1bc80110
>>
>> The corresponding definitions in the Linux kernel code seem to be these
>> lines:
>>
>> #define GCMP_BASE_ADDR                  0x1fbf8000
>> #define GCMP_ADDRSPACE_SZ               (256 * 1024)
>> #define GCMP_GCB_GCMPB_OFS              0x0008          /* Global GCMP
>> Base */
>>
>> #define MSC01_BIU_REG_BASE              0x1bc80000
>> #define MSC01_BIU_ADDRSPACE_SZ          (256 * 1024)
>> #define MSC01_SC_CFG_OFS                0x0110
>>
>> => mips_malta.c needs a handler for reads of
>> (GCMP_BASE_ADDR + GCMP_GCB_GCMPB_OFS) and
>> (MSC01_BIU_REG_BASE + MSC01_SC_CFG_OFS).
> 
> I don't think it would be correct to emulate them as this are not
> present on the real Malta board, at least for the model emulated by
> QEMU. Theses addresses correspond to the SMP controller, and is
> therefore only present when an SMP daughter card is installed.
> 
> The Linux kernel probes theses addresses, and look if they return
> something consistent. If not the corresponding devices are latter
> ignored.
> 
> The real hardware probably returns all 1 or all 0 for addresses not
> decoded to a device. This is what QEMU should model, and it should
> not trigger a DBE or IBE exception.
[snip]

Have you tested Jan's patches limiting the new unassigned read value -1
to PIO?

Andreas
Jan Kiszka Aug. 5, 2013, 8:47 a.m. UTC | #12
On 2013-08-05 10:45, Andreas Färber wrote:
> Am 05.08.2013 00:04, schrieb Aurélien Jarno:
>> On Mon, Jul 29, 2013 at 10:35:31PM +0200, Stefan Weil wrote:
>>> Am 27.07.2013 22:58, schrieb Stefan Weil:
>>>> Am 27.07.2013 22:43, schrieb Andreas Färber:
>>>>> Am 27.07.2013 21:37, schrieb Stefan Weil:
>>>>>> Am 27.07.2013 19:43, schrieb Peter Maydell:
>>>>>>> On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
>>>>>>>> Another solution would be to add a big dummy memory regions on all MIPS boards
>>>>>>>> to catch memory accesses and not raise an exception. However, this means that
>>>>>>>> each MIPS board will have its own unassigned memory handler, different from the
>>>>>>>> global QEMU one.
>>>>>>> Better would be to at least provide fake RAZ/WI implementations of
>>>>>>> devices for the boards, rather than making the dummy region cover
>>>>>>> the whole of the address space. Not 1.6 material, though.
>>>
>>>
>>> For MIPS Malta, Linux boot can be fixed by handling read access for two
>>> addresses:
>>>
>>> 0x1fbf8008
>>> 0x1bc80110
>>>
>>> The corresponding definitions in the Linux kernel code seem to be these
>>> lines:
>>>
>>> #define GCMP_BASE_ADDR                  0x1fbf8000
>>> #define GCMP_ADDRSPACE_SZ               (256 * 1024)
>>> #define GCMP_GCB_GCMPB_OFS              0x0008          /* Global GCMP
>>> Base */
>>>
>>> #define MSC01_BIU_REG_BASE              0x1bc80000
>>> #define MSC01_BIU_ADDRSPACE_SZ          (256 * 1024)
>>> #define MSC01_SC_CFG_OFS                0x0110
>>>
>>> => mips_malta.c needs a handler for reads of
>>> (GCMP_BASE_ADDR + GCMP_GCB_GCMPB_OFS) and
>>> (MSC01_BIU_REG_BASE + MSC01_SC_CFG_OFS).
>>
>> I don't think it would be correct to emulate them as this are not
>> present on the real Malta board, at least for the model emulated by
>> QEMU. Theses addresses correspond to the SMP controller, and is
>> therefore only present when an SMP daughter card is installed.
>>
>> The Linux kernel probes theses addresses, and look if they return
>> something consistent. If not the corresponding devices are latter
>> ignored.
>>
>> The real hardware probably returns all 1 or all 0 for addresses not
>> decoded to a device. This is what QEMU should model, and it should
>> not trigger a DBE or IBE exception.
> [snip]
> 
> Have you tested Jan's patches limiting the new unassigned read value -1
> to PIO?

Yeah, this sounds a lot like another side effect of using
unassigned_mem_ops for PIO...

Jan
Aurelien Jarno Aug. 5, 2013, 12:27 p.m. UTC | #13
On Mon, Aug 05, 2013 at 07:19:08AM +0200, Stefan Weil wrote:
> Am 05.08.2013 00:37, schrieb Peter Maydell:
> > On 4 August 2013 23:04, Aurélien Jarno <aurelien@aurel32.net> wrote:
> >> The real hardware probably returns all 1 or all 0 for addresses not
> >> decoded to a device. This is what QEMU should model, and it should
> >> not trigger a DBE or IBE exception. Looking at the current MIPS
> >> documentation, Bus Error is defined as:
> >>
> >>   A bus error exception occurs when an instruction or data access makes a
> >>   bus request (due to a cache miss or an  uncacheable reference) and
> >>   that request terminates in an error.
> >>
> >> Older CPU documentation like the R4000 have a more precise definition:
> >>
> >>   A Bus Error exception is raised by board-level circuitry for events such
> >>   as bus time-out, backplane bus parity errors, and invalid physical memory
> >>   addresses or access types.
> >>
> >> As we don't model this kind of errors, we should definitely just not
> >> trigger an exception in that case, and even logging the event as
> >> unimplemented is probably wrong.
> > Well, we certainly can model invalid-physical-address and
> > bus-timeout where that's what the board does for accesses
> > to non-decoded addresses; but presumably in this case it
> > doesn't...
> >
> > -- PMM
> 
> Is there anybody who has access to physical Malta hardware?
> It would be interesting to see whether there is an exception
> during the gcmp test or not.
> 
> With latest QEMU, the MIPS Malta system emulation starts
> handling the exception caused by the gcmp test, but then
> gets a second exception which is fatal (see below).
> 
> There might be something missing in our very simple bios
> emulation.

Booting YAMON in QEMU also shows the same behaviour, that is trying to
access to the 1fbf8008 address and getting a DBE exception, causing it
to fail. So it is clearly not due to our simple bios emulation, but
rather to the way the I/O are emulated.
Aurelien Jarno Aug. 5, 2013, 1:31 p.m. UTC | #14
On Mon, Aug 05, 2013 at 10:45:31AM +0200, Andreas Färber wrote:
> Am 05.08.2013 00:04, schrieb Aurélien Jarno:
> > On Mon, Jul 29, 2013 at 10:35:31PM +0200, Stefan Weil wrote:
> >> Am 27.07.2013 22:58, schrieb Stefan Weil:
> >>> Am 27.07.2013 22:43, schrieb Andreas Färber:
> >>>> Am 27.07.2013 21:37, schrieb Stefan Weil:
> >>>>> Am 27.07.2013 19:43, schrieb Peter Maydell:
> >>>>>> On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
> >>>>>>> Another solution would be to add a big dummy memory regions on all MIPS boards
> >>>>>>> to catch memory accesses and not raise an exception. However, this means that
> >>>>>>> each MIPS board will have its own unassigned memory handler, different from the
> >>>>>>> global QEMU one.
> >>>>>> Better would be to at least provide fake RAZ/WI implementations of
> >>>>>> devices for the boards, rather than making the dummy region cover
> >>>>>> the whole of the address space. Not 1.6 material, though.
> >>
> >>
> >> For MIPS Malta, Linux boot can be fixed by handling read access for two
> >> addresses:
> >>
> >> 0x1fbf8008
> >> 0x1bc80110
> >>
> >> The corresponding definitions in the Linux kernel code seem to be these
> >> lines:
> >>
> >> #define GCMP_BASE_ADDR                  0x1fbf8000
> >> #define GCMP_ADDRSPACE_SZ               (256 * 1024)
> >> #define GCMP_GCB_GCMPB_OFS              0x0008          /* Global GCMP
> >> Base */
> >>
> >> #define MSC01_BIU_REG_BASE              0x1bc80000
> >> #define MSC01_BIU_ADDRSPACE_SZ          (256 * 1024)
> >> #define MSC01_SC_CFG_OFS                0x0110
> >>
> >> => mips_malta.c needs a handler for reads of
> >> (GCMP_BASE_ADDR + GCMP_GCB_GCMPB_OFS) and
> >> (MSC01_BIU_REG_BASE + MSC01_SC_CFG_OFS).
> > 
> > I don't think it would be correct to emulate them as this are not
> > present on the real Malta board, at least for the model emulated by
> > QEMU. Theses addresses correspond to the SMP controller, and is
> > therefore only present when an SMP daughter card is installed.
> > 
> > The Linux kernel probes theses addresses, and look if they return
> > something consistent. If not the corresponding devices are latter
> > ignored.
> > 
> > The real hardware probably returns all 1 or all 0 for addresses not
> > decoded to a device. This is what QEMU should model, and it should
> > not trigger a DBE or IBE exception.
> [snip]
> 
> Have you tested Jan's patches limiting the new unassigned read value -1
> to PIO?
> 

I have tried this patches, and they don't fix the problem.
Andreas Färber Aug. 5, 2013, 1:45 p.m. UTC | #15
Am 05.08.2013 15:31, schrieb Aurélien Jarno:
> On Mon, Aug 05, 2013 at 10:45:31AM +0200, Andreas Färber wrote:
>> Am 05.08.2013 00:04, schrieb Aurélien Jarno:
>>> On Mon, Jul 29, 2013 at 10:35:31PM +0200, Stefan Weil wrote:
>>>> Am 27.07.2013 22:58, schrieb Stefan Weil:
>>>>> Am 27.07.2013 22:43, schrieb Andreas Färber:
>>>>>> Am 27.07.2013 21:37, schrieb Stefan Weil:
>>>>>>> Am 27.07.2013 19:43, schrieb Peter Maydell:
>>>>>>>> On 27 July 2013 17:18, Hervé Poussineau <hpoussin@reactos.org> wrote:
>>>>>>>>> Another solution would be to add a big dummy memory regions on all MIPS boards
>>>>>>>>> to catch memory accesses and not raise an exception. However, this means that
>>>>>>>>> each MIPS board will have its own unassigned memory handler, different from the
>>>>>>>>> global QEMU one.
>>>>>>>> Better would be to at least provide fake RAZ/WI implementations of
>>>>>>>> devices for the boards, rather than making the dummy region cover
>>>>>>>> the whole of the address space. Not 1.6 material, though.
>>>>
>>>>
>>>> For MIPS Malta, Linux boot can be fixed by handling read access for two
>>>> addresses:
>>>>
>>>> 0x1fbf8008
>>>> 0x1bc80110
>>>>
>>>> The corresponding definitions in the Linux kernel code seem to be these
>>>> lines:
>>>>
>>>> #define GCMP_BASE_ADDR                  0x1fbf8000
>>>> #define GCMP_ADDRSPACE_SZ               (256 * 1024)
>>>> #define GCMP_GCB_GCMPB_OFS              0x0008          /* Global GCMP
>>>> Base */
>>>>
>>>> #define MSC01_BIU_REG_BASE              0x1bc80000
>>>> #define MSC01_BIU_ADDRSPACE_SZ          (256 * 1024)
>>>> #define MSC01_SC_CFG_OFS                0x0110
>>>>
>>>> => mips_malta.c needs a handler for reads of
>>>> (GCMP_BASE_ADDR + GCMP_GCB_GCMPB_OFS) and
>>>> (MSC01_BIU_REG_BASE + MSC01_SC_CFG_OFS).
>>>
>>> I don't think it would be correct to emulate them as this are not
>>> present on the real Malta board, at least for the model emulated by
>>> QEMU. Theses addresses correspond to the SMP controller, and is
>>> therefore only present when an SMP daughter card is installed.
>>>
>>> The Linux kernel probes theses addresses, and look if they return
>>> something consistent. If not the corresponding devices are latter
>>> ignored.
>>>
>>> The real hardware probably returns all 1 or all 0 for addresses not
>>> decoded to a device. This is what QEMU should model, and it should
>>> not trigger a DBE or IBE exception.
>> [snip]
>>
>> Have you tested Jan's patches limiting the new unassigned read value -1
>> to PIO?
>>
> 
> I have tried this patches, and they don't fix the problem.

Too bad. So what do you propose? Restoring #ifdef and using
empty_slot_init() have been suggested so far, any other concrete ideas?

Andreas
Hervé Poussineau Aug. 5, 2013, 1:53 p.m. UTC | #16
Andreas Färber a écrit :
>>> [snip]
>>>
>>> Have you tested Jan's patches limiting the new unassigned read value -1
>>> to PIO?
>>>
>> I have tried this patches, and they don't fix the problem.
> 
> Too bad. So what do you propose? Restoring #ifdef and using
> empty_slot_init() have been suggested so far, any other concrete ideas?

Another idea (not tested): override the CPUClass->do_unassigned_level on 
board level, to only raise IBE and no DBE.
That way, right behaviour is kept in global code, and "bad" code is only 
at board level, where it can be removed later board after board.

Hervé
Aurelien Jarno Aug. 5, 2013, 2:07 p.m. UTC | #17
On Mon, Aug 05, 2013 at 03:53:08PM +0200, Hervé Poussineau wrote:
> Andreas Färber a écrit :
> >>>[snip]
> >>>
> >>>Have you tested Jan's patches limiting the new unassigned read value -1
> >>>to PIO?
> >>>
> >>I have tried this patches, and they don't fix the problem.
> >
> >Too bad. So what do you propose? Restoring #ifdef and using
> >empty_slot_init() have been suggested so far, any other concrete ideas?
> 
> Another idea (not tested): override the
> CPUClass->do_unassigned_level on board level, to only raise IBE and
> no DBE.
> That way, right behaviour is kept in global code, and "bad" code is
> only at board level, where it can be removed later board after
> board.

The problem is that it looks like the code is not "bad". It seems that
real hardware just ignore such accesses, so this should stay forever.
Peter Maydell Aug. 5, 2013, 2:15 p.m. UTC | #18
On 5 August 2013 15:07, Aurélien Jarno <aurelien@aurel32.net> wrote:
> On Mon, Aug 05, 2013 at 03:53:08PM +0200, Hervé Poussineau wrote:
>> Another idea (not tested): override the
>> CPUClass->do_unassigned_level on board level, to only raise IBE and
>> no DBE.

This sounds like a bit of a layering violation...

>> That way, right behaviour is kept in global code, and "bad" code is
>> only at board level, where it can be removed later board after
>> board.
>
> The problem is that it looks like the code is not "bad". It seems that
> real hardware just ignore such accesses, so this should stay forever.

But this is just board level behaviour, right? So the right
place to implement it is definitely in the board model.
If this is how the board works I think my first try would
be to have the board register a background region covering
the whole system memory space which returns 0 or -1 or whatever
the board does.

-- PMM
diff mbox

Patch

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 5cf1c3f..94f1692 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2156,7 +2156,8 @@  void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr,
     if (is_exec) {
         helper_raise_exception(env, EXCP_IBE);
     } else {
-        helper_raise_exception(env, EXCP_DBE);
+        qemu_log_mask(LOG_UNIMP, "should raise DBE exception "
+                      "due to accessing memory at %" HWADDR_PRIx "\n", addr);
     }
 }
 #endif /* !CONFIG_USER_ONLY */