diff mbox

[v3,2/5] hw/mips: Do not clear BEV for MIPS malta kernel load

Message ID 1434708524-25434-3-git-send-email-leon.alrae@imgtec.com
State New
Headers show

Commit Message

Leon Alrae June 19, 2015, 10:08 a.m. UTC
From: Matthew Fortune <matthew.fortune@imgtec.com>

The BEV flag controls whether the boot exception vector is still
in place when starting a kernel.  When cleared the exception vector
at EBASE (or hard coded address of 0x80000000) is used instead.

The early stages of the linux kernel would benefit from BEV still
being set to ensure any faults get handled by the boot rom exception
handlers.  This is a moot point for system qemu as there aren't really
any BEV handlers, but there are other good reasons to change this...

The UHI (semi-hosting interface) defines special behaviours depending
on whether an application starts in an environment with BEV set or
cleared. When BEV is set then UHI assumes that a bootloader is
relatively dumb and has no advanced exception handling logic.
However, when BEV is cleared then UHI assumes that the bootloader
has the ability to handle UHI exceptions with its exception handlers
and will unwind and forward UHI SYSCALL exceptions to the exception
vector that was installed prior to running the application.

Signed-off-by: Matthew Fortune <matthew.fortune@imgtec.com>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 hw/mips/mips_malta.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Aurelien Jarno June 24, 2015, 2:29 p.m. UTC | #1
On 2015-06-19 11:08, Leon Alrae wrote:
> From: Matthew Fortune <matthew.fortune@imgtec.com>
> 
> The BEV flag controls whether the boot exception vector is still
> in place when starting a kernel.  When cleared the exception vector
> at EBASE (or hard coded address of 0x80000000) is used instead.
> 
> The early stages of the linux kernel would benefit from BEV still
> being set to ensure any faults get handled by the boot rom exception
> handlers.  This is a moot point for system qemu as there aren't really
> any BEV handlers, but there are other good reasons to change this...

The fake boot loader doesn't provide any exception handler at address
0xbcf00200. On the other hand the kernel might provide an exception
handler at address 0x80000000 through the ELF file (this doesn't seem to
be the case currently).

Is there a clear interface which defines the value of this bit when
booting a kernel. If not, it would be a good idea to look what YAMON or
U-Boot do and mimic that.

> The UHI (semi-hosting interface) defines special behaviours depending
> on whether an application starts in an environment with BEV set or
> cleared. When BEV is set then UHI assumes that a bootloader is
> relatively dumb and has no advanced exception handling logic.
> However, when BEV is cleared then UHI assumes that the bootloader
> has the ability to handle UHI exceptions with its exception handlers
> and will unwind and forward UHI SYSCALL exceptions to the exception
> vector that was installed prior to running the application.

In UHI mode that indeed makes sense.

> Signed-off-by: Matthew Fortune <matthew.fortune@imgtec.com>
> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
>  hw/mips/mips_malta.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index 786a8f0..a5d64d5 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -887,7 +887,7 @@ static void main_cpu_reset(void *opaque)
>         read only location. The kernel location and the arguments table
>         location does not change. */
>      if (loaderparams.kernel_filename) {
> -        env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
> +        env->CP0_Status &= ~(1 << CP0St_ERL);
>      }
>  
>      malta_mips_config(cpu);
>
Matthew Fortune June 24, 2015, 4:21 p.m. UTC | #2
Aurelien Jarno <aurelien@aurel32.net> writes:
> On 2015-06-19 11:08, Leon Alrae wrote:
> > From: Matthew Fortune <matthew.fortune@imgtec.com>
> >
> > The BEV flag controls whether the boot exception vector is still in
> > place when starting a kernel.  When cleared the exception vector at
> > EBASE (or hard coded address of 0x80000000) is used instead.
> >
> > The early stages of the linux kernel would benefit from BEV still
> > being set to ensure any faults get handled by the boot rom exception
> > handlers.  This is a moot point for system qemu as there aren't really
> > any BEV handlers, but there are other good reasons to change this...
> 
> The fake boot loader doesn't provide any exception handler at address
> 0xbcf00200. On the other hand the kernel might provide an exception
> handler at address 0x80000000 through the ELF file (this doesn't seem to
> be the case currently).

I don't think this would be a reasonable thing to support. If something
clears BEV then IMO it is responsible for putting an exception handler
in 0x80000000 (/EBASE). The fact that the fake bootloader has nothing at
0xbfc00200 doesn't really make anything any worse, it doesn't have one
at 0x80000000 either. An application that is aware of the need for
providing an exception vector is also going to have to account for BEV
and EBASE to operate safely so I'd call it an app bug if it did anything
other.
 
> Is there a clear interface which defines the value of this bit when
> booting a kernel. If not, it would be a good idea to look what YAMON or
> U-Boot do and mimic that.

My investigation at the time (as a non-kernel developer) showed that
the status register is taken over entirely with the only exception being
that the ERL bit is mostly expected to be clear by the time the kernel
is entered.

u-boot and yamon clear BEV but, importantly, provide an exception vector
at EBASE.

Thanks,
Matthew

> > The UHI (semi-hosting interface) defines special behaviours depending
> > on whether an application starts in an environment with BEV set or
> > cleared. When BEV is set then UHI assumes that a bootloader is
> > relatively dumb and has no advanced exception handling logic.
> > However, when BEV is cleared then UHI assumes that the bootloader has
> > the ability to handle UHI exceptions with its exception handlers and
> > will unwind and forward UHI SYSCALL exceptions to the exception vector
> > that was installed prior to running the application.
> 
> In UHI mode that indeed makes sense.
> 
> > Signed-off-by: Matthew Fortune <matthew.fortune@imgtec.com>
> > Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
> > ---
> >  hw/mips/mips_malta.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index
> > 786a8f0..a5d64d5 100644
> > --- a/hw/mips/mips_malta.c
> > +++ b/hw/mips/mips_malta.c
> > @@ -887,7 +887,7 @@ static void main_cpu_reset(void *opaque)
> >         read only location. The kernel location and the arguments
> table
> >         location does not change. */
> >      if (loaderparams.kernel_filename) {
> > -        env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
> > +        env->CP0_Status &= ~(1 << CP0St_ERL);
> >      }
> >
> >      malta_mips_config(cpu);
> >
> 
> --
> Aurelien Jarno                          GPG: 4096R/1DDD8C9B
> aurelien@aurel32.net                 http://www.aurel32.net
diff mbox

Patch

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 786a8f0..a5d64d5 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -887,7 +887,7 @@  static void main_cpu_reset(void *opaque)
        read only location. The kernel location and the arguments table
        location does not change. */
     if (loaderparams.kernel_filename) {
-        env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
+        env->CP0_Status &= ~(1 << CP0St_ERL);
     }
 
     malta_mips_config(cpu);