Skip to contentSkip to conversation

qemu-m68k: add support for interrupt masking/unmasking

PATCH In review Waldemar Brodkorb 2 participants 8 messages Mar 28, 2015 – Apr 3, 2015

lore
Share & tools
lore
#0 lore raw

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
index 621423c..dcd14b9 100644
@@ -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
#1 lore raw

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 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

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
index 621423c..dcd14b9 100644
@@ -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;
#2 lore raw

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 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

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
index 621423c..bcdd7c4 100644
@@ -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;
#3 lore raw

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

#4 lore raw

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, 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

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

#5 lore raw

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, 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

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

#6 lore raw

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, 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

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=HEAD

best 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

#7 lore raw

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, 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

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=HEAD

best 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);
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