mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-27 04:13:53 -06:00

- Ignore writes to CNTP_CTL_EL0 on HVF ARM (Alexander) - Add '-d invalid_mem' logging option (Zoltan) - Create QOM containers explicitly (Peter) - Rename sysemu/ -> system/ (Philippe) - Re-orderning of include/exec/ headers (Philippe) Move a lot of declarations from these legacy mixed bag headers: . "exec/cpu-all.h" . "exec/cpu-common.h" . "exec/cpu-defs.h" . "exec/exec-all.h" . "exec/translate-all" to these more specific ones: . "exec/page-protection.h" . "exec/translation-block.h" . "user/cpu_loop.h" . "user/guest-host.h" . "user/page-protection.h" -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmdlnyAACgkQ4+MsLN6t wN6mBw//QFWi7CrU+bb8KMM53kOU9C507tjn99LLGFb5or73/umDsw6eo/b8DHBt KIwGLgATel42oojKfNKavtAzLK5rOrywpboPDpa3SNeF1onW+99NGJ52LQUqIX6K A6bS0fPdGG9ZzEuPpbjDXlp++0yhDcdSgZsS42fEsT7Dyj5gzJYlqpqhiXGqpsn8 4Y0UMxSL21K3HEexlzw2hsoOBFA3tUm2ujNDhNkt8QASr85yQVLCypABJnuoe/// 5Ojl5wTBeDwhANET0rhwHK8eIYaNboiM9fHopJYhvyw1bz6yAu9jQwzF/MrL3s/r xa4OBHBy5mq2hQV9Shcl3UfCQdk/vDaYaWpgzJGX8stgMGYfnfej1SIl8haJIfcl VMX8/jEFdYbjhO4AeGRYcBzWjEJymkDJZoiSWp2NuEDi6jqIW+7yW1q0Rnlg9lay ShAqLK5Pv4zUw3t0Jy3qv9KSW8sbs6PQxtzXjk8p97rTf76BJ2pF8sv1tVzmsidP 9L92Hv5O34IqzBu2oATOUZYJk89YGmTIUSLkpT7asJZpBLwNM2qLp5jO00WVU0Sd +kAn324guYPkko/TVnjC/AY7CMu55EOtD9NU35k3mUAnxXT9oDUeL4NlYtfgrJx6 x1Nzr2FkS68+wlPAFKNSSU5lTjsjNaFM0bIJ4LCNtenJVP+SnRo= =cjz8 -----END PGP SIGNATURE----- Merge tag 'exec-20241220' of https://github.com/philmd/qemu into staging Accel & Exec patch queue - Ignore writes to CNTP_CTL_EL0 on HVF ARM (Alexander) - Add '-d invalid_mem' logging option (Zoltan) - Create QOM containers explicitly (Peter) - Rename sysemu/ -> system/ (Philippe) - Re-orderning of include/exec/ headers (Philippe) Move a lot of declarations from these legacy mixed bag headers: . "exec/cpu-all.h" . "exec/cpu-common.h" . "exec/cpu-defs.h" . "exec/exec-all.h" . "exec/translate-all" to these more specific ones: . "exec/page-protection.h" . "exec/translation-block.h" . "user/cpu_loop.h" . "user/guest-host.h" . "user/page-protection.h" # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmdlnyAACgkQ4+MsLN6t # wN6mBw//QFWi7CrU+bb8KMM53kOU9C507tjn99LLGFb5or73/umDsw6eo/b8DHBt # KIwGLgATel42oojKfNKavtAzLK5rOrywpboPDpa3SNeF1onW+99NGJ52LQUqIX6K # A6bS0fPdGG9ZzEuPpbjDXlp++0yhDcdSgZsS42fEsT7Dyj5gzJYlqpqhiXGqpsn8 # 4Y0UMxSL21K3HEexlzw2hsoOBFA3tUm2ujNDhNkt8QASr85yQVLCypABJnuoe/// # 5Ojl5wTBeDwhANET0rhwHK8eIYaNboiM9fHopJYhvyw1bz6yAu9jQwzF/MrL3s/r # xa4OBHBy5mq2hQV9Shcl3UfCQdk/vDaYaWpgzJGX8stgMGYfnfej1SIl8haJIfcl # VMX8/jEFdYbjhO4AeGRYcBzWjEJymkDJZoiSWp2NuEDi6jqIW+7yW1q0Rnlg9lay # ShAqLK5Pv4zUw3t0Jy3qv9KSW8sbs6PQxtzXjk8p97rTf76BJ2pF8sv1tVzmsidP # 9L92Hv5O34IqzBu2oATOUZYJk89YGmTIUSLkpT7asJZpBLwNM2qLp5jO00WVU0Sd # +kAn324guYPkko/TVnjC/AY7CMu55EOtD9NU35k3mUAnxXT9oDUeL4NlYtfgrJx6 # x1Nzr2FkS68+wlPAFKNSSU5lTjsjNaFM0bIJ4LCNtenJVP+SnRo= # =cjz8 # -----END PGP SIGNATURE----- # gpg: Signature made Fri 20 Dec 2024 11:45:20 EST # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'exec-20241220' of https://github.com/philmd/qemu: (59 commits) util/qemu-timer: fix indentation meson: Do not define CONFIG_DEVICES on user emulation system/accel-ops: Remove unnecessary 'exec/cpu-common.h' header system/numa: Remove unnecessary 'exec/cpu-common.h' header hw/xen: Remove unnecessary 'exec/cpu-common.h' header target/mips: Drop left-over comment about Jazz machine target/mips: Remove tswap() calls in semihosting uhi_fstat_cb() target/xtensa: Remove tswap() calls in semihosting simcall() helper accel/tcg: Un-inline translator_is_same_page() accel/tcg: Include missing 'exec/translation-block.h' header accel/tcg: Move tcg_cflags_has/set() to 'exec/translation-block.h' accel/tcg: Restrict curr_cflags() declaration to 'internal-common.h' qemu/coroutine: Include missing 'qemu/atomic.h' header exec/translation-block: Include missing 'qemu/atomic.h' header accel/tcg: Declare cpu_loop_exit_requested() in 'exec/cpu-common.h' exec/cpu-all: Include 'cpu.h' earlier so MMU_USER_IDX is always defined target/sparc: Move sparc_restore_state_to_opc() to cpu.c target/sparc: Uninline cpu_get_tb_cpu_state() target/loongarch: Declare loongarch_cpu_dump_state() locally user: Move various declarations out of 'exec/exec-all.h' ... Conflicts: hw/char/riscv_htif.c hw/intc/riscv_aplic.c target/s390x/cpu.c Apply sysemu header path changes to not in the pull request. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
221 lines
7 KiB
C
221 lines
7 KiB
C
/*
|
|
* Generic Loader
|
|
*
|
|
* Copyright (C) 2014 Li Guang
|
|
* Copyright (C) 2016 Xilinx Inc.
|
|
* Written by Li Guang <lig.fnst@cn.fujitsu.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Internally inside QEMU this is a device. It is a strange device that
|
|
* provides no hardware interface but allows QEMU to monkey patch memory
|
|
* specified when it is created. To be able to do this it has a reset
|
|
* callback that does the memory operations.
|
|
|
|
* This device allows the user to monkey patch memory. To be able to do
|
|
* this it needs a backend to manage the data, the same as other
|
|
* memory-related devices. In this case as the backend is so trivial we
|
|
* have merged it with the frontend instead of creating and maintaining a
|
|
* separate backend.
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "exec/tswap.h"
|
|
#include "system/dma.h"
|
|
#include "system/reset.h"
|
|
#include "hw/boards.h"
|
|
#include "hw/loader.h"
|
|
#include "hw/qdev-properties.h"
|
|
#include "qapi/error.h"
|
|
#include "qemu/module.h"
|
|
#include "hw/core/generic-loader.h"
|
|
|
|
#define CPU_NONE 0xFFFFFFFF
|
|
|
|
static void generic_loader_reset(void *opaque)
|
|
{
|
|
GenericLoaderState *s = GENERIC_LOADER(opaque);
|
|
|
|
if (s->set_pc) {
|
|
CPUClass *cc = CPU_GET_CLASS(s->cpu);
|
|
cpu_reset(s->cpu);
|
|
if (cc) {
|
|
cc->set_pc(s->cpu, s->addr);
|
|
}
|
|
}
|
|
|
|
if (s->data_len) {
|
|
assert(s->data_len <= sizeof(s->data));
|
|
dma_memory_write(s->cpu->as, s->addr, &s->data, s->data_len,
|
|
MEMTXATTRS_UNSPECIFIED);
|
|
}
|
|
}
|
|
|
|
static void generic_loader_realize(DeviceState *dev, Error **errp)
|
|
{
|
|
GenericLoaderState *s = GENERIC_LOADER(dev);
|
|
hwaddr entry;
|
|
int big_endian;
|
|
ssize_t size = 0;
|
|
|
|
s->set_pc = false;
|
|
|
|
/* Perform some error checking on the user's options */
|
|
if (s->data || s->data_len || s->data_be) {
|
|
/* User is loading memory values */
|
|
if (s->file) {
|
|
error_setg(errp, "Specifying a file is not supported when loading "
|
|
"memory values");
|
|
return;
|
|
} else if (s->force_raw) {
|
|
error_setg(errp, "Specifying force-raw is not supported when "
|
|
"loading memory values");
|
|
return;
|
|
} else if (!s->data_len) {
|
|
/* We can't check for !data here as a value of 0 is still valid. */
|
|
error_setg(errp, "Both data and data-len must be specified");
|
|
return;
|
|
} else if (s->data_len > 8) {
|
|
error_setg(errp, "data-len cannot be greater then 8 bytes");
|
|
return;
|
|
}
|
|
} else if (s->file || s->force_raw) {
|
|
/* User is loading an image */
|
|
if (s->data || s->data_len || s->data_be) {
|
|
error_setg(errp, "data can not be specified when loading an "
|
|
"image");
|
|
return;
|
|
}
|
|
/* The user specified a file, only set the PC if they also specified
|
|
* a CPU to use.
|
|
*/
|
|
if (s->cpu_num != CPU_NONE) {
|
|
s->set_pc = true;
|
|
}
|
|
} else if (s->addr) {
|
|
/* User is setting the PC */
|
|
if (s->data || s->data_len || s->data_be) {
|
|
error_setg(errp, "data can not be specified when setting a "
|
|
"program counter");
|
|
return;
|
|
} else if (s->cpu_num == CPU_NONE) {
|
|
error_setg(errp, "cpu_num must be specified when setting a "
|
|
"program counter");
|
|
return;
|
|
}
|
|
s->set_pc = true;
|
|
} else {
|
|
/* Did the user specify anything? */
|
|
error_setg(errp, "please include valid arguments");
|
|
return;
|
|
}
|
|
|
|
qemu_register_reset(generic_loader_reset, dev);
|
|
|
|
if (s->cpu_num != CPU_NONE) {
|
|
s->cpu = qemu_get_cpu(s->cpu_num);
|
|
if (!s->cpu) {
|
|
error_setg(errp, "Specified boot CPU#%d is nonexistent",
|
|
s->cpu_num);
|
|
return;
|
|
}
|
|
} else {
|
|
s->cpu = first_cpu;
|
|
}
|
|
|
|
big_endian = target_words_bigendian();
|
|
|
|
if (s->file) {
|
|
AddressSpace *as = s->cpu ? s->cpu->as : NULL;
|
|
|
|
if (!s->force_raw) {
|
|
size = load_elf_as(s->file, NULL, NULL, NULL, &entry, NULL, NULL,
|
|
NULL, big_endian, 0, 0, 0, as);
|
|
|
|
if (size < 0) {
|
|
size = load_uimage_as(s->file, &entry, NULL, NULL, NULL, NULL,
|
|
as);
|
|
}
|
|
|
|
if (size < 0) {
|
|
size = load_targphys_hex_as(s->file, &entry, as);
|
|
}
|
|
}
|
|
|
|
if (size < 0 || s->force_raw) {
|
|
/* Default to the maximum size being the machine's ram size */
|
|
size = load_image_targphys_as(s->file, s->addr, current_machine->ram_size, as);
|
|
} else {
|
|
s->addr = entry;
|
|
}
|
|
|
|
if (size < 0) {
|
|
error_setg(errp, "Cannot load specified image %s", s->file);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* Convert the data endianness */
|
|
if (s->data_be) {
|
|
s->data = cpu_to_be64(s->data);
|
|
} else {
|
|
s->data = cpu_to_le64(s->data);
|
|
}
|
|
}
|
|
|
|
static void generic_loader_unrealize(DeviceState *dev)
|
|
{
|
|
qemu_unregister_reset(generic_loader_reset, dev);
|
|
}
|
|
|
|
static const Property generic_loader_props[] = {
|
|
DEFINE_PROP_UINT64("addr", GenericLoaderState, addr, 0),
|
|
DEFINE_PROP_UINT64("data", GenericLoaderState, data, 0),
|
|
DEFINE_PROP_UINT8("data-len", GenericLoaderState, data_len, 0),
|
|
DEFINE_PROP_BOOL("data-be", GenericLoaderState, data_be, false),
|
|
DEFINE_PROP_UINT32("cpu-num", GenericLoaderState, cpu_num, CPU_NONE),
|
|
DEFINE_PROP_BOOL("force-raw", GenericLoaderState, force_raw, false),
|
|
DEFINE_PROP_STRING("file", GenericLoaderState, file),
|
|
};
|
|
|
|
static void generic_loader_class_init(ObjectClass *klass, void *data)
|
|
{
|
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
|
|
|
/* The reset function is not registered here and is instead registered in
|
|
* the realize function to allow this device to be added via the device_add
|
|
* command in the QEMU monitor.
|
|
* TODO: Improve the device_add functionality to allow resets to be
|
|
* connected
|
|
*/
|
|
dc->realize = generic_loader_realize;
|
|
dc->unrealize = generic_loader_unrealize;
|
|
device_class_set_props(dc, generic_loader_props);
|
|
dc->desc = "Generic Loader";
|
|
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
|
}
|
|
|
|
static const TypeInfo generic_loader_info = {
|
|
.name = TYPE_GENERIC_LOADER,
|
|
.parent = TYPE_DEVICE,
|
|
.instance_size = sizeof(GenericLoaderState),
|
|
.class_init = generic_loader_class_init,
|
|
};
|
|
|
|
static void generic_loader_register_type(void)
|
|
{
|
|
type_register_static(&generic_loader_info);
|
|
}
|
|
|
|
type_init(generic_loader_register_type)
|