|
@@ -25,6 +25,7 @@
|
|
#include "sysemu/sysemu.h"
|
|
#include "sysemu/sysemu.h"
|
|
#include "qapi/visitor.h"
|
|
#include "qapi/visitor.h"
|
|
#include "qemu/error-report.h"
|
|
#include "qemu/error-report.h"
|
|
|
|
+#include "hw/hw.h"
|
|
|
|
|
|
typedef struct FWBootEntry FWBootEntry;
|
|
typedef struct FWBootEntry FWBootEntry;
|
|
|
|
|
|
@@ -37,6 +38,67 @@ struct FWBootEntry {
|
|
|
|
|
|
static QTAILQ_HEAD(, FWBootEntry) fw_boot_order =
|
|
static QTAILQ_HEAD(, FWBootEntry) fw_boot_order =
|
|
QTAILQ_HEAD_INITIALIZER(fw_boot_order);
|
|
QTAILQ_HEAD_INITIALIZER(fw_boot_order);
|
|
|
|
+static QEMUBootSetHandler *boot_set_handler;
|
|
|
|
+static void *boot_set_opaque;
|
|
|
|
+
|
|
|
|
+void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
|
|
|
|
+{
|
|
|
|
+ boot_set_handler = func;
|
|
|
|
+ boot_set_opaque = opaque;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int qemu_boot_set(const char *boot_order)
|
|
|
|
+{
|
|
|
|
+ if (!boot_set_handler) {
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ return boot_set_handler(boot_set_opaque, boot_order);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void validate_bootdevices(const char *devices)
|
|
|
|
+{
|
|
|
|
+ /* We just do some generic consistency checks */
|
|
|
|
+ const char *p;
|
|
|
|
+ int bitmap = 0;
|
|
|
|
+
|
|
|
|
+ for (p = devices; *p != '\0'; p++) {
|
|
|
|
+ /* Allowed boot devices are:
|
|
|
|
+ * a-b: floppy disk drives
|
|
|
|
+ * c-f: IDE disk drives
|
|
|
|
+ * g-m: machine implementation dependent drives
|
|
|
|
+ * n-p: network devices
|
|
|
|
+ * It's up to each machine implementation to check if the given boot
|
|
|
|
+ * devices match the actual hardware implementation and firmware
|
|
|
|
+ * features.
|
|
|
|
+ */
|
|
|
|
+ if (*p < 'a' || *p > 'p') {
|
|
|
|
+ fprintf(stderr, "Invalid boot device '%c'\n", *p);
|
|
|
|
+ exit(1);
|
|
|
|
+ }
|
|
|
|
+ if (bitmap & (1 << (*p - 'a'))) {
|
|
|
|
+ fprintf(stderr, "Boot device '%c' was given twice\n", *p);
|
|
|
|
+ exit(1);
|
|
|
|
+ }
|
|
|
|
+ bitmap |= 1 << (*p - 'a');
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void restore_boot_order(void *opaque)
|
|
|
|
+{
|
|
|
|
+ char *normal_boot_order = opaque;
|
|
|
|
+ static int first = 1;
|
|
|
|
+
|
|
|
|
+ /* Restore boot order and remove ourselves after the first boot */
|
|
|
|
+ if (first) {
|
|
|
|
+ first = 0;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ qemu_boot_set(normal_boot_order);
|
|
|
|
+
|
|
|
|
+ qemu_unregister_reset(restore_boot_order, normal_boot_order);
|
|
|
|
+ g_free(normal_boot_order);
|
|
|
|
+}
|
|
|
|
|
|
void check_boot_index(int32_t bootindex, Error **errp)
|
|
void check_boot_index(int32_t bootindex, Error **errp)
|
|
{
|
|
{
|