From 5bf6104a5f5891cc68a11f498240ed1d15c887b5 Mon Sep 17 00:00:00 2001
From: "Eugene (jno) Dvurechenski" <jno@linux.vnet.ibm.com>
Date: Mon, 19 May 2014 20:09:50 +0200
Subject: [PATCH] pc-bios/s390-ccw: add some utility code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

IPL_assert(term,message) is introduced to handle error conditions.
ebcdic_to_ascii() to convert chars (mostly to print VOLSERs).
read_block() provision for unified block-number handling.

Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Eugene (jno) Dvurechenski <jno@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit a94b485e17dab77d96a8b958305e485c3b9a7a91)
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 pc-bios/s390-ccw/bootmap.c | 15 +------
 pc-bios/s390-ccw/bootmap.h | 83 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+), 14 deletions(-)

diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 46d681ef7c..e8db75d65a 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -88,25 +88,12 @@ static int zipl_magic(uint8_t *ptr)
     return 1;
 }
 
-static inline bool unused_space(const void *p, unsigned int size)
-{
-    int i;
-    const unsigned char *m = p;
-
-    for (i = 0; i < size; i++) {
-        if (m[i] != FREE_SPACE_FILLER) {
-            return false;
-        }
-    }
-    return true;
-}
-
 static int zipl_load_segment(ComponentEntry *entry)
 {
     const int max_entries = (MAX_SECTOR_SIZE / sizeof(ScsiBlockPtr));
     ScsiBlockPtr *bprs = (void *)sec;
     const int bprs_size = sizeof(sec);
-    uint64_t blockno;
+    block_number_t blockno;
     long address;
     int i;
 
diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
index 59267b0db3..184663252a 100644
--- a/pc-bios/s390-ccw/bootmap.h
+++ b/pc-bios/s390-ccw/bootmap.h
@@ -12,6 +12,10 @@
 #define _PC_BIOS_S390_CCW_BOOTMAP_H
 
 #include "s390-ccw.h"
+#include "virtio.h"
+
+typedef uint64_t block_number_t;
+#define NULL_BLOCK_NR 0xffffffffffffffff
 
 #define FREE_SPACE_FILLER '\xAA'
 
@@ -251,4 +255,83 @@ typedef struct IplVolumeLabel {
     };
 } __attribute__((packed)) IplVolumeLabel;
 
+/* utility code below */
+
+static inline void IPL_assert(bool term, const char *message)
+{
+    if (!term) {
+        sclp_print("\n! ");
+        sclp_print(message);
+        virtio_panic(" !\n"); /* no return */
+    }
+}
+
+static const unsigned char ebc2asc[256] =
+      /* 0123456789abcdef0123456789abcdef */
+        "................................" /* 1F */
+        "................................" /* 3F */
+        " ...........<(+|&.........!$*);." /* 5F first.chr.here.is.real.space */
+        "-/.........,%_>?.........`:#@'=\""/* 7F */
+        ".abcdefghi.......jklmnopqr......" /* 9F */
+        "..stuvwxyz......................" /* BF */
+        ".ABCDEFGHI.......JKLMNOPQR......" /* DF */
+        "..STUVWXYZ......0123456789......";/* FF */
+
+static inline void ebcdic_to_ascii(const char *src,
+                                   char *dst,
+                                   unsigned int size)
+{
+    unsigned int i;
+    for (i = 0; i < size; i++) {
+        unsigned c = src[i];
+        dst[i] = ebc2asc[c];
+    }
+}
+
+static inline void print_volser(const void *volser)
+{
+    char ascii[8];
+
+    ebcdic_to_ascii((char *)volser, ascii, 6);
+    ascii[6] = '\0';
+    sclp_print("VOLSER=[");
+    sclp_print(ascii);
+    sclp_print("]\n");
+}
+
+static inline bool unused_space(const void *p, size_t size)
+{
+    size_t i;
+    const unsigned char *m = p;
+
+    for (i = 0; i < size; i++) {
+        if (m[i] != FREE_SPACE_FILLER) {
+            return false;
+        }
+    }
+    return true;
+}
+
+static inline bool is_null_block_number(block_number_t x)
+{
+    return x == NULL_BLOCK_NR;
+}
+
+static inline void read_block(block_number_t blockno,
+                              void *buffer,
+                              const char *errmsg)
+{
+    IPL_assert(virtio_read(blockno, buffer) == 0, errmsg);
+}
+
+static inline bool block_size_ok(uint32_t block_size)
+{
+    return block_size == virtio_get_block_size();
+}
+
+static inline bool magic_match(const void *data, const void *magic)
+{
+    return *((uint32_t *)data) == *((uint32_t *)magic);
+}
+
 #endif /* _PC_BIOS_S390_CCW_BOOTMAP_H */
