qemu/hw/misc/debugexit.c
Thomas Weißschuh af1cf62401 hw/misc/debugexit: use runstate API instead of plain exit()
Directly calling exit() prevents any kind of management or handling.
Instead use the corresponding runstate API.
The default behavior of the runstate API is the same as exit().

Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240523-debugexit-v1-1-d52fcaf7bf8b@t-8ch.de>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2024-06-04 11:53:43 +02:00

87 lines
2.4 KiB
C

/*
* debug exit port emulation
*
* 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 or
* (at your option) any later version.
*/
#include "qemu/osdep.h"
#include "hw/isa/isa.h"
#include "hw/qdev-properties.h"
#include "qemu/module.h"
#include "qom/object.h"
#include "sysemu/runstate.h"
#define TYPE_ISA_DEBUG_EXIT_DEVICE "isa-debug-exit"
OBJECT_DECLARE_SIMPLE_TYPE(ISADebugExitState, ISA_DEBUG_EXIT_DEVICE)
struct ISADebugExitState {
ISADevice parent_obj;
uint32_t iobase;
uint32_t iosize;
MemoryRegion io;
};
static uint64_t debug_exit_read(void *opaque, hwaddr addr, unsigned size)
{
return 0;
}
static void debug_exit_write(void *opaque, hwaddr addr, uint64_t val,
unsigned width)
{
qemu_system_shutdown_request_with_code(SHUTDOWN_CAUSE_GUEST_SHUTDOWN,
(val << 1) | 1);
}
static const MemoryRegionOps debug_exit_ops = {
.read = debug_exit_read,
.write = debug_exit_write,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static void debug_exit_realizefn(DeviceState *d, Error **errp)
{
ISADevice *dev = ISA_DEVICE(d);
ISADebugExitState *isa = ISA_DEBUG_EXIT_DEVICE(d);
memory_region_init_io(&isa->io, OBJECT(dev), &debug_exit_ops, isa,
TYPE_ISA_DEBUG_EXIT_DEVICE, isa->iosize);
memory_region_add_subregion(isa_address_space_io(dev),
isa->iobase, &isa->io);
}
static Property debug_exit_properties[] = {
DEFINE_PROP_UINT32("iobase", ISADebugExitState, iobase, 0x501),
DEFINE_PROP_UINT32("iosize", ISADebugExitState, iosize, 0x02),
DEFINE_PROP_END_OF_LIST(),
};
static void debug_exit_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = debug_exit_realizefn;
device_class_set_props(dc, debug_exit_properties);
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo debug_exit_info = {
.name = TYPE_ISA_DEBUG_EXIT_DEVICE,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISADebugExitState),
.class_init = debug_exit_class_initfn,
};
static void debug_exit_register_types(void)
{
type_register_static(&debug_exit_info);
}
type_init(debug_exit_register_types)