mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
Four changes here. Polling for reconnection of character devices, the QOMification of accelerators, a fix for -kernel support on x86, and one for a recently-introduced virtio-scsi optimization. # gpg: Signature made Thu 09 Oct 2014 14:36:50 BST using RSA key ID 4E6B09D7 # gpg: Good signature from "Paolo Bonzini <pbonzini@redhat.com>" # gpg: aka "Paolo Bonzini <bonzini@gnu.org>" * remotes/bonzini/tags/for-upstream: (28 commits) qemu-char: Fix reconnect socket error reporting qemu-sockets: Add error to non-blocking connect handler qemu-error: Add error_vreport() virtio-scsi: fix use-after-free of VirtIOSCSIReq linuxboot: compute initrd loading address kvm: Make KVMState be the TYPE_KVM_ACCEL instance struct accel: Create accel object when initializing machine accel: Pass MachineState object to accel init functions accel: Rename 'init' method to 'init_machine' accel: Move accel init/allowed code to separate function accel: Remove tcg_available() function accel: Move qtest accel registration to qtest.c accel: Move Xen registration code to xen-common.c accel: Move KVM accel registration to kvm-all.c accel: Report unknown accelerator as "not found" instead of "does not exist" accel: Make AccelClass.available() optional accel: Use QOM classes for accel types accel: Move accel name lookup to separate function accel: Simplify configure_accelerator() using AccelType *acc variable accel: Create AccelType typedef ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -62,6 +62,7 @@ common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
|
||||
|
||||
common-obj-y += audio/
|
||||
common-obj-y += hw/
|
||||
common-obj-y += accel.o
|
||||
|
||||
common-obj-y += ui/
|
||||
common-obj-y += bt-host.o bt-vhci.o
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* QEMU System Emulator, accelerator interfaces
|
||||
*
|
||||
* Copyright (c) 2003-2008 Fabrice Bellard
|
||||
* Copyright (c) 2014 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sysemu/accel.h"
|
||||
#include "hw/boards.h"
|
||||
#include "qemu-common.h"
|
||||
#include "sysemu/arch_init.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "sysemu/qtest.h"
|
||||
#include "hw/xen/xen.h"
|
||||
#include "qom/object.h"
|
||||
#include "hw/boards.h"
|
||||
|
||||
int tcg_tb_size;
|
||||
static bool tcg_allowed = true;
|
||||
|
||||
static int tcg_init(MachineState *ms)
|
||||
{
|
||||
tcg_exec_init(tcg_tb_size * 1024 * 1024);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const TypeInfo accel_type = {
|
||||
.name = TYPE_ACCEL,
|
||||
.parent = TYPE_OBJECT,
|
||||
.class_size = sizeof(AccelClass),
|
||||
.instance_size = sizeof(AccelState),
|
||||
};
|
||||
|
||||
/* Lookup AccelClass from opt_name. Returns NULL if not found */
|
||||
static AccelClass *accel_find(const char *opt_name)
|
||||
{
|
||||
char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name);
|
||||
AccelClass *ac = ACCEL_CLASS(object_class_by_name(class_name));
|
||||
g_free(class_name);
|
||||
return ac;
|
||||
}
|
||||
|
||||
static int accel_init_machine(AccelClass *acc, MachineState *ms)
|
||||
{
|
||||
ObjectClass *oc = OBJECT_CLASS(acc);
|
||||
const char *cname = object_class_get_name(oc);
|
||||
AccelState *accel = ACCEL(object_new(cname));
|
||||
int ret;
|
||||
ms->accelerator = accel;
|
||||
*(acc->allowed) = true;
|
||||
ret = acc->init_machine(ms);
|
||||
if (ret < 0) {
|
||||
ms->accelerator = NULL;
|
||||
*(acc->allowed) = false;
|
||||
object_unref(OBJECT(accel));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int configure_accelerator(MachineState *ms)
|
||||
{
|
||||
const char *p;
|
||||
char buf[10];
|
||||
int ret;
|
||||
bool accel_initialised = false;
|
||||
bool init_failed = false;
|
||||
AccelClass *acc = NULL;
|
||||
|
||||
p = qemu_opt_get(qemu_get_machine_opts(), "accel");
|
||||
if (p == NULL) {
|
||||
/* Use the default "accelerator", tcg */
|
||||
p = "tcg";
|
||||
}
|
||||
|
||||
while (!accel_initialised && *p != '\0') {
|
||||
if (*p == ':') {
|
||||
p++;
|
||||
}
|
||||
p = get_opt_name(buf, sizeof(buf), p, ':');
|
||||
acc = accel_find(buf);
|
||||
if (!acc) {
|
||||
fprintf(stderr, "\"%s\" accelerator not found.\n", buf);
|
||||
continue;
|
||||
}
|
||||
if (acc->available && !acc->available()) {
|
||||
printf("%s not supported for this target\n",
|
||||
acc->name);
|
||||
continue;
|
||||
}
|
||||
ret = accel_init_machine(acc, ms);
|
||||
if (ret < 0) {
|
||||
init_failed = true;
|
||||
fprintf(stderr, "failed to initialize %s: %s\n",
|
||||
acc->name,
|
||||
strerror(-ret));
|
||||
} else {
|
||||
accel_initialised = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!accel_initialised) {
|
||||
if (!init_failed) {
|
||||
fprintf(stderr, "No accelerator found!\n");
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (init_failed) {
|
||||
fprintf(stderr, "Back to %s accelerator.\n", acc->name);
|
||||
}
|
||||
|
||||
return !accel_initialised;
|
||||
}
|
||||
|
||||
|
||||
static void tcg_accel_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
AccelClass *ac = ACCEL_CLASS(oc);
|
||||
ac->name = "tcg";
|
||||
ac->init_machine = tcg_init;
|
||||
ac->allowed = &tcg_allowed;
|
||||
}
|
||||
|
||||
#define TYPE_TCG_ACCEL ACCEL_CLASS_NAME("tcg")
|
||||
|
||||
static const TypeInfo tcg_accel_type = {
|
||||
.name = TYPE_TCG_ACCEL,
|
||||
.parent = TYPE_ACCEL,
|
||||
.class_init = tcg_accel_class_init,
|
||||
};
|
||||
|
||||
static void register_accel_types(void)
|
||||
{
|
||||
type_register_static(&accel_type);
|
||||
type_register_static(&tcg_accel_type);
|
||||
}
|
||||
|
||||
type_init(register_accel_types);
|
||||
@@ -1337,11 +1337,6 @@ void cpudef_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
int tcg_available(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int kvm_available(void)
|
||||
{
|
||||
#ifdef CONFIG_KVM
|
||||
|
||||
@@ -545,11 +545,12 @@ bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
|
||||
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
{
|
||||
if (scsi_req_enqueue(req->sreq)) {
|
||||
scsi_req_continue(req->sreq);
|
||||
SCSIRequest *sreq = req->sreq;
|
||||
if (scsi_req_enqueue(sreq)) {
|
||||
scsi_req_continue(sreq);
|
||||
}
|
||||
bdrv_io_unplug(req->sreq->dev->conf.bs);
|
||||
scsi_req_unref(req->sreq);
|
||||
bdrv_io_unplug(sreq->dev->conf.bs);
|
||||
scsi_req_unref(sreq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
||||
|
||||
+2
-2
@@ -5,12 +5,11 @@
|
||||
|
||||
#include "qemu/typedefs.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "sysemu/accel.h"
|
||||
#include "hw/qdev.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
|
||||
typedef struct MachineState MachineState;
|
||||
|
||||
typedef void QEMUMachineInitFunc(MachineState *ms);
|
||||
|
||||
typedef void QEMUMachineResetFunc(void);
|
||||
@@ -135,6 +134,7 @@ struct MachineState {
|
||||
char *kernel_cmdline;
|
||||
char *initrd_filename;
|
||||
const char *cpu_model;
|
||||
AccelState *accelerator;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,7 +36,6 @@ void xen_cmos_set_s3_resume(void *opaque, int irq, int level);
|
||||
|
||||
qemu_irq *xen_interrupt_controller_init(void);
|
||||
|
||||
int xen_init(MachineClass *mc);
|
||||
void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);
|
||||
|
||||
#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
|
||||
|
||||
@@ -38,6 +38,7 @@ void error_vprintf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
|
||||
void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
||||
void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
||||
void error_set_progname(const char *argv0);
|
||||
void error_vreport(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
|
||||
void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
||||
const char *error_get_progname(void);
|
||||
extern bool enable_timestamp_msg;
|
||||
|
||||
@@ -47,7 +47,7 @@ int recv_all(int fd, void *buf, int len1, bool single_read);
|
||||
/* callback function for nonblocking connect
|
||||
* valid fd on success, negative error code on failure
|
||||
*/
|
||||
typedef void NonBlockingConnectHandler(int fd, void *opaque);
|
||||
typedef void NonBlockingConnectHandler(int fd, Error *errp, void *opaque);
|
||||
|
||||
InetSocketAddress *inet_parse(const char *str, Error **errp);
|
||||
int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp);
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef struct MemoryMappingList MemoryMappingList;
|
||||
|
||||
typedef struct QEMUMachine QEMUMachine;
|
||||
typedef struct MachineClass MachineClass;
|
||||
typedef struct MachineState MachineState;
|
||||
typedef struct NICInfo NICInfo;
|
||||
typedef struct HCIInfo HCIInfo;
|
||||
typedef struct AudioState AudioState;
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/* QEMU accelerator interfaces
|
||||
*
|
||||
* Copyright (c) 2014 Red Hat Inc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef HW_ACCEL_H
|
||||
#define HW_ACCEL_H
|
||||
|
||||
#include "qemu/typedefs.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
typedef struct AccelState {
|
||||
/*< private >*/
|
||||
Object parent_obj;
|
||||
} AccelState;
|
||||
|
||||
typedef struct AccelClass {
|
||||
/*< private >*/
|
||||
ObjectClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
const char *opt_name;
|
||||
const char *name;
|
||||
int (*available)(void);
|
||||
int (*init_machine)(MachineState *ms);
|
||||
bool *allowed;
|
||||
} AccelClass;
|
||||
|
||||
#define TYPE_ACCEL "accel"
|
||||
|
||||
#define ACCEL_CLASS_SUFFIX "-" TYPE_ACCEL
|
||||
#define ACCEL_CLASS_NAME(a) (a ACCEL_CLASS_SUFFIX)
|
||||
|
||||
#define ACCEL_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(AccelClass, (klass), TYPE_ACCEL)
|
||||
#define ACCEL(obj) \
|
||||
OBJECT_CHECK(AccelState, (obj), TYPE_ACCEL)
|
||||
#define ACCEL_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(AccelClass, (obj), TYPE_ACCEL)
|
||||
|
||||
extern int tcg_tb_size;
|
||||
|
||||
int configure_accelerator(MachineState *ms);
|
||||
|
||||
#endif
|
||||
@@ -33,7 +33,6 @@ void do_smbios_option(QemuOpts *opts);
|
||||
void ram_mig_init(void);
|
||||
void cpudef_init(void);
|
||||
void audio_init(void);
|
||||
int tcg_available(void);
|
||||
int kvm_available(void);
|
||||
int xen_available(void);
|
||||
|
||||
|
||||
@@ -163,8 +163,6 @@ extern KVMState *kvm_state;
|
||||
|
||||
/* external API */
|
||||
|
||||
int kvm_init(MachineClass *mc);
|
||||
|
||||
int kvm_has_sync_mmu(void);
|
||||
int kvm_has_vcpu_events(void);
|
||||
int kvm_has_robust_singlestep(void);
|
||||
|
||||
@@ -26,7 +26,6 @@ static inline bool qtest_enabled(void)
|
||||
|
||||
bool qtest_driver(void);
|
||||
|
||||
int qtest_init_accel(MachineClass *mc);
|
||||
void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
|
||||
|
||||
static inline int qtest_available(void)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/accel.h"
|
||||
#include "hw/hw.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "hw/s390x/adapter.h"
|
||||
@@ -70,8 +71,10 @@ typedef struct KVMSlot
|
||||
|
||||
typedef struct kvm_dirty_log KVMDirtyLog;
|
||||
|
||||
struct KVMState
|
||||
typedef struct KVMState
|
||||
{
|
||||
AccelState parent_obj;
|
||||
|
||||
KVMSlot *slots;
|
||||
int nr_slots;
|
||||
int fd;
|
||||
@@ -104,7 +107,12 @@ struct KVMState
|
||||
QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
|
||||
bool direct_msi;
|
||||
#endif
|
||||
};
|
||||
} KVMState;
|
||||
|
||||
#define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm")
|
||||
|
||||
#define KVM_STATE(obj) \
|
||||
OBJECT_CHECK(KVMState, (obj), TYPE_KVM_ACCEL)
|
||||
|
||||
KVMState *kvm_state;
|
||||
bool kvm_kernel_irqchip;
|
||||
@@ -1377,8 +1385,9 @@ static int kvm_max_vcpus(KVMState *s)
|
||||
return (ret) ? ret : kvm_recommended_vcpus(s);
|
||||
}
|
||||
|
||||
int kvm_init(MachineClass *mc)
|
||||
static int kvm_init(MachineState *ms)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
static const char upgrade_note[] =
|
||||
"Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
|
||||
"(see http://sourceforge.net/projects/kvm).\n";
|
||||
@@ -1397,7 +1406,7 @@ int kvm_init(MachineClass *mc)
|
||||
int i, type = 0;
|
||||
const char *kvm_type;
|
||||
|
||||
s = g_malloc0(sizeof(KVMState));
|
||||
s = KVM_STATE(ms->accelerator);
|
||||
|
||||
/*
|
||||
* On systems where the kernel can support different base page
|
||||
@@ -1586,7 +1595,6 @@ err:
|
||||
close(s->fd);
|
||||
}
|
||||
g_free(s->slots);
|
||||
g_free(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2225,3 +2233,25 @@ int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target)
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static void kvm_accel_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
AccelClass *ac = ACCEL_CLASS(oc);
|
||||
ac->name = "KVM";
|
||||
ac->init_machine = kvm_init;
|
||||
ac->allowed = &kvm_allowed;
|
||||
}
|
||||
|
||||
static const TypeInfo kvm_accel_type = {
|
||||
.name = TYPE_KVM_ACCEL,
|
||||
.parent = TYPE_ACCEL,
|
||||
.class_init = kvm_accel_class_init,
|
||||
.instance_size = sizeof(KVMState),
|
||||
};
|
||||
|
||||
static void kvm_type_init(void)
|
||||
{
|
||||
type_register_static(&kvm_accel_type);
|
||||
}
|
||||
|
||||
type_init(kvm_type_init);
|
||||
|
||||
@@ -35,11 +35,6 @@ int kvm_init_vcpu(CPUState *cpu)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int kvm_init(MachineClass *mc)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
void kvm_flush_coalesced_mmio_buffer(void)
|
||||
{
|
||||
}
|
||||
|
||||
+2
-2
@@ -33,12 +33,12 @@
|
||||
do { } while (0)
|
||||
#endif
|
||||
|
||||
static void tcp_wait_for_connect(int fd, void *opaque)
|
||||
static void tcp_wait_for_connect(int fd, Error *err, void *opaque)
|
||||
{
|
||||
MigrationState *s = opaque;
|
||||
|
||||
if (fd < 0) {
|
||||
DPRINTF("migrate connect error\n");
|
||||
DPRINTF("migrate connect error: %s\n", error_get_pretty(err));
|
||||
s->file = NULL;
|
||||
migrate_fd_error(s);
|
||||
} else {
|
||||
|
||||
+2
-2
@@ -33,12 +33,12 @@
|
||||
do { } while (0)
|
||||
#endif
|
||||
|
||||
static void unix_wait_for_connect(int fd, void *opaque)
|
||||
static void unix_wait_for_connect(int fd, Error *err, void *opaque)
|
||||
{
|
||||
MigrationState *s = opaque;
|
||||
|
||||
if (fd < 0) {
|
||||
DPRINTF("migrate connect error\n");
|
||||
DPRINTF("migrate connect error: %s\n", error_get_pretty(err));
|
||||
s->file = NULL;
|
||||
migrate_fd_error(s);
|
||||
} else {
|
||||
|
||||
Binary file not shown.
@@ -76,14 +76,45 @@ boot_kernel:
|
||||
|
||||
|
||||
copy_kernel:
|
||||
/* Compute initrd address */
|
||||
mov $0xe801, %ax
|
||||
xor %cx, %cx
|
||||
xor %dx, %dx
|
||||
int $0x15
|
||||
|
||||
/* Output could be in AX/BX or CX/DX */
|
||||
or %cx, %cx
|
||||
jnz 1f
|
||||
or %dx, %dx
|
||||
jnz 1f
|
||||
mov %ax, %cx
|
||||
mov %bx, %dx
|
||||
1:
|
||||
|
||||
or %dx, %dx
|
||||
jnz 2f
|
||||
addw $1024, %cx /* add 1 MB */
|
||||
movzwl %cx, %edi
|
||||
shll $10, %edi /* convert to bytes */
|
||||
jmp 3f
|
||||
|
||||
2:
|
||||
addw $16777216 >> 16, %dx /* add 16 MB */
|
||||
movzwl %dx, %edi
|
||||
shll $16, %edi /* convert to bytes */
|
||||
|
||||
3:
|
||||
read_fw FW_CFG_INITRD_SIZE
|
||||
subl %eax, %edi
|
||||
andl $-4096, %edi /* EDI = start of initrd */
|
||||
|
||||
/* We need to load the kernel into memory we can't access in 16 bit
|
||||
mode, so let's get into 32 bit mode, write the kernel and jump
|
||||
back again. */
|
||||
|
||||
/* Reserve space on the stack for our GDT descriptor. */
|
||||
mov %esp, %ebp
|
||||
sub $16, %esp
|
||||
mov %esp, %ebp
|
||||
sub $16, %esp
|
||||
|
||||
/* Now create the GDT descriptor */
|
||||
movw $((3 * 8) - 1), -16(%bp)
|
||||
@@ -108,10 +139,18 @@ copy_kernel:
|
||||
/* We're now running in 16-bit CS, but 32-bit ES! */
|
||||
|
||||
/* Load kernel and initrd */
|
||||
pushl %edi
|
||||
read_fw_blob_addr32_edi(FW_CFG_INITRD)
|
||||
read_fw_blob_addr32(FW_CFG_KERNEL)
|
||||
read_fw_blob_addr32(FW_CFG_INITRD)
|
||||
read_fw_blob_addr32(FW_CFG_CMDLINE)
|
||||
read_fw_blob_addr32(FW_CFG_SETUP)
|
||||
|
||||
read_fw FW_CFG_SETUP_ADDR
|
||||
mov %eax, %edi
|
||||
mov %eax, %ebx
|
||||
read_fw_blob_addr32_edi(FW_CFG_SETUP)
|
||||
|
||||
/* Update the header with the initrd address we chose above */
|
||||
popl %es:0x218(%ebx)
|
||||
|
||||
/* And now jump into Linux! */
|
||||
mov $0, %eax
|
||||
|
||||
@@ -51,8 +51,6 @@
|
||||
.endm
|
||||
|
||||
#define read_fw_blob_pre(var) \
|
||||
read_fw var ## _ADDR; \
|
||||
mov %eax, %edi; \
|
||||
read_fw var ## _SIZE; \
|
||||
mov %eax, %ecx; \
|
||||
mov $var ## _DATA, %ax; \
|
||||
@@ -68,6 +66,8 @@
|
||||
* Clobbers: %eax, %edx, %es, %ecx, %edi
|
||||
*/
|
||||
#define read_fw_blob(var) \
|
||||
read_fw var ## _ADDR; \
|
||||
mov %eax, %edi; \
|
||||
read_fw_blob_pre(var); \
|
||||
/* old as(1) doesn't like this insn so emit the bytes instead: \
|
||||
rep insb (%dx), %es:(%edi); \
|
||||
@@ -80,7 +80,22 @@
|
||||
*
|
||||
* Clobbers: %eax, %edx, %es, %ecx, %edi
|
||||
*/
|
||||
#define read_fw_blob_addr32(var) \
|
||||
#define read_fw_blob_addr32(var) \
|
||||
read_fw var ## _ADDR; \
|
||||
mov %eax, %edi; \
|
||||
read_fw_blob_pre(var); \
|
||||
/* old as(1) doesn't like this insn so emit the bytes instead: \
|
||||
addr32 rep insb (%dx), %es:(%edi); \
|
||||
*/ \
|
||||
.dc.b 0x67,0xf3,0x6c
|
||||
|
||||
/*
|
||||
* Read a blob from the fw_cfg device in forced addr32 mode, address is in %edi.
|
||||
* Requires _SIZE and _DATA values for the parameter.
|
||||
*
|
||||
* Clobbers: %eax, %edx, %edi, %es, %ecx
|
||||
*/
|
||||
#define read_fw_blob_addr32_edi(var) \
|
||||
read_fw_blob_pre(var); \
|
||||
/* old as(1) doesn't like this insn so emit the bytes instead: \
|
||||
addr32 rep insb (%dx), %es:(%edi); \
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user