s390-ccw.img: Consume service interrupts
authorChristian Borntraeger <borntraeger@de.ibm.com>
Fri, 19 Jun 2015 13:40:45 +0000 (15:40 +0200)
committerCornelia Huck <cornelia.huck@de.ibm.com>
Tue, 30 Jun 2015 07:34:58 +0000 (09:34 +0200)
We have to consume the outstanding service interrupt after each
service call, otherwise a correct implementation will return
CC=2 on subsequent service calls.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
pc-bios/s390-ccw/s390-ccw.h
pc-bios/s390-ccw/sclp-ascii.c
pc-bios/s390-ccw/start.S

index 9b3868bd6e419d537a8068b8772248d3c5088ff1..5484c2a45cab6ddb95d62104925860ff62e5ff0a 100644 (file)
@@ -47,6 +47,7 @@ typedef unsigned long long __u64;
 
 /* start.s */
 void disabled_wait(void);
+void consume_sclp_int(void);
 
 /* main.c */
 void virtio_panic(const char *string);
index 761fb44ff57f7a8a8d953bcdfb9309bcf0ab6b94..dc1c3e4f4df01a9b3dd5a68fff16c883216e80f6 100644 (file)
@@ -24,6 +24,7 @@ static int sclp_service_call(unsigned int command, void *sccb)
                 "       srl     %0,28"
                 : "=&d" (cc) : "d" (command), "a" (__pa(sccb))
                 : "cc", "memory");
+        consume_sclp_int();
         if (cc == 3)
                 return -EIO;
         if (cc == 2)
index 5d5df0d616efd1a6028acbeccbcd7666a5611e7f..b6dd8c2fbebd1b999d58a3422c88a94e68505a58 100644 (file)
@@ -28,6 +28,38 @@ disabled_wait:
         larl %r1,disabled_wait_psw
         lpswe   0(%r1)
 
+
+/*
+ * void consume_sclp_int(void)
+ *
+ * eats one sclp interrupt
+ */
+        .globl consume_sclp_int
+consume_sclp_int:
+        /* enable service interrupts in cr0 */
+        stctg 0,0,0(15)
+        oi 6(15), 0x2
+        lctlg 0,0,0(15)
+        /* prepare external call handler */
+        larl %r1, external_new_code
+        stg %r1, 0x1b8
+        larl %r1, external_new_mask
+        mvc 0x1b0(8),0(%r1)
+        /* load enabled wait PSW */
+        larl %r1, enabled_wait_psw
+        lpswe 0(%r1)
+
+external_new_code:
+        /* disable service interrupts in cr0 */
+        stctg 0,0,0(15)
+        ni 6(15), 0xfd
+        lctlg 0,0,0(15)
+        br 14
+
         .align  8
 disabled_wait_psw:
         .quad   0x0002000180000000,0x0000000000000000
+enabled_wait_psw:
+        .quad   0x0302000180000000,0x0000000000000000
+external_new_mask:
+        .quad   0x0000000180000000