Compare commits

..

7 Commits

Author SHA1 Message Date
Gerd Hoffmann
6e24ee0c1e ps2: reset queue in ps2_reset_keyboard
When the guest resets the keyboard also clear the queue.  It is highly
unlikely that the guest is still interested in the events stuck in the
queue, and it avoids confusing the guest in case the queue is full and
the ACK can't be queued up.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1372583
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170606112105.13331-4-kraxel@redhat.com
2017-06-23 11:51:50 +02:00
Gerd Hoffmann
954ee55bd5 ps2: add ps2_reset_queue
Factor out ps2 queue reset to a separate function.
No functional change.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170606112105.13331-3-kraxel@redhat.com
2017-06-23 11:51:50 +02:00
Gerd Hoffmann
8498bb8d2e ps2: add and use PS2State typedef
Cleanup: Create and use a typedef for PS2State and stop passing void
pointers.  No functional change.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170606112105.13331-2-kraxel@redhat.com
2017-06-23 11:51:50 +02:00
Gerd Hoffmann
85970a627f sdl2: add assert to make coverity happy
There is a loop a few lines up counting consoles and setting
sdl2_num_outputs accordingly, so con ptr can't be NULL there.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170621122234.12751-1-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2017-06-23 11:50:46 +02:00
Alexander Graf
51dbea77a2 hid: Reset kbd modifiers on reset
When resetting the keyboard, we need to reset not just the pending keystrokes,
but also any pending modifiers. Otherwise there's a race when we're getting
reset while running an escape sequence (modifier 0x100).

Cc: qemu-stable@nongnu.org
Signed-off-by: Alexander Graf <agraf@suse.de>
Message-id: 1498117295-162030-1-git-send-email-agraf@suse.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2017-06-23 11:50:05 +02:00
Alexander Graf
77b0359bf4 input: Decrement queue count on kbd delay
Delays in the input layer are special cased input events. Every input
event is accounted for in a global intput queue count. The special cased
delays however did not get removed from the queue, leading to queue overruns
and thus silent key drops after typing quite a few characters.

Signed-off-by: Alexander Graf <agraf@suse.de>
Message-id: 1498117318-162102-1-git-send-email-agraf@suse.de
Fixes: be1a7176 ("input: add support for kbd delays")
Cc: qemu-stable@nongnu.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2017-06-23 11:49:44 +02:00
Gerd Hoffmann
d3b787fa7d keymaps: add tracing
Drop commented debug logging, add trace points instead.

Also cleanup parser code a bit, the key name is copied into a new
variable instead of patching the input line, that way we can log
the unmodified line.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170606134736.26080-1-kraxel@redhat.com
2017-06-23 11:47:59 +02:00
18 changed files with 512 additions and 1186 deletions

2
configure vendored
View File

@@ -6066,7 +6066,7 @@ case "$target_name" in
;;
m68k)
bflt="yes"
gdb_xml_files="cf-core.xml cf-fp.xml m68k-fp.xml"
gdb_xml_files="cf-core.xml cf-fp.xml"
;;
microblaze|microblazeel)
TARGET_ARCH=microblaze

View File

@@ -1,21 +0,0 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2008 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. -->
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.coldfire.fp">
<reg name="fp0" bitsize="96" type="float" group="float"/>
<reg name="fp1" bitsize="96" type="float" group="float"/>
<reg name="fp2" bitsize="96" type="float" group="float"/>
<reg name="fp3" bitsize="96" type="float" group="float"/>
<reg name="fp4" bitsize="96" type="float" group="float"/>
<reg name="fp5" bitsize="96" type="float" group="float"/>
<reg name="fp6" bitsize="96" type="float" group="float"/>
<reg name="fp7" bitsize="96" type="float" group="float"/>
<reg name="fpcontrol" bitsize="32" group="float"/>
<reg name="fpstatus" bitsize="32" group="float"/>,
<reg name="fpiaddr" bitsize="32" type="code_ptr" group="float"/>
</feature>

View File

@@ -487,6 +487,7 @@ void hid_reset(HIDState *hs)
memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
hs->kbd.keys = 0;
hs->kbd.modifiers = 0;
break;
case HID_MOUSE:
case HID_TABLET:

View File

@@ -85,12 +85,12 @@ typedef struct {
int rptr, wptr, count;
} PS2Queue;
typedef struct {
struct PS2State {
PS2Queue queue;
int32_t write_cmd;
void (*update_irq)(void *, int);
void *update_arg;
} PS2State;
};
typedef struct {
PS2State common;
@@ -551,9 +551,17 @@ static uint8_t translate_table[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
};
void ps2_queue(void *opaque, int b)
static void ps2_reset_queue(PS2State *s)
{
PS2Queue *q = &s->queue;
q->rptr = 0;
q->wptr = 0;
q->count = 0;
}
void ps2_queue(PS2State *s, int b)
{
PS2State *s = (PS2State *)opaque;
PS2Queue *q = &s->queue;
if (q->count >= PS2_QUEUE_SIZE - 1)
@@ -692,13 +700,12 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
}
}
uint32_t ps2_read_data(void *opaque)
uint32_t ps2_read_data(PS2State *s)
{
PS2State *s = (PS2State *)opaque;
PS2Queue *q;
int val, index;
trace_ps2_read_data(opaque);
trace_ps2_read_data(s);
q = &s->queue;
if (q->count == 0) {
/* NOTE: if no data left, we return the last keyboard one
@@ -733,6 +740,7 @@ static void ps2_reset_keyboard(PS2KbdState *s)
trace_ps2_reset_keyboard(s);
s->scan_enabled = 1;
s->scancode_set = 2;
ps2_reset_queue(&s->common);
ps2_set_ledstate(s, 0);
}
@@ -1081,12 +1089,8 @@ void ps2_write_mouse(void *opaque, int val)
static void ps2_common_reset(PS2State *s)
{
PS2Queue *q;
s->write_cmd = -1;
q = &s->queue;
q->rptr = 0;
q->wptr = 0;
q->count = 0;
ps2_reset_queue(s);
s->update_irq(s->update_arg, 0);
}

View File

@@ -39,43 +39,21 @@
/* #define DEBUG_SMC */
#define APPLESMC_DEFAULT_IOBASE 0x300
/* data port used by Apple SMC */
#define APPLESMC_DATA_PORT 0x0
/* command/status port used by Apple SMC */
#define APPLESMC_CMD_PORT 0x4
#define APPLESMC_NR_PORTS 32
enum {
APPLESMC_DATA_PORT = 0x00,
APPLESMC_CMD_PORT = 0x04,
APPLESMC_ERR_PORT = 0x1e,
APPLESMC_NUM_PORTS = 0x20,
};
enum {
APPLESMC_READ_CMD = 0x10,
APPLESMC_WRITE_CMD = 0x11,
APPLESMC_GET_KEY_BY_INDEX_CMD = 0x12,
APPLESMC_GET_KEY_TYPE_CMD = 0x13,
};
enum {
APPLESMC_ST_CMD_DONE = 0x00,
APPLESMC_ST_DATA_READY = 0x01,
APPLESMC_ST_BUSY = 0x02,
APPLESMC_ST_ACK = 0x04,
APPLESMC_ST_NEW_CMD = 0x08,
};
enum {
APPLESMC_ST_1E_CMD_INTRUPTED = 0x80,
APPLESMC_ST_1E_STILL_BAD_CMD = 0x81,
APPLESMC_ST_1E_BAD_CMD = 0x82,
APPLESMC_ST_1E_NOEXIST = 0x84,
APPLESMC_ST_1E_WRITEONLY = 0x85,
APPLESMC_ST_1E_READONLY = 0x86,
APPLESMC_ST_1E_BAD_INDEX = 0xb8,
};
#define APPLESMC_READ_CMD 0x10
#define APPLESMC_WRITE_CMD 0x11
#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
#define APPLESMC_GET_KEY_TYPE_CMD 0x13
#ifdef DEBUG_SMC
#define smc_debug(...) fprintf(stderr, "AppleSMC: " __VA_ARGS__)
#else
#define smc_debug(...) do { } while (0)
#define smc_debug(...) do { } while(0)
#endif
static char default_osk[64] = "This is a dummy key. Enter the real key "
@@ -96,17 +74,15 @@ struct AppleSMCState {
MemoryRegion io_data;
MemoryRegion io_cmd;
MemoryRegion io_err;
uint32_t iobase;
uint8_t cmd;
uint8_t status;
uint8_t status_1e;
uint8_t last_ret;
char key[4];
uint8_t key[4];
uint8_t read_pos;
uint8_t data_len;
uint8_t data_pos;
uint8_t data[255];
uint8_t charactic[4];
char *osk;
QLIST_HEAD(, AppleSMCData) data_def;
};
@@ -115,138 +91,89 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
AppleSMCState *s = opaque;
uint8_t status = s->status & 0x0f;
smc_debug("CMD received: 0x%02x\n", (uint8_t)val);
switch (val) {
case APPLESMC_READ_CMD:
/* did last command run through OK? */
if (status == APPLESMC_ST_CMD_DONE || status == APPLESMC_ST_NEW_CMD) {
s->cmd = val;
s->status = APPLESMC_ST_NEW_CMD | APPLESMC_ST_ACK;
} else {
smc_debug("ERROR: previous command interrupted!\n");
s->status = APPLESMC_ST_NEW_CMD;
s->status_1e = APPLESMC_ST_1E_CMD_INTRUPTED;
}
break;
default:
smc_debug("UNEXPECTED CMD 0x%02x\n", (uint8_t)val);
s->status = APPLESMC_ST_NEW_CMD;
s->status_1e = APPLESMC_ST_1E_BAD_CMD;
smc_debug("CMD Write B: %#x = %#x\n", addr, val);
switch(val) {
case APPLESMC_READ_CMD:
s->status = 0x0c;
break;
}
s->cmd = val;
s->read_pos = 0;
s->data_pos = 0;
}
static struct AppleSMCData *applesmc_find_key(AppleSMCState *s)
static void applesmc_fill_data(AppleSMCState *s)
{
struct AppleSMCData *d;
QLIST_FOREACH(d, &s->data_def, node) {
if (!memcmp(d->key, s->key, 4)) {
return d;
smc_debug("Key matched (%s Len=%d Data=%s)\n", d->key,
d->len, d->data);
memcpy(s->data, d->data, d->len);
return;
}
}
return NULL;
}
static void applesmc_io_data_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
AppleSMCState *s = opaque;
struct AppleSMCData *d;
smc_debug("DATA received: 0x%02x\n", (uint8_t)val);
switch (s->cmd) {
case APPLESMC_READ_CMD:
if ((s->status & 0x0f) == APPLESMC_ST_CMD_DONE) {
break;
}
if (s->read_pos < 4) {
s->key[s->read_pos] = val;
s->status = APPLESMC_ST_ACK;
} else if (s->read_pos == 4) {
d = applesmc_find_key(s);
if (d != NULL) {
memcpy(s->data, d->data, d->len);
s->data_len = d->len;
smc_debug("DATA Write B: %#x = %#x\n", addr, val);
switch(s->cmd) {
case APPLESMC_READ_CMD:
if(s->read_pos < 4) {
s->key[s->read_pos] = val;
s->status = 0x04;
} else if(s->read_pos == 4) {
s->data_len = val;
s->status = 0x05;
s->data_pos = 0;
s->status = APPLESMC_ST_ACK | APPLESMC_ST_DATA_READY;
s->status_1e = APPLESMC_ST_CMD_DONE; /* clear on valid key */
} else {
smc_debug("READ_CMD: key '%c%c%c%c' not found!\n",
s->key[0], s->key[1], s->key[2], s->key[3]);
s->status = APPLESMC_ST_CMD_DONE;
s->status_1e = APPLESMC_ST_1E_NOEXIST;
smc_debug("Key = %c%c%c%c Len = %d\n", s->key[0],
s->key[1], s->key[2], s->key[3], val);
applesmc_fill_data(s);
}
}
s->read_pos++;
break;
default:
s->status = APPLESMC_ST_CMD_DONE;
s->status_1e = APPLESMC_ST_1E_STILL_BAD_CMD;
}
}
static void applesmc_io_err_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
smc_debug("ERR_CODE received: 0x%02x, ignoring!\n", (uint8_t)val);
/* NOTE: writing to the error port not supported! */
}
static uint64_t applesmc_io_data_read(void *opaque, hwaddr addr, unsigned size)
{
AppleSMCState *s = opaque;
switch (s->cmd) {
case APPLESMC_READ_CMD:
if (!(s->status & APPLESMC_ST_DATA_READY)) {
s->read_pos++;
break;
}
if (s->data_pos < s->data_len) {
s->last_ret = s->data[s->data_pos];
smc_debug("READ '%c%c%c%c'[%d] = %02x\n",
s->key[0], s->key[1], s->key[2], s->key[3],
s->data_pos, s->last_ret);
s->data_pos++;
if (s->data_pos == s->data_len) {
s->status = APPLESMC_ST_CMD_DONE;
smc_debug("READ '%c%c%c%c' Len=%d complete!\n",
s->key[0], s->key[1], s->key[2], s->key[3],
s->data_len);
} else {
s->status = APPLESMC_ST_ACK | APPLESMC_ST_DATA_READY;
}
}
break;
default:
s->status = APPLESMC_ST_CMD_DONE;
s->status_1e = APPLESMC_ST_1E_STILL_BAD_CMD;
}
smc_debug("DATA sent: 0x%02x\n", s->last_ret);
return s->last_ret;
}
static uint64_t applesmc_io_cmd_read(void *opaque, hwaddr addr, unsigned size)
static uint64_t applesmc_io_data_read(void *opaque, hwaddr addr1,
unsigned size)
{
AppleSMCState *s = opaque;
uint8_t retval = 0;
switch(s->cmd) {
case APPLESMC_READ_CMD:
if(s->data_pos < s->data_len) {
retval = s->data[s->data_pos];
smc_debug("READ_DATA[%d] = %#hhx\n", s->data_pos,
retval);
s->data_pos++;
if(s->data_pos == s->data_len) {
s->status = 0x00;
smc_debug("EOF\n");
} else
s->status = 0x05;
}
}
smc_debug("DATA Read b: %#x = %#x\n", addr1, retval);
return retval;
}
static uint64_t applesmc_io_cmd_read(void *opaque, hwaddr addr1, unsigned size)
{
AppleSMCState *s = opaque;
smc_debug("CMD sent: 0x%02x\n", s->status);
smc_debug("CMD Read B: %#x\n", addr1);
return s->status;
}
static uint64_t applesmc_io_err_read(void *opaque, hwaddr addr, unsigned size)
{
AppleSMCState *s = opaque;
/* NOTE: read does not clear the 1e status */
smc_debug("ERR_CODE sent: 0x%02x\n", s->status_1e);
return s->status_1e;
}
static void applesmc_add_key(AppleSMCState *s, const char *key,
int len, const char *data)
{
@@ -269,9 +196,6 @@ static void qdev_applesmc_isa_reset(DeviceState *dev)
QLIST_FOREACH_SAFE(d, &s->data_def, node, next) {
QLIST_REMOVE(d, node);
}
s->status = 0x00;
s->status_1e = 0x00;
s->last_ret = 0x00;
applesmc_add_key(s, "REV ", 6, "\x01\x13\x0f\x00\x00\x03");
applesmc_add_key(s, "OSK0", 32, s->osk);
@@ -301,35 +225,20 @@ static const MemoryRegionOps applesmc_cmd_io_ops = {
},
};
static const MemoryRegionOps applesmc_err_io_ops = {
.write = applesmc_io_err_write,
.read = applesmc_io_err_read,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
},
};
static void applesmc_isa_realize(DeviceState *dev, Error **errp)
{
AppleSMCState *s = APPLE_SMC(dev);
memory_region_init_io(&s->io_data, OBJECT(s), &applesmc_data_io_ops, s,
"applesmc-data", 1);
"applesmc-data", 4);
isa_register_ioport(&s->parent_obj, &s->io_data,
s->iobase + APPLESMC_DATA_PORT);
memory_region_init_io(&s->io_cmd, OBJECT(s), &applesmc_cmd_io_ops, s,
"applesmc-cmd", 1);
"applesmc-cmd", 4);
isa_register_ioport(&s->parent_obj, &s->io_cmd,
s->iobase + APPLESMC_CMD_PORT);
memory_region_init_io(&s->io_err, OBJECT(s), &applesmc_err_io_ops, s,
"applesmc-err", 1);
isa_register_ioport(&s->parent_obj, &s->io_err,
s->iobase + APPLESMC_ERR_PORT);
if (!s->osk || (strlen(s->osk) != 64)) {
fprintf(stderr, "WARNING: Using AppleSMC with invalid key\n");
s->osk = default_osk;

View File

@@ -36,8 +36,8 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg);
void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg);
void ps2_write_mouse(void *, int val);
void ps2_write_keyboard(void *, int val);
uint32_t ps2_read_data(void *);
void ps2_queue(void *, int b);
uint32_t ps2_read_data(PS2State *s);
void ps2_queue(PS2State *s, int b);
void ps2_keyboard_set_translation(void *opaque, int mode);
void ps2_mouse_fake_event(void *opaque);

View File

@@ -76,6 +76,7 @@ typedef struct PixelFormat PixelFormat;
typedef struct PostcopyDiscardState PostcopyDiscardState;
typedef struct Property Property;
typedef struct PropertyInfo PropertyInfo;
typedef struct PS2State PS2State;
typedef struct QEMUBH QEMUBH;
typedef struct QemuConsole QemuConsole;
typedef struct QEMUFile QEMUFile;

View File

@@ -49,8 +49,6 @@ static void m68k_cpu_reset(CPUState *s)
M68kCPU *cpu = M68K_CPU(s);
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu);
CPUM68KState *env = &cpu->env;
floatx80 nan = floatx80_default_nan(NULL);
int i;
mcc->parent_reset(s);
@@ -59,12 +57,7 @@ static void m68k_cpu_reset(CPUState *s)
env->sr = 0x2700;
#endif
m68k_switch_sp(env);
for (i = 0; i < 8; i++) {
env->fregs[i].d = nan;
}
cpu_m68k_set_fpcr(env, 0);
env->fpsr = 0;
/* ??? FP regs should be initialized to NaN. */
cpu_m68k_set_ccr(env, 0);
/* TODO: We should set PC from the interrupt vector. */
env->pc = 0;

View File

@@ -55,15 +55,8 @@
#define EXCP_UNINITIALIZED 15
#define EXCP_TRAP0 32 /* User trap #0. */
#define EXCP_TRAP15 47 /* User trap #15. */
#define EXCP_FP_BSUN 48 /* Branch Set on Unordered */
#define EXCP_FP_INEX 49 /* Inexact result */
#define EXCP_FP_DZ 50 /* Divide by Zero */
#define EXCP_FP_UNFL 51 /* Underflow */
#define EXCP_FP_OPERR 52 /* Operand Error */
#define EXCP_FP_OVFL 53 /* Overflow */
#define EXCP_FP_SNAN 54 /* Signaling Not-A-Number */
#define EXCP_FP_UNIMP 55 /* Unimplemented Data type */
#define EXCP_UNSUPPORTED 61
#define EXCP_ICE 13
#define EXCP_RTE 0x100
#define EXCP_HALT_INSN 0x101
@@ -71,8 +64,6 @@
#define NB_MMU_MODES 2
#define TARGET_INSN_START_EXTRA_WORDS 1
typedef CPU_LDoubleU FPReg;
typedef struct CPUM68KState {
uint32_t dregs[8];
uint32_t aregs[8];
@@ -91,8 +82,8 @@ typedef struct CPUM68KState {
uint32_t cc_c; /* either 0/1, unused, or computed from cc_n and cc_v */
uint32_t cc_z; /* == 0 or unused */
FPReg fregs[8];
FPReg fp_result;
float64 fregs[8];
float64 fp_result;
uint32_t fpcr;
uint32_t fpsr;
float_status fp_status;
@@ -171,7 +162,6 @@ int cpu_m68k_signal_handler(int host_signum, void *pinfo,
void *puc);
uint32_t cpu_m68k_get_ccr(CPUM68KState *env);
void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t);
void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val);
/* Instead of computing the condition codes after each m68k instruction,
@@ -216,43 +206,6 @@ typedef enum {
#define M68K_SSP 0
#define M68K_USP 1
#define M68K_FPIAR_SHIFT 0
#define M68K_FPIAR (1 << M68K_FPIAR_SHIFT)
#define M68K_FPSR_SHIFT 1
#define M68K_FPSR (1 << M68K_FPSR_SHIFT)
#define M68K_FPCR_SHIFT 2
#define M68K_FPCR (1 << M68K_FPCR_SHIFT)
/* Floating-Point Status Register */
/* Condition Code */
#define FPSR_CC_MASK 0x0f000000
#define FPSR_CC_A 0x01000000 /* Not-A-Number */
#define FPSR_CC_I 0x02000000 /* Infinity */
#define FPSR_CC_Z 0x04000000 /* Zero */
#define FPSR_CC_N 0x08000000 /* Negative */
/* Quotient */
#define FPSR_QT_MASK 0x00ff0000
/* Floating-Point Control Register */
/* Rounding mode */
#define FPCR_RND_MASK 0x0030
#define FPCR_RND_N 0x0000
#define FPCR_RND_Z 0x0010
#define FPCR_RND_M 0x0020
#define FPCR_RND_P 0x0030
/* Rounding precision */
#define FPCR_PREC_MASK 0x00c0
#define FPCR_PREC_X 0x0000
#define FPCR_PREC_S 0x0040
#define FPCR_PREC_D 0x0080
#define FPCR_PREC_U 0x00c0
#define FPCR_EXCP_MASK 0xff00
/* CACR fields are implementation defined, but some bits are common. */
#define M68K_CACR_EUSP 0x10
@@ -269,6 +222,8 @@ typedef enum {
void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector);
void m68k_switch_sp(CPUM68KState *env);
#define M68K_FPCR_PREC (1 << 6)
void do_m68k_semihosting(CPUM68KState *env, int nr);
/* There are 4 ColdFire core ISA revisions: A, A+, B and C.
@@ -346,7 +301,8 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc,
{
*pc = env->pc;
*cs_base = 0;
*flags = (env->sr & SR_S) /* Bit 13 */
*flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */
| (env->sr & SR_S) /* Bit 13 */
| ((env->macsr >> 4) & 0xf); /* Bits 0-3 */
}

View File

@@ -21,186 +21,92 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/helper-proto.h"
#include "exec/exec-all.h"
int32_t HELPER(reds32)(CPUM68KState *env, FPReg *val)
uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val)
{
return floatx80_to_int32(val->d, &env->fp_status);
return float64_to_int32(val, &env->fp_status);
}
float32 HELPER(redf32)(CPUM68KState *env, FPReg *val)
float32 HELPER(f64_to_f32)(CPUM68KState *env, float64 val)
{
return floatx80_to_float32(val->d, &env->fp_status);
return float64_to_float32(val, &env->fp_status);
}
void HELPER(exts32)(CPUM68KState *env, FPReg *res, int32_t val)
float64 HELPER(i32_to_f64)(CPUM68KState *env, uint32_t val)
{
res->d = int32_to_floatx80(val, &env->fp_status);
return int32_to_float64(val, &env->fp_status);
}
void HELPER(extf32)(CPUM68KState *env, FPReg *res, float32 val)
float64 HELPER(f32_to_f64)(CPUM68KState *env, float32 val)
{
res->d = float32_to_floatx80(val, &env->fp_status);
return float32_to_float64(val, &env->fp_status);
}
void HELPER(extf64)(CPUM68KState *env, FPReg *res, float64 val)
float64 HELPER(iround_f64)(CPUM68KState *env, float64 val)
{
res->d = float64_to_floatx80(val, &env->fp_status);
return float64_round_to_int(val, &env->fp_status);
}
float64 HELPER(redf64)(CPUM68KState *env, FPReg *val)
float64 HELPER(itrunc_f64)(CPUM68KState *env, float64 val)
{
return floatx80_to_float64(val->d, &env->fp_status);
return float64_trunc_to_int(val, &env->fp_status);
}
void HELPER(firound)(CPUM68KState *env, FPReg *res, FPReg *val)
float64 HELPER(sqrt_f64)(CPUM68KState *env, float64 val)
{
res->d = floatx80_round_to_int(val->d, &env->fp_status);
return float64_sqrt(val, &env->fp_status);
}
static void m68k_restore_precision_mode(CPUM68KState *env)
float64 HELPER(abs_f64)(float64 val)
{
switch (env->fpcr & FPCR_PREC_MASK) {
case FPCR_PREC_X: /* extended */
set_floatx80_rounding_precision(80, &env->fp_status);
break;
case FPCR_PREC_S: /* single */
set_floatx80_rounding_precision(32, &env->fp_status);
break;
case FPCR_PREC_D: /* double */
set_floatx80_rounding_precision(64, &env->fp_status);
break;
case FPCR_PREC_U: /* undefined */
default:
break;
return float64_abs(val);
}
float64 HELPER(chs_f64)(float64 val)
{
return float64_chs(val);
}
float64 HELPER(add_f64)(CPUM68KState *env, float64 a, float64 b)
{
return float64_add(a, b, &env->fp_status);
}
float64 HELPER(sub_f64)(CPUM68KState *env, float64 a, float64 b)
{
return float64_sub(a, b, &env->fp_status);
}
float64 HELPER(mul_f64)(CPUM68KState *env, float64 a, float64 b)
{
return float64_mul(a, b, &env->fp_status);
}
float64 HELPER(div_f64)(CPUM68KState *env, float64 a, float64 b)
{
return float64_div(a, b, &env->fp_status);
}
float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b)
{
/* ??? This may incorrectly raise exceptions. */
/* ??? Should flush denormals to zero. */
float64 res;
res = float64_sub(a, b, &env->fp_status);
if (float64_is_quiet_nan(res, &env->fp_status)) {
/* +/-inf compares equal against itself, but sub returns nan. */
if (!float64_is_quiet_nan(a, &env->fp_status)
&& !float64_is_quiet_nan(b, &env->fp_status)) {
res = float64_zero;
if (float64_lt_quiet(a, res, &env->fp_status)) {
res = float64_chs(res);
}
}
}
return res;
}
static void cf_restore_precision_mode(CPUM68KState *env)
uint32_t HELPER(compare_f64)(CPUM68KState *env, float64 val)
{
if (env->fpcr & FPCR_PREC_S) { /* single */
set_floatx80_rounding_precision(32, &env->fp_status);
} else { /* double */
set_floatx80_rounding_precision(64, &env->fp_status);
}
}
static void restore_rounding_mode(CPUM68KState *env)
{
switch (env->fpcr & FPCR_RND_MASK) {
case FPCR_RND_N: /* round to nearest */
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
break;
case FPCR_RND_Z: /* round to zero */
set_float_rounding_mode(float_round_to_zero, &env->fp_status);
break;
case FPCR_RND_M: /* round toward minus infinity */
set_float_rounding_mode(float_round_down, &env->fp_status);
break;
case FPCR_RND_P: /* round toward positive infinity */
set_float_rounding_mode(float_round_up, &env->fp_status);
break;
}
}
void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val)
{
env->fpcr = val & 0xffff;
if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
cf_restore_precision_mode(env);
} else {
m68k_restore_precision_mode(env);
}
restore_rounding_mode(env);
}
void HELPER(fitrunc)(CPUM68KState *env, FPReg *res, FPReg *val)
{
int rounding_mode = get_float_rounding_mode(&env->fp_status);
set_float_rounding_mode(float_round_to_zero, &env->fp_status);
res->d = floatx80_round_to_int(val->d, &env->fp_status);
set_float_rounding_mode(rounding_mode, &env->fp_status);
}
void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val)
{
cpu_m68k_set_fpcr(env, val);
}
void HELPER(fsqrt)(CPUM68KState *env, FPReg *res, FPReg *val)
{
res->d = floatx80_sqrt(val->d, &env->fp_status);
}
void HELPER(fabs)(CPUM68KState *env, FPReg *res, FPReg *val)
{
res->d = floatx80_abs(val->d);
}
void HELPER(fchs)(CPUM68KState *env, FPReg *res, FPReg *val)
{
res->d = floatx80_chs(val->d);
}
void HELPER(fadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
{
res->d = floatx80_add(val0->d, val1->d, &env->fp_status);
}
void HELPER(fsub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
{
res->d = floatx80_sub(val1->d, val0->d, &env->fp_status);
}
void HELPER(fmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
{
res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
}
void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
{
res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
}
static int float_comp_to_cc(int float_compare)
{
switch (float_compare) {
case float_relation_equal:
return FPSR_CC_Z;
case float_relation_less:
return FPSR_CC_N;
case float_relation_unordered:
return FPSR_CC_A;
case float_relation_greater:
return 0;
default:
g_assert_not_reached();
}
}
void HELPER(fcmp)(CPUM68KState *env, FPReg *val0, FPReg *val1)
{
int float_compare;
float_compare = floatx80_compare(val1->d, val0->d, &env->fp_status);
env->fpsr = (env->fpsr & ~FPSR_CC_MASK) | float_comp_to_cc(float_compare);
}
void HELPER(ftst)(CPUM68KState *env, FPReg *val)
{
uint32_t cc = 0;
if (floatx80_is_neg(val->d)) {
cc |= FPSR_CC_N;
}
if (floatx80_is_any_nan(val->d)) {
cc |= FPSR_CC_A;
} else if (floatx80_is_infinity(val->d)) {
cc |= FPSR_CC_I;
} else if (floatx80_is_zero(val->d)) {
cc |= FPSR_CC_Z;
}
env->fpsr = (env->fpsr & ~FPSR_CC_MASK) | cc;
return float64_compare_quiet(val, float64_zero, &env->fp_status);
}

View File

@@ -73,84 +73,28 @@ void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf)
g_slist_free(list);
}
static int cf_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
{
if (n < 8) {
float_status s;
stfq_p(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
stfq_p(mem_buf, env->fregs[n]);
return 8;
}
switch (n) {
case 8: /* fpcontrol */
stl_be_p(mem_buf, env->fpcr);
return 4;
case 9: /* fpstatus */
stl_be_p(mem_buf, env->fpsr);
return 4;
case 10: /* fpiar, not implemented */
if (n < 11) {
/* FP control registers (not implemented) */
memset(mem_buf, 0, 4);
return 4;
}
return 0;
}
static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
{
if (n < 8) {
float_status s;
env->fregs[n].d = float64_to_floatx80(ldfq_p(mem_buf), &s);
env->fregs[n] = ldfq_p(mem_buf);
return 8;
}
switch (n) {
case 8: /* fpcontrol */
cpu_m68k_set_fpcr(env, ldl_p(mem_buf));
return 4;
case 9: /* fpstatus */
env->fpsr = ldl_p(mem_buf);
return 4;
case 10: /* fpiar, not implemented */
return 4;
}
return 0;
}
static int m68k_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
{
if (n < 8) {
stw_be_p(mem_buf, env->fregs[n].l.upper);
memset(mem_buf + 2, 0, 2);
stq_be_p(mem_buf + 4, env->fregs[n].l.lower);
return 12;
}
switch (n) {
case 8: /* fpcontrol */
stl_be_p(mem_buf, env->fpcr);
return 4;
case 9: /* fpstatus */
stl_be_p(mem_buf, env->fpsr);
return 4;
case 10: /* fpiar, not implemented */
memset(mem_buf, 0, 4);
return 4;
}
return 0;
}
static int m68k_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
{
if (n < 8) {
env->fregs[n].l.upper = lduw_be_p(mem_buf);
env->fregs[n].l.lower = ldq_be_p(mem_buf + 4);
return 12;
}
switch (n) {
case 8: /* fpcontrol */
cpu_m68k_set_fpcr(env, ldl_p(mem_buf));
return 4;
case 9: /* fpstatus */
env->fpsr = ldl_p(mem_buf);
return 4;
case 10: /* fpiar, not implemented */
if (n < 11) {
/* FP control registers (not implemented) */
return 4;
}
return 0;
@@ -182,11 +126,8 @@ void m68k_cpu_init_gdb(M68kCPU *cpu)
CPUM68KState *env = &cpu->env;
if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
gdb_register_coprocessor(cs, cf_fpu_gdb_get_reg, cf_fpu_gdb_set_reg,
gdb_register_coprocessor(cs, fpu_gdb_get_reg, fpu_gdb_set_reg,
11, "cf-fp.xml", 18);
} else if (m68k_feature(env, M68K_FEATURE_FPU)) {
gdb_register_coprocessor(cs, m68k_fpu_gdb_get_reg,
m68k_fpu_gdb_set_reg, 11, "m68k-fp.xml", 18);
}
/* TODO: Add [E]MAC registers. */
}

View File

@@ -12,29 +12,21 @@ DEF_HELPER_3(movec, void, env, i32, i32)
DEF_HELPER_4(cas2w, void, env, i32, i32, i32)
DEF_HELPER_4(cas2l, void, env, i32, i32, i32)
#define dh_alias_fp ptr
#define dh_ctype_fp FPReg *
#define dh_is_signed_fp dh_is_signed_ptr
DEF_HELPER_3(exts32, void, env, fp, s32)
DEF_HELPER_3(extf32, void, env, fp, f32)
DEF_HELPER_3(extf64, void, env, fp, f64)
DEF_HELPER_2(redf32, f32, env, fp)
DEF_HELPER_2(redf64, f64, env, fp)
DEF_HELPER_2(reds32, s32, env, fp)
DEF_HELPER_3(firound, void, env, fp, fp)
DEF_HELPER_3(fitrunc, void, env, fp, fp)
DEF_HELPER_3(fsqrt, void, env, fp, fp)
DEF_HELPER_3(fabs, void, env, fp, fp)
DEF_HELPER_3(fchs, void, env, fp, fp)
DEF_HELPER_4(fadd, void, env, fp, fp, fp)
DEF_HELPER_4(fsub, void, env, fp, fp, fp)
DEF_HELPER_4(fmul, void, env, fp, fp, fp)
DEF_HELPER_4(fdiv, void, env, fp, fp, fp)
DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
DEF_HELPER_FLAGS_2(ftst, TCG_CALL_NO_RWG, void, env, fp)
DEF_HELPER_2(f64_to_i32, f32, env, f64)
DEF_HELPER_2(f64_to_f32, f32, env, f64)
DEF_HELPER_2(i32_to_f64, f64, env, i32)
DEF_HELPER_2(f32_to_f64, f64, env, f32)
DEF_HELPER_2(iround_f64, f64, env, f64)
DEF_HELPER_2(itrunc_f64, f64, env, f64)
DEF_HELPER_2(sqrt_f64, f64, env, f64)
DEF_HELPER_1(abs_f64, f64, f64)
DEF_HELPER_1(chs_f64, f64, f64)
DEF_HELPER_3(add_f64, f64, env, f64, f64)
DEF_HELPER_3(sub_f64, f64, env, f64, f64)
DEF_HELPER_3(mul_f64, f64, env, f64, f64)
DEF_HELPER_3(div_f64, f64, env, f64, f64)
DEF_HELPER_3(sub_cmp_f64, f64, env, f64, f64)
DEF_HELPER_2(compare_f64, i32, env, f64)
DEF_HELPER_3(mac_move, void, env, i32, i32)
DEF_HELPER_3(macmulf, i64, env, i32, i32)

View File

@@ -1,3 +1,4 @@
DEFF64(FP_RESULT, fp_result)
DEFO32(PC, pc)
DEFO32(SR, sr)
DEFO32(CC_OP, cc_op)

File diff suppressed because it is too large Load Diff

View File

@@ -256,6 +256,7 @@ static void qemu_input_queue_process(void *opaque)
item = QTAILQ_FIRST(queue);
g_assert(item->type == QEMU_INPUT_QUEUE_DELAY);
QTAILQ_REMOVE(queue, item, node);
queue_count--;
g_free(item);
while (!QTAILQ_EMPTY(queue)) {

View File

@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "keymaps.h"
#include "sysemu/sysemu.h"
#include "trace.h"
static int get_keysym(const name2keysym_t *table,
const char *name)
@@ -71,18 +72,14 @@ static void add_to_key_range(struct key_range **krp, int code) {
static void add_keysym(char *line, int keysym, int keycode, kbd_layout_t *k) {
if (keysym < MAX_NORMAL_KEYCODE) {
/* fprintf(stderr,"Setting keysym %s (%d) to %d\n",
line, keysym, keycode); */
trace_keymap_add("normal", keysym, keycode, line);
k->keysym2keycode[keysym] = keycode;
} else {
if (k->extra_count >= MAX_EXTRA_COUNT) {
fprintf(stderr, "Warning: Could not assign keysym %s (0x%x)"
" because of memory constraints.\n", line, keysym);
} else {
#if 0
fprintf(stderr, "Setting %d: %d,%d\n",
k->extra_count, keysym, keycode);
#endif
trace_keymap_add("extra", keysym, keycode, line);
k->keysym2keycode_extra[k->extra_count].
keysym = keysym;
k->keysym2keycode_extra[k->extra_count].
@@ -99,9 +96,11 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
FILE *f;
char * filename;
char line[1024];
char keyname[64];
int len;
filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language);
trace_keymap_parse(filename);
f = filename ? fopen(filename, "r") : NULL;
g_free(filename);
if (!f) {
@@ -130,18 +129,21 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
if (!strncmp(line, "include ", 8)) {
parse_keyboard_layout(table, line + 8, k);
} else {
char *end_of_keysym = line;
while (*end_of_keysym != 0 && *end_of_keysym != ' ') {
end_of_keysym++;
int offset = 0;
while (line[offset] != 0 &&
line[offset] != ' ' &&
offset < sizeof(keyname) - 1) {
keyname[offset] = line[offset];
offset++;
}
if (*end_of_keysym) {
keyname[offset] = 0;
if (strlen(keyname)) {
int keysym;
*end_of_keysym = 0;
keysym = get_keysym(table, line);
keysym = get_keysym(table, keyname);
if (keysym == 0) {
/* fprintf(stderr, "Warning: unknown keysym %s\n", line);*/
} else {
const char *rest = end_of_keysym + 1;
const char *rest = line + offset + 1;
int keycode = strtol(rest, NULL, 0);
if (strstr(rest, "numlock")) {
@@ -165,10 +167,10 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
if (strstr(rest, "addupper")) {
char *c;
for (c = line; *c; c++) {
for (c = keyname; *c; c++) {
*c = qemu_toupper(*c);
}
keysym = get_keysym(table, line);
keysym = get_keysym(table, keyname);
if (keysym) {
add_keysym(line, keysym,
keycode | SCANCODE_SHIFT, k);
@@ -194,6 +196,7 @@ int keysym2scancode(void *kbd_layout, int keysym)
kbd_layout_t *k = kbd_layout;
if (keysym < MAX_NORMAL_KEYCODE) {
if (k->keysym2keycode[keysym] == 0) {
trace_keymap_unmapped(keysym);
fprintf(stderr, "Warning: no scancode found for keysym %d\n",
keysym);
}

View File

@@ -804,6 +804,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
sdl2_console = g_new0(struct sdl2_console, sdl2_num_outputs);
for (i = 0; i < sdl2_num_outputs; i++) {
QemuConsole *con = qemu_console_lookup_by_index(i);
assert(con != NULL);
if (!qemu_console_is_graphic(con)) {
sdl2_console[i].hidden = true;
}

View File

@@ -46,3 +46,8 @@ qemu_spice_create_primary_surface(int qid, uint32_t sid, void *surface, int asyn
qemu_spice_destroy_primary_surface(int qid, uint32_t sid, int async) "%d sid=%u async=%d"
qemu_spice_wakeup(uint32_t qid) "%d"
qemu_spice_create_update(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "lr %d -> %d, tb -> %d -> %d"
# ui/keymaps.c
keymap_parse(const char *file) "file %s"
keymap_add(const char *type, int sym, int code, const char *line) "%-6s sym=0x%04x code=0x%04x (line: %s)"
keymap_unmapped(int sym) "sym=0x%04x"