qemu-m68k: add support for interrupt masking/unmasking
PATCH v2 1/1 qemu-m68k: add support for interrupt masking/unmasking
Fixes following problem, when trying to boot linux:
qemu: hardware error: mcf_intc_write: Bad write offset 28
CPU #0:
D0 = 000000ff A0 = 402ea5dc F0 = 0000000000000000 ( 0) D1 = 00000004 A1 = 402ea5e0 F1 = 0000000000000000 ( 0) D2 = 00000040 A2 = 40040752 F2 = 0000000000000000 ( 0) D3 = 00000000 A3 = 40040a98 F3 = 0000000000000000 ( 0) D4 = 00000000 A4 = 400407b4 F4 = 0000000000000000 ( 0) D5 = 00000000 A5 = 00000000 F5 = 0000000000000000 ( 0) D6 = 00000000 A6 = 40195ff8 F6 = 0000000000000000 ( 0) D7 = 00000000 A7 = 40195fd0 F7 = 0000000000000000 ( 0) PC = 401b2058 SR = 2704 --Z-- FPRESULT = 0
Aborted
System started via:
qemu-system-m68k -nographic -nographic -M mcf5208evb -cpu m5208 -kernel kernel
Patch originally posted here:
http://lists.busybox.net/pipermail/buildroot/2012-April/052585.html
---
v1 -> v2:
- add {} to conform to Qemu Coding Style suggested by Stefan Weil
- add short comments to case statements with return 0 suggested by Peter Maydell
- ull as suffix to integer 1 suggested by Peter Maydell does not work for me as I get a kernel panic shortly after boot
--- hw/m68k/mcf_intc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
hw/m68k/mcf_intc.c +19 -0
@@ -65,6 +65,9 @@ static uint64_t mcf_intc_read(void *opaque, hwaddr addr,return (uint32_t )(s->ifr >>32 );case 0x14 :return (uint32_t )s->ifr; +case 0x1c :/* SIMR */ +case 0x1d :/* CIMR */ +return 0 ;case 0xe0 :/* SWIACK. */ return s->active_vector;case 0xe1 :case 0xe2 :case 0xe3 :case 0xe4 :
@@ -102,6 +105,22 @@ static void mcf_intc_write(void *opaque, hwaddr addr,case 0x0c : s->imr = (s->imr &0xffffffff00000000ull ) | (uint32_t )val;break ; +/* SIMR allows to easily mask interrupts */ +case 0x1c : +if (val &0x40 ) { + s->imr = ~0ull ; + }else { + s->imr |= (1 << (val &0x3f )); + } +break ; +/* CIMR allows to easily unmask interrupts */ +case 0x1d : +if (val &0x40 ) { + s->imr =0ull ; + }else { + s->imr &= ~(1 << (val &0x3f )); + } +break ;default :hw_error ("mcf_intc_write: Bad write offset %d\n" , offset);break ;
Signature · 1 line
1.7.10.4
Am 28.03.2015 um 17:07 schrieb Waldemar Brodkorb:
Quoted 24 lines
Fixes following problem, when trying to boot linux:
qemu: hardware error:mcf_intc_write: Bad write offset 28CPU #0:
D0 = 000000ff A0 = 402ea5dc F0 = 0000000000000000 ( 0) D1 = 00000004 A1 = 402ea5e0 F1 = 0000000000000000 ( 0) D2 = 00000040 A2 = 40040752 F2 = 0000000000000000 ( 0) D3 = 00000000 A3 = 40040a98 F3 = 0000000000000000 ( 0) D4 = 00000000 A4 = 400407b4 F4 = 0000000000000000 ( 0) D5 = 00000000 A5 = 00000000 F5 = 0000000000000000 ( 0) D6 = 00000000 A6 = 40195ff8 F6 = 0000000000000000 ( 0) D7 = 00000000 A7 = 40195fd0 F7 = 0000000000000000 ( 0) PC = 401b2058 SR = 2704 --Z-- FPRESULT = 0Aborted
System started via:
qemu-system-m68k -nographic -nographic -M mcf5208evb -cpu m5208 -kernel kernelPatch originally posted here:
http://lists.busybox.net/pipermail/buildroot/2012-April/052585.htmlSigned-off-by Thomas Petazzoni <[email protected]>Tested-by Waldemar Brodkorb <[email protected]>Signed-off-by Waldemar Brodkorb <[email protected]>
Quoted 6 lines
---
v1 -> v2:
- add {} to conform to Qemu Coding Style suggested by Stefan Weil
- add short comments to case statements with return 0 suggested by Peter Maydell
- ull as suffix to integer 1 suggested by Peter Maydell does not work for me as I get a kernel panic shortly after boot
Maybe that's an indicator that it only works with 1ULL. :-)
Did you add it at both locations (for set and clear of interrupt mask)?
If not: does it work if you fix this?
If yes: does it work if you only use 1ULL for SIMR?
You can debug the kernel panic by attaching a cross debugger to the running kernel. If you have a kernel image with debug symbols, this is very comfortable.
Quoted 19 lines
--- hw/m68k/mcf_intc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)hw/m68k/mcf_intc.c +3
-0@@ -65,6 +65,9 @@ static uint64_t mcf_intc_read(void *opaque, hwaddr addr,return (uint32_t )(s->ifr >>32 );case 0x14 :return (uint32_t )s->ifr; +case 0x1c :/* SIMR */ +case 0x1d :/* CIMR */ +return 0 ;case 0xe0 :/* SWIACK. */ return s->active_vector;case 0xe1 :case 0xe2 :case 0xe3 :case 0xe4 :
hw/m68k/mcf_intc.c static void mcf_intc_write(void *opaque, hwaddr addr, · line 111
Quoted 7 lines
hw/m68k/mcf_intc.c +4
-0@@ -102,6 +105,22 @@ static void mcf_intc_write(void *opaque, hwaddr addr,case 0x0c : s->imr = (s->imr &0xffffffff00000000ull ) | (uint32_t )val;break ; +/* SIMR allows to easily mask interrupts */ +case 0x1c : +if (val &0x40 ) { + s->imr = ~0ull ;
Maybe UINT64_MAX is better than ~0ull.
hw/m68k/mcf_intc.c static void mcf_intc_write(void *opaque, hwaddr addr, · line 113
Quoted 2 lines
hw/m68k/mcf_intc.c +2
-0+ }else { + s->imr |= (1 << (val &0x3f ));
As Peter already said, 1ULL is needed if you want to allow shifts resulting in a 64 bit value. It's also possible to use a type cast like this: (uint64_t)1.
hw/m68k/mcf_intc.c static void mcf_intc_write(void *opaque, hwaddr addr, · line 119
Quoted 6 lines
hw/m68k/mcf_intc.c +6
-0+ } +break ; +/* CIMR allows to easily unmask interrupts */ +case 0x1d : +if (val &0x40 ) { + s->imr =0ull ;
Here the ULL is redundant.
hw/m68k/mcf_intc.c static void mcf_intc_write(void *opaque, hwaddr addr, · line 121
Quoted 2 lines
hw/m68k/mcf_intc.c +2
-0+ }else { + s->imr &= ~(1 << (val &0x3f ));
Here also 1ULL or a type cast is needed.
Quoted 5 lines
hw/m68k/mcf_intc.c +2
-0+ } +break ;default :hw_error ("mcf_intc_write: Bad write offset %d\n" , offset);break ;
Hi Stefan,
Stefan Weil wrote,
Quoted 32 lines
Am 28.03.2015 um 17:07 schrieb Waldemar Brodkorb:
Quoted 24 lines
Fixes following problem, when trying to boot linux:
qemu: hardware error:mcf_intc_write: Bad write offset 28CPU #0:
D0 = 000000ff A0 = 402ea5dc F0 = 0000000000000000 ( 0) D1 = 00000004 A1 = 402ea5e0 F1 = 0000000000000000 ( 0) D2 = 00000040 A2 = 40040752 F2 = 0000000000000000 ( 0) D3 = 00000000 A3 = 40040a98 F3 = 0000000000000000 ( 0) D4 = 00000000 A4 = 400407b4 F4 = 0000000000000000 ( 0) D5 = 00000000 A5 = 00000000 F5 = 0000000000000000 ( 0) D6 = 00000000 A6 = 40195ff8 F6 = 0000000000000000 ( 0) D7 = 00000000 A7 = 40195fd0 F7 = 0000000000000000 ( 0) PC = 401b2058 SR = 2704 --Z-- FPRESULT = 0Aborted
System started via:
qemu-system-m68k -nographic -nographic -M mcf5208evb -cpu m5208 -kernel kernelPatch originally posted here:
http://lists.busybox.net/pipermail/buildroot/2012-April/052585.htmlSigned-off-by Thomas Petazzoni <[email protected]>Tested-by Waldemar Brodkorb <[email protected]>Signed-off-by Waldemar Brodkorb <[email protected]>Quoted 6 lines
---
v1 -> v2:
- add {} to conform to Qemu Coding Style suggested by Stefan Weil
- add short comments to case statements with return 0 suggested by Peter Maydell
- ull as suffix to integer 1 suggested by Peter Maydell does not work for me as I get a kernel panic shortly after boot
Quoted 3 lines
Maybe that's an indicator that it only works with 1ULL. :-)
Did you add it at both locations (for set and clear of interrupt mask)?
Yes.
Quoted 2 lines
If not: does it work if you fix this?
If yes: does it work if you only use 1ULL for SIMR?
No.
Quoted 3 lines
You can debug the kernel panic by attaching a cross debugger to the running kernel.
If you have a kernel image with debug symbols, this is very comfortable.
How would I do this?
Tried to start qemu with -s -S and then attach with my cross-gdb using the kernel with debug symbols. But gdb does not recognize the panic:
Command: mdev -s
Command: ifconfig lo 127.0.0.1 up
Execution Finished, Exiting
Sash command shell (version 1.1.1)
/> Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
---[ end Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0000000b
best regards
Waldemar
Using this:
hw/m68k/mcf_intc.c +0 -0
@@ -65,6 +65,9 @@ static uint64_t mcf_intc_read(void *opaque, hwaddr
addr,
return (uint32_t)(s->ifr >> 32);
case 0x14:
return (uint32_t)s->ifr;
+ case 0x1c: /* SIMR */
+ case 0x1d: /* CIMR */
+ return 0;
case 0xe0: /* SWIACK. */
return s->active_vector;
case 0xe1: case 0xe2: case 0xe3: case 0xe4:
@@ -102,6 +105,22 @@ static void mcf_intc_write(void *opaque, hwaddr
addr,
case 0x0c:
s->imr = (s->imr & 0xffffffff00000000ull) | (uint32_t)val;
break;+ /* SIMR allows to easily mask interrupts */
+ case 0x1c:
+ if (val & 0x40) {
+ s->imr = UINT64_MAX;
+ } else {
+ s->imr |= ((uint64_t)1 << (val & 0x3f));
+ }
+ break;
+ /* CIMR allows to easily unmask interrupts */
+ case 0x1d:
+ if (val & 0x40) {
+ s->imr = 0;
+ } else {
+ s->imr &= ~((uint64_t)1 << (val & 0x3f));
+ }
+ break;
default:
hw_error("mcf_intc_write: Bad write offset %d\n", offset);
break;Am 29.03.2015 um 15:47 schrieb Waldemar Brodkorb:
Quoted 14 lines
Hi Stefan,
Stefan Weil wrote,Quoted 3 lines
You can debug the kernel panic by attaching a cross debugger to the running kernel.
If you have a kernel image with debug symbols, this is very comfortable.How would I do this?
Tried to start qemu with -s -S and then attach with my cross-gdb using the kernel with debug symbols. But gdb does not recognize the panic:
Command: mdev -s
Command: ifconfig lo 127.0.0.1 up
Execution Finished, Exiting
Quoted 7 lines
Sash command shell (version 1.1.1)
/> Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b---[ end Kernel panic - not syncing: Attempted to kill init!exitcode=0x0000000b
Yes, the cross gdb won't recognize a kernel panic.
But you can set a breakpoint on the kernel code which handles such panics, on one of the functions shown in the kernel panic backtrace, or on printk.
Regards
Stefan
Am 29.03.2015 um 17:53 schrieb Stefan Weil:
Quoted 21 lines
Am 29.03.2015 um 15:47 schrieb Waldemar Brodkorb:
Quoted 20 lines
Hi Stefan,
Stefan Weil wrote,Quoted 3 lines
You can debug the kernel panic by attaching a cross debugger to the running kernel.
If you have a kernel image with debug symbols, this is very comfortable.How would I do this?
Tried to start qemu with -s -S and then attach with my cross-gdb using the kernel with debug symbols. But gdb does not recognize the panic:
Command: mdev -s
Command: ifconfig lo 127.0.0.1 up
Execution Finished, ExitingSash command shell (version 1.1.1)
/> Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b---[ end Kernel panic - not syncing: Attempted to kill init!exitcode=0x0000000b
Is this the kernel panic which you get? I did not have a closer look on it before, but now I see that it is something quite common:
Your kernel runs an init script (or binary) which terminates (obviously normally). Then the kernel does not know what to do, so it throws a kernel panic "Attempted to kill init".
Usually the init process should only terminate at a system shutdown.
Stefan
Hi Stefan,
Stefan Weil wrote,
Quoted 24 lines
Am 29.03.2015 um 17:53 schrieb Stefan Weil:
Quoted 22 lines
Am 29.03.2015 um 15:47 schrieb Waldemar Brodkorb:
Quoted 21 lines
Hi Stefan,
Stefan Weil wrote,Quoted 4 lines
You can debug the kernel panic by attaching a cross debugger to the running kernel.
If you have a kernel image with debug symbols, this is very comfortable.How would I do this?
Tried to start qemu with -s -S and then attach with my cross-gdb using the kernel with debug symbols. But gdb does not recognize the panic:
Command: mdev -s
Command: ifconfig lo 127.0.0.1 up
Execution Finished, ExitingSash command shell (version 1.1.1)
/> Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b---[ end Kernel panic - not syncing: Attempted to kill init!exitcode=0x0000000b
Quoted 8 lines
Is this the kernel panic which you get? I did not have a closer look on it before, but now I see that it is something quite common:
Your kernel runs an init script (or binary) which terminates (obviously normally). Then the kernel does not know what to do, so it throws a kernel panic "Attempted to kill init".
Usually the init process should only terminate at a system shutdown.
The init is a simple C programm called simpleinit. The strange thing is, why it only happens with the ull version of qemu and not with the other one?
http://www.openadk.org/cgi-bin/gitweb.cgi?p=openadk.git;a=blob;f=package/simpleinit/src/simpleinit.c;h=291f88f479cf9ad4e24d727bc09120d0e6739ac3;hb=HEAD
best regards
Waldemar
Am 03.04.2015 um 10:04 schrieb Waldemar Brodkorb:
Quoted 33 lines
Hi Stefan,
Stefan Weil wrote,Quoted 30 lines
Am 29.03.2015 um 17:53 schrieb Stefan Weil:
Quoted 22 lines
Am 29.03.2015 um 15:47 schrieb Waldemar Brodkorb:
Quoted 21 lines
Hi Stefan,
Stefan Weil wrote,Quoted 4 lines
You can debug the kernel panic by attaching a cross debugger to the running kernel.
If you have a kernel image with debug symbols, this is very comfortable.How would I do this?
Tried to start qemu with -s -S and then attach with my cross-gdb using the kernel with debug symbols. But gdb does not recognize the panic:
Command: mdev -s
Command: ifconfig lo 127.0.0.1 up
Execution Finished, ExitingSash command shell (version 1.1.1)
/> Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b---[ end Kernel panic - not syncing: Attempted to kill init!exitcode=0x0000000b
Is this the kernel panic which you get? I did not have a closer look on it before, but now I see that it is something quite common:
Your kernel runs an init script (or binary) which terminates (obviously normally). Then the kernel does not know what to do, so it throws a kernel panic "Attempted to kill init".
Quoted 8 lines
Quoted 1 line
Usually the init process should only terminate at a system shutdown.
The init is a simple C programm called simpleinit. The strange thing is, why it only happens with the ull version of qemu and not with the other one?
http://www.openadk.org/cgi-bin/gitweb.cgi?p=openadk.git;a=blob;f=package/simpleinit/src/simpleinit.c;h=291f88f479cf9ad4e24d727bc09120d0e6739ac3;hb=HEADbest regards
Waldemar
Do you see any console output from that init process? Can you build it with the DEBUGGING macro included?
There is one program exit without a log message in function read_inittab:
if (numcmd == 0)
_exit(1);Add a printf or an err call there, too. Add also some log messages in main. main includes an endless for loop, so that init program is supposed to run without termination. By additional log messages, it should be possible to see why it terminates nevertheless.
As soon as the point of termination is known, we can think of the relation to the ULL postfix.
Regards
Stefan
Hi Stefan,
Stefan Weil wrote,
Quoted 52 lines
Am 03.04.2015 um 10:04 schrieb Waldemar Brodkorb:
Quoted 33 lines
Hi Stefan,
Stefan Weil wrote,Quoted 30 lines
Am 29.03.2015 um 17:53 schrieb Stefan Weil:
Quoted 22 lines
Am 29.03.2015 um 15:47 schrieb Waldemar Brodkorb:
Quoted 21 lines
Hi Stefan,
Stefan Weil wrote,Quoted 4 lines
You can debug the kernel panic by attaching a cross debugger to the running kernel.
If you have a kernel image with debug symbols, this is very comfortable.How would I do this?
Tried to start qemu with -s -S and then attach with my cross-gdb using the kernel with debug symbols. But gdb does not recognize the panic:
Command: mdev -s
Command: ifconfig lo 127.0.0.1 up
Execution Finished, ExitingSash command shell (version 1.1.1)
/> Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b---[ end Kernel panic - not syncing: Attempted to kill init!exitcode=0x0000000b
Is this the kernel panic which you get? I did not have a closer look on it before, but now I see that it is something quite common:
Your kernel runs an init script (or binary) which terminates (obviously normally). Then the kernel does not know what to do, so it throws a kernel panic "Attempted to kill init".
Quoted 8 lines
Quoted 1 line
Usually the init process should only terminate at a system shutdown.
The init is a simple C programm called simpleinit. The strange thing is, why it only happens with the ull version of qemu and not with the other one?
http://www.openadk.org/cgi-bin/gitweb.cgi?p=openadk.git;a=blob;f=package/simpleinit/src/simpleinit.c;h=291f88f479cf9ad4e24d727bc09120d0e6739ac3;hb=HEADbest regards
WaldemarDo you see any console output from that init process? Can you build it with the DEBUGGING macro included?
There is one program exit without a log message in function
read_inittab:if (numcmd == 0) _exit(1);
Quoted 8 lines
Add a printf or an err call there, too. Add also some log messages in main. main includes an endless for loop, so that init program is supposed to run without termination. By additional log messages, it should be possible to see why it terminates nevertheless.
As soon as the point of termination is known, we can think of the relation to the ULL postfix.
Shell invoked to run file: /etc/rc
Sash command shell signal handler
Command: echo Starting OpenADK
Starting OpenADK
Command: hostname openadk
Command: mount -t proc proc /proc
Command: mount -t sysfs sys /sys
Command: mkdir -m 755 /dev/pts
Command: mount -t devpts devpts /dev/pts
Command: mount -t tmpfs -o size=8M tmpfs /tmp
Command: chmod 1777 /tmp
Command: mkdir -p /var/log
Command: mkdir -p /var/run
Command: mkdir -p /var/tmp
Command: mdev -s
Command: ifconfig lo 127.0.0.1 up
Execution Finished, Exiting
Sash command shell exit with 0
toks= -/bin/sh (null)
tty= console
termcap= linux
init: main loop
Sash command shell (version 1.1.1)
Sash command shell signal handler
/> Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
---[ end Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0000000b
The code execution path is, kernel exec simpleinit and simpleinit exec sash. After the second call to sash, when /etc/rc is finished, 2-3 seconds later the kernel panic's.
I had a similar issue once I have used busybox hush instead of sash. The switching to sash fixed the issue for me and now when adding ull it happens again.
Sash code ( i added some printf locally )
http://www.openadk.org/cgi-bin/gitweb.cgi?p=openadk.git;a=tree;f=package/sash/src;h=476c254af2fb4c211d32d9418807736970fbb536;hb=HEAD
Discussion about the issue with hush:
http://lists.busybox.net/pipermail/busybox/2014-September/081634.html
best regards
Waldemar