1 /* 2 * QEMU S390 bootmap interpreter 3 * 4 * Copyright (c) 2009 Alexander Graf <agraf@suse.de> 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or (at 7 * your option) any later version. See the COPYING file in the top-level 8 * directory. 9 */ 10 11 #include "s390-ccw.h" 12 13 // #define DEBUG_FALLBACK 14 15 #ifdef DEBUG_FALLBACK 16 #define dputs(txt) \ 17 do { sclp_print("zipl: " txt); } while (0) 18 #else 19 #define dputs(fmt, ...) \ 20 do { } while (0) 21 #endif 22 23 struct scsi_blockptr { 24 uint64_t blockno; 25 uint16_t size; 26 uint16_t blockct; 27 uint8_t reserved[4]; 28 } __attribute__ ((packed)); 29 30 struct component_entry { 31 struct scsi_blockptr data; 32 uint8_t pad[7]; 33 uint8_t component_type; 34 uint64_t load_address; 35 } __attribute((packed)); 36 37 struct component_header { 38 uint8_t magic[4]; 39 uint8_t type; 40 uint8_t reserved[27]; 41 } __attribute((packed)); 42 43 struct mbr { 44 uint8_t magic[4]; 45 uint32_t version_id; 46 uint8_t reserved[8]; 47 struct scsi_blockptr blockptr; 48 } __attribute__ ((packed)); 49 50 #define ZIPL_MAGIC "zIPL" 51 52 #define ZIPL_COMP_HEADER_IPL 0x00 53 #define ZIPL_COMP_HEADER_DUMP 0x01 54 55 #define ZIPL_COMP_ENTRY_LOAD 0x02 56 #define ZIPL_COMP_ENTRY_EXEC 0x01 57 58 /* Scratch space */ 59 static uint8_t sec[SECTOR_SIZE] __attribute__((__aligned__(SECTOR_SIZE))); 60 61 typedef struct ResetInfo { 62 uint32_t ipl_mask; 63 uint32_t ipl_addr; 64 uint32_t ipl_continue; 65 } ResetInfo; 66 67 ResetInfo save; 68 69 static void jump_to_IPL_2(void) 70 { 71 ResetInfo *current = 0; 72 73 void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue; 74 debug_print_addr("set IPL addr to", ipl); 75 76 /* Ensure the guest output starts fresh */ 77 sclp_print("\n"); 78 79 *current = save; 80 ipl(); /* should not return */ 81 } 82 83 static void jump_to_IPL_code(uint64_t address) 84 { 85 /* 86 * The IPL PSW is at address 0. We also must not overwrite the 87 * content of non-BIOS memory after we loaded the guest, so we 88 * save the original content and restore it in jump_to_IPL_2. 89 */ 90 ResetInfo *current = 0; 91 92 save = *current; 93 current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2; 94 current->ipl_continue = address & 0x7fffffff; 95 96 /* 97 * HACK ALERT. 98 * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2 99 * can then use r15 as its stack pointer. 100 */ 101 asm volatile("lghi 1,1\n\t" 102 "diag 1,1,0x308\n\t" 103 : : : "1", "memory"); 104 virtio_panic("\n! IPL returns !\n"); 105 } 106 107 /* Check for ZIPL magic. Returns 0 if not matched. */ 108 static int zipl_magic(uint8_t *ptr) 109 { 110 uint32_t *p = (void*)ptr; 111 uint32_t *z = (void*)ZIPL_MAGIC; 112 113 if (*p != *z) { 114 debug_print_int("invalid magic", *p); 115 virtio_panic("invalid magic"); 116 } 117 118 return 1; 119 } 120 121 #define FREE_SPACE_FILLER '\xAA' 122 123 static inline bool unused_space(const void *p, unsigned int size) 124 { 125 int i; 126 const unsigned char *m = p; 127 128 for (i = 0; i < size; i++) { 129 if (m[i] != FREE_SPACE_FILLER) { 130 return false; 131 } 132 } 133 return true; 134 } 135 136 static int zipl_load_segment(struct component_entry *entry) 137 { 138 const int max_entries = (SECTOR_SIZE / sizeof(struct scsi_blockptr)); 139 struct scsi_blockptr *bprs = (void*)sec; 140 const int bprs_size = sizeof(sec); 141 uint64_t blockno; 142 long address; 143 int i; 144 145 blockno = entry->data.blockno; 146 address = entry->load_address; 147 148 debug_print_int("loading segment at block", blockno); 149 debug_print_int("addr", address); 150 151 do { 152 memset(bprs, FREE_SPACE_FILLER, bprs_size); 153 if (virtio_read(blockno, (uint8_t *)bprs)) { 154 debug_print_int("failed reading bprs at", blockno); 155 goto fail; 156 } 157 158 for (i = 0;; i++) { 159 u64 *cur_desc = (void*)&bprs[i]; 160 161 blockno = bprs[i].blockno; 162 if (!blockno) 163 break; 164 165 /* we need the updated blockno for the next indirect entry in the 166 chain, but don't want to advance address */ 167 if (i == (max_entries - 1)) 168 break; 169 170 if (bprs[i].blockct == 0 && unused_space(&bprs[i + 1], 171 sizeof(struct scsi_blockptr))) { 172 /* This is a "continue" pointer. 173 * This ptr is the last one in the current script section. 174 * I.e. the next ptr must point to the unused memory area. 175 * The blockno is not zero, so the upper loop must continue 176 * reading next section of BPRS. 177 */ 178 break; 179 } 180 address = virtio_load_direct(cur_desc[0], cur_desc[1], 0, 181 (void*)address); 182 if (address == -1) 183 goto fail; 184 } 185 } while (blockno); 186 187 return 0; 188 189 fail: 190 sclp_print("failed loading segment\n"); 191 return -1; 192 } 193 194 /* Run a zipl program */ 195 static int zipl_run(struct scsi_blockptr *pte) 196 { 197 struct component_header *header; 198 struct component_entry *entry; 199 uint8_t tmp_sec[SECTOR_SIZE]; 200 201 virtio_read(pte->blockno, tmp_sec); 202 header = (struct component_header *)tmp_sec; 203 204 if (!zipl_magic(tmp_sec)) { 205 goto fail; 206 } 207 208 if (header->type != ZIPL_COMP_HEADER_IPL) { 209 goto fail; 210 } 211 212 dputs("start loading images\n"); 213 214 /* Load image(s) into RAM */ 215 entry = (struct component_entry *)(&header[1]); 216 while (entry->component_type == ZIPL_COMP_ENTRY_LOAD) { 217 if (zipl_load_segment(entry) < 0) { 218 goto fail; 219 } 220 221 entry++; 222 223 if ((uint8_t*)(&entry[1]) > (tmp_sec + SECTOR_SIZE)) { 224 goto fail; 225 } 226 } 227 228 if (entry->component_type != ZIPL_COMP_ENTRY_EXEC) { 229 goto fail; 230 } 231 232 /* should not return */ 233 jump_to_IPL_code(entry->load_address); 234 235 return 0; 236 237 fail: 238 sclp_print("failed running zipl\n"); 239 return -1; 240 } 241 242 int zipl_load(void) 243 { 244 struct mbr *mbr = (void*)sec; 245 uint8_t *ns, *ns_end; 246 int program_table_entries = 0; 247 int pte_len = sizeof(struct scsi_blockptr); 248 struct scsi_blockptr *prog_table_entry; 249 const char *error = ""; 250 251 /* Grab the MBR */ 252 virtio_read(0, (void*)mbr); 253 254 dputs("checking magic\n"); 255 256 if (!zipl_magic(mbr->magic)) { 257 error = "zipl_magic 1"; 258 goto fail; 259 } 260 261 debug_print_int("program table", mbr->blockptr.blockno); 262 263 /* Parse the program table */ 264 if (virtio_read(mbr->blockptr.blockno, sec)) { 265 error = "virtio_read"; 266 goto fail; 267 } 268 269 if (!zipl_magic(sec)) { 270 error = "zipl_magic 2"; 271 goto fail; 272 } 273 274 ns_end = sec + SECTOR_SIZE; 275 for (ns = (sec + pte_len); (ns + pte_len) < ns_end; ns++) { 276 prog_table_entry = (struct scsi_blockptr *)ns; 277 if (!prog_table_entry->blockno) { 278 break; 279 } 280 281 program_table_entries++; 282 } 283 284 debug_print_int("program table entries", program_table_entries); 285 286 if (!program_table_entries) { 287 goto fail; 288 } 289 290 /* Run the default entry */ 291 292 prog_table_entry = (struct scsi_blockptr *)(sec + pte_len); 293 294 return zipl_run(prog_table_entry); 295 296 fail: 297 sclp_print("failed loading zipl: "); 298 sclp_print(error); 299 sclp_print("\n"); 300 return -1; 301 } 302