xref: /openbmc/qemu/hw/s390x/ipl.c (revision 5b723a5d8df44b69b8ba350e643059c8fd889315)
1  /*
2   * bootloader support
3   *
4   * Copyright IBM, Corp. 2012, 2020
5   *
6   * Authors:
7   *  Christian Borntraeger <borntraeger@de.ibm.com>
8   *  Janosch Frank <frankja@linux.ibm.com>
9   *
10   * This work is licensed under the terms of the GNU GPL, version 2 or (at your
11   * option) any later version.  See the COPYING file in the top-level directory.
12   *
13   */
14  
15  #include "qemu/osdep.h"
16  #include "qemu-common.h"
17  #include "qemu/datadir.h"
18  #include "qapi/error.h"
19  #include "sysemu/reset.h"
20  #include "sysemu/runstate.h"
21  #include "sysemu/sysemu.h"
22  #include "sysemu/tcg.h"
23  #include "cpu.h"
24  #include "elf.h"
25  #include "hw/loader.h"
26  #include "hw/qdev-properties.h"
27  #include "hw/boards.h"
28  #include "hw/s390x/virtio-ccw.h"
29  #include "hw/s390x/vfio-ccw.h"
30  #include "hw/s390x/css.h"
31  #include "hw/s390x/ebcdic.h"
32  #include "hw/s390x/pv.h"
33  #include "ipl.h"
34  #include "qemu/error-report.h"
35  #include "qemu/config-file.h"
36  #include "qemu/cutils.h"
37  #include "qemu/option.h"
38  #include "exec/exec-all.h"
39  
40  #define KERN_IMAGE_START                0x010000UL
41  #define LINUX_MAGIC_ADDR                0x010008UL
42  #define KERN_PARM_AREA                  0x010480UL
43  #define INITRD_START                    0x800000UL
44  #define INITRD_PARM_START               0x010408UL
45  #define PARMFILE_START                  0x001000UL
46  #define ZIPL_IMAGE_START                0x009000UL
47  #define IPL_PSW_MASK                    (PSW_MASK_32 | PSW_MASK_64)
48  
49  static bool iplb_extended_needed(void *opaque)
50  {
51      S390IPLState *ipl = S390_IPL(object_resolve_path(TYPE_S390_IPL, NULL));
52  
53      return ipl->iplbext_migration;
54  }
55  
56  static const VMStateDescription vmstate_iplb_extended = {
57      .name = "ipl/iplb_extended",
58      .version_id = 0,
59      .minimum_version_id = 0,
60      .needed = iplb_extended_needed,
61      .fields = (VMStateField[]) {
62          VMSTATE_UINT8_ARRAY(reserved_ext, IplParameterBlock, 4096 - 200),
63          VMSTATE_END_OF_LIST()
64      }
65  };
66  
67  static const VMStateDescription vmstate_iplb = {
68      .name = "ipl/iplb",
69      .version_id = 0,
70      .minimum_version_id = 0,
71      .fields = (VMStateField[]) {
72          VMSTATE_UINT8_ARRAY(reserved1, IplParameterBlock, 110),
73          VMSTATE_UINT16(devno, IplParameterBlock),
74          VMSTATE_UINT8_ARRAY(reserved2, IplParameterBlock, 88),
75          VMSTATE_END_OF_LIST()
76      },
77      .subsections = (const VMStateDescription*[]) {
78          &vmstate_iplb_extended,
79          NULL
80      }
81  };
82  
83  static const VMStateDescription vmstate_ipl = {
84      .name = "ipl",
85      .version_id = 0,
86      .minimum_version_id = 0,
87      .fields = (VMStateField[]) {
88          VMSTATE_UINT64(compat_start_addr, S390IPLState),
89          VMSTATE_UINT64(compat_bios_start_addr, S390IPLState),
90          VMSTATE_STRUCT(iplb, S390IPLState, 0, vmstate_iplb, IplParameterBlock),
91          VMSTATE_BOOL(iplb_valid, S390IPLState),
92          VMSTATE_UINT8(cssid, S390IPLState),
93          VMSTATE_UINT8(ssid, S390IPLState),
94          VMSTATE_UINT16(devno, S390IPLState),
95          VMSTATE_END_OF_LIST()
96       }
97  };
98  
99  static S390IPLState *get_ipl_device(void)
100  {
101      return S390_IPL(object_resolve_path_type("", TYPE_S390_IPL, NULL));
102  }
103  
104  static uint64_t bios_translate_addr(void *opaque, uint64_t srcaddr)
105  {
106      uint64_t dstaddr = *(uint64_t *) opaque;
107      /*
108       * Assuming that our s390-ccw.img was linked for starting at address 0,
109       * we can simply add the destination address for the final location
110       */
111      return srcaddr + dstaddr;
112  }
113  
114  static void s390_ipl_realize(DeviceState *dev, Error **errp)
115  {
116      MachineState *ms = MACHINE(qdev_get_machine());
117      S390IPLState *ipl = S390_IPL(dev);
118      uint32_t *ipl_psw;
119      uint64_t pentry;
120      char *magic;
121      int kernel_size;
122  
123      int bios_size;
124      char *bios_filename;
125  
126      /*
127       * Always load the bios if it was enforced,
128       * even if an external kernel has been defined.
129       */
130      if (!ipl->kernel || ipl->enforce_bios) {
131          uint64_t fwbase = (MIN(ms->ram_size, 0x80000000U) - 0x200000) & ~0xffffUL;
132  
133          bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->firmware);
134          if (bios_filename == NULL) {
135              error_setg(errp, "could not find stage1 bootloader");
136              return;
137          }
138  
139          bios_size = load_elf(bios_filename, NULL,
140                               bios_translate_addr, &fwbase,
141                               &ipl->bios_start_addr, NULL, NULL, NULL, 1,
142                               EM_S390, 0, 0);
143          if (bios_size > 0) {
144              /* Adjust ELF start address to final location */
145              ipl->bios_start_addr += fwbase;
146          } else {
147              /* Try to load non-ELF file */
148              bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,
149                                              4096);
150              ipl->bios_start_addr = ZIPL_IMAGE_START;
151          }
152          g_free(bios_filename);
153  
154          if (bios_size == -1) {
155              error_setg(errp, "could not load bootloader '%s'", ipl->firmware);
156              return;
157          }
158  
159          /* default boot target is the bios */
160          ipl->start_addr = ipl->bios_start_addr;
161      }
162  
163      if (ipl->kernel) {
164          kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL,
165                                 &pentry, NULL,
166                                 NULL, NULL, 1, EM_S390, 0, 0);
167          if (kernel_size < 0) {
168              kernel_size = load_image_targphys(ipl->kernel, 0, ms->ram_size);
169              if (kernel_size < 0) {
170                  error_setg(errp, "could not load kernel '%s'", ipl->kernel);
171                  return;
172              }
173              /* if this is Linux use KERN_IMAGE_START */
174              magic = rom_ptr(LINUX_MAGIC_ADDR, 6);
175              if (magic && !memcmp(magic, "S390EP", 6)) {
176                  pentry = KERN_IMAGE_START;
177              } else {
178                  /* if not Linux load the address of the (short) IPL PSW */
179                  ipl_psw = rom_ptr(4, 4);
180                  if (ipl_psw) {
181                      pentry = be32_to_cpu(*ipl_psw) & PSW_MASK_SHORT_ADDR;
182                  } else {
183                      error_setg(errp, "Could not get IPL PSW");
184                      return;
185                  }
186              }
187          }
188          /*
189           * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the
190           * kernel parameters here as well. Note: For old kernels (up to 3.2)
191           * we can not rely on the ELF entry point - it was 0x800 (the SALIPL
192           * loader) and it won't work. For this case we force it to 0x10000, too.
193           */
194          if (pentry == KERN_IMAGE_START || pentry == 0x800) {
195              char *parm_area = rom_ptr(KERN_PARM_AREA, strlen(ipl->cmdline) + 1);
196              ipl->start_addr = KERN_IMAGE_START;
197              /* Overwrite parameters in the kernel image, which are "rom" */
198              if (parm_area) {
199                  strcpy(parm_area, ipl->cmdline);
200              }
201          } else {
202              ipl->start_addr = pentry;
203          }
204  
205          if (ipl->initrd) {
206              ram_addr_t initrd_offset;
207              int initrd_size;
208              uint64_t *romptr;
209  
210              initrd_offset = INITRD_START;
211              while (kernel_size + 0x100000 > initrd_offset) {
212                  initrd_offset += 0x100000;
213              }
214              initrd_size = load_image_targphys(ipl->initrd, initrd_offset,
215                                                ms->ram_size - initrd_offset);
216              if (initrd_size == -1) {
217                  error_setg(errp, "could not load initrd '%s'", ipl->initrd);
218                  return;
219              }
220  
221              /*
222               * we have to overwrite values in the kernel image,
223               * which are "rom"
224               */
225              romptr = rom_ptr(INITRD_PARM_START, 16);
226              if (romptr) {
227                  stq_p(romptr, initrd_offset);
228                  stq_p(romptr + 1, initrd_size);
229              }
230          }
231      }
232      /*
233       * Don't ever use the migrated values, they could come from a different
234       * BIOS and therefore don't work. But still migrate the values, so
235       * QEMUs relying on it don't break.
236       */
237      ipl->compat_start_addr = ipl->start_addr;
238      ipl->compat_bios_start_addr = ipl->bios_start_addr;
239      /*
240       * Because this Device is not on any bus in the qbus tree (it is
241       * not a sysbus device and it's not on some other bus like a PCI
242       * bus) it will not be automatically reset by the 'reset the
243       * sysbus' hook registered by vl.c like most devices. So we must
244       * manually register a reset hook for it.
245       * TODO: there should be a better way to do this.
246       */
247      qemu_register_reset(resettable_cold_reset_fn, dev);
248  }
249  
250  static Property s390_ipl_properties[] = {
251      DEFINE_PROP_STRING("kernel", S390IPLState, kernel),
252      DEFINE_PROP_STRING("initrd", S390IPLState, initrd),
253      DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline),
254      DEFINE_PROP_STRING("firmware", S390IPLState, firmware),
255      DEFINE_PROP_STRING("netboot_fw", S390IPLState, netboot_fw),
256      DEFINE_PROP_BOOL("enforce_bios", S390IPLState, enforce_bios, false),
257      DEFINE_PROP_BOOL("iplbext_migration", S390IPLState, iplbext_migration,
258                       true),
259      DEFINE_PROP_END_OF_LIST(),
260  };
261  
262  static void s390_ipl_set_boot_menu(S390IPLState *ipl)
263  {
264      QemuOptsList *plist = qemu_find_opts("boot-opts");
265      QemuOpts *opts = QTAILQ_FIRST(&plist->head);
266      const char *tmp;
267      unsigned long splash_time = 0;
268  
269      if (!get_boot_device(0)) {
270          if (boot_menu) {
271              error_report("boot menu requires a bootindex to be specified for "
272                           "the IPL device");
273          }
274          return;
275      }
276  
277      switch (ipl->iplb.pbt) {
278      case S390_IPL_TYPE_CCW:
279          /* In the absence of -boot menu, use zipl parameters */
280          if (!qemu_opt_get(opts, "menu")) {
281              ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_ZIPL;
282              return;
283          }
284          break;
285      case S390_IPL_TYPE_QEMU_SCSI:
286          break;
287      default:
288          if (boot_menu) {
289              error_report("boot menu is not supported for this device type");
290          }
291          return;
292      }
293  
294      if (!boot_menu) {
295          return;
296      }
297  
298      ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_CMD;
299  
300      tmp = qemu_opt_get(opts, "splash-time");
301  
302      if (tmp && qemu_strtoul(tmp, NULL, 10, &splash_time)) {
303          error_report("splash-time is invalid, forcing it to 0");
304          ipl->qipl.boot_menu_timeout = 0;
305          return;
306      }
307  
308      if (splash_time > 0xffffffff) {
309          error_report("splash-time is too large, forcing it to max value");
310          ipl->qipl.boot_menu_timeout = 0xffffffff;
311          return;
312      }
313  
314      ipl->qipl.boot_menu_timeout = cpu_to_be32(splash_time);
315  }
316  
317  #define CCW_DEVTYPE_NONE        0x00
318  #define CCW_DEVTYPE_VIRTIO      0x01
319  #define CCW_DEVTYPE_VIRTIO_NET  0x02
320  #define CCW_DEVTYPE_SCSI        0x03
321  #define CCW_DEVTYPE_VFIO        0x04
322  
323  static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype)
324  {
325      CcwDevice *ccw_dev = NULL;
326      int tmp_dt = CCW_DEVTYPE_NONE;
327  
328      if (dev_st) {
329          VirtIONet *virtio_net_dev = (VirtIONet *)
330              object_dynamic_cast(OBJECT(dev_st), TYPE_VIRTIO_NET);
331          VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
332              object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
333                                  TYPE_VIRTIO_CCW_DEVICE);
334          VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *)
335              object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
336  
337          if (virtio_ccw_dev) {
338              ccw_dev = CCW_DEVICE(virtio_ccw_dev);
339              if (virtio_net_dev) {
340                  tmp_dt = CCW_DEVTYPE_VIRTIO_NET;
341              } else {
342                  tmp_dt = CCW_DEVTYPE_VIRTIO;
343              }
344          } else if (vfio_ccw_dev) {
345              ccw_dev = CCW_DEVICE(vfio_ccw_dev);
346              tmp_dt = CCW_DEVTYPE_VFIO;
347          } else {
348              SCSIDevice *sd = (SCSIDevice *)
349                  object_dynamic_cast(OBJECT(dev_st),
350                                      TYPE_SCSI_DEVICE);
351              if (sd) {
352                  SCSIBus *bus = scsi_bus_from_device(sd);
353                  VirtIOSCSI *vdev = container_of(bus, VirtIOSCSI, bus);
354                  VirtIOSCSICcw *scsi_ccw = container_of(vdev, VirtIOSCSICcw,
355                                                         vdev);
356  
357                  ccw_dev = (CcwDevice *)object_dynamic_cast(OBJECT(scsi_ccw),
358                                                             TYPE_CCW_DEVICE);
359                  tmp_dt = CCW_DEVTYPE_SCSI;
360              }
361          }
362      }
363      if (devtype) {
364          *devtype = tmp_dt;
365      }
366      return ccw_dev;
367  }
368  
369  static bool s390_gen_initial_iplb(S390IPLState *ipl)
370  {
371      DeviceState *dev_st;
372      CcwDevice *ccw_dev = NULL;
373      SCSIDevice *sd;
374      int devtype;
375  
376      dev_st = get_boot_device(0);
377      if (dev_st) {
378          ccw_dev = s390_get_ccw_device(dev_st, &devtype);
379      }
380  
381      /*
382       * Currently allow IPL only from CCW devices.
383       */
384      if (ccw_dev) {
385          switch (devtype) {
386          case CCW_DEVTYPE_SCSI:
387              sd = SCSI_DEVICE(dev_st);
388              ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
389              ipl->iplb.blk0_len =
390                  cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN);
391              ipl->iplb.pbt = S390_IPL_TYPE_QEMU_SCSI;
392              ipl->iplb.scsi.lun = cpu_to_be32(sd->lun);
393              ipl->iplb.scsi.target = cpu_to_be16(sd->id);
394              ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
395              ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
396              ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
397              break;
398          case CCW_DEVTYPE_VFIO:
399              ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
400              ipl->iplb.pbt = S390_IPL_TYPE_CCW;
401              ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
402              ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
403              break;
404          case CCW_DEVTYPE_VIRTIO_NET:
405              ipl->netboot = true;
406              /* Fall through to CCW_DEVTYPE_VIRTIO case */
407          case CCW_DEVTYPE_VIRTIO:
408              ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
409              ipl->iplb.blk0_len =
410                  cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
411              ipl->iplb.pbt = S390_IPL_TYPE_CCW;
412              ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
413              ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
414              break;
415          }
416  
417          if (!s390_ipl_set_loadparm(ipl->iplb.loadparm)) {
418              ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID;
419          }
420  
421          return true;
422      }
423  
424      return false;
425  }
426  
427  int s390_ipl_set_loadparm(uint8_t *loadparm)
428  {
429      MachineState *machine = MACHINE(qdev_get_machine());
430      char *lp = object_property_get_str(OBJECT(machine), "loadparm", NULL);
431  
432      if (lp) {
433          int i;
434  
435          /* lp is an uppercase string without leading/embedded spaces */
436          for (i = 0; i < 8 && lp[i]; i++) {
437              loadparm[i] = ascii2ebcdic[(uint8_t) lp[i]];
438          }
439  
440          if (i < 8) {
441              memset(loadparm + i, 0x40, 8 - i); /* fill with EBCDIC spaces */
442          }
443  
444          g_free(lp);
445          return 0;
446      }
447  
448      return -1;
449  }
450  
451  static int load_netboot_image(Error **errp)
452  {
453      MachineState *ms = MACHINE(qdev_get_machine());
454      S390IPLState *ipl = get_ipl_device();
455      char *netboot_filename;
456      MemoryRegion *sysmem =  get_system_memory();
457      MemoryRegion *mr = NULL;
458      void *ram_ptr = NULL;
459      int img_size = -1;
460  
461      mr = memory_region_find(sysmem, 0, 1).mr;
462      if (!mr) {
463          error_setg(errp, "Failed to find memory region at address 0");
464          return -1;
465      }
466  
467      ram_ptr = memory_region_get_ram_ptr(mr);
468      if (!ram_ptr) {
469          error_setg(errp, "No RAM found");
470          goto unref_mr;
471      }
472  
473      netboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->netboot_fw);
474      if (netboot_filename == NULL) {
475          error_setg(errp, "Could not find network bootloader '%s'",
476                     ipl->netboot_fw);
477          goto unref_mr;
478      }
479  
480      img_size = load_elf_ram(netboot_filename, NULL, NULL, NULL,
481                              &ipl->start_addr,
482                              NULL, NULL, NULL, 1, EM_S390, 0, 0, NULL,
483                              false);
484  
485      if (img_size < 0) {
486          img_size = load_image_size(netboot_filename, ram_ptr, ms->ram_size);
487          ipl->start_addr = KERN_IMAGE_START;
488      }
489  
490      if (img_size < 0) {
491          error_setg(errp, "Failed to load network bootloader");
492      }
493  
494      g_free(netboot_filename);
495  
496  unref_mr:
497      memory_region_unref(mr);
498      return img_size;
499  }
500  
501  static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb,
502                                           int virtio_id)
503  {
504      uint8_t cssid;
505      uint8_t ssid;
506      uint16_t devno;
507      uint16_t schid;
508      SubchDev *sch = NULL;
509  
510      if (iplb->pbt != S390_IPL_TYPE_CCW) {
511          return false;
512      }
513  
514      devno = be16_to_cpu(iplb->ccw.devno);
515      ssid = iplb->ccw.ssid & 3;
516  
517      for (schid = 0; schid < MAX_SCHID; schid++) {
518          for (cssid = 0; cssid < MAX_CSSID; cssid++) {
519              sch = css_find_subch(1, cssid, ssid, schid);
520  
521              if (sch && sch->devno == devno) {
522                  return sch->id.cu_model == virtio_id;
523              }
524          }
525      }
526      return false;
527  }
528  
529  static bool is_virtio_net_device(IplParameterBlock *iplb)
530  {
531      return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_NET);
532  }
533  
534  static bool is_virtio_scsi_device(IplParameterBlock *iplb)
535  {
536      return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI);
537  }
538  
539  static void update_machine_ipl_properties(IplParameterBlock *iplb)
540  {
541      Object *machine = qdev_get_machine();
542      Error *err = NULL;
543  
544      /* Sync loadparm */
545      if (iplb->flags & DIAG308_FLAGS_LP_VALID) {
546          uint8_t *ebcdic_loadparm = iplb->loadparm;
547          char ascii_loadparm[9];
548          int i;
549  
550          for (i = 0; i < 8 && ebcdic_loadparm[i]; i++) {
551              ascii_loadparm[i] = ebcdic2ascii[(uint8_t) ebcdic_loadparm[i]];
552          }
553          ascii_loadparm[i] = 0;
554          object_property_set_str(machine, "loadparm", ascii_loadparm, &err);
555      } else {
556          object_property_set_str(machine, "loadparm", "", &err);
557      }
558      if (err) {
559          warn_report_err(err);
560      }
561  }
562  
563  void s390_ipl_update_diag308(IplParameterBlock *iplb)
564  {
565      S390IPLState *ipl = get_ipl_device();
566  
567      /*
568       * The IPLB set and retrieved by subcodes 8/9 is completely
569       * separate from the one managed via subcodes 5/6.
570       */
571      if (iplb->pbt == S390_IPL_TYPE_PV) {
572          ipl->iplb_pv = *iplb;
573          ipl->iplb_valid_pv = true;
574      } else {
575          ipl->iplb = *iplb;
576          ipl->iplb_valid = true;
577      }
578      ipl->netboot = is_virtio_net_device(iplb);
579      update_machine_ipl_properties(iplb);
580  }
581  
582  IplParameterBlock *s390_ipl_get_iplb_pv(void)
583  {
584      S390IPLState *ipl = get_ipl_device();
585  
586      if (!ipl->iplb_valid_pv) {
587          return NULL;
588      }
589      return &ipl->iplb_pv;
590  }
591  
592  IplParameterBlock *s390_ipl_get_iplb(void)
593  {
594      S390IPLState *ipl = get_ipl_device();
595  
596      if (!ipl->iplb_valid) {
597          return NULL;
598      }
599      return &ipl->iplb;
600  }
601  
602  void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type)
603  {
604      S390IPLState *ipl = get_ipl_device();
605  
606      if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL) {
607          /* use CPU 0 for full resets */
608          ipl->reset_cpu_index = 0;
609      } else {
610          ipl->reset_cpu_index = cs->cpu_index;
611      }
612      ipl->reset_type = reset_type;
613  
614      if (reset_type == S390_RESET_REIPL &&
615          ipl->iplb_valid &&
616          !ipl->netboot &&
617          ipl->iplb.pbt == S390_IPL_TYPE_CCW &&
618          is_virtio_scsi_device(&ipl->iplb)) {
619          CcwDevice *ccw_dev = s390_get_ccw_device(get_boot_device(0), NULL);
620  
621          if (ccw_dev &&
622              cpu_to_be16(ccw_dev->sch->devno) == ipl->iplb.ccw.devno &&
623              (ccw_dev->sch->ssid & 3) == ipl->iplb.ccw.ssid) {
624              /*
625               * this is the original boot device's SCSI
626               * so restore IPL parameter info from it
627               */
628              ipl->iplb_valid = s390_gen_initial_iplb(ipl);
629          }
630      }
631      if (reset_type == S390_RESET_MODIFIED_CLEAR ||
632          reset_type == S390_RESET_LOAD_NORMAL ||
633          reset_type == S390_RESET_PV) {
634          /* ignore -no-reboot, send no event  */
635          qemu_system_reset_request(SHUTDOWN_CAUSE_SUBSYSTEM_RESET);
636      } else {
637          qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
638      }
639      /* as this is triggered by a CPU, make sure to exit the loop */
640      if (tcg_enabled()) {
641          cpu_loop_exit(cs);
642      }
643  }
644  
645  void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type)
646  {
647      S390IPLState *ipl = get_ipl_device();
648  
649      *cs = qemu_get_cpu(ipl->reset_cpu_index);
650      if (!*cs) {
651          /* use any CPU */
652          *cs = first_cpu;
653      }
654      *reset_type = ipl->reset_type;
655  }
656  
657  void s390_ipl_clear_reset_request(void)
658  {
659      S390IPLState *ipl = get_ipl_device();
660  
661      ipl->reset_type = S390_RESET_EXTERNAL;
662      /* use CPU 0 for full resets */
663      ipl->reset_cpu_index = 0;
664  }
665  
666  static void s390_ipl_prepare_qipl(S390CPU *cpu)
667  {
668      S390IPLState *ipl = get_ipl_device();
669      uint8_t *addr;
670      uint64_t len = 4096;
671  
672      addr = cpu_physical_memory_map(cpu->env.psa, &len, true);
673      if (!addr || len < QIPL_ADDRESS + sizeof(QemuIplParameters)) {
674          error_report("Cannot set QEMU IPL parameters");
675          return;
676      }
677      memcpy(addr + QIPL_ADDRESS, &ipl->qipl, sizeof(QemuIplParameters));
678      cpu_physical_memory_unmap(addr, len, 1, len);
679  }
680  
681  int s390_ipl_prepare_pv_header(void)
682  {
683      IplParameterBlock *ipib = s390_ipl_get_iplb_pv();
684      IPLBlockPV *ipib_pv = &ipib->pv;
685      void *hdr = g_malloc(ipib_pv->pv_header_len);
686      int rc;
687  
688      cpu_physical_memory_read(ipib_pv->pv_header_addr, hdr,
689                               ipib_pv->pv_header_len);
690      rc = s390_pv_set_sec_parms((uintptr_t)hdr,
691                                 ipib_pv->pv_header_len);
692      g_free(hdr);
693      return rc;
694  }
695  
696  int s390_ipl_pv_unpack(void)
697  {
698      IplParameterBlock *ipib = s390_ipl_get_iplb_pv();
699      IPLBlockPV *ipib_pv = &ipib->pv;
700      int i, rc = 0;
701  
702      for (i = 0; i < ipib_pv->num_comp; i++) {
703          rc = s390_pv_unpack(ipib_pv->components[i].addr,
704                              TARGET_PAGE_ALIGN(ipib_pv->components[i].size),
705                              ipib_pv->components[i].tweak_pref);
706          if (rc) {
707              break;
708          }
709      }
710      return rc;
711  }
712  
713  void s390_ipl_prepare_cpu(S390CPU *cpu)
714  {
715      S390IPLState *ipl = get_ipl_device();
716      Error *err = NULL;
717  
718      cpu->env.psw.addr = ipl->start_addr;
719      cpu->env.psw.mask = IPL_PSW_MASK;
720  
721      if (!ipl->kernel || ipl->iplb_valid) {
722          cpu->env.psw.addr = ipl->bios_start_addr;
723          if (!ipl->iplb_valid) {
724              ipl->iplb_valid = s390_gen_initial_iplb(ipl);
725          }
726      }
727      if (ipl->netboot) {
728          if (load_netboot_image(&err) < 0) {
729              error_report_err(err);
730              exit(1);
731          }
732          ipl->qipl.netboot_start_addr = cpu_to_be64(ipl->start_addr);
733      }
734      s390_ipl_set_boot_menu(ipl);
735      s390_ipl_prepare_qipl(cpu);
736  }
737  
738  static void s390_ipl_reset(DeviceState *dev)
739  {
740      S390IPLState *ipl = S390_IPL(dev);
741  
742      if (ipl->reset_type != S390_RESET_REIPL) {
743          ipl->iplb_valid = false;
744          memset(&ipl->iplb, 0, sizeof(IplParameterBlock));
745      }
746  }
747  
748  static void s390_ipl_class_init(ObjectClass *klass, void *data)
749  {
750      DeviceClass *dc = DEVICE_CLASS(klass);
751  
752      dc->realize = s390_ipl_realize;
753      device_class_set_props(dc, s390_ipl_properties);
754      dc->reset = s390_ipl_reset;
755      dc->vmsd = &vmstate_ipl;
756      set_bit(DEVICE_CATEGORY_MISC, dc->categories);
757      /* Reason: Loads the ROMs and thus can only be used one time - internally */
758      dc->user_creatable = false;
759  }
760  
761  static const TypeInfo s390_ipl_info = {
762      .class_init = s390_ipl_class_init,
763      .parent = TYPE_DEVICE,
764      .name  = TYPE_S390_IPL,
765      .instance_size  = sizeof(S390IPLState),
766  };
767  
768  static void s390_ipl_register_types(void)
769  {
770      type_register_static(&s390_ipl_info);
771  }
772  
773  type_init(s390_ipl_register_types)
774