Filip Bozuta <filip.bozuta@syrmia.com> <filip.bozuta@rt-rk.com.com>
Frederic Konrad <konrad@adacore.com> <fred.konrad@greensocs.com>
Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
+Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
+Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
Leif Lindholm <leif@nuviainc.com> <leif.lindholm@linaro.org>
Radoslaw Biernacki <rad@semihalf.com> <radoslaw.biernacki@linaro.org>
Lines should be 80 characters; try not to make them longer.
Sometimes it is hard to do, especially when dealing with QEMU subsystems
-that use long function or symbol names. Even in that case, do not make
-lines much longer than 80 characters.
+that use long function or symbol names. If wrapping the line at 80 columns
+is obviously less readable and more awkward, prefer not to wrap it; better
+to have an 85 character line than one which is awkwardly wrapped.
+
+Even in that case, try not to make lines much longer than 80 characters.
+(The checkpatch script will warn at 100 characters, but this is intended
+as a guard against obviously-overlength lines, not a target.)
Rationale:
F: target/arm/kvm.c
MIPS KVM CPUs
-M: Huacai Chen <chenhc@lemote.com>
+M: Huacai Chen <chenhuacai@kernel.org>
S: Odd Fixes
F: target/mips/kvm.c
F: hw/net/mipsnet.c
Fuloong 2E
-M: Huacai Chen <chenhc@lemote.com>
+M: Huacai Chen <chenhuacai@kernel.org>
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
R: Jiaxun Yang <jiaxun.yang@flygoat.com>
S: Odd Fixes
F: include/hw/isa/vt82c686.h
Loongson-3 virtual platforms
-M: Huacai Chen <chenhc@lemote.com>
+M: Huacai Chen <chenhuacai@kernel.org>
R: Jiaxun Yang <jiaxun.yang@flygoat.com>
S: Maintained
F: hw/intc/loongson_liointc.c
QAPI
M: Markus Armbruster <armbru@redhat.com>
-M: Michael Roth <mdroth@linux.vnet.ibm.com>
+M: Michael Roth <michael.roth@amd.com>
S: Supported
F: qapi/
X: qapi/*.json
T: git https://repo.or.cz/qemu/armbru.git qapi-next
QEMU Guest Agent
-M: Michael Roth <mdroth@linux.vnet.ibm.com>
+M: Michael Roth <michael.roth@amd.com>
S: Maintained
F: qga/
F: docs/interop/qemu-ga.rst
MIPS TCG target
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
R: Aurelien Jarno <aurelien@aurel32.net>
-R: Huacai Chen <chenhc@lemote.com>
+R: Huacai Chen <chenhuacai@kernel.org>
R: Jiaxun Yang <jiaxun.yang@flygoat.com>
R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>
S: Odd Fixes
static bool legacy_config = true;
-#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
-#error No its not
-#else
int audio_bug (const char *funcname, int cond)
{
if (cond) {
AUD_log (NULL, "I am sorry\n");
}
AUD_log (NULL, "Context:\n");
-
-#if defined AUDIO_BREAKPOINT_ON_BUG
-# if defined HOST_I386
-# if defined __GNUC__
- __asm__ ("int3");
-# elif defined _MSC_VER
- _asm _emit 0xcc;
-# else
- abort ();
-# endif
-# else
- abort ();
-# endif
-#endif
+ abort();
}
return cond;
}
-#endif
static inline int audio_bits_to_index (int bits)
{
audio_reset_timer (s);
}
-static bool is_cleaning_up;
-
-bool audio_is_cleaning_up(void)
-{
- return is_cleaning_up;
-}
-
static void free_audio_state(AudioState *s)
{
HWVoiceOut *hwo, *hwon;
void audio_cleanup(void)
{
- is_cleaning_up = true;
while (!QTAILQ_EMPTY(&audio_states)) {
AudioState *s = QTAILQ_FIRST(&audio_states);
QTAILQ_REMOVE(&audio_states, s, list);
* backend and this can go away.
*/
driver = audio_driver_lookup("spice");
- driver->can_be_default = 1;
+ if (driver) {
+ driver->can_be_default = 1;
+ }
}
if (dev) {
int wav_start_capture(AudioState *state, CaptureState *s, const char *path,
int freq, int bits, int nchannels);
-bool audio_is_cleaning_up(void);
void audio_cleanup(void);
void audio_sample_to_uint64(const void *samples, int pos,
Audiodev *dev = drv_opaque;
AudiodevCoreaudioPerDirectionOptions *cpdo = dev->u.coreaudio.out;
int frames;
- struct audsettings fake_as;
+ struct audsettings obt_as;
/* create mutex */
err = pthread_mutex_init(&core->mutex, NULL);
return -1;
}
- fake_as = *as;
- as = &fake_as;
+ obt_as = *as;
+ as = &obt_as;
as->fmt = AUDIO_FORMAT_F32;
audio_pcm_init_info (&hw->info, as);
return -1;
}
- /* start Playback */
- if (!isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStart(core->outputDeviceID, core->ioprocid);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ, "Could not start playback\n");
- AudioDeviceDestroyIOProcID(core->outputDeviceID, core->ioprocid);
- core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
- }
- }
-
return 0;
}
int err;
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
- if (!audio_is_cleaning_up()) {
- /* stop playback */
- if (isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStop(core->outputDeviceID, core->ioprocid);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not stop playback\n");
- }
- }
-
- /* remove callback */
- status = AudioDeviceDestroyIOProcID(core->outputDeviceID,
- core->ioprocid);
+ /* stop playback */
+ if (isPlaying(core->outputDeviceID)) {
+ status = AudioDeviceStop(core->outputDeviceID, core->ioprocid);
if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not remove IOProc\n");
+ coreaudio_logerr(status, "Could not stop playback\n");
}
}
+
+ /* remove callback */
+ status = AudioDeviceDestroyIOProcID(core->outputDeviceID,
+ core->ioprocid);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr(status, "Could not remove IOProc\n");
+ }
core->outputDeviceID = kAudioDeviceUnknown;
/* destroy mutex */
}
} else {
/* stop playback */
- if (!audio_is_cleaning_up()) {
- if (isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStop(core->outputDeviceID,
- core->ioprocid);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not pause playback\n");
- }
+ if (isPlaying(core->outputDeviceID)) {
+ status = AudioDeviceStop(core->outputDeviceID,
+ core->ioprocid);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr(status, "Could not pause playback\n");
}
}
}
#endif
#ifdef CONFIG_LINUX_IO_URING
if (s->use_linux_io_uring) {
- Error *local_err;
+ Error *local_err = NULL;
if (!aio_setup_linux_io_uring(new_context, &local_err)) {
error_reportf_err(local_err, "Unable to use linux io_uring, "
"falling back to thread pool: ");
if (set_backing_hd) {
bdrv_set_backing_hd(target_bs, source, &local_err);
if (local_err) {
+ error_propagate(errp, local_err);
goto unref;
}
}
then
error_exit "Python not found. Use --python=/path/to/python"
fi
+if ! has "$make"
+then
+ error_exit "GNU make ($make) not found"
+fi
# Note that if the Python conditional here evaluates True we will exit
# with status 1 which is a shell 'false' value.
l2tpv3=no
fi
-if check_include "pty.h" ; then
- pty_h=yes
-else
- pty_h=no
-fi
-
cat > $TMPC <<EOF
#include <sys/mman.h>
int main(int argc, char *argv[]) {
fi
fi
-##########################################
-# getifaddrs (for tests/test-io-channel-socket )
-
-have_ifaddrs_h=yes
-if ! check_include "ifaddrs.h" ; then
- have_ifaddrs_h=no
-fi
-
-#########################################
-# libdrm check
-have_drm_h=no
-if check_include "libdrm/drm.h" ; then
- have_drm_h=yes
-fi
-
-#########################################
-# sys/signal.h check
-have_sys_signal_h=no
-if check_include "sys/signal.h" ; then
- have_sys_signal_h=yes
-fi
-
##########################################
# VTE probe
syncfs=yes
fi
-# check for kcov support (kernel must be 4.4+, compiled with certain options)
-kcov=no
-if check_include sys/kcov.h ; then
- kcov=yes
-fi
-
-# check for btrfs filesystem support (kernel must be 3.9+)
-btrfs=no
-if check_include linux/btrfs.h ; then
- btrfs=yes
-fi
-
# Search for bswap_32 function
byteswap_h=no
cat > $TMPC << EOF
if test "$syncfs" = "yes" ; then
echo "CONFIG_SYNCFS=y" >> $config_host_mak
fi
-if test "$kcov" = "yes" ; then
- echo "CONFIG_KCOV=y" >> $config_host_mak
-fi
-if test "$btrfs" = "yes" ; then
- echo "CONFIG_BTRFS=y" >> $config_host_mak
-fi
if test "$inotify" = "yes" ; then
echo "CONFIG_INOTIFY=y" >> $config_host_mak
fi
if test "$auth_pam" = "yes" ; then
echo "CONFIG_AUTH_PAM=y" >> $config_host_mak
fi
-if test "$have_ifaddrs_h" = "yes" ; then
- echo "HAVE_IFADDRS_H=y" >> $config_host_mak
-fi
-if test "$have_drm_h" = "yes" ; then
- echo "HAVE_DRM_H=y" >> $config_host_mak
-fi
if test "$have_broken_size_max" = "yes" ; then
echo "HAVE_BROKEN_SIZE_MAX=y" >> $config_host_mak
fi
if test "$have_openpty" = "yes" ; then
echo "HAVE_OPENPTY=y" >> $config_host_mak
fi
-if test "$have_sys_signal_h" = "yes" ; then
- echo "HAVE_SYS_SIGNAL_H=y" >> $config_host_mak
-fi
# Work around a system header bug with some kernel/XFS header
# versions where they both try to define 'struct fsxattr':
add_to deprecated_features "sheepdog"
echo "CONFIG_SHEEPDOG=y" >> $config_host_mak
fi
-if test "$pty_h" = "yes" ; then
- echo "HAVE_PTY_H=y" >> $config_host_mak
-fi
if test "$have_mlockall" = "yes" ; then
echo "HAVE_MLOCKALL=y" >> $config_host_mak
fi
reader->gmf = g_mapped_file_new(name, TRUE, &gerr);
if (gerr) {
eprintf("Failed to map PDB file \'%s\'\n", name);
+ g_error_free(gerr);
return 1;
}
qe->gmf = g_mapped_file_new(filename, TRUE, &gerr);
if (gerr) {
eprintf("Failed to map ELF dump file \'%s\'\n", filename);
+ g_error_free(gerr);
return 1;
}
#ifndef QEMU_9P_MARSHAL_H
#define QEMU_9P_MARSHAL_H
-typedef struct V9fsString
-{
+typedef struct V9fsString {
uint16_t size;
char *data;
} V9fsString;
-typedef struct V9fsQID
-{
+typedef struct V9fsQID {
uint8_t type;
uint32_t version;
uint64_t path;
} V9fsQID;
-typedef struct V9fsStat
-{
+typedef struct V9fsStat {
int16_t size;
int16_t type;
int32_t dev;
int32_t n_muid;
} V9fsStat;
-typedef struct V9fsIattr
-{
+typedef struct V9fsIattr {
int32_t valid;
int32_t mode;
int32_t uid;
void cred_init(FsCred *);
-struct FileOperations
-{
+struct FileOperations {
int (*parse_opts)(QemuOpts *, FsDriverEntry *, Error **errp);
int (*init)(FsContext *, Error **errp);
void (*cleanup)(FsContext *);
config SPITZ
bool
- select ADS7846 # display
+ select ADS7846 # touch-screen controller
select MAX111X # A/D converter
select WM8750 # audio codec
select MAX7310 # GPIO expander
config FW_CFG_DMA
bool
-config ADS7846
- bool
-
config VGA_CIRRUS
bool
default y if PCI_DEVICES
+++ /dev/null
-/*
- * TI ADS7846 / TSC2046 chip emulation.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/ssi/ssi.h"
-#include "migration/vmstate.h"
-#include "qemu/module.h"
-#include "ui/console.h"
-#include "qom/object.h"
-
-struct ADS7846State {
- SSIPeripheral ssidev;
- qemu_irq interrupt;
-
- int input[8];
- int pressure;
- int noise;
-
- int cycle;
- int output;
-};
-
-#define TYPE_ADS7846 "ads7846"
-OBJECT_DECLARE_SIMPLE_TYPE(ADS7846State, ADS7846)
-
-/* Control-byte bitfields */
-#define CB_PD0 (1 << 0)
-#define CB_PD1 (1 << 1)
-#define CB_SER (1 << 2)
-#define CB_MODE (1 << 3)
-#define CB_A0 (1 << 4)
-#define CB_A1 (1 << 5)
-#define CB_A2 (1 << 6)
-#define CB_START (1 << 7)
-
-#define X_AXIS_DMAX 3470
-#define X_AXIS_MIN 290
-#define Y_AXIS_DMAX 3450
-#define Y_AXIS_MIN 200
-
-#define ADS_VBAT 2000
-#define ADS_VAUX 2000
-#define ADS_TEMP0 2000
-#define ADS_TEMP1 3000
-#define ADS_XPOS(x, y) (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15))
-#define ADS_YPOS(x, y) (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15))
-#define ADS_Z1POS(x, y) 600
-#define ADS_Z2POS(x, y) (600 + 6000 / ADS_XPOS(x, y))
-
-static void ads7846_int_update(ADS7846State *s)
-{
- if (s->interrupt)
- qemu_set_irq(s->interrupt, s->pressure == 0);
-}
-
-static uint32_t ads7846_transfer(SSIPeripheral *dev, uint32_t value)
-{
- ADS7846State *s = ADS7846(dev);
-
- switch (s->cycle ++) {
- case 0:
- if (!(value & CB_START)) {
- s->cycle = 0;
- break;
- }
-
- s->output = s->input[(value >> 4) & 7];
-
- /* Imitate the ADC noise, some drivers expect this. */
- s->noise = (s->noise + 3) & 7;
- switch ((value >> 4) & 7) {
- case 1: s->output += s->noise ^ 2; break;
- case 3: s->output += s->noise ^ 0; break;
- case 4: s->output += s->noise ^ 7; break;
- case 5: s->output += s->noise ^ 5; break;
- }
-
- if (value & CB_MODE)
- s->output >>= 4; /* 8 bits instead of 12 */
-
- break;
- case 1:
- s->cycle = 0;
- break;
- }
- return s->output;
-}
-
-static void ads7846_ts_event(void *opaque,
- int x, int y, int z, int buttons_state)
-{
- ADS7846State *s = opaque;
-
- if (buttons_state) {
- x = 0x7fff - x;
- s->input[1] = ADS_XPOS(x, y);
- s->input[3] = ADS_Z1POS(x, y);
- s->input[4] = ADS_Z2POS(x, y);
- s->input[5] = ADS_YPOS(x, y);
- }
-
- if (s->pressure == !buttons_state) {
- s->pressure = !!buttons_state;
-
- ads7846_int_update(s);
- }
-}
-
-static int ads7856_post_load(void *opaque, int version_id)
-{
- ADS7846State *s = opaque;
-
- s->pressure = 0;
- ads7846_int_update(s);
- return 0;
-}
-
-static const VMStateDescription vmstate_ads7846 = {
- .name = "ads7846",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = ads7856_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_SSI_PERIPHERAL(ssidev, ADS7846State),
- VMSTATE_INT32_ARRAY(input, ADS7846State, 8),
- VMSTATE_INT32(noise, ADS7846State),
- VMSTATE_INT32(cycle, ADS7846State),
- VMSTATE_INT32(output, ADS7846State),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void ads7846_realize(SSIPeripheral *d, Error **errp)
-{
- DeviceState *dev = DEVICE(d);
- ADS7846State *s = ADS7846(d);
-
- qdev_init_gpio_out(dev, &s->interrupt, 1);
-
- s->input[0] = ADS_TEMP0; /* TEMP0 */
- s->input[2] = ADS_VBAT; /* VBAT */
- s->input[6] = ADS_VAUX; /* VAUX */
- s->input[7] = ADS_TEMP1; /* TEMP1 */
-
- /* We want absolute coordinates */
- qemu_add_mouse_event_handler(ads7846_ts_event, s, 1,
- "QEMU ADS7846-driven Touchscreen");
-
- ads7846_int_update(s);
-
- vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_ads7846, s);
-}
-
-static void ads7846_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
-
- k->realize = ads7846_realize;
- k->transfer = ads7846_transfer;
- set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
-}
-
-static const TypeInfo ads7846_info = {
- .name = TYPE_ADS7846,
- .parent = TYPE_SSI_PERIPHERAL,
- .instance_size = sizeof(ADS7846State),
- .class_init = ads7846_class_init,
-};
-
-static void ads7846_register_types(void)
-{
- type_register_static(&ads7846_info);
-}
-
-type_init(ads7846_register_types)
softmmu_ss.add(when: 'CONFIG_FW_CFG_DMA', if_true: files('ramfb.c'))
softmmu_ss.add(when: 'CONFIG_FW_CFG_DMA', if_true: files('ramfb-standalone.c'))
-softmmu_ss.add(when: 'CONFIG_ADS7846', if_true: files('ads7846.c'))
softmmu_ss.add(when: 'CONFIG_VGA_CIRRUS', if_true: files('cirrus_vga.c'))
softmmu_ss.add(when: ['CONFIG_VGA_CIRRUS', 'CONFIG_VGA_ISA'], if_true: files('cirrus_vga_isa.c'))
softmmu_ss.add(when: 'CONFIG_G364FB', if_true: files('g364fb.c'))
config ADB
bool
+config ADS7846
+ bool
+
config LM832X
bool
depends on I2C
--- /dev/null
+/*
+ * TI ADS7846 / TSC2046 chip emulation.
+ *
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Written by Andrzej Zaborowski <balrog@zabor.org>
+ *
+ * This code is licensed under the GNU GPL v2.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/ssi/ssi.h"
+#include "migration/vmstate.h"
+#include "qemu/module.h"
+#include "ui/console.h"
+#include "qom/object.h"
+
+struct ADS7846State {
+ SSIPeripheral ssidev;
+ qemu_irq interrupt;
+
+ int input[8];
+ int pressure;
+ int noise;
+
+ int cycle;
+ int output;
+};
+
+#define TYPE_ADS7846 "ads7846"
+OBJECT_DECLARE_SIMPLE_TYPE(ADS7846State, ADS7846)
+
+/* Control-byte bitfields */
+#define CB_PD0 (1 << 0)
+#define CB_PD1 (1 << 1)
+#define CB_SER (1 << 2)
+#define CB_MODE (1 << 3)
+#define CB_A0 (1 << 4)
+#define CB_A1 (1 << 5)
+#define CB_A2 (1 << 6)
+#define CB_START (1 << 7)
+
+#define X_AXIS_DMAX 3470
+#define X_AXIS_MIN 290
+#define Y_AXIS_DMAX 3450
+#define Y_AXIS_MIN 200
+
+#define ADS_VBAT 2000
+#define ADS_VAUX 2000
+#define ADS_TEMP0 2000
+#define ADS_TEMP1 3000
+#define ADS_XPOS(x, y) (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15))
+#define ADS_YPOS(x, y) (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15))
+#define ADS_Z1POS(x, y) 600
+#define ADS_Z2POS(x, y) (600 + 6000 / ADS_XPOS(x, y))
+
+static void ads7846_int_update(ADS7846State *s)
+{
+ if (s->interrupt)
+ qemu_set_irq(s->interrupt, s->pressure == 0);
+}
+
+static uint32_t ads7846_transfer(SSIPeripheral *dev, uint32_t value)
+{
+ ADS7846State *s = ADS7846(dev);
+
+ switch (s->cycle ++) {
+ case 0:
+ if (!(value & CB_START)) {
+ s->cycle = 0;
+ break;
+ }
+
+ s->output = s->input[(value >> 4) & 7];
+
+ /* Imitate the ADC noise, some drivers expect this. */
+ s->noise = (s->noise + 3) & 7;
+ switch ((value >> 4) & 7) {
+ case 1: s->output += s->noise ^ 2; break;
+ case 3: s->output += s->noise ^ 0; break;
+ case 4: s->output += s->noise ^ 7; break;
+ case 5: s->output += s->noise ^ 5; break;
+ }
+
+ if (value & CB_MODE)
+ s->output >>= 4; /* 8 bits instead of 12 */
+
+ break;
+ case 1:
+ s->cycle = 0;
+ break;
+ }
+ return s->output;
+}
+
+static void ads7846_ts_event(void *opaque,
+ int x, int y, int z, int buttons_state)
+{
+ ADS7846State *s = opaque;
+
+ if (buttons_state) {
+ x = 0x7fff - x;
+ s->input[1] = ADS_XPOS(x, y);
+ s->input[3] = ADS_Z1POS(x, y);
+ s->input[4] = ADS_Z2POS(x, y);
+ s->input[5] = ADS_YPOS(x, y);
+ }
+
+ if (s->pressure == !buttons_state) {
+ s->pressure = !!buttons_state;
+
+ ads7846_int_update(s);
+ }
+}
+
+static int ads7856_post_load(void *opaque, int version_id)
+{
+ ADS7846State *s = opaque;
+
+ s->pressure = 0;
+ ads7846_int_update(s);
+ return 0;
+}
+
+static const VMStateDescription vmstate_ads7846 = {
+ .name = "ads7846",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = ads7856_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_SSI_PERIPHERAL(ssidev, ADS7846State),
+ VMSTATE_INT32_ARRAY(input, ADS7846State, 8),
+ VMSTATE_INT32(noise, ADS7846State),
+ VMSTATE_INT32(cycle, ADS7846State),
+ VMSTATE_INT32(output, ADS7846State),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void ads7846_realize(SSIPeripheral *d, Error **errp)
+{
+ DeviceState *dev = DEVICE(d);
+ ADS7846State *s = ADS7846(d);
+
+ qdev_init_gpio_out(dev, &s->interrupt, 1);
+
+ s->input[0] = ADS_TEMP0; /* TEMP0 */
+ s->input[2] = ADS_VBAT; /* VBAT */
+ s->input[6] = ADS_VAUX; /* VAUX */
+ s->input[7] = ADS_TEMP1; /* TEMP1 */
+
+ /* We want absolute coordinates */
+ qemu_add_mouse_event_handler(ads7846_ts_event, s, 1,
+ "QEMU ADS7846-driven Touchscreen");
+
+ ads7846_int_update(s);
+
+ vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_ads7846, s);
+}
+
+static void ads7846_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
+
+ k->realize = ads7846_realize;
+ k->transfer = ads7846_transfer;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+}
+
+static const TypeInfo ads7846_info = {
+ .name = TYPE_ADS7846,
+ .parent = TYPE_SSI_PERIPHERAL,
+ .instance_size = sizeof(ADS7846State),
+ .class_init = ads7846_class_init,
+};
+
+static void ads7846_register_types(void)
+{
+ type_register_static(&ads7846_info);
+}
+
+type_init(ads7846_register_types)
softmmu_ss.add(files('hid.c'))
softmmu_ss.add(when: 'CONFIG_ADB', if_true: files('adb.c', 'adb-mouse.c', 'adb-kbd.c'))
+softmmu_ss.add(when: 'CONFIG_ADS7846', if_true: files('ads7846.c'))
softmmu_ss.add(when: 'CONFIG_LM832X', if_true: files('lm832x.c'))
softmmu_ss.add(when: 'CONFIG_PCKBD', if_true: files('pckbd.c'))
softmmu_ss.add(when: 'CONFIG_PL050', if_true: files('pl050.c'))
+++ /dev/null
-/*
- * QEMU MIPS address translation support
- *
- * 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 "qemu/osdep.h"
-#include "hw/mips/cpudevs.h"
-
-static int mips_um_ksegs;
-
-uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr)
-{
- return addr & 0x1fffffffll;
-}
-
-uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr)
-{
- return addr | ~0x7fffffffll;
-}
-
-uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr)
-{
- return addr | 0x40000000ll;
-}
-
-bool mips_um_ksegs_enabled(void)
-{
- return mips_um_ksegs;
-}
-
-void mips_um_ksegs_enable(void)
-{
- mips_um_ksegs = 1;
-}
#include "hw/loader.h"
#include "hw/loader-fit.h"
#include "hw/mips/cps.h"
-#include "hw/mips/cpudevs.h"
#include "hw/pci-host/xilinx-pcie.h"
#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
s = BOSTON(dev);
s->mach = machine;
- if (!cpu_supports_cps_smp(machine->cpu_type)) {
+ if (!cpu_type_supports_cps_smp(machine->cpu_type)) {
error_report("Boston requires CPUs which support CPS");
exit(1);
}
- is_64b = cpu_supports_isa(machine->cpu_type, ISA_MIPS64);
+ is_64b = cpu_type_supports_isa(machine->cpu_type, ISA_MIPS64);
object_initialize_child(OBJECT(machine), "cps", &s->cps, TYPE_MIPS_CPS);
object_property_set_str(OBJECT(&s->cps), "cpu-type", machine->cpu_type,
static bool cpu_mips_itu_supported(CPUMIPSState *env)
{
- bool is_mt = (env->CP0_Config5 & (1 << CP0C5_VP)) ||
- (env->CP0_Config3 & (1 << CP0C3_MT));
+ bool is_mt = (env->CP0_Config5 & (1 << CP0C5_VP)) || ase_mt_available(env);
return is_mt && !kvm_enabled();
}
#include "qemu/osdep.h"
#include "qemu/units.h"
+#include "qemu/bitops.h"
#include "qemu-common.h"
#include "qemu/datadir.h"
#include "cpu.h"
CPUMIPSState *env = &cpu->env;
CPUState *cs = CPU(cpu);
- env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
- ((smp_cpus * cs->nr_threads - 1) << CP0MVPC0_PTC);
+ if (ase_mt_available(env)) {
+ env->mvp->CP0_MVPConf0 = deposit32(env->mvp->CP0_MVPConf0,
+ CP0MVPC0_PTC, 8,
+ smp_cpus * cs->nr_threads - 1);
+ env->mvp->CP0_MVPConf0 = deposit32(env->mvp->CP0_MVPConf0,
+ CP0MVPC0_PVPE, 4, smp_cpus - 1);
+ }
}
static void main_cpu_reset(void *opaque)
static void mips_create_cpu(MachineState *ms, MaltaState *s,
qemu_irq *cbus_irq, qemu_irq *i8259_irq)
{
- if ((ms->smp.cpus > 1) && cpu_supports_cps_smp(ms->cpu_type)) {
+ if ((ms->smp.cpus > 1) && cpu_type_supports_cps_smp(ms->cpu_type)) {
create_cps(ms, s, cbus_irq, i8259_irq);
} else {
create_cpu_without_cps(ms, s, cbus_irq, i8259_irq);
loaderparams.initrd_filename = initrd_filename;
kernel_entry = load_kernel();
- if (!cpu_supports_isa(machine->cpu_type, ISA_NANOMIPS32)) {
+ if (!cpu_type_supports_isa(machine->cpu_type, ISA_NANOMIPS32)) {
write_bootloader(memory_region_get_ram_ptr(bios),
bootloader_run_addr, kernel_entry);
} else {
mips_ss = ss.source_set()
-mips_ss.add(files('addr.c', 'mips_int.c'))
+mips_ss.add(files('mips_int.c'))
mips_ss.add(when: 'CONFIG_FULOONG', if_true: files('fuloong2e.c'))
mips_ss.add(when: 'CONFIG_JAZZ', if_true: files('jazz.c'))
mips_ss.add(when: 'CONFIG_MALTA', if_true: files('gt64xxx_pci.c', 'malta.c'))
void pam_update(PAMMemoryRegion *pam, int idx, uint8_t val)
{
- assert(0 <= idx && idx <= 12);
+ assert(0 <= idx && idx < PAM_REGIONS_COUNT);
memory_region_set_enabled(&pam->alias[pam->current], false);
pam->current = (val >> ((!(idx & 1)) * 4)) & PAM_ATTR_MASK;
init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
mch->pci_address_space, &mch->pam_regions[0],
PAM_BIOS_BASE, PAM_BIOS_SIZE);
- for (i = 0; i < 12; ++i) {
+ for (i = 0; i < ARRAY_SIZE(mch->pam_regions) - 1; ++i) {
init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
mch->pci_address_space, &mch->pam_regions[i+1],
PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);
pci_register_bar(&s->dev, i, type, &s->bar[i]);
XEN_PT_LOG(&s->dev, "IO region %i registered (size=0x%08"PRIx64
- " base_addr=0x%08"PRIx64" type: %#x)\n",
+ " base_addr=0x%08"PRIx64" type: 0x%x)\n",
i, r->size, r->base_addr, type);
}
if (ranges_overlap(arg->addr, arg->size, r->addr, r->size)) {
XEN_PT_WARN(&s->dev,
"Overlapped to device [%02x:%02x.%d] Region: %i"
- " (addr: %#"FMT_PCIBUS", len: %#"FMT_PCIBUS")\n",
+ " (addr: 0x%"FMT_PCIBUS", len: 0x%"FMT_PCIBUS")\n",
pci_bus_num(bus), PCI_SLOT(d->devfn),
PCI_FUNC(d->devfn), i, r->addr, r->size);
arg->rc = true;
pci_for_each_device(pci_get_bus(d), pci_dev_bus_num(d),
xen_pt_check_bar_overlap, &args);
if (args.rc) {
- XEN_PT_WARN(d, "Region: %d (addr: %#"FMT_PCIBUS
- ", len: %#"FMT_PCIBUS") is overlapped.\n",
+ XEN_PT_WARN(d, "Region: %d (addr: 0x%"FMT_PCIBUS
+ ", len: 0x%"FMT_PCIBUS") is overlapped.\n",
bar, sec->offset_within_address_space,
int128_get64(sec->size));
}
/* register real device */
XEN_PT_LOG(d, "Assigning real physical device %02x:%02x.%d"
- " to devfn %#x\n",
+ " to devfn 0x%x\n",
s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function,
s->dev.devfn);
case PCI_EXP_TYPE_PCIE_BRIDGE:
case PCI_EXP_TYPE_RC_EC:
default:
- XEN_PT_ERR(d, "Unsupported device/port type %#x.\n", type);
+ XEN_PT_ERR(d, "Unsupported device/port type 0x%x.\n", type);
return -1;
}
}
case PCI_EXP_TYPE_PCIE_BRIDGE:
case PCI_EXP_TYPE_RC_EC:
default:
- XEN_PT_ERR(d, "Unsupported device/port type %#x.\n", type);
+ XEN_PT_ERR(d, "Unsupported device/port type 0x%x.\n", type);
return -1;
}
} else {
- XEN_PT_ERR(d, "Unsupported capability version %#x.\n", version);
+ XEN_PT_ERR(d, "Unsupported capability version 0x%x.\n", version);
return -1;
}
*ppirq = XEN_PT_UNASSIGNED_PIRQ;
} else {
XEN_PT_LOG(&s->dev, "requested pirq %d for MSI%s"
- " (vec: %#x, entry: %#x)\n",
+ " (vec: 0x%x, entry: 0x%x)\n",
*ppirq, is_msix ? "-X" : "", gvec, msix_entry);
}
}
msix_entry, table_base);
if (rc) {
XEN_PT_ERR(&s->dev,
- "Mapping of MSI%s (err: %i, vec: %#x, entry %#x)\n",
+ "Mapping of MSI%s (err: %i, vec: 0x%x, entry 0x%x)\n",
is_msix ? "-X" : "", errno, gvec, msix_entry);
return rc;
}
int rc = 0;
uint64_t table_addr = 0;
- XEN_PT_LOG(d, "Updating MSI%s with pirq %d gvec %#x gflags %#x"
- " (entry: %#x)\n",
+ XEN_PT_LOG(d, "Updating MSI%s with pirq %d gvec 0x%x gflags 0x%x"
+ " (entry: 0x%x)\n",
is_msix ? "-X" : "", pirq, gvec, gflags, msix_entry);
if (is_msix) {
}
if (is_binded) {
- XEN_PT_LOG(d, "Unbind MSI%s with pirq %d, gvec %#x\n",
+ XEN_PT_LOG(d, "Unbind MSI%s with pirq %d, gvec 0x%x\n",
is_msix ? "-X" : "", pirq, gvec);
rc = xc_domain_unbind_msi_irq(xen_xc, xen_domid, gvec, pirq, gflags);
if (rc) {
- XEN_PT_ERR(d, "Unbinding of MSI%s failed. (err: %d, pirq: %d, gvec: %#x)\n",
+ XEN_PT_ERR(d, "Unbinding of MSI%s failed. (err: %d, pirq: %d, gvec: 0x%x)\n",
is_msix ? "-X" : "", errno, pirq, gvec);
return rc;
}
}
if (id != PCI_CAP_ID_MSIX) {
- XEN_PT_ERR(d, "Invalid id %#x base %#x\n", id, base);
+ XEN_PT_ERR(d, "Invalid id 0x%x base 0x%x\n", id, base);
return -1;
}
XEN_PT_ERR(d, "Can't open /dev/mem: %s\n", strerror(errno));
goto error_out;
}
- XEN_PT_LOG(d, "table_off = %#x, total_entries = %d\n",
+ XEN_PT_LOG(d, "table_off = 0x%x, total_entries = %d\n",
table_off, total_entries);
msix->table_offset_adjust = table_off & 0x0fff;
msix->phys_iomem_base =
/* Definitions for MIPS CPU internal devices. */
-/* addr.c */
-uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr);
-uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr);
-uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr);
-bool mips_um_ksegs_enabled(void);
-void mips_um_ksegs_enable(void);
-
/* mips_int.c */
void cpu_mips_irq_init_cpu(MIPSCPU *cpu);
MemoryRegion *system_memory;
MemoryRegion *pci_address_space;
MemoryRegion *ram_memory;
- PAMMemoryRegion pam_regions[13];
+ PAMMemoryRegion pam_regions[PAM_REGIONS_COUNT];
MemoryRegion smram_region;
MemoryRegion smram, low_smram;
};
#define SMRAM_C_BASE_SEG_MASK ((uint8_t)0x7)
#define SMRAM_C_BASE_SEG ((uint8_t)0x2) /* hardwired to b010 */
+#define PAM_REGIONS_COUNT 13
+
typedef struct PAMMemoryRegion {
MemoryRegion alias[4]; /* index = PAM value */
unsigned current;
MemoryRegion *pci_address_space;
MemoryRegion *system_memory;
MemoryRegion *address_space_io;
- PAMMemoryRegion pam_regions[13];
+ PAMMemoryRegion pam_regions[PAM_REGIONS_COUNT];
MemoryRegion smram_region, open_high_smram;
MemoryRegion smram, low_smram, high_smram;
MemoryRegion tseg_blackhole, tseg_window;
IOCTL_IGNORE(TIOCSTOP)
#endif
-#ifdef CONFIG_KCOV
+#ifdef HAVE_SYS_KCOV_H
IOCTL(KCOV_ENABLE, 0, TYPE_NULL)
IOCTL(KCOV_DISABLE, 0, TYPE_NULL)
IOCTL(KCOV_INIT_TRACE, IOC_R, TYPE_ULONG)
#ifdef CONFIG_SENDFILE
#include <sys/sendfile.h>
#endif
-#ifdef CONFIG_KCOV
+#ifdef HAVE_SYS_KCOV_H
#include <sys/kcov.h>
#endif
#include <linux/if_alg.h>
#include <linux/rtc.h>
#include <sound/asound.h>
-#ifdef CONFIG_BTRFS
+#ifdef HAVE_BTRFS_H
#include <linux/btrfs.h>
#endif
#ifdef HAVE_DRM_H
#define TARGET_FS_IOC32_SETVERSION TARGET_IOW('v', 2, int)
/* btrfs ioctls */
-#ifdef CONFIG_BTRFS
+#ifdef HAVE_BTRFS_H
#define TARGET_BTRFS_IOC_SNAP_CREATE TARGET_IOWU(BTRFS_IOCTL_MAGIC, 1)
#define TARGET_BTRFS_IOC_SCAN_DEV TARGET_IOWU(BTRFS_IOCTL_MAGIC, 4)
#define TARGET_BTRFS_IOC_FORGET_DEV TARGET_IOWU(BTRFS_IOCTL_MAGIC, 5)
config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
+config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
+config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
+config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
+config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
+config_host_data.set('HAVE_SYS_SIGNAL_H', cc.has_header('sys/signal.h'))
ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
ERST
DEF("icount", HAS_ARG, QEMU_OPTION_icount, \
- "-icount [shift=N|auto][,align=on|off][,sleep=on|off,rr=record|replay,rrfile=<filename>,rrsnapshot=<snapshot>]\n" \
+ "-icount [shift=N|auto][,align=on|off][,sleep=on|off][,rr=record|replay,rrfile=<filename>[,rrsnapshot=<snapshot>]]\n" \
" enable virtual instruction counter with 2^N clock ticks per\n" \
" instruction, enable aligning the host and virtual clocks\n" \
- " or disable real time cpu sleeping\n", QEMU_ARCH_ALL)
+ " or disable real time cpu sleeping, and optionally enable\n" \
+ " record-and-replay mode\n", QEMU_ARCH_ALL)
SRST
-``-icount [shift=N|auto][,rr=record|replay,rrfile=filename,rrsnapshot=snapshot]``
+``-icount [shift=N|auto][,align=on|off][,sleep=on|off][,rr=record|replay,rrfile=filename[,rrsnapshot=snapshot]]``
Enable virtual instruction counter. The virtual cpu will execute one
instruction every 2^N ns of virtual time. If ``auto`` is specified
then the virtual cpu speed will be automatically adjusted to keep
virtual time within a few seconds of real time.
- When the virtual cpu is sleeping, the virtual time will advance at
- default speed unless ``sleep=on|off`` is specified. With
- ``sleep=on|off``, the virtual time will jump to the next timer
- deadline instantly whenever the virtual cpu goes to sleep mode and
- will not advance if no timer is enabled. This behavior give
- deterministic execution times from the guest point of view.
-
Note that while this option can give deterministic behavior, it does
not provide cycle accurate emulation. Modern CPUs contain
superscalar out of order cores with complex cache hierarchies. The
number of instructions executed often has little or no correlation
with actual performance.
+ When the virtual cpu is sleeping, the virtual time will advance at
+ default speed unless ``sleep=on`` is specified. With
+ ``sleep=on``, the virtual time will jump to the next timer
+ deadline instantly whenever the virtual cpu goes to sleep mode and
+ will not advance if no timer is enabled. This behavior gives
+ deterministic execution times from the guest point of view.
+ The default if icount is enabled is ``sleep=off``.
+ ``sleep=on`` cannot be used together with either ``shift=auto``
+ or ``align=on``.
+
``align=on`` will activate the delay algorithm which will try to
synchronise the host clock and the virtual clock. The goal is to
have a guest running at the real frequency imposed by the shift
``shift`` is ``auto``. Note: The sync algorithm will work for those
shift values for which the guest clock runs ahead of the host clock.
Typically this happens when the shift value is high (how high
- depends on the host machine).
-
- When ``rr`` option is specified deterministic record/replay is
- enabled. Replay log is written into filename file in record mode and
- read from this file in replay mode.
-
- Option rrsnapshot is used to create new vm snapshot named snapshot
- at the start of execution recording. In replay mode this option is
- used to load the initial VM state.
+ depends on the host machine). The default if icount is enabled
+ is ``align=off``.
+
+ When the ``rr`` option is specified deterministic record/replay is
+ enabled. The ``rrfile=`` option must also be provided to
+ specify the path to the replay log. In record mode data is written
+ to this file, and in replay mode it is read back.
+ If the ``rrsnapshot`` option is given then it specifies a VM snapshot
+ name. In record mode, a new VM snapshot with the given name is created
+ at the start of execution recording. In replay mode this option
+ specifies the snapshot name used to load the initial VM state.
ERST
DEF("watchdog", HAS_ARG, QEMU_OPTION_watchdog, \
# sev.c
kvm_sev_init(void) ""
-kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%zu"
-kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%zu"
+kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%zx"
+kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%zx"
kvm_sev_change_state(const char *old, const char *new) "%s -> %s"
kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p"
-kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len 0x%" PRIu64
+kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len 0x%" PRIx64
kvm_sev_launch_measurement(const char *value) "data %s"
kvm_sev_launch_finish(void) ""
kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d"
--- /dev/null
+/*
+ * QEMU MIPS address translation support
+ *
+ * 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 "qemu/osdep.h"
+#include "cpu.h"
+
+static int mips_um_ksegs;
+
+uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr)
+{
+ return addr & 0x1fffffffll;
+}
+
+uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr)
+{
+ return addr | ~0x7fffffffll;
+}
+
+uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr)
+{
+ return addr | 0x40000000ll;
+}
+
+bool mips_um_ksegs_enabled(void)
+{
+ return mips_um_ksegs;
+}
+
+void mips_um_ksegs_enable(void)
+{
+ mips_um_ksegs = 1;
+}
*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "cpu.h"
#include "internal.h"
#include "qemu/host-utils.h"
#include "exec/helper-proto.h"
#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-#include "exec/memop.h"
-#include "sysemu/kvm.h"
-#ifndef CONFIG_USER_ONLY
/* SMP helpers. */
static bool mips_vpe_is_wfi(MIPSCPU *c)
{
goto invalid;
}
/* We don't support VTLB entry smaller than target page */
- if ((maskbits + 12) < TARGET_PAGE_BITS) {
+ if ((maskbits + TARGET_PAGE_BITS_MIN) < TARGET_PAGE_BITS) {
goto invalid;
}
env->CP0_PageMask = mask << CP0PM_MASK;
invalid:
/* When invalid, set to default target page size. */
- env->CP0_PageMask = (~TARGET_PAGE_MASK >> 12) << CP0PM_MASK;
+ mask = (~TARGET_PAGE_MASK >> TARGET_PAGE_BITS_MIN);
+ env->CP0_PageMask = mask << CP0PM_MASK;
}
void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
old = env->CP0_EntryHi;
val = (arg1 & mask) | (old & ~mask);
env->CP0_EntryHi = val;
- if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+ if (ase_mt_available(env)) {
sync_c0_entryhi(env, env->current_tc);
}
/* If the ASID changes, flush qemu's TLB. */
}
return prev;
}
-#endif /* !CONFIG_USER_ONLY */
/* R6 Multi-threading */
-#ifndef CONFIG_USER_ONLY
target_ulong helper_dvp(CPUMIPSState *env)
{
CPUState *other_cs = first_cpu;
}
return prev;
}
-#endif /* !CONFIG_USER_ONLY */
#include "qemu/osdep.h"
#include "qemu/cutils.h"
+#include "qemu/qemu-print.h"
#include "qapi/error.h"
#include "cpu.h"
#include "internal.h"
#include "exec/exec-all.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-clock.h"
+#include "hw/semihosting/semihost.h"
+#include "qapi/qapi-commands-machine-target.h"
static void mips_cpu_set_pc(CPUState *cs, vaddr value)
{
}
/* MIPS-MT has the ability to halt the CPU. */
- if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+ if (ase_mt_available(env)) {
/*
* The QEMU model will issue an _WAKE request whenever the CPUs
* should be woken up.
return has_work;
}
+#include "translate_init.c.inc"
+
+/* TODO QOM'ify CPU reset and remove */
+static void cpu_state_reset(CPUMIPSState *env)
+{
+ CPUState *cs = env_cpu(env);
+
+ /* Reset registers to their default values */
+ env->CP0_PRid = env->cpu_model->CP0_PRid;
+ env->CP0_Config0 = env->cpu_model->CP0_Config0;
+#ifdef TARGET_WORDS_BIGENDIAN
+ env->CP0_Config0 |= (1 << CP0C0_BE);
+#endif
+ env->CP0_Config1 = env->cpu_model->CP0_Config1;
+ env->CP0_Config2 = env->cpu_model->CP0_Config2;
+ env->CP0_Config3 = env->cpu_model->CP0_Config3;
+ env->CP0_Config4 = env->cpu_model->CP0_Config4;
+ env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
+ env->CP0_Config5 = env->cpu_model->CP0_Config5;
+ env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
+ env->CP0_Config6 = env->cpu_model->CP0_Config6;
+ env->CP0_Config6_rw_bitmask = env->cpu_model->CP0_Config6_rw_bitmask;
+ env->CP0_Config7 = env->cpu_model->CP0_Config7;
+ env->CP0_Config7_rw_bitmask = env->cpu_model->CP0_Config7_rw_bitmask;
+ env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
+ << env->cpu_model->CP0_LLAddr_shift;
+ env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
+ env->SYNCI_Step = env->cpu_model->SYNCI_Step;
+ env->CCRes = env->cpu_model->CCRes;
+ env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
+ env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
+ env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
+ env->current_tc = 0;
+ env->SEGBITS = env->cpu_model->SEGBITS;
+ env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
+#if defined(TARGET_MIPS64)
+ if (env->cpu_model->insn_flags & ISA_MIPS3) {
+ env->SEGMask |= 3ULL << 62;
+ }
+#endif
+ env->PABITS = env->cpu_model->PABITS;
+ env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
+ env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
+ env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
+ env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
+ env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
+ env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
+ env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
+ env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
+ env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
+ env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
+ env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
+ env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
+ env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
+ env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
+ env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
+ env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
+ env->msair = env->cpu_model->MSAIR;
+ env->insn_flags = env->cpu_model->insn_flags;
+
+#if defined(CONFIG_USER_ONLY)
+ env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
+# ifdef TARGET_MIPS64
+ /* Enable 64-bit register mode. */
+ env->CP0_Status |= (1 << CP0St_PX);
+# endif
+# ifdef TARGET_ABI_MIPSN64
+ /* Enable 64-bit address mode. */
+ env->CP0_Status |= (1 << CP0St_UX);
+# endif
+ /*
+ * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
+ * hardware registers.
+ */
+ env->CP0_HWREna |= 0x0000000F;
+ if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+ env->CP0_Status |= (1 << CP0St_CU1);
+ }
+ if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
+ env->CP0_Status |= (1 << CP0St_MX);
+ }
+# if defined(TARGET_MIPS64)
+ /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
+ if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
+ (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
+ env->CP0_Status |= (1 << CP0St_FR);
+ }
+# endif
+#else /* !CONFIG_USER_ONLY */
+ if (env->hflags & MIPS_HFLAG_BMASK) {
+ /*
+ * If the exception was raised from a delay slot,
+ * come back to the jump.
+ */
+ env->CP0_ErrorEPC = (env->active_tc.PC
+ - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
+ } else {
+ env->CP0_ErrorEPC = env->active_tc.PC;
+ }
+ env->active_tc.PC = env->exception_base;
+ env->CP0_Random = env->tlb->nb_tlb - 1;
+ env->tlb->tlb_in_use = env->tlb->nb_tlb;
+ env->CP0_Wired = 0;
+ env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
+ env->CP0_EBase = (cs->cpu_index & 0x3FF);
+ if (mips_um_ksegs_enabled()) {
+ env->CP0_EBase |= 0x40000000;
+ } else {
+ env->CP0_EBase |= (int32_t)0x80000000;
+ }
+ if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
+ env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
+ }
+ env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
+ 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
+ env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
+ /*
+ * Vectored interrupts not implemented, timer on int 7,
+ * no performance counters.
+ */
+ env->CP0_IntCtl = 0xe0000000;
+ {
+ int i;
+
+ for (i = 0; i < 7; i++) {
+ env->CP0_WatchLo[i] = 0;
+ env->CP0_WatchHi[i] = 0x80000000;
+ }
+ env->CP0_WatchLo[7] = 0;
+ env->CP0_WatchHi[7] = 0;
+ }
+ /* Count register increments in debug mode, EJTAG version 1 */
+ env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
+
+ cpu_mips_store_count(env, 1);
+
+ if (ase_mt_available(env)) {
+ int i;
+
+ /* Only TC0 on VPE 0 starts as active. */
+ for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
+ env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
+ env->tcs[i].CP0_TCHalt = 1;
+ }
+ env->active_tc.CP0_TCHalt = 1;
+ cs->halted = 1;
+
+ if (cs->cpu_index == 0) {
+ /* VPE0 starts up enabled. */
+ env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
+ env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
+
+ /* TC0 starts up unhalted. */
+ cs->halted = 0;
+ env->active_tc.CP0_TCHalt = 0;
+ env->tcs[0].CP0_TCHalt = 0;
+ /* With thread 0 active. */
+ env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
+ env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
+ }
+ }
+
+ /*
+ * Configure default legacy segmentation control. We use this regardless of
+ * whether segmentation control is presented to the guest.
+ */
+ /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
+ env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
+ /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
+ env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
+ /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
+ env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
+ (2 << CP0SC_C);
+ /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
+ env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
+ (3 << CP0SC_C)) << 16;
+ /* USeg (seg4 0x40000000..0x7FFFFFFF) */
+ env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
+ (1 << CP0SC_EU) | (2 << CP0SC_C);
+ /* USeg (seg5 0x00000000..0x3FFFFFFF) */
+ env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
+ (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
+ /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
+ env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
+#endif /* !CONFIG_USER_ONLY */
+ if ((env->insn_flags & ISA_MIPS32R6) &&
+ (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
+ /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
+ env->CP0_Status |= (1 << CP0St_FR);
+ }
+
+ if (env->insn_flags & ISA_MIPS32R6) {
+ /* PTW = 1 */
+ env->CP0_PWSize = 0x40;
+ /* GDI = 12 */
+ /* UDI = 12 */
+ /* MDI = 12 */
+ /* PRI = 12 */
+ /* PTEI = 2 */
+ env->CP0_PWField = 0x0C30C302;
+ } else {
+ /* GDI = 0 */
+ /* UDI = 0 */
+ /* MDI = 0 */
+ /* PRI = 0 */
+ /* PTEI = 2 */
+ env->CP0_PWField = 0x02;
+ }
+
+ if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
+ /* microMIPS on reset when Config3.ISA is 3 */
+ env->hflags |= MIPS_HFLAG_M16;
+ }
+
+ /* MSA */
+ if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+ msa_reset(env);
+ }
+
+ compute_hflags(env);
+ restore_fp_status(env);
+ restore_pamask(env);
+ cs->exception_index = EXCP_NONE;
+
+ if (semihosting_get_argc()) {
+ /* UHI interface can be used to obtain argc and argv */
+ env->active_tc.gpr[4] = -1;
+ }
+}
+
static void mips_cpu_reset(DeviceState *dev)
{
CPUState *s = CPU(dev);
{
CPUState *cs = CPU(dev);
MIPSCPU *cpu = MIPS_CPU(dev);
+ CPUMIPSState *env = &cpu->env;
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(dev);
Error *local_err = NULL;
return;
}
- cpu_mips_realize_env(&cpu->env);
+ env->exception_base = (int32_t)0xBFC00000;
+
+#ifndef CONFIG_USER_ONLY
+ mmu_init(env, env->cpu_model);
+#endif
+ fpu_init(env, env->cpu_model);
+ mvp_init(env);
cpu_reset(cs);
qemu_init_vcpu(cs);
type_init(mips_cpu_register_types)
+static void mips_cpu_add_definition(gpointer data, gpointer user_data)
+{
+ ObjectClass *oc = data;
+ CpuDefinitionInfoList **cpu_list = user_data;
+ CpuDefinitionInfoList *entry;
+ CpuDefinitionInfo *info;
+ const char *typename;
+
+ typename = object_class_get_name(oc);
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strndup(typename,
+ strlen(typename) - strlen("-" TYPE_MIPS_CPU));
+ info->q_typename = g_strdup(typename);
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+ entry->next = *cpu_list;
+ *cpu_list = entry;
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+ CpuDefinitionInfoList *cpu_list = NULL;
+ GSList *list;
+
+ list = object_class_get_list(TYPE_MIPS_CPU, false);
+ g_slist_foreach(list, mips_cpu_add_definition, &cpu_list);
+ g_slist_free(list);
+
+ return cpu_list;
+}
+
/* Could be used by generic CPU object */
MIPSCPU *mips_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk)
{
return MIPS_CPU(cpu);
}
+
+bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask)
+{
+ return (env->cpu_model->insn_flags & isa_mask) != 0;
+}
+
+bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa)
+{
+ const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
+ return (mcc->cpu_def->insn_flags & isa) != 0;
+}
+
+bool cpu_type_supports_cps_smp(const char *cpu_type)
+{
+ const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
+ return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
+}
+
+void cpu_set_exception_base(int vp_index, target_ulong address)
+{
+ MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
+ vp->env.exception_base = address;
+}
#define MIPS_CPU_TYPE_NAME(model) model MIPS_CPU_TYPE_SUFFIX
#define CPU_RESOLVING_TYPE TYPE_MIPS_CPU
-bool cpu_supports_cps_smp(const char *cpu_type);
-bool cpu_supports_isa(const char *cpu_type, uint64_t isa);
+bool cpu_type_supports_cps_smp(const char *cpu_type);
+bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask);
+bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa);
+
+/* Check presence of multi-threading ASE implementation */
+static inline bool ase_mt_available(CPUMIPSState *env)
+{
+ return env->CP0_Config3 & (1 << CP0C3_MT);
+}
+
void cpu_set_exception_base(int vp_index, target_ulong address);
+/* addr.c */
+uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr);
+uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr);
+
+uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr);
+bool mips_um_ksegs_enabled(void);
+void mips_um_ksegs_enable(void);
+
/* mips_int.c */
void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level);
*/
#include "qemu/osdep.h"
-#include "qemu/main-loop.h"
#include "cpu.h"
#include "internal.h"
-#include "qemu/host-utils.h"
#include "exec/helper-proto.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
-#include "exec/memop.h"
-#include "sysemu/kvm.h"
#include "fpu/softfloat.h"
#define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
/* convert MIPS rounding mode in FCR31 to IEEE library */
-unsigned int ieee_rm[] = {
+const FloatRoundMode ieee_rm[4] = {
float_round_nearest_even,
float_round_to_zero,
float_round_up,
#include "exec/cpu_ldst.h"
#include "exec/log.h"
#include "hw/mips/cpudevs.h"
-#include "qapi/qapi-commands-machine-target.h"
enum {
TLBRET_XI = -6,
tlb_flush(env_cpu(env));
}
#endif
- if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+ if (ase_mt_available(env)) {
sync_c0_status(env, env, env->current_tc);
} else {
compute_hflags(env);
break;
}
}
- pw_pagemask = m >> 12;
- update_pagemask(env, pw_pagemask << 13, &pw_pagemask);
+ pw_pagemask = m >> TARGET_PAGE_BITS_MIN;
+ update_pagemask(env, pw_pagemask << CP0PM_MASK, &pw_pagemask);
pw_entryhi = (address & ~0x1fff) | (env->CP0_EntryHi & 0xFF);
{
target_ulong tmp_entryhi = env->CP0_EntryHi;
return physical;
}
}
+#endif /* !CONFIG_USER_ONLY */
static const char * const excp_names[EXCP_LAST + 1] = {
[EXCP_RESET] = "reset",
[EXCP_MSADIS] = "MSA disabled",
[EXCP_MSAFPE] = "MSA floating point",
};
-#endif
+
+static const char *mips_exception_name(int32_t exception)
+{
+ if (exception < 0 || exception > EXCP_LAST) {
+ return "unknown";
+ }
+ return excp_names[exception];
+}
target_ulong exception_resume_pc(CPUMIPSState *env)
{
bool update_badinstr = 0;
target_ulong offset;
int cause = -1;
- const char *name;
if (qemu_loglevel_mask(CPU_LOG_INT)
&& cs->exception_index != EXCP_EXT_INTERRUPT) {
- if (cs->exception_index < 0 || cs->exception_index > EXCP_LAST) {
- name = "unknown";
- } else {
- name = excp_names[cs->exception_index];
- }
-
qemu_log("%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx
" %s exception\n",
- __func__, env->active_tc.PC, env->CP0_EPC, name);
+ __func__, env->active_tc.PC, env->CP0_EPC,
+ mips_exception_name(cs->exception_index));
}
if (cs->exception_index == EXCP_EXT_INTERRUPT &&
(env->hflags & MIPS_HFLAG_DM)) {
{
CPUState *cs = env_cpu(env);
- qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n",
- __func__, exception, error_code);
+ qemu_log_mask(CPU_LOG_INT, "%s: %d (%s) %d\n",
+ __func__, exception, mips_exception_name(exception),
+ error_code);
cs->exception_index = exception;
env->error_code = error_code;
cpu_loop_exit_restore(cs, pc);
}
-
-static void mips_cpu_add_definition(gpointer data, gpointer user_data)
-{
- ObjectClass *oc = data;
- CpuDefinitionInfoList **cpu_list = user_data;
- CpuDefinitionInfoList *entry;
- CpuDefinitionInfo *info;
- const char *typename;
-
- typename = object_class_get_name(oc);
- info = g_malloc0(sizeof(*info));
- info->name = g_strndup(typename,
- strlen(typename) - strlen("-" TYPE_MIPS_CPU));
- info->q_typename = g_strdup(typename);
-
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = *cpu_list;
- *cpu_list = entry;
-}
-
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
-{
- CpuDefinitionInfoList *cpu_list = NULL;
- GSList *list;
-
- list = object_class_get_list(TYPE_MIPS_CPU, false);
- g_slist_foreach(list, mips_cpu_add_definition, &cpu_list);
- g_slist_free(list);
-
- return cpu_list;
-}
#ifndef MIPS_INTERNAL_H
#define MIPS_INTERNAL_H
+#include "exec/memattrs.h"
#include "fpu/softfloat-helpers.h"
/*
* CP0C0_MT field.
*/
enum mips_mmu_types {
- MMU_TYPE_NONE,
- MMU_TYPE_R4000,
- MMU_TYPE_RESERVED,
- MMU_TYPE_FMT,
+ MMU_TYPE_NONE = 0,
+ MMU_TYPE_R4000 = 1, /* Standard TLB */
+ MMU_TYPE_BAT = 2, /* Block Address Translation */
+ MMU_TYPE_FMT = 3, /* Fixed Mapping */
+ MMU_TYPE_DVF = 4, /* Dual VTLB and FTLB */
MMU_TYPE_R3000,
MMU_TYPE_R6000,
MMU_TYPE_R8000
void mips_tcg_init(void);
-/* TODO QOM'ify CPU reset and remove */
-void cpu_state_reset(CPUMIPSState *s);
-void cpu_mips_realize_env(CPUMIPSState *env);
-
/* cp0_timer.c */
uint32_t cpu_mips_get_count(CPUMIPSState *env);
void cpu_mips_store_count(CPUMIPSState *env, uint32_t value);
uint32_t float_class_s(uint32_t arg, float_status *fst);
uint64_t float_class_d(uint64_t arg, float_status *fst);
-extern unsigned int ieee_rm[];
+extern const FloatRoundMode ieee_rm[4];
+
void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask);
static inline void restore_rounding_mode(CPUMIPSState *env)
#include "internal.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
-#include "qemu/timer.h"
#include "sysemu/kvm.h"
#include "sysemu/kvm_int.h"
#include "sysemu/runstate.h"
-#include "sysemu/cpus.h"
#include "kvm_mips.h"
-#include "exec/memattrs.h"
#include "hw/boards.h"
#define DEBUG_KVM 0
CPUState *cs = CPU(cpu);
struct kvm_mips_interrupt intr;
- if (!kvm_enabled()) {
- return 0;
- }
+ assert(kvm_enabled());
intr.cpu = -1;
CPUState *dest_cs = CPU(cpu);
struct kvm_mips_interrupt intr;
- if (!kvm_enabled()) {
- return 0;
- }
+ assert(kvm_enabled());
intr.cpu = dest_cs->cpu_index;
mips_ss = ss.source_set()
mips_ss.add(files(
- 'cp0_helper.c',
'cpu.c',
'dsp_helper.c',
'fpu_helper.c',
mips_softmmu_ss = ss.source_set()
mips_softmmu_ss.add(files(
+ 'addr.c',
+ 'cp0_helper.c',
'cp0_timer.c',
'machine.c',
'mips-semi.c',
*/
#include "qemu/osdep.h"
-#include "qemu/main-loop.h"
#include "cpu.h"
#include "internal.h"
-#include "qemu/host-utils.h"
#include "exec/helper-proto.h"
#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
#include "exec/memop.h"
-#include "sysemu/kvm.h"
/*****************************************************************************/
#include "qemu/osdep.h"
#include "cpu.h"
#include "internal.h"
-#include "disas/disas.h"
-#include "exec/exec-all.h"
#include "tcg/tcg-op.h"
#include "exec/cpu_ldst.h"
-#include "hw/mips/cpudevs.h"
-
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
#include "hw/semihosting/semihost.h"
#endif
}
-#include "translate_init.c.inc"
-
-void cpu_mips_realize_env(CPUMIPSState *env)
-{
- env->exception_base = (int32_t)0xBFC00000;
-
-#ifndef CONFIG_USER_ONLY
- mmu_init(env, env->cpu_model);
-#endif
- fpu_init(env, env->cpu_model);
- mvp_init(env, env->cpu_model);
-}
-
-bool cpu_supports_cps_smp(const char *cpu_type)
-{
- const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
- return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
-}
-
-bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
-{
- const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
- return (mcc->cpu_def->insn_flags & isa) != 0;
-}
-
-void cpu_set_exception_base(int vp_index, target_ulong address)
-{
- MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
- vp->env.exception_base = address;
-}
-
-void cpu_state_reset(CPUMIPSState *env)
-{
- CPUState *cs = env_cpu(env);
-
- /* Reset registers to their default values */
- env->CP0_PRid = env->cpu_model->CP0_PRid;
- env->CP0_Config0 = env->cpu_model->CP0_Config0;
-#ifdef TARGET_WORDS_BIGENDIAN
- env->CP0_Config0 |= (1 << CP0C0_BE);
-#endif
- env->CP0_Config1 = env->cpu_model->CP0_Config1;
- env->CP0_Config2 = env->cpu_model->CP0_Config2;
- env->CP0_Config3 = env->cpu_model->CP0_Config3;
- env->CP0_Config4 = env->cpu_model->CP0_Config4;
- env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
- env->CP0_Config5 = env->cpu_model->CP0_Config5;
- env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
- env->CP0_Config6 = env->cpu_model->CP0_Config6;
- env->CP0_Config6_rw_bitmask = env->cpu_model->CP0_Config6_rw_bitmask;
- env->CP0_Config7 = env->cpu_model->CP0_Config7;
- env->CP0_Config7_rw_bitmask = env->cpu_model->CP0_Config7_rw_bitmask;
- env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
- << env->cpu_model->CP0_LLAddr_shift;
- env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
- env->SYNCI_Step = env->cpu_model->SYNCI_Step;
- env->CCRes = env->cpu_model->CCRes;
- env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
- env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
- env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
- env->current_tc = 0;
- env->SEGBITS = env->cpu_model->SEGBITS;
- env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
-#if defined(TARGET_MIPS64)
- if (env->cpu_model->insn_flags & ISA_MIPS3) {
- env->SEGMask |= 3ULL << 62;
- }
-#endif
- env->PABITS = env->cpu_model->PABITS;
- env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
- env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
- env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
- env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
- env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
- env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
- env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
- env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
- env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
- env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
- env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
- env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
- env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
- env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
- env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
- env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
- env->msair = env->cpu_model->MSAIR;
- env->insn_flags = env->cpu_model->insn_flags;
-
-#if defined(CONFIG_USER_ONLY)
- env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
-# ifdef TARGET_MIPS64
- /* Enable 64-bit register mode. */
- env->CP0_Status |= (1 << CP0St_PX);
-# endif
-# ifdef TARGET_ABI_MIPSN64
- /* Enable 64-bit address mode. */
- env->CP0_Status |= (1 << CP0St_UX);
-# endif
- /*
- * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
- * hardware registers.
- */
- env->CP0_HWREna |= 0x0000000F;
- if (env->CP0_Config1 & (1 << CP0C1_FP)) {
- env->CP0_Status |= (1 << CP0St_CU1);
- }
- if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
- env->CP0_Status |= (1 << CP0St_MX);
- }
-# if defined(TARGET_MIPS64)
- /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
- if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
- (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
- env->CP0_Status |= (1 << CP0St_FR);
- }
-# endif
-#else
- if (env->hflags & MIPS_HFLAG_BMASK) {
- /*
- * If the exception was raised from a delay slot,
- * come back to the jump.
- */
- env->CP0_ErrorEPC = (env->active_tc.PC
- - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
- } else {
- env->CP0_ErrorEPC = env->active_tc.PC;
- }
- env->active_tc.PC = env->exception_base;
- env->CP0_Random = env->tlb->nb_tlb - 1;
- env->tlb->tlb_in_use = env->tlb->nb_tlb;
- env->CP0_Wired = 0;
- env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
- env->CP0_EBase = (cs->cpu_index & 0x3FF);
- if (mips_um_ksegs_enabled()) {
- env->CP0_EBase |= 0x40000000;
- } else {
- env->CP0_EBase |= (int32_t)0x80000000;
- }
- if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
- env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
- }
- env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
- 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
- env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
- /*
- * Vectored interrupts not implemented, timer on int 7,
- * no performance counters.
- */
- env->CP0_IntCtl = 0xe0000000;
- {
- int i;
-
- for (i = 0; i < 7; i++) {
- env->CP0_WatchLo[i] = 0;
- env->CP0_WatchHi[i] = 0x80000000;
- }
- env->CP0_WatchLo[7] = 0;
- env->CP0_WatchHi[7] = 0;
- }
- /* Count register increments in debug mode, EJTAG version 1 */
- env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
-
- cpu_mips_store_count(env, 1);
-
- if (env->CP0_Config3 & (1 << CP0C3_MT)) {
- int i;
-
- /* Only TC0 on VPE 0 starts as active. */
- for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
- env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
- env->tcs[i].CP0_TCHalt = 1;
- }
- env->active_tc.CP0_TCHalt = 1;
- cs->halted = 1;
-
- if (cs->cpu_index == 0) {
- /* VPE0 starts up enabled. */
- env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
- env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
-
- /* TC0 starts up unhalted. */
- cs->halted = 0;
- env->active_tc.CP0_TCHalt = 0;
- env->tcs[0].CP0_TCHalt = 0;
- /* With thread 0 active. */
- env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
- env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
- }
- }
-
- /*
- * Configure default legacy segmentation control. We use this regardless of
- * whether segmentation control is presented to the guest.
- */
- /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
- env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
- /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
- env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
- /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
- env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
- (2 << CP0SC_C);
- /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
- env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
- (3 << CP0SC_C)) << 16;
- /* USeg (seg4 0x40000000..0x7FFFFFFF) */
- env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
- (1 << CP0SC_EU) | (2 << CP0SC_C);
- /* USeg (seg5 0x00000000..0x3FFFFFFF) */
- env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
- (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
- /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
- env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
-#endif
- if ((env->insn_flags & ISA_MIPS32R6) &&
- (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
- /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
- env->CP0_Status |= (1 << CP0St_FR);
- }
-
- if (env->insn_flags & ISA_MIPS32R6) {
- /* PTW = 1 */
- env->CP0_PWSize = 0x40;
- /* GDI = 12 */
- /* UDI = 12 */
- /* MDI = 12 */
- /* PRI = 12 */
- /* PTEI = 2 */
- env->CP0_PWField = 0x0C30C302;
- } else {
- /* GDI = 0 */
- /* UDI = 0 */
- /* MDI = 0 */
- /* PRI = 0 */
- /* PTEI = 2 */
- env->CP0_PWField = 0x02;
- }
-
- if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
- /* microMIPS on reset when Config3.ISA is 3 */
- env->hflags |= MIPS_HFLAG_M16;
- }
-
- /* MSA */
- if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
- msa_reset(env);
- }
-
- compute_hflags(env);
- restore_fp_status(env);
- restore_pamask(env);
- cs->exception_index = EXCP_NONE;
-
- if (semihosting_get_argc()) {
- /* UHI interface can be used to obtain argc and argv */
- env->active_tc.gpr[4] = -1;
- }
-}
-
void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
target_ulong *data)
{
.mmu_type = MMU_TYPE_R4000,
},
{
- .name = "Loongson-3A4000",
+ .name = "Loongson-3A4000", /* GS464V-based */
.CP0_PRid = 0x14C000,
/* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */
.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
.CP1_fcr31_rw_bitmask = 0xFF83FFFF,
.SEGBITS = 48,
.PABITS = 48,
- .insn_flags = CPU_LOONGSON3A,
+ .insn_flags = CPU_LOONGSON3A | ASE_MSA,
.mmu_type = MMU_TYPE_R4000,
},
{
memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu));
}
-static void mvp_init (CPUMIPSState *env, const mips_def_t *def)
+static void mvp_init(CPUMIPSState *env)
{
env->mvp = g_malloc0(sizeof(CPUMIPSMVPContext));
+ if (!ase_mt_available(env)) {
+ return;
+ }
+
/* MVPConf1 implemented, TLB sharable, no gating storage support,
programmable cache partitioning implemented, number of allocatable
and shareable TLB entries, MVP has allocatable TCs, 2 VPEs