1 /* 2 * S390 virtio-ccw loading program 3 * 4 * Copyright (c) 2013 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 <stdlib.h> 12 #include <string.h> 13 #include <stdio.h> 14 #include "helper.h" 15 #include "s390-arch.h" 16 #include "s390-ccw.h" 17 #include "cio.h" 18 #include "virtio.h" 19 #include "virtio-scsi.h" 20 #include "dasd-ipl.h" 21 22 static SubChannelId blk_schid = { .one = 1 }; 23 static char loadparm_str[LOADPARM_LEN + 1]; 24 QemuIplParameters qipl; 25 IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); 26 bool have_iplb; 27 static uint16_t cutype; 28 LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */ 29 30 #define LOADPARM_PROMPT "PROMPT " 31 #define LOADPARM_EMPTY " " 32 #define BOOT_MENU_FLAG_MASK (QIPL_FLAG_BM_OPTS_CMD | QIPL_FLAG_BM_OPTS_ZIPL) 33 34 /* 35 * Principles of Operations (SA22-7832-09) chapter 17 requires that 36 * a subsystem-identification is at 184-187 and bytes 188-191 are zero 37 * after list-directed-IPL and ccw-IPL. 38 */ 39 void write_subsystem_identification(void) 40 { 41 if (cutype == CU_TYPE_VIRTIO && virtio_get_device_type() == VIRTIO_ID_NET) { 42 lowcore->subchannel_id = net_schid.sch_id; 43 lowcore->subchannel_nr = net_schid.sch_no; 44 } else { 45 lowcore->subchannel_id = blk_schid.sch_id; 46 lowcore->subchannel_nr = blk_schid.sch_no; 47 } 48 lowcore->io_int_parm = 0; 49 } 50 51 void write_iplb_location(void) 52 { 53 if (cutype == CU_TYPE_VIRTIO && virtio_get_device_type() != VIRTIO_ID_NET) { 54 lowcore->ptr_iplb = ptr2u32(&iplb); 55 } 56 } 57 58 static void copy_qipl(void) 59 { 60 QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS; 61 memcpy(&qipl, early_qipl, sizeof(QemuIplParameters)); 62 } 63 64 unsigned int get_loadparm_index(void) 65 { 66 return atoi(loadparm_str); 67 } 68 69 static int is_dev_possibly_bootable(int dev_no, int sch_no) 70 { 71 bool is_virtio; 72 Schib schib; 73 int r; 74 75 blk_schid.sch_no = sch_no; 76 r = stsch_err(blk_schid, &schib); 77 if (r == 3 || r == -EIO) { 78 return -ENODEV; 79 } 80 if (!schib.pmcw.dnv) { 81 return false; 82 } 83 84 enable_subchannel(blk_schid); 85 cutype = cu_type(blk_schid); 86 if (cutype == CU_TYPE_UNKNOWN) { 87 return -EIO; 88 } 89 90 /* 91 * Note: we always have to run virtio_is_supported() here to make 92 * sure that the vdev.senseid data gets pre-initialized correctly 93 */ 94 is_virtio = virtio_is_supported(blk_schid); 95 96 /* No specific devno given, just return whether the device is possibly bootable */ 97 if (dev_no < 0) { 98 switch (cutype) { 99 case CU_TYPE_VIRTIO: 100 if (is_virtio) { 101 /* 102 * Skip net devices since no IPLB is created and therefore 103 * no network bootloader has been loaded 104 */ 105 if (virtio_get_device_type() != VIRTIO_ID_NET) { 106 return true; 107 } 108 } 109 return false; 110 case CU_TYPE_DASD_3990: 111 case CU_TYPE_DASD_2107: 112 return true; 113 default: 114 return false; 115 } 116 } 117 118 /* Caller asked for a specific devno */ 119 if (schib.pmcw.dev == dev_no) { 120 return true; 121 } 122 123 return false; 124 } 125 126 /* 127 * Find the subchannel connected to the given device (dev_no) and fill in the 128 * subchannel information block (schib) with the connected subchannel's info. 129 * NOTE: The global variable blk_schid is updated to contain the subchannel 130 * information. 131 * 132 * If the caller gives dev_no=-1 then the user did not specify a boot device. 133 * In this case we'll just use the first potentially bootable device we find. 134 */ 135 static bool find_subch(int dev_no) 136 { 137 int i, r; 138 139 for (i = 0; i < 0x10000; i++) { 140 r = is_dev_possibly_bootable(dev_no, i); 141 if (r < 0) { 142 break; 143 } 144 if (r == true) { 145 return true; 146 } 147 } 148 149 return false; 150 } 151 152 static void menu_setup(void) 153 { 154 if (memcmp(loadparm_str, LOADPARM_PROMPT, LOADPARM_LEN) == 0) { 155 menu_set_parms(QIPL_FLAG_BM_OPTS_CMD, 0); 156 return; 157 } 158 159 /* If loadparm was set to any other value, then do not enable menu */ 160 if (memcmp(loadparm_str, LOADPARM_EMPTY, LOADPARM_LEN) != 0) { 161 menu_set_parms(qipl.qipl_flags & ~BOOT_MENU_FLAG_MASK, 0); 162 return; 163 } 164 165 switch (iplb.pbt) { 166 case S390_IPL_TYPE_CCW: 167 case S390_IPL_TYPE_QEMU_SCSI: 168 menu_set_parms(qipl.qipl_flags & BOOT_MENU_FLAG_MASK, 169 qipl.boot_menu_timeout); 170 return; 171 } 172 } 173 174 /* 175 * Initialize the channel I/O subsystem so we can talk to our ipl/boot device. 176 */ 177 static void css_setup(void) 178 { 179 /* 180 * Unconditionally enable mss support. In every sane configuration this 181 * will succeed; and even if it doesn't, stsch_err() can handle it. 182 */ 183 enable_mss_facility(); 184 } 185 186 /* 187 * Collect various pieces of information from the hypervisor/hardware that 188 * we'll use to determine exactly how we'll boot. 189 */ 190 static void boot_setup(void) 191 { 192 char lpmsg[] = "LOADPARM=[________]\n"; 193 194 if (memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) { 195 ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN); 196 } else { 197 sclp_get_loadparm_ascii(loadparm_str); 198 } 199 200 if (have_iplb) { 201 menu_setup(); 202 } 203 204 memcpy(lpmsg + 10, loadparm_str, 8); 205 puts(lpmsg); 206 207 /* 208 * Clear out any potential S390EP magic (see jump_to_low_kernel()), 209 * so we don't taint our decision-making process during a reboot. 210 */ 211 memset((char *)S390EP, 0, 6); 212 } 213 214 static bool find_boot_device(void) 215 { 216 VDev *vdev = virtio_get_device(); 217 bool found = false; 218 219 switch (iplb.pbt) { 220 case S390_IPL_TYPE_CCW: 221 vdev->scsi_device_selected = false; 222 debug_print_int("device no. ", iplb.ccw.devno); 223 blk_schid.ssid = iplb.ccw.ssid & 0x3; 224 debug_print_int("ssid ", blk_schid.ssid); 225 found = find_subch(iplb.ccw.devno); 226 break; 227 case S390_IPL_TYPE_QEMU_SCSI: 228 vdev->scsi_device_selected = true; 229 vdev->selected_scsi_device.channel = iplb.scsi.channel; 230 vdev->selected_scsi_device.target = iplb.scsi.target; 231 vdev->selected_scsi_device.lun = iplb.scsi.lun; 232 blk_schid.ssid = iplb.scsi.ssid & 0x3; 233 found = find_subch(iplb.scsi.devno); 234 break; 235 default: 236 puts("Unsupported IPLB"); 237 } 238 239 return found; 240 } 241 242 static int virtio_setup(void) 243 { 244 VDev *vdev = virtio_get_device(); 245 int ret; 246 247 switch (vdev->senseid.cu_model) { 248 case VIRTIO_ID_NET: 249 puts("Network boot device detected"); 250 return 0; 251 case VIRTIO_ID_BLOCK: 252 ret = virtio_blk_setup_device(blk_schid); 253 break; 254 case VIRTIO_ID_SCSI: 255 ret = virtio_scsi_setup_device(blk_schid); 256 break; 257 default: 258 puts("\n! No IPL device available !\n"); 259 return -1; 260 } 261 262 if (!ret && !virtio_ipl_disk_is_valid()) { 263 puts("No valid IPL device detected"); 264 return -ENODEV; 265 } 266 267 return ret; 268 } 269 270 static void ipl_boot_device(void) 271 { 272 switch (cutype) { 273 case CU_TYPE_DASD_3990: 274 case CU_TYPE_DASD_2107: 275 dasd_ipl(blk_schid, cutype); 276 break; 277 case CU_TYPE_VIRTIO: 278 if (virtio_setup() == 0) { 279 zipl_load(); 280 } 281 break; 282 default: 283 printf("Attempting to boot from unexpected device type 0x%X\n", cutype); 284 } 285 } 286 287 /* 288 * No boot device has been specified, so we have to scan through the 289 * channels to find one. 290 */ 291 static void probe_boot_device(void) 292 { 293 int ssid, sch_no, ret; 294 295 for (ssid = 0; ssid < 0x3; ssid++) { 296 blk_schid.ssid = ssid; 297 for (sch_no = 0; sch_no < 0x10000; sch_no++) { 298 ret = is_dev_possibly_bootable(-1, sch_no); 299 if (ret < 0) { 300 break; 301 } 302 if (ret == true) { 303 ipl_boot_device(); /* Only returns if unsuccessful */ 304 } 305 } 306 } 307 308 puts("Could not find a suitable boot device (none specified)"); 309 } 310 311 void main(void) 312 { 313 copy_qipl(); 314 sclp_setup(); 315 css_setup(); 316 have_iplb = store_iplb(&iplb); 317 if (!have_iplb) { 318 probe_boot_device(); 319 } 320 321 while (have_iplb) { 322 boot_setup(); 323 if (have_iplb && find_boot_device()) { 324 ipl_boot_device(); 325 } 326 have_iplb = load_next_iplb(); 327 } 328 329 panic("No suitable device for IPL. Halting..."); 330 331 } 332